001
014
015 package com.liferay.portal.struts;
016
017 import com.liferay.portal.NoSuchLayoutException;
018 import com.liferay.portal.kernel.log.Log;
019 import com.liferay.portal.kernel.log.LogFactoryUtil;
020 import com.liferay.portal.kernel.util.ArrayUtil;
021 import com.liferay.portal.kernel.util.HttpUtil;
022 import com.liferay.portal.kernel.util.ParamUtil;
023 import com.liferay.portal.kernel.util.StringBundler;
024 import com.liferay.portal.kernel.util.Validator;
025 import com.liferay.portal.kernel.util.WebKeys;
026 import com.liferay.portal.model.Group;
027 import com.liferay.portal.model.Layout;
028 import com.liferay.portal.model.LayoutConstants;
029 import com.liferay.portal.model.LayoutTypePortlet;
030 import com.liferay.portal.model.PortletConstants;
031 import com.liferay.portal.model.impl.VirtualLayout;
032 import com.liferay.portal.security.permission.ActionKeys;
033 import com.liferay.portal.security.permission.PermissionChecker;
034 import com.liferay.portal.service.GroupLocalServiceUtil;
035 import com.liferay.portal.service.LayoutLocalServiceUtil;
036 import com.liferay.portal.service.permission.LayoutPermissionUtil;
037 import com.liferay.portal.theme.ThemeDisplay;
038 import com.liferay.portal.util.PortalUtil;
039 import com.liferay.portlet.PortletURLFactoryUtil;
040 import com.liferay.portlet.sites.util.SitesUtil;
041
042 import javax.portlet.PortletMode;
043 import javax.portlet.PortletRequest;
044 import javax.portlet.PortletURL;
045 import javax.portlet.WindowState;
046
047 import javax.servlet.http.HttpServletRequest;
048 import javax.servlet.http.HttpServletResponse;
049
050 import org.apache.struts.action.Action;
051 import org.apache.struts.action.ActionForm;
052 import org.apache.struts.action.ActionForward;
053 import org.apache.struts.action.ActionMapping;
054
055
058 public abstract class FindAction extends Action {
059
060 public FindAction() {
061 _portletIds = initPortletIds();
062
063 if (ArrayUtil.isEmpty(_portletIds)) {
064 throw new RuntimeException("Portlet IDs cannot be null or empty");
065 }
066 }
067
068 @Override
069 public ActionForward execute(
070 ActionMapping actionMapping, ActionForm actionForm,
071 HttpServletRequest request, HttpServletResponse response)
072 throws Exception {
073
074 ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
075 WebKeys.THEME_DISPLAY);
076
077 try {
078 long plid = ParamUtil.getLong(request, "p_l_id");
079 long primaryKey = ParamUtil.getLong(
080 request, getPrimaryKeyParameterName());
081
082 long groupId = ParamUtil.getLong(
083 request, "groupId", themeDisplay.getScopeGroupId());
084
085 if (primaryKey > 0) {
086 try {
087 long overrideGroupId = getGroupId(primaryKey);
088
089 if (overrideGroupId > 0) {
090 groupId = overrideGroupId;
091 }
092 }
093 catch (Exception e) {
094 if (_log.isDebugEnabled()) {
095 _log.debug(e, e);
096 }
097 }
098 }
099
100 Object[] plidAndPortletId = getPlidAndPortletId(
101 themeDisplay, groupId, plid, _portletIds);
102
103 plid = (Long)plidAndPortletId[0];
104
105 setTargetGroup(request, groupId, plid);
106
107 String portletId = (String)plidAndPortletId[1];
108
109 PortletURL portletURL = PortletURLFactoryUtil.create(
110 request, portletId, plid, PortletRequest.RENDER_PHASE);
111
112 portletURL.setParameter(
113 "struts_action", getStrutsAction(request, portletId));
114
115 boolean inheritRedirect = ParamUtil.getBoolean(
116 request, "inheritRedirect");
117
118 String redirect = null;
119
120 if (inheritRedirect) {
121 String noSuchEntryRedirect = ParamUtil.getString(
122 request, "noSuchEntryRedirect");
123
124 redirect = HttpUtil.getParameter(
125 noSuchEntryRedirect, "redirect", false);
126
127 redirect = HttpUtil.decodeURL(redirect);
128 }
129 else {
130 redirect = ParamUtil.getString(request, "redirect");
131 }
132
133 if (Validator.isNotNull(redirect)) {
134 portletURL.setParameter("redirect", redirect);
135 }
136
137 setPrimaryKeyParameter(portletURL, primaryKey);
138
139 portletURL.setPortletMode(PortletMode.VIEW);
140 portletURL.setWindowState(WindowState.NORMAL);
141
142 portletURL = processPortletURL(request, portletURL);
143
144 response.sendRedirect(portletURL.toString());
145
146 return null;
147 }
148 catch (Exception e) {
149 String noSuchEntryRedirect = ParamUtil.getString(
150 request, "noSuchEntryRedirect");
151
152 noSuchEntryRedirect = PortalUtil.escapeRedirect(
153 noSuchEntryRedirect);
154
155 if (Validator.isNotNull(noSuchEntryRedirect) &&
156 (e instanceof NoSuchLayoutException)) {
157
158 response.sendRedirect(noSuchEntryRedirect);
159 }
160 else {
161 PortalUtil.sendError(e, request, response);
162 }
163
164 return null;
165 }
166 }
167
168 protected static Object[] fetchPlidAndPortletId(
169 PermissionChecker permissionChecker, long groupId,
170 String[] portletIds)
171 throws Exception {
172
173 for (String portletId : portletIds) {
174 long plid = PortalUtil.getPlidFromPortletId(groupId, portletId);
175
176 if (plid == LayoutConstants.DEFAULT_PLID) {
177 continue;
178 }
179
180 Layout layout = LayoutLocalServiceUtil.getLayout(plid);
181
182 if (!LayoutPermissionUtil.contains(
183 permissionChecker, layout, ActionKeys.VIEW)) {
184
185 continue;
186 }
187
188 LayoutTypePortlet layoutTypePortlet =
189 (LayoutTypePortlet)layout.getLayoutType();
190
191 portletId = getPortletId(layoutTypePortlet, portletId);
192
193 return new Object[] {plid, portletId};
194 }
195
196 return null;
197 }
198
199 protected static Object[] getPlidAndPortletId(
200 ThemeDisplay themeDisplay, long groupId, long plid,
201 String[] portletIds)
202 throws Exception {
203
204 if ((plid != LayoutConstants.DEFAULT_PLID) &&
205 (groupId == themeDisplay.getScopeGroupId())) {
206
207 try {
208 Layout layout = LayoutLocalServiceUtil.getLayout(plid);
209
210 LayoutTypePortlet layoutTypePortlet =
211 (LayoutTypePortlet)layout.getLayoutType();
212
213 for (String portletId : portletIds) {
214 if (!layoutTypePortlet.hasPortletId(portletId, false) ||
215 !LayoutPermissionUtil.contains(
216 themeDisplay.getPermissionChecker(), layout,
217 ActionKeys.VIEW)) {
218
219 continue;
220 }
221
222 portletId = getPortletId(layoutTypePortlet, portletId);
223
224 return new Object[] {plid, portletId};
225 }
226 }
227 catch (NoSuchLayoutException nsle) {
228 }
229 }
230
231 Object[] plidAndPortletId = fetchPlidAndPortletId(
232 themeDisplay.getPermissionChecker(), groupId, portletIds);
233
234 if ((plidAndPortletId == null) &&
235 SitesUtil.isUserGroupLayoutSetViewable(
236 themeDisplay.getPermissionChecker(),
237 themeDisplay.getScopeGroup())) {
238
239 plidAndPortletId = fetchPlidAndPortletId(
240 themeDisplay.getPermissionChecker(),
241 themeDisplay.getScopeGroupId(), portletIds);
242 }
243
244 if (plidAndPortletId != null) {
245 return plidAndPortletId;
246 }
247
248 StringBundler sb = new StringBundler(portletIds.length * 2 + 5);
249
250 sb.append("{groupId=");
251 sb.append(groupId);
252 sb.append(", plid=");
253 sb.append(plid);
254
255 for (String portletId : portletIds) {
256 sb.append(", portletId=");
257 sb.append(portletId);
258 }
259
260 sb.append("}");
261
262 throw new NoSuchLayoutException(sb.toString());
263 }
264
265 protected static String getPortletId(
266 LayoutTypePortlet layoutTypePortlet, String portletId) {
267
268 for (String curPortletId : layoutTypePortlet.getPortletIds()) {
269 String curRootPortletId = PortletConstants.getRootPortletId(
270 curPortletId);
271
272 if (portletId.equals(curRootPortletId)) {
273 return curPortletId;
274 }
275 }
276
277 return portletId;
278 }
279
280 protected abstract long getGroupId(long primaryKey) throws Exception;
281
282 protected abstract String getPrimaryKeyParameterName();
283
284 protected abstract String getStrutsAction(
285 HttpServletRequest request, String portletId);
286
287 protected abstract String[] initPortletIds();
288
289 protected PortletURL processPortletURL(
290 HttpServletRequest request, PortletURL portletURL)
291 throws Exception {
292
293 return portletURL;
294 }
295
296 protected void setPrimaryKeyParameter(
297 PortletURL portletURL, long primaryKey)
298 throws Exception {
299
300 portletURL.setParameter(
301 getPrimaryKeyParameterName(), String.valueOf(primaryKey));
302 }
303
304 protected void setTargetGroup(
305 HttpServletRequest request, long groupId, long plid)
306 throws Exception {
307
308 ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
309 WebKeys.THEME_DISPLAY);
310
311 PermissionChecker permissionChecker =
312 themeDisplay.getPermissionChecker();
313
314 Group group = GroupLocalServiceUtil.getGroup(groupId);
315 Layout layout = LayoutLocalServiceUtil.getLayout(plid);
316
317 if ((groupId == layout.getGroupId()) ||
318 (group.getParentGroupId() == layout.getGroupId()) ||
319 (layout.isPrivateLayout() &&
320 !SitesUtil.isUserGroupLayoutSetViewable(
321 permissionChecker, layout.getGroup()))) {
322
323 return;
324 }
325
326 layout = new VirtualLayout(layout, group);
327
328 request.setAttribute(WebKeys.LAYOUT, layout);
329 }
330
331 private static Log _log = LogFactoryUtil.getLog(FindAction.class);
332
333 private String[] _portletIds;
334
335 }