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