001
014
015 package com.liferay.portlet.sites.util;
016
017 import com.liferay.portal.events.EventsProcessorUtil;
018 import com.liferay.portal.kernel.exception.PortalException;
019 import com.liferay.portal.kernel.exception.SystemException;
020 import com.liferay.portal.kernel.language.LanguageUtil;
021 import com.liferay.portal.kernel.lar.PortletDataHandlerKeys;
022 import com.liferay.portal.kernel.lar.UserIdStrategy;
023 import com.liferay.portal.kernel.util.GetterUtil;
024 import com.liferay.portal.kernel.util.ParamUtil;
025 import com.liferay.portal.kernel.util.PropsKeys;
026 import com.liferay.portal.kernel.util.Validator;
027 import com.liferay.portal.model.Group;
028 import com.liferay.portal.model.Layout;
029 import com.liferay.portal.model.LayoutSet;
030 import com.liferay.portal.model.LayoutSetPrototype;
031 import com.liferay.portal.model.LayoutTypePortlet;
032 import com.liferay.portal.model.impl.LayoutTypePortletImpl;
033 import com.liferay.portal.security.auth.PrincipalException;
034 import com.liferay.portal.security.permission.ActionKeys;
035 import com.liferay.portal.security.permission.PermissionChecker;
036 import com.liferay.portal.service.GroupServiceUtil;
037 import com.liferay.portal.service.LayoutLocalServiceUtil;
038 import com.liferay.portal.service.LayoutServiceUtil;
039 import com.liferay.portal.service.LayoutSetLocalServiceUtil;
040 import com.liferay.portal.service.LayoutSetPrototypeLocalServiceUtil;
041 import com.liferay.portal.service.ServiceContext;
042 import com.liferay.portal.service.ServiceContextFactory;
043 import com.liferay.portal.service.permission.GroupPermissionUtil;
044 import com.liferay.portal.service.permission.LayoutPermissionUtil;
045 import com.liferay.portal.theme.PortletDisplay;
046 import com.liferay.portal.theme.ThemeDisplay;
047 import com.liferay.portal.util.LayoutSettings;
048 import com.liferay.portal.util.PortalUtil;
049 import com.liferay.portal.util.PortletKeys;
050 import com.liferay.portal.util.WebKeys;
051
052 import java.io.File;
053 import java.io.InputStream;
054
055 import java.util.Date;
056 import java.util.LinkedHashMap;
057 import java.util.List;
058 import java.util.Locale;
059 import java.util.Map;
060
061 import javax.portlet.ActionRequest;
062 import javax.portlet.ActionResponse;
063 import javax.portlet.PortletURL;
064 import javax.portlet.RenderRequest;
065 import javax.portlet.RenderResponse;
066
067 import javax.servlet.http.HttpServletRequest;
068 import javax.servlet.http.HttpServletResponse;
069
070
075 public class SitesUtil {
076
077 public static void addPortletBreadcrumbEntries(
078 Group group, String pagesName, PortletURL redirectURL,
079 HttpServletRequest request, RenderResponse renderResponse)
080 throws Exception {
081
082 ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
083 com.liferay.portal.kernel.util.WebKeys.THEME_DISPLAY);
084
085 PortletDisplay portletDisplay = themeDisplay.getPortletDisplay();
086
087 String portletName = portletDisplay.getPortletName();
088
089 if ((renderResponse == null) ||
090 portletName.equals(PortletKeys.GROUP_PAGES) ||
091 portletName.equals(PortletKeys.MY_PAGES)) {
092
093 return;
094 }
095
096 Locale locale = themeDisplay.getLocale();
097
098 if (group.isLayoutPrototype()) {
099 PortalUtil.addPortletBreadcrumbEntry(
100 request, LanguageUtil.get(locale, "page-template"), null);
101
102 PortalUtil.addPortletBreadcrumbEntry(
103 request, group.getDescriptiveName(), redirectURL.toString());
104 }
105 else {
106 PortalUtil.addPortletBreadcrumbEntry(
107 request, group.getDescriptiveName(), null);
108 }
109
110 if (!group.isLayoutPrototype()) {
111 PortalUtil.addPortletBreadcrumbEntry(
112 request, LanguageUtil.get(locale, pagesName),
113 redirectURL.toString());
114 }
115 }
116
117 public static void applyLayoutSetPrototypes(
118 Group group, long publicLayoutSetPrototypeId,
119 long privateLayoutSetPrototypeId, ServiceContext serviceContext)
120 throws Exception {
121
122 Group sourceGroup = null;
123
124 if (publicLayoutSetPrototypeId > 0) {
125 LayoutSetPrototype layoutSetPrototype =
126 LayoutSetPrototypeLocalServiceUtil.getLayoutSetPrototype(
127 publicLayoutSetPrototypeId);
128
129 LayoutSet publicLayoutSet = group.getPublicLayoutSet();
130
131 copyLayoutSet(
132 layoutSetPrototype.getLayoutSet(), publicLayoutSet,
133 serviceContext);
134
135 sourceGroup = layoutSetPrototype.getGroup();
136 }
137
138 if (privateLayoutSetPrototypeId > 0) {
139 LayoutSetPrototype layoutSetPrototype =
140 LayoutSetPrototypeLocalServiceUtil.getLayoutSetPrototype(
141 privateLayoutSetPrototypeId);
142
143 LayoutSet privateLayoutSet = group.getPrivateLayoutSet();
144
145 copyLayoutSet(
146 layoutSetPrototype.getLayoutSet(), privateLayoutSet,
147 serviceContext);
148
149 if (sourceGroup == null) {
150 sourceGroup = layoutSetPrototype.getGroup();
151 }
152 }
153
154 if (sourceGroup != null) {
155 copyTypeSettings(sourceGroup, group);
156 }
157 }
158
159 public static void copyLayout(
160 long userId, Layout sourceLayout, Layout targetLayout,
161 ServiceContext serviceContext)
162 throws Exception {
163
164 Map<String, String[]> parameterMap =
165 getLayoutSetPrototypeParameters(serviceContext);
166
167 parameterMap.put(
168 PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS,
169 new String[] {Boolean.FALSE.toString()});
170
171 File file = LayoutLocalServiceUtil.exportLayoutsAsFile(
172 sourceLayout.getGroupId(), sourceLayout.isPrivateLayout(),
173 new long[] {sourceLayout.getLayoutId()}, parameterMap, null, null);
174
175 try {
176 LayoutLocalServiceUtil.importLayouts(
177 userId, targetLayout.getGroupId(),
178 targetLayout.isPrivateLayout(), parameterMap, file);
179 }
180 finally {
181 file.delete();
182 }
183 }
184
185 public static void copyLayoutSet(
186 LayoutSet sourceLayoutSet, LayoutSet targetLayoutSet,
187 ServiceContext serviceContext)
188 throws Exception {
189
190 Map<String, String[]> parameterMap = getLayoutSetPrototypeParameters(
191 serviceContext);
192
193 if (!targetLayoutSet.isPrivateLayout()) {
194 parameterMap.put(
195 PortletDataHandlerKeys.PUBLIC_LAYOUT_PERMISSIONS,
196 new String[] {Boolean.TRUE.toString()});
197 }
198
199 File file = LayoutLocalServiceUtil.exportLayoutsAsFile(
200 sourceLayoutSet.getGroupId(), sourceLayoutSet.isPrivateLayout(),
201 null, parameterMap, null, null);
202
203 try {
204 LayoutServiceUtil.importLayouts(
205 targetLayoutSet.getGroupId(), targetLayoutSet.isPrivateLayout(),
206 parameterMap, file);
207 }
208 finally {
209 file.delete();
210 }
211 }
212
213 public static void copyTypeSettings(Group sourceGroup, Group targetGroup)
214 throws Exception {
215
216 GroupServiceUtil.updateGroup(
217 targetGroup.getGroupId(), sourceGroup.getTypeSettings());
218 }
219
220 public static Object[] deleteLayout(
221 ActionRequest actionRequest, ActionResponse actionResponse)
222 throws Exception {
223
224 HttpServletRequest request = PortalUtil.getHttpServletRequest(
225 actionRequest);
226 HttpServletResponse response = PortalUtil.getHttpServletResponse(
227 actionResponse);
228
229 return deleteLayout(request, response);
230 }
231
232 public static Object[] deleteLayout(
233 HttpServletRequest request, HttpServletResponse response)
234 throws Exception {
235
236 ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
237 WebKeys.THEME_DISPLAY);
238
239 PermissionChecker permissionChecker =
240 themeDisplay.getPermissionChecker();
241
242 long plid = ParamUtil.getLong(request, "plid");
243
244 long groupId = ParamUtil.getLong(request, "groupId");
245 boolean privateLayout = ParamUtil.getBoolean(request, "privateLayout");
246 long layoutId = ParamUtil.getLong(request, "layoutId");
247
248 Layout layout = null;
249
250 if (plid <= 0) {
251 layout = LayoutLocalServiceUtil.getLayout(
252 groupId, privateLayout, layoutId);
253 }
254 else {
255 layout = LayoutLocalServiceUtil.getLayout(plid);
256
257 groupId = layout.getGroupId();
258 privateLayout = layout.isPrivateLayout();
259 layoutId = layout.getLayoutId();
260 }
261
262 Group group = layout.getGroup();
263 String oldFriendlyURL = layout.getFriendlyURL();
264
265 if (group.isStagingGroup() &&
266 !GroupPermissionUtil.contains(
267 permissionChecker, groupId, ActionKeys.MANAGE_STAGING) &&
268 !GroupPermissionUtil.contains(
269 permissionChecker, groupId, ActionKeys.PUBLISH_STAGING)) {
270
271 throw new PrincipalException();
272 }
273
274 if (LayoutPermissionUtil.contains(
275 permissionChecker, layout, ActionKeys.DELETE)) {
276
277 LayoutSettings layoutSettings = LayoutSettings.getInstance(layout);
278
279 EventsProcessorUtil.process(
280 PropsKeys.LAYOUT_CONFIGURATION_ACTION_DELETE,
281 layoutSettings.getConfigurationActionDelete(), request,
282 response);
283 }
284
285 LayoutSet layoutSet = layout.getLayoutSet();
286
287 Group layoutSetGroup = layoutSet.getGroup();
288
289 ServiceContext serviceContext = ServiceContextFactory.getInstance(
290 request);
291
292 if (layoutSetGroup.isLayoutSetPrototype()) {
293 LayoutSetPrototype layoutSetPrototype =
294 LayoutSetPrototypeLocalServiceUtil.getLayoutSetPrototype(
295 layoutSetGroup.getClassPK());
296
297 List<LayoutSet> linkedLayoutSets =
298 LayoutSetLocalServiceUtil.getLayoutSetsByLayoutSetPrototypeUuid(
299 layoutSetPrototype.getUuid());
300
301 for (LayoutSet linkedLayoutSet : linkedLayoutSets) {
302 Layout linkedLayout =
303 LayoutLocalServiceUtil.fetchLayoutByUuidAndGroupId(
304 layout.getUuid(), linkedLayoutSet.getGroupId());
305
306 if ((linkedLayout != null) &&
307 (isLayoutLocked(linkedLayout) ||
308 isLayoutToBeUpdatedFromTemplate(linkedLayout))) {
309
310 LayoutServiceUtil.deleteLayout(
311 linkedLayout.getPlid(), serviceContext);
312 }
313 }
314 }
315
316 LayoutServiceUtil.deleteLayout(
317 groupId, privateLayout, layoutId, serviceContext);
318
319 return new Object[] {group, oldFriendlyURL};
320 }
321
322 public static void deleteLayout(
323 RenderRequest renderRequest, RenderResponse renderResponse)
324 throws Exception {
325
326 HttpServletRequest request = PortalUtil.getHttpServletRequest(
327 renderRequest);
328 HttpServletResponse response = PortalUtil.getHttpServletResponse(
329 renderResponse);
330
331 deleteLayout(request, response);
332 }
333
334 public static File exportLayoutSetPrototype(
335 LayoutSetPrototype layoutSetPrototype,
336 ServiceContext serviceContext)
337 throws PortalException, SystemException {
338
339 LayoutSet layoutSet = layoutSetPrototype.getLayoutSet();
340
341 Map<String, String[]> parameterMap = getLayoutSetPrototypeParameters(
342 serviceContext);
343
344 return LayoutLocalServiceUtil.exportLayoutsAsFile(
345 layoutSet.getGroupId(), layoutSet.isPrivateLayout(),
346 null, parameterMap, null, null);
347 }
348
349 public static Map<String, String[]> getLayoutSetPrototypeParameters(
350 ServiceContext serviceContext) {
351
352 Map<String, String[]> parameterMap =
353 new LinkedHashMap<String, String[]>();
354
355 parameterMap.put(
356 PortletDataHandlerKeys.CATEGORIES,
357 new String[] {Boolean.TRUE.toString()});
358 parameterMap.put(
359 PortletDataHandlerKeys.DATA_STRATEGY,
360 new String[] {PortletDataHandlerKeys.DATA_STRATEGY_MIRROR});
361 parameterMap.put(
362 PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS,
363 new String[] {Boolean.TRUE.toString()});
364 parameterMap.put(
365 PortletDataHandlerKeys.DELETE_PORTLET_DATA,
366 new String[] {Boolean.FALSE.toString()});
367
368 String siteTemplateRelationship = ParamUtil.getString(
369 serviceContext, "siteTemplateRelationship");
370
371 if (siteTemplateRelationship.equals("inherited")) {
372 parameterMap.put(
373 PortletDataHandlerKeys.LAYOUT_SET_PROTOTYPE_INHERITED,
374 new String[] {Boolean.TRUE.toString()});
375 }
376
377 parameterMap.put(
378 PortletDataHandlerKeys.LAYOUTS_IMPORT_MODE,
379 new String[] {
380 PortletDataHandlerKeys.
381 LAYOUTS_IMPORT_MODE_CREATED_FROM_PROTOTYPE
382 });
383 parameterMap.put(
384 PortletDataHandlerKeys.PERFORM_DIRECT_BINARY_IMPORT,
385 new String[] {Boolean.TRUE.toString()});
386 parameterMap.put(
387 PortletDataHandlerKeys.PERMISSIONS,
388 new String[] {Boolean.TRUE.toString()});
389 parameterMap.put(
390 PortletDataHandlerKeys.PORTLET_DATA,
391 new String[] {Boolean.TRUE.toString()});
392 parameterMap.put(
393 PortletDataHandlerKeys.PORTLET_DATA_ALL,
394 new String[] {Boolean.TRUE.toString()});
395 parameterMap.put(
396 PortletDataHandlerKeys.PORTLET_SETUP,
397 new String[] {Boolean.TRUE.toString()});
398 parameterMap.put(
399 PortletDataHandlerKeys.PORTLET_USER_PREFERENCES,
400 new String[] {Boolean.TRUE.toString()});
401 parameterMap.put(
402 PortletDataHandlerKeys.THEME,
403 new String[] {Boolean.FALSE.toString()});
404 parameterMap.put(
405 PortletDataHandlerKeys.THEME_REFERENCE,
406 new String[] {Boolean.TRUE.toString()});
407 parameterMap.put(
408 PortletDataHandlerKeys.USER_ID_STRATEGY,
409 new String[] {UserIdStrategy.CURRENT_USER_ID});
410 parameterMap.put(
411 PortletDataHandlerKeys.USER_PERMISSIONS,
412 new String[] {Boolean.FALSE.toString()});
413
414 return parameterMap;
415 }
416
417 public static void importLayoutSetPrototype(
418 LayoutSetPrototype layoutSetPrototype, InputStream inputStream,
419 ServiceContext serviceContext)
420 throws PortalException, SystemException {
421
422 LayoutSet layoutSet = layoutSetPrototype.getLayoutSet();
423
424 Map<String, String[]> parameterMap = getLayoutSetPrototypeParameters(
425 serviceContext);
426
427 LayoutServiceUtil.importLayouts(
428 layoutSet.getGroupId(), layoutSet.isPrivateLayout(),
429 parameterMap, inputStream);
430 }
431
432 public static boolean isLayoutLocked(Layout layout) {
433 try {
434 LayoutSet layoutSet = layout.getLayoutSet();
435
436 if (layout.isLayoutPrototypeLinkEnabled() ||
437 layoutSet.isLayoutSetPrototypeLinkEnabled()) {
438
439 LayoutTypePortletImpl layoutTypePortlet =
440 new LayoutTypePortletImpl(layout);
441
442 return isLayoutLocked(layoutTypePortlet);
443 }
444 }
445 catch (Exception e) {
446 }
447
448 return false;
449 }
450
451 public static boolean isLayoutLocked(
452 LayoutTypePortlet layoutTypePortlet) {
453
454 Layout layout = layoutTypePortlet.getLayout();
455
456 try {
457 LayoutSet layoutSet = layout.getLayoutSet();
458
459 if (layout.isLayoutPrototypeLinkEnabled() ||
460 layoutSet.isLayoutSetPrototypeLinkEnabled()) {
461
462 String locked = layoutTypePortlet.getTemplateProperty("locked");
463
464 if (Validator.isNotNull(locked)) {
465 return GetterUtil.getBoolean(locked);
466 }
467 else if (Validator.isNotNull(layout.getTemplateLayoutUuid())) {
468 return isLayoutSetLocked(layoutSet);
469 }
470 }
471 }
472 catch (Exception e) {
473 }
474
475 return false;
476 }
477
478 public static boolean isLayoutSetLocked(
479 Group group, boolean privateLayout) {
480
481 try {
482 LayoutSet layoutSet = LayoutSetLocalServiceUtil.getLayoutSet(
483 group.getGroupId(), privateLayout);
484
485 return isLayoutSetLocked(layoutSet);
486 }
487 catch (Exception e) {
488 }
489
490 return true;
491 }
492
493 public static boolean isLayoutSetLocked(LayoutSet layoutSet) {
494 if (layoutSet.isLayoutSetPrototypeLinkEnabled()) {
495 try {
496 LayoutSetPrototype layoutSetPrototype =
497 LayoutSetPrototypeLocalServiceUtil.
498 getLayoutSetPrototypeByUuid(
499 layoutSet.getLayoutSetPrototypeUuid());
500
501 String allowModifications =
502 layoutSetPrototype.getSettingsProperty(
503 "allowModifications");
504
505 if (Validator.isNotNull(allowModifications)) {
506 return !GetterUtil.getBoolean(allowModifications);
507 }
508 }
509 catch (Exception e) {
510 }
511 }
512
513 return false;
514 }
515
516 public static boolean isLayoutToBeUpdatedFromTemplate(Layout layout)
517 throws Exception {
518
519 if (layout == null) {
520 return false;
521 }
522
523 LayoutSet layoutSet = layout.getLayoutSet();
524
525 if (!layoutSet.isLayoutSetPrototypeLinkEnabled()) {
526 return false;
527 }
528
529 Layout templateLayout = LayoutTypePortletImpl.getTemplateLayout(
530 layout);
531
532 Date layoutModifiedDate = layout.getModifiedDate();
533
534 Date lastCopyDate = null;
535
536 String lastCopyDateString = layout.getTypeSettingsProperty(
537 "layoutSetPrototypeLastCopyDate");
538
539 if (Validator.isNotNull(lastCopyDateString)) {
540 lastCopyDate = new Date(GetterUtil.getLong(lastCopyDateString));
541 }
542
543 if ((lastCopyDate != null) &&
544 lastCopyDate.after(templateLayout.getModifiedDate())) {
545
546 return false;
547 }
548
549 if (isLayoutLocked(layout)) {
550 return true;
551 }
552
553 if ((layoutModifiedDate == null) ||
554 ((lastCopyDate != null) &&
555 layoutModifiedDate.before(lastCopyDate))) {
556
557 return true;
558 }
559
560 return false;
561 }
562
563 }