001
014
015 package com.liferay.portlet.sites.util;
016
017 import com.liferay.portal.RequiredLayoutException;
018 import com.liferay.portal.events.EventsProcessorUtil;
019 import com.liferay.portal.kernel.exception.PortalException;
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.log.Log;
024 import com.liferay.portal.kernel.log.LogFactoryUtil;
025 import com.liferay.portal.kernel.staging.MergeLayoutPrototypesThreadLocal;
026 import com.liferay.portal.kernel.util.ArrayUtil;
027 import com.liferay.portal.kernel.util.FileUtil;
028 import com.liferay.portal.kernel.util.GetterUtil;
029 import com.liferay.portal.kernel.util.ListUtil;
030 import com.liferay.portal.kernel.util.ParamUtil;
031 import com.liferay.portal.kernel.util.PrefsPropsUtil;
032 import com.liferay.portal.kernel.util.PropsKeys;
033 import com.liferay.portal.kernel.util.StringBundler;
034 import com.liferay.portal.kernel.util.StringPool;
035 import com.liferay.portal.kernel.util.StringUtil;
036 import com.liferay.portal.kernel.util.SystemProperties;
037 import com.liferay.portal.kernel.util.UnicodeProperties;
038 import com.liferay.portal.kernel.util.Validator;
039 import com.liferay.portal.kernel.uuid.PortalUUIDUtil;
040 import com.liferay.portal.model.Group;
041 import com.liferay.portal.model.GroupConstants;
042 import com.liferay.portal.model.Layout;
043 import com.liferay.portal.model.LayoutConstants;
044 import com.liferay.portal.model.LayoutPrototype;
045 import com.liferay.portal.model.LayoutSet;
046 import com.liferay.portal.model.LayoutSetPrototype;
047 import com.liferay.portal.model.LayoutType;
048 import com.liferay.portal.model.LayoutTypePortlet;
049 import com.liferay.portal.model.Lock;
050 import com.liferay.portal.model.Organization;
051 import com.liferay.portal.model.PortletConstants;
052 import com.liferay.portal.model.ResourceConstants;
053 import com.liferay.portal.model.Role;
054 import com.liferay.portal.model.RoleConstants;
055 import com.liferay.portal.model.User;
056 import com.liferay.portal.model.UserGroup;
057 import com.liferay.portal.model.impl.VirtualLayout;
058 import com.liferay.portal.security.auth.PrincipalException;
059 import com.liferay.portal.security.permission.ActionKeys;
060 import com.liferay.portal.security.permission.PermissionChecker;
061 import com.liferay.portal.security.permission.PermissionThreadLocal;
062 import com.liferay.portal.security.permission.ResourceActionsUtil;
063 import com.liferay.portal.service.GroupLocalServiceUtil;
064 import com.liferay.portal.service.GroupServiceUtil;
065 import com.liferay.portal.service.LayoutLocalServiceUtil;
066 import com.liferay.portal.service.LayoutPrototypeLocalServiceUtil;
067 import com.liferay.portal.service.LayoutServiceUtil;
068 import com.liferay.portal.service.LayoutSetLocalServiceUtil;
069 import com.liferay.portal.service.LayoutSetPrototypeLocalServiceUtil;
070 import com.liferay.portal.service.LayoutSetServiceUtil;
071 import com.liferay.portal.service.LockLocalServiceUtil;
072 import com.liferay.portal.service.OrganizationLocalServiceUtil;
073 import com.liferay.portal.service.PortletPreferencesLocalServiceUtil;
074 import com.liferay.portal.service.ResourcePermissionLocalServiceUtil;
075 import com.liferay.portal.service.RoleLocalServiceUtil;
076 import com.liferay.portal.service.ServiceContext;
077 import com.liferay.portal.service.ServiceContextFactory;
078 import com.liferay.portal.service.ServiceContextThreadLocal;
079 import com.liferay.portal.service.UserGroupLocalServiceUtil;
080 import com.liferay.portal.service.UserLocalServiceUtil;
081 import com.liferay.portal.service.impl.LayoutLocalServiceVirtualLayoutsAdvice;
082 import com.liferay.portal.service.permission.GroupPermissionUtil;
083 import com.liferay.portal.service.permission.LayoutPermissionUtil;
084 import com.liferay.portal.service.permission.PortalPermissionUtil;
085 import com.liferay.portal.service.permission.PortletPermissionUtil;
086 import com.liferay.portal.service.persistence.LayoutSetUtil;
087 import com.liferay.portal.service.persistence.LayoutUtil;
088 import com.liferay.portal.theme.PortletDisplay;
089 import com.liferay.portal.theme.ThemeDisplay;
090 import com.liferay.portal.util.PortalUtil;
091 import com.liferay.portal.util.PortletKeys;
092 import com.liferay.portal.util.PropsValues;
093 import com.liferay.portal.util.WebKeys;
094 import com.liferay.portlet.PortletPreferencesFactoryUtil;
095 import com.liferay.portlet.PortletPreferencesImpl;
096
097 import java.io.File;
098 import java.io.InputStream;
099
100 import java.util.ArrayList;
101 import java.util.Collections;
102 import java.util.Date;
103 import java.util.LinkedHashMap;
104 import java.util.List;
105 import java.util.Locale;
106 import java.util.Map;
107
108 import javax.portlet.ActionRequest;
109 import javax.portlet.ActionResponse;
110 import javax.portlet.PortletPreferences;
111 import javax.portlet.PortletURL;
112 import javax.portlet.RenderRequest;
113 import javax.portlet.RenderResponse;
114
115 import javax.servlet.http.HttpServletRequest;
116 import javax.servlet.http.HttpServletResponse;
117
118
123 public class SitesImpl implements Sites {
124
125 @Override
126 public void addMergeFailFriendlyURLLayout(Layout layout)
127 throws PortalException {
128
129 LayoutSet layoutSet = layout.getLayoutSet();
130
131 layoutSet = LayoutSetLocalServiceUtil.getLayoutSet(
132 layoutSet.getGroupId(), layoutSet.isPrivateLayout());
133
134 UnicodeProperties settingsProperties =
135 layoutSet.getSettingsProperties();
136
137 String mergeFailFriendlyURLLayouts = settingsProperties.getProperty(
138 MERGE_FAIL_FRIENDLY_URL_LAYOUTS, StringPool.BLANK);
139
140 mergeFailFriendlyURLLayouts = StringUtil.add(
141 mergeFailFriendlyURLLayouts, layout.getUuid());
142
143 settingsProperties.setProperty(
144 MERGE_FAIL_FRIENDLY_URL_LAYOUTS, mergeFailFriendlyURLLayouts);
145
146 LayoutSetLocalServiceUtil.updateLayoutSet(layoutSet);
147 }
148
149 @Override
150 public void addPortletBreadcrumbEntries(
151 Group group, HttpServletRequest request,
152 RenderResponse renderResponse)
153 throws Exception {
154
155 PortletURL portletURL = renderResponse.createRenderURL();
156
157 portletURL.setParameter("struts_action", "/sites_admin/view");
158
159 List<Group> ancestorGroups = group.getAncestors();
160
161 Collections.reverse(ancestorGroups);
162
163 for (Group ancestorGroup : ancestorGroups) {
164 portletURL.setParameter(
165 "groupId", String.valueOf(ancestorGroup.getGroupId()));
166
167 PortalUtil.addPortletBreadcrumbEntry(
168 request, ancestorGroup.getDescriptiveName(),
169 portletURL.toString());
170 }
171
172 Group unescapedGroup = group.toUnescapedModel();
173
174 portletURL.setParameter(
175 "groupId", String.valueOf(unescapedGroup.getGroupId()));
176
177 PortalUtil.addPortletBreadcrumbEntry(
178 request, unescapedGroup.getDescriptiveName(),
179 portletURL.toString());
180 }
181
182 @Override
183 public void addPortletBreadcrumbEntries(
184 Group group, String pagesName, PortletURL redirectURL,
185 HttpServletRequest request, RenderResponse renderResponse)
186 throws Exception {
187
188 ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
189 com.liferay.portal.kernel.util.WebKeys.THEME_DISPLAY);
190
191 PortletDisplay portletDisplay = themeDisplay.getPortletDisplay();
192
193 String portletName = portletDisplay.getPortletName();
194
195 if ((renderResponse == null) ||
196 portletName.equals(PortletKeys.GROUP_PAGES) ||
197 portletName.equals(PortletKeys.MY_PAGES)) {
198
199 return;
200 }
201
202 Group unescapedGroup = group.toUnescapedModel();
203
204 Locale locale = themeDisplay.getLocale();
205
206 if (group.isLayoutPrototype()) {
207 PortalUtil.addPortletBreadcrumbEntry(
208 request, LanguageUtil.get(locale, "page-template"), null);
209
210 PortalUtil.addPortletBreadcrumbEntry(
211 request, unescapedGroup.getDescriptiveName(),
212 redirectURL.toString());
213 }
214 else {
215 PortalUtil.addPortletBreadcrumbEntry(
216 request, unescapedGroup.getDescriptiveName(), null);
217 }
218
219 if (!group.isLayoutPrototype()) {
220 PortalUtil.addPortletBreadcrumbEntry(
221 request, LanguageUtil.get(locale, pagesName),
222 redirectURL.toString());
223 }
224 }
225
226 @Override
227 public void applyLayoutPrototype(
228 LayoutPrototype layoutPrototype, Layout targetLayout,
229 boolean linkEnabled)
230 throws Exception {
231
232 Layout layoutPrototypeLayout = layoutPrototype.getLayout();
233
234 ServiceContext serviceContext =
235 ServiceContextThreadLocal.getServiceContext();
236
237 serviceContext.setAttribute("layoutPrototypeLinkEnabled", linkEnabled);
238 serviceContext.setAttribute(
239 "layoutPrototypeUuid", layoutPrototype.getUuid());
240
241 targetLayout = LayoutLocalServiceUtil.updateLayout(
242 targetLayout.getGroupId(), targetLayout.isPrivateLayout(),
243 targetLayout.getLayoutId(), targetLayout.getParentLayoutId(),
244 targetLayout.getNameMap(), targetLayout.getTitleMap(),
245 targetLayout.getDescriptionMap(), targetLayout.getKeywordsMap(),
246 targetLayout.getRobotsMap(), layoutPrototypeLayout.getType(),
247 targetLayout.getHidden(), targetLayout.getFriendlyURLMap(),
248 targetLayout.getIconImage(), null, serviceContext);
249
250 targetLayout = LayoutLocalServiceUtil.updateLayout(
251 targetLayout.getGroupId(), targetLayout.isPrivateLayout(),
252 targetLayout.getLayoutId(),
253 layoutPrototypeLayout.getTypeSettings());
254
255 copyPortletPermissions(targetLayout, layoutPrototypeLayout);
256
257 copyPortletSetups(layoutPrototypeLayout, targetLayout);
258
259 copyLookAndFeel(targetLayout, layoutPrototypeLayout);
260
261 targetLayout = LayoutLocalServiceUtil.getLayout(targetLayout.getPlid());
262
263 UnicodeProperties typeSettingsProperties =
264 targetLayout.getTypeSettingsProperties();
265
266 typeSettingsProperties.setProperty(
267 LAST_MERGE_TIME,
268 String.valueOf(targetLayout.getModifiedDate().getTime()));
269
270 LayoutLocalServiceUtil.updateLayout(targetLayout);
271
272 UnicodeProperties prototypeTypeSettingsProperties =
273 layoutPrototypeLayout.getTypeSettingsProperties();
274
275 prototypeTypeSettingsProperties.setProperty(MERGE_FAIL_COUNT, "0");
276
277 LayoutLocalServiceUtil.updateLayout(layoutPrototypeLayout);
278 }
279
280 @Override
281 public void copyLayout(
282 long userId, Layout sourceLayout, Layout targetLayout,
283 ServiceContext serviceContext)
284 throws Exception {
285
286 Map<String, String[]> parameterMap = getLayoutSetPrototypeParameters(
287 serviceContext);
288
289 parameterMap.put(
290 PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS,
291 new String[] {Boolean.FALSE.toString()});
292
293 File file = LayoutLocalServiceUtil.exportLayoutsAsFile(
294 sourceLayout.getGroupId(), sourceLayout.isPrivateLayout(),
295 new long[] {sourceLayout.getLayoutId()}, parameterMap, null, null);
296
297 try {
298 LayoutLocalServiceUtil.importLayouts(
299 userId, targetLayout.getGroupId(),
300 targetLayout.isPrivateLayout(), parameterMap, file);
301 }
302 finally {
303 file.delete();
304 }
305 }
306
307 @Override
308 public void copyLookAndFeel(Layout targetLayout, Layout sourceLayout)
309 throws Exception {
310
311 LayoutLocalServiceUtil.updateLookAndFeel(
312 targetLayout.getGroupId(), targetLayout.isPrivateLayout(),
313 targetLayout.getLayoutId(), sourceLayout.getThemeId(),
314 sourceLayout.getColorSchemeId(), sourceLayout.getCss(), false);
315
316 LayoutLocalServiceUtil.updateLookAndFeel(
317 targetLayout.getGroupId(), targetLayout.isPrivateLayout(),
318 targetLayout.getLayoutId(), sourceLayout.getWapThemeId(),
319 sourceLayout.getWapColorSchemeId(), sourceLayout.getCss(), true);
320 }
321
322 @Override
323 public void copyPortletPermissions(Layout targetLayout, Layout sourceLayout)
324 throws Exception {
325
326 List<Role> roles = RoleLocalServiceUtil.getGroupRelatedRoles(
327 targetLayout.getGroupId());
328
329 LayoutTypePortlet sourceLayoutTypePortlet =
330 (LayoutTypePortlet)sourceLayout.getLayoutType();
331
332 List<String> sourcePortletIds = sourceLayoutTypePortlet.getPortletIds();
333
334 for (String sourcePortletId : sourcePortletIds) {
335 String resourceName = PortletConstants.getRootPortletId(
336 sourcePortletId);
337
338 String sourceResourcePrimKey = PortletPermissionUtil.getPrimaryKey(
339 sourceLayout.getPlid(), sourcePortletId);
340
341 String targetResourcePrimKey = PortletPermissionUtil.getPrimaryKey(
342 targetLayout.getPlid(), sourcePortletId);
343
344 List<String> actionIds =
345 ResourceActionsUtil.getPortletResourceActions(resourceName);
346
347 for (Role role : roles) {
348 String roleName = role.getName();
349
350 if (roleName.equals(RoleConstants.ADMINISTRATOR) ||
351 (targetLayout.isPrivateLayout() &&
352 roleName.equals(RoleConstants.GUEST))) {
353
354 continue;
355 }
356
357 List<String> actions =
358 ResourcePermissionLocalServiceUtil.
359 getAvailableResourcePermissionActionIds(
360 targetLayout.getCompanyId(), resourceName,
361 ResourceConstants.SCOPE_INDIVIDUAL,
362 sourceResourcePrimKey, role.getRoleId(), actionIds);
363
364 ResourcePermissionLocalServiceUtil.setResourcePermissions(
365 targetLayout.getCompanyId(), resourceName,
366 ResourceConstants.SCOPE_INDIVIDUAL, targetResourcePrimKey,
367 role.getRoleId(),
368 actions.toArray(new String[actions.size()]));
369 }
370 }
371 }
372
373 @Override
374 public void copyPortletSetups(Layout sourceLayout, Layout targetLayout)
375 throws Exception {
376
377 LayoutTypePortlet sourceLayoutTypePortlet =
378 (LayoutTypePortlet)sourceLayout.getLayoutType();
379
380 List<String> sourcePortletIds = sourceLayoutTypePortlet.getPortletIds();
381
382 for (String sourcePortletId : sourcePortletIds) {
383 PortletPreferences sourcePreferences =
384 PortletPreferencesFactoryUtil.getPortletSetup(
385 sourceLayout, sourcePortletId, null);
386
387 PortletPreferencesImpl sourcePreferencesImpl =
388 (PortletPreferencesImpl)sourcePreferences;
389
390 PortletPreferences targetPreferences =
391 PortletPreferencesFactoryUtil.getPortletSetup(
392 targetLayout, sourcePortletId, null);
393
394 PortletPreferencesImpl targetPreferencesImpl =
395 (PortletPreferencesImpl)targetPreferences;
396
397 PortletPreferencesLocalServiceUtil.updatePreferences(
398 targetPreferencesImpl.getOwnerId(),
399 targetPreferencesImpl.getOwnerType(),
400 targetPreferencesImpl.getPlid(), sourcePortletId,
401 sourcePreferences);
402
403 if ((sourcePreferencesImpl.getOwnerId() !=
404 PortletKeys.PREFS_OWNER_ID_DEFAULT) &&
405 (sourcePreferencesImpl.getOwnerType() !=
406 PortletKeys.PREFS_OWNER_TYPE_LAYOUT)) {
407
408 sourcePreferences =
409 PortletPreferencesFactoryUtil.getLayoutPortletSetup(
410 sourceLayout, sourcePortletId);
411
412 sourcePreferencesImpl =
413 (PortletPreferencesImpl)sourcePreferences;
414
415 targetPreferences =
416 PortletPreferencesFactoryUtil.getLayoutPortletSetup(
417 targetLayout, sourcePortletId);
418
419 targetPreferencesImpl =
420 (PortletPreferencesImpl)targetPreferences;
421
422 PortletPreferencesLocalServiceUtil.updatePreferences(
423 targetPreferencesImpl.getOwnerId(),
424 targetPreferencesImpl.getOwnerType(),
425 targetPreferencesImpl.getPlid(), sourcePortletId,
426 sourcePreferences);
427 }
428
429 ServiceContext serviceContext =
430 ServiceContextThreadLocal.getServiceContext();
431
432 updateLayoutScopes(
433 serviceContext.getUserId(), sourceLayout, targetLayout,
434 sourcePreferences, targetPreferences, sourcePortletId,
435 serviceContext.getLanguageId());
436 }
437 }
438
439 @Override
440 public void copyTypeSettings(Group sourceGroup, Group targetGroup)
441 throws Exception {
442
443 GroupServiceUtil.updateGroup(
444 targetGroup.getGroupId(), sourceGroup.getTypeSettings());
445 }
446
447 @Override
448 public Object[] deleteLayout(
449 ActionRequest actionRequest, ActionResponse actionResponse)
450 throws Exception {
451
452 HttpServletRequest request = PortalUtil.getHttpServletRequest(
453 actionRequest);
454 HttpServletResponse response = PortalUtil.getHttpServletResponse(
455 actionResponse);
456
457 return deleteLayout(request, response);
458 }
459
460 @Override
461 public Object[] deleteLayout(
462 HttpServletRequest request, HttpServletResponse response)
463 throws Exception {
464
465 ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
466 WebKeys.THEME_DISPLAY);
467
468 PermissionChecker permissionChecker =
469 themeDisplay.getPermissionChecker();
470
471 long plid = ParamUtil.getLong(request, "plid");
472
473 long groupId = ParamUtil.getLong(request, "groupId");
474 boolean privateLayout = ParamUtil.getBoolean(request, "privateLayout");
475 long layoutId = ParamUtil.getLong(request, "layoutId");
476
477 Layout layout = null;
478
479 if (plid <= 0) {
480 layout = LayoutLocalServiceUtil.getLayout(
481 groupId, privateLayout, layoutId);
482 }
483 else {
484 layout = LayoutLocalServiceUtil.getLayout(plid);
485
486 groupId = layout.getGroupId();
487 privateLayout = layout.isPrivateLayout();
488 layoutId = layout.getLayoutId();
489 }
490
491 Group group = layout.getGroup();
492 String oldFriendlyURL = layout.getFriendlyURL(themeDisplay.getLocale());
493
494 if (group.isStagingGroup() &&
495 !GroupPermissionUtil.contains(
496 permissionChecker, group, ActionKeys.MANAGE_STAGING) &&
497 !GroupPermissionUtil.contains(
498 permissionChecker, group, ActionKeys.PUBLISH_STAGING)) {
499
500 throw new PrincipalException();
501 }
502
503 if (LayoutPermissionUtil.contains(
504 permissionChecker, layout, ActionKeys.DELETE)) {
505
506 LayoutType layoutType = layout.getLayoutType();
507
508 EventsProcessorUtil.process(
509 PropsKeys.LAYOUT_CONFIGURATION_ACTION_DELETE,
510 layoutType.getConfigurationActionDelete(), request, response);
511 }
512
513 if (group.isGuest() && !layout.isPrivateLayout() &&
514 layout.isRootLayout() &&
515 (LayoutLocalServiceUtil.getLayoutsCount(
516 group, false, LayoutConstants.DEFAULT_PARENT_LAYOUT_ID) == 1)) {
517
518 throw new RequiredLayoutException(
519 RequiredLayoutException.AT_LEAST_ONE);
520 }
521
522 ServiceContext serviceContext = ServiceContextFactory.getInstance(
523 request);
524
525 LayoutServiceUtil.deleteLayout(
526 groupId, privateLayout, layoutId, serviceContext);
527
528 long newPlid = layout.getParentPlid();
529
530 if (newPlid <= 0) {
531 LayoutSet layoutSet = layout.getLayoutSet();
532
533 Layout firstLayout = LayoutLocalServiceUtil.fetchFirstLayout(
534 layoutSet.getGroupId(), layoutSet.isPrivateLayout(),
535 LayoutConstants.DEFAULT_PARENT_LAYOUT_ID);
536
537 if (firstLayout != null) {
538 newPlid = firstLayout.getPlid();
539 }
540 }
541
542 return new Object[] {group, oldFriendlyURL, newPlid};
543 }
544
545 @Override
546 public void deleteLayout(
547 RenderRequest renderRequest, RenderResponse renderResponse)
548 throws Exception {
549
550 HttpServletRequest request = PortalUtil.getHttpServletRequest(
551 renderRequest);
552 HttpServletResponse response = PortalUtil.getHttpServletResponse(
553 renderResponse);
554
555 deleteLayout(request, response);
556 }
557
558 @Override
559 public File exportLayoutSetPrototype(
560 LayoutSetPrototype layoutSetPrototype,
561 ServiceContext serviceContext)
562 throws PortalException {
563
564 LayoutSet layoutSet = layoutSetPrototype.getLayoutSet();
565
566 Map<String, String[]> parameterMap = getLayoutSetPrototypeParameters(
567 serviceContext);
568
569 return LayoutLocalServiceUtil.exportLayoutsAsFile(
570 layoutSet.getGroupId(), layoutSet.isPrivateLayout(), null,
571 parameterMap, null, null);
572 }
573
574 @Override
575 public Long[] filterGroups(List<Group> groups, String[] names) {
576 List<Long> groupIds = new ArrayList<Long>();
577
578 for (Group group : groups) {
579 if (!ArrayUtil.contains(names, group.getName())) {
580 groupIds.add(group.getGroupId());
581 }
582 }
583
584 return ArrayUtil.toArray(ArrayUtil.toLongArray(groupIds));
585 }
586
587 @Override
588 public Layout getLayoutSetPrototypeLayout(Layout layout) {
589 try {
590 LayoutSet layoutSet = layout.getLayoutSet();
591
592 if (!layoutSet.isLayoutSetPrototypeLinkActive()) {
593 return null;
594 }
595
596 LayoutSetPrototype layoutSetPrototype =
597 LayoutSetPrototypeLocalServiceUtil.
598 getLayoutSetPrototypeByUuidAndCompanyId(
599 layoutSet.getLayoutSetPrototypeUuid(),
600 layout.getCompanyId());
601
602 return LayoutLocalServiceUtil.fetchLayoutByUuidAndGroupId(
603 layout.getSourcePrototypeLayoutUuid(),
604 layoutSetPrototype.getGroupId(), true);
605 }
606 catch (Exception e) {
607 _log.error(
608 "Unable to fetch the the layout set prototype's layout", e);
609 }
610
611 return null;
612 }
613
614 @Override
615 public Map<String, String[]> getLayoutSetPrototypeParameters(
616 ServiceContext serviceContext) {
617
618 Map<String, String[]> parameterMap =
619 new LinkedHashMap<String, String[]>();
620
621 parameterMap.put(
622 PortletDataHandlerKeys.DATA_STRATEGY,
623 new String[] {PortletDataHandlerKeys.DATA_STRATEGY_MIRROR});
624 parameterMap.put(
625 PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS,
626 new String[] {Boolean.TRUE.toString()});
627 parameterMap.put(
628 PortletDataHandlerKeys.DELETE_PORTLET_DATA,
629 new String[] {Boolean.FALSE.toString()});
630 parameterMap.put(
631 PortletDataHandlerKeys.LAYOUT_SET_PROTOTYPE_LINK_ENABLED,
632 new String[] {Boolean.TRUE.toString()});
633 parameterMap.put(
634 PortletDataHandlerKeys.LAYOUT_SET_SETTINGS,
635 new String[] {Boolean.TRUE.toString()});
636 parameterMap.put(
637 PortletDataHandlerKeys.LAYOUTS_IMPORT_MODE,
638 new String[] {
639 PortletDataHandlerKeys.
640 LAYOUTS_IMPORT_MODE_CREATED_FROM_PROTOTYPE
641 });
642 parameterMap.put(
643 PortletDataHandlerKeys.LOGO,
644 new String[] {Boolean.TRUE.toString()});
645 parameterMap.put(
646 PortletDataHandlerKeys.PERFORM_DIRECT_BINARY_IMPORT,
647 new String[] {Boolean.TRUE.toString()});
648 parameterMap.put(
649 PortletDataHandlerKeys.PERMISSIONS,
650 new String[] {Boolean.TRUE.toString()});
651 parameterMap.put(
652 PortletDataHandlerKeys.PORTLET_CONFIGURATION,
653 new String[] {Boolean.TRUE.toString()});
654 parameterMap.put(
655 PortletDataHandlerKeys.PORTLET_CONFIGURATION_ALL,
656 new String[] {Boolean.TRUE.toString()});
657 parameterMap.put(
658 PortletDataHandlerKeys.PORTLET_DATA,
659 new String[] {Boolean.TRUE.toString()});
660 parameterMap.put(
661 PortletDataHandlerKeys.PORTLET_DATA + StringPool.UNDERLINE +
662 PortletKeys.ASSET_CATEGORIES_ADMIN,
663 new String[] {Boolean.TRUE.toString()});
664 parameterMap.put(
665 PortletDataHandlerKeys.PORTLET_DATA_ALL,
666 new String[] {Boolean.TRUE.toString()});
667 parameterMap.put(
668 PortletDataHandlerKeys.PORTLET_SETUP_ALL,
669 new String[] {Boolean.TRUE.toString()});
670 parameterMap.put(
671 PortletDataHandlerKeys.THEME_REFERENCE,
672 new String[] {Boolean.TRUE.toString()});
673 parameterMap.put(
674 PortletDataHandlerKeys.USER_ID_STRATEGY,
675 new String[] {UserIdStrategy.CURRENT_USER_ID});
676
677 return parameterMap;
678 }
679
680
690 @Override
691 public int getMergeFailCount(LayoutPrototype layoutPrototype)
692 throws PortalException {
693
694 if ((layoutPrototype == null) ||
695 (layoutPrototype.getLayoutPrototypeId() == 0)) {
696
697 return 0;
698 }
699
700 Layout layoutPrototypeLayout = layoutPrototype.getLayout();
701
702 UnicodeProperties prototypeTypeSettingsProperties =
703 layoutPrototypeLayout.getTypeSettingsProperties();
704
705 return GetterUtil.getInteger(
706 prototypeTypeSettingsProperties.getProperty(MERGE_FAIL_COUNT));
707 }
708
709
719 @Override
720 public int getMergeFailCount(LayoutSetPrototype layoutSetPrototype)
721 throws PortalException {
722
723 if ((layoutSetPrototype == null) ||
724 (layoutSetPrototype.getLayoutSetPrototypeId() == 0)) {
725
726 return 0;
727 }
728
729 LayoutSet layoutSetPrototypeLayoutSet =
730 layoutSetPrototype.getLayoutSet();
731
732 UnicodeProperties layoutSetPrototypeSettingsProperties =
733 layoutSetPrototypeLayoutSet.getSettingsProperties();
734
735 return GetterUtil.getInteger(
736 layoutSetPrototypeSettingsProperties.getProperty(MERGE_FAIL_COUNT));
737 }
738
739 @Override
740 public List<Layout> getMergeFailFriendlyURLLayouts(LayoutSet layoutSet)
741 throws PortalException {
742
743 if (layoutSet == null) {
744 return Collections.emptyList();
745 }
746
747 UnicodeProperties settingsProperties =
748 layoutSet.getSettingsProperties();
749
750 String uuids = settingsProperties.getProperty(
751 MERGE_FAIL_FRIENDLY_URL_LAYOUTS);
752
753 if (Validator.isNotNull(uuids)) {
754 List<Layout> layouts = new ArrayList<Layout>();
755
756 for (String uuid : StringUtil.split(uuids)) {
757 Layout layout =
758 LayoutLocalServiceUtil.getLayoutByUuidAndGroupId(
759 uuid, layoutSet.getGroupId(),
760 layoutSet.isPrivateLayout());
761
762 layouts.add(layout);
763 }
764
765 return layouts;
766 }
767
768 return Collections.emptyList();
769 }
770
771 @Override
772 public List<String> getOrganizationNames(Group group, User user)
773 throws Exception {
774
775 List<Organization> organizations =
776 OrganizationLocalServiceUtil.getGroupUserOrganizations(
777 group.getGroupId(), user.getUserId());
778
779 return ListUtil.toList(organizations, Organization.NAME_ACCESSOR);
780 }
781
782 @Override
783 public List<String> getUserGroupNames(Group group, User user)
784 throws Exception {
785
786 List<UserGroup> userGroups =
787 UserGroupLocalServiceUtil.getGroupUserUserGroups(
788 group.getGroupId(), user.getUserId());
789
790 return ListUtil.toList(userGroups, UserGroup.NAME_ACCESSOR);
791 }
792
793 @Override
794 public void importLayoutSetPrototype(
795 LayoutSetPrototype layoutSetPrototype, InputStream inputStream,
796 ServiceContext serviceContext)
797 throws PortalException {
798
799 LayoutSet layoutSet = layoutSetPrototype.getLayoutSet();
800
801 Map<String, String[]> parameterMap = getLayoutSetPrototypeParameters(
802 serviceContext);
803
804 setLayoutSetPrototypeLinkEnabledParameter(
805 parameterMap, layoutSet, serviceContext);
806
807 LayoutServiceUtil.importLayouts(
808 layoutSet.getGroupId(), layoutSet.isPrivateLayout(), parameterMap,
809 inputStream);
810 }
811
812 @Override
813 public boolean isContentSharingWithChildrenEnabled(Group group) {
814 UnicodeProperties typeSettingsProperties =
815 group.getParentLiveGroupTypeSettingsProperties();
816
817 int companyContentSharingEnabled = PrefsPropsUtil.getInteger(
818 group.getCompanyId(),
819 PropsKeys.SITES_CONTENT_SHARING_WITH_CHILDREN_ENABLED);
820
821 if (companyContentSharingEnabled ==
822 CONTENT_SHARING_WITH_CHILDREN_DISABLED) {
823
824 return false;
825 }
826
827 int groupContentSharingEnabled = GetterUtil.getInteger(
828 typeSettingsProperties.getProperty(
829 "contentSharingWithChildrenEnabled"),
830 CONTENT_SHARING_WITH_CHILDREN_DEFAULT_VALUE);
831
832 if ((groupContentSharingEnabled ==
833 CONTENT_SHARING_WITH_CHILDREN_ENABLED) ||
834 ((companyContentSharingEnabled ==
835 CONTENT_SHARING_WITH_CHILDREN_ENABLED_BY_DEFAULT) &&
836 (groupContentSharingEnabled ==
837 CONTENT_SHARING_WITH_CHILDREN_DEFAULT_VALUE))) {
838
839 return true;
840 }
841
842 return false;
843 }
844
845 @Override
846 public boolean isFirstLayout(
847 long groupId, boolean privateLayout, long layoutId) {
848
849 Layout firstLayout = LayoutLocalServiceUtil.fetchFirstLayout(
850 groupId, privateLayout, LayoutConstants.DEFAULT_PARENT_LAYOUT_ID);
851
852 if ((firstLayout != null) && (firstLayout.getLayoutId() == layoutId )) {
853 return true;
854 }
855
856 return false;
857 }
858
859 @Override
860 public boolean isLayoutDeleteable(Layout layout) {
861 try {
862 if (layout instanceof VirtualLayout) {
863 return false;
864 }
865
866 if (Validator.isNull(layout.getSourcePrototypeLayoutUuid())) {
867 return true;
868 }
869
870 LayoutSet layoutSet = layout.getLayoutSet();
871
872 if (!layoutSet.isLayoutSetPrototypeLinkActive()) {
873 return true;
874 }
875
876 if (LayoutLocalServiceUtil.hasLayoutSetPrototypeLayout(
877 layoutSet.getLayoutSetPrototypeUuid(),
878 layout.getCompanyId(),
879 layout.getSourcePrototypeLayoutUuid())) {
880
881 return false;
882 }
883 }
884 catch (Exception e) {
885 if (_log.isDebugEnabled()) {
886 _log.debug(e, e);
887 }
888 }
889
890 return true;
891 }
892
893 @Override
894 public boolean isLayoutModifiedSinceLastMerge(Layout layout) {
895 if ((layout == null) ||
896 Validator.isNull(layout.getSourcePrototypeLayoutUuid()) ||
897 layout.isLayoutPrototypeLinkActive() ||
898 !isLayoutUpdateable(layout)) {
899
900 return false;
901 }
902
903 long lastMergeTime = GetterUtil.getLong(
904 layout.getTypeSettingsProperty(LAST_MERGE_TIME));
905
906 if (lastMergeTime == 0) {
907 return false;
908 }
909
910 Date existingLayoutModifiedDate = layout.getModifiedDate();
911
912 if ((existingLayoutModifiedDate != null) &&
913 (existingLayoutModifiedDate.getTime() > lastMergeTime)) {
914
915 return true;
916 }
917
918 return false;
919 }
920
921
936 @Override
937 public boolean isLayoutSetMergeable(Group group, LayoutSet layoutSet)
938 throws PortalException {
939
940 if (!layoutSet.isLayoutSetPrototypeLinkActive() ||
941 group.isLayoutPrototype() || group.isLayoutSetPrototype()) {
942
943 return false;
944 }
945
946 UnicodeProperties settingsProperties =
947 layoutSet.getSettingsProperties();
948
949 long lastMergeTime = GetterUtil.getLong(
950 settingsProperties.getProperty(LAST_MERGE_TIME));
951
952 LayoutSetPrototype layoutSetPrototype =
953 LayoutSetPrototypeLocalServiceUtil.
954 getLayoutSetPrototypeByUuidAndCompanyId(
955 layoutSet.getLayoutSetPrototypeUuid(),
956 layoutSet.getCompanyId());
957
958 Date modifiedDate = layoutSetPrototype.getModifiedDate();
959
960 if (lastMergeTime >= modifiedDate.getTime()) {
961 return false;
962 }
963
964 LayoutSet layoutSetPrototypeLayoutSet =
965 layoutSetPrototype.getLayoutSet();
966
967 UnicodeProperties layoutSetPrototypeSettingsProperties =
968 layoutSetPrototypeLayoutSet.getSettingsProperties();
969
970 int mergeFailCount = GetterUtil.getInteger(
971 layoutSetPrototypeSettingsProperties.getProperty(MERGE_FAIL_COUNT));
972
973 if (mergeFailCount >
974 PropsValues.LAYOUT_SET_PROTOTYPE_MERGE_FAIL_THRESHOLD) {
975
976 if (_log.isWarnEnabled()) {
977 StringBundler sb = new StringBundler(6);
978
979 sb.append("Merge not performed because the fail threshold ");
980 sb.append("was reached for layoutSetPrototypeId ");
981 sb.append(layoutSetPrototype.getLayoutSetPrototypeId());
982 sb.append(" and layoutId ");
983 sb.append(layoutSetPrototypeLayoutSet.getLayoutSetId());
984 sb.append(". Update the count in the database to try again.");
985
986 _log.warn(sb.toString());
987 }
988
989 return false;
990 }
991
992 return true;
993 }
994
995 @Override
996 public boolean isLayoutSetPrototypeUpdateable(LayoutSet layoutSet) {
997 if (!layoutSet.isLayoutSetPrototypeLinkActive()) {
998 return true;
999 }
1000
1001 try {
1002 LayoutSetPrototype layoutSetPrototype =
1003 LayoutSetPrototypeLocalServiceUtil.
1004 getLayoutSetPrototypeByUuidAndCompanyId(
1005 layoutSet.getLayoutSetPrototypeUuid(),
1006 layoutSet.getCompanyId());
1007
1008 String layoutsUpdateable = layoutSetPrototype.getSettingsProperty(
1009 "layoutsUpdateable");
1010
1011 if (Validator.isNotNull(layoutsUpdateable)) {
1012 return GetterUtil.getBoolean(layoutsUpdateable, true);
1013 }
1014 }
1015 catch (Exception e) {
1016 if (_log.isDebugEnabled()) {
1017 _log.debug(e, e);
1018 }
1019 }
1020
1021 return true;
1022 }
1023
1024 @Override
1025 public boolean isLayoutSortable(Layout layout) {
1026 return isLayoutDeleteable(layout);
1027 }
1028
1029 @Override
1030 public boolean isLayoutUpdateable(Layout layout) {
1031 try {
1032 if (layout instanceof VirtualLayout) {
1033 return false;
1034 }
1035
1036 if (Validator.isNull(layout.getLayoutPrototypeUuid()) &&
1037 Validator.isNull(layout.getSourcePrototypeLayoutUuid())) {
1038
1039 return true;
1040 }
1041
1042 LayoutSet layoutSet = layout.getLayoutSet();
1043
1044 if (layoutSet.isLayoutSetPrototypeLinkActive()) {
1045 boolean layoutSetPrototypeUpdateable =
1046 isLayoutSetPrototypeUpdateable(layoutSet);
1047
1048 if (!layoutSetPrototypeUpdateable) {
1049 return false;
1050 }
1051
1052 Layout layoutSetPrototypeLayout = getLayoutSetPrototypeLayout(
1053 layout);
1054
1055 String layoutUpdateable =
1056 layoutSetPrototypeLayout.getTypeSettingsProperty(
1057 LAYOUT_UPDATEABLE);
1058
1059 if (Validator.isNull(layoutUpdateable)) {
1060 return true;
1061 }
1062
1063 return GetterUtil.getBoolean(layoutUpdateable);
1064 }
1065 }
1066 catch (Exception e) {
1067 if (_log.isDebugEnabled()) {
1068 _log.debug(e, e);
1069 }
1070 }
1071
1072 return true;
1073 }
1074
1075 @Override
1076 public boolean isUserGroupLayoutSetViewable(
1077 PermissionChecker permissionChecker, Group userGroupGroup)
1078 throws PortalException {
1079
1080 if (!userGroupGroup.isUserGroup()) {
1081 return false;
1082 }
1083
1084 if (GroupPermissionUtil.contains(
1085 permissionChecker, userGroupGroup, ActionKeys.VIEW)) {
1086
1087 return true;
1088 }
1089
1090 UserGroup userGroup = UserGroupLocalServiceUtil.getUserGroup(
1091 userGroupGroup.getClassPK());
1092
1093 if (UserLocalServiceUtil.hasUserGroupUser(
1094 userGroup.getUserGroupId(), permissionChecker.getUserId())) {
1095
1096 return true;
1097 }
1098 else {
1099 return false;
1100 }
1101 }
1102
1103 @Override
1104 public void mergeLayoutPrototypeLayout(Group group, Layout layout)
1105 throws Exception {
1106
1107 String sourcePrototypeLayoutUuid =
1108 layout.getSourcePrototypeLayoutUuid();
1109
1110 if (Validator.isNull(sourcePrototypeLayoutUuid)) {
1111 doMergeLayoutPrototypeLayout(group, layout);
1112
1113 return;
1114 }
1115
1116 LayoutSet layoutSet = layout.getLayoutSet();
1117
1118 long layoutSetPrototypeId = layoutSet.getLayoutSetPrototypeId();
1119
1120 if (layoutSetPrototypeId > 0) {
1121 Group layoutSetPrototypeGroup =
1122 GroupLocalServiceUtil.getLayoutSetPrototypeGroup(
1123 layout.getCompanyId(), layoutSetPrototypeId);
1124
1125 Layout sourcePrototypeLayout =
1126 LayoutLocalServiceUtil.fetchLayoutByUuidAndGroupId(
1127 sourcePrototypeLayoutUuid,
1128 layoutSetPrototypeGroup.getGroupId(), true);
1129
1130 if (sourcePrototypeLayout != null) {
1131 doMergeLayoutPrototypeLayout(
1132 layoutSetPrototypeGroup, sourcePrototypeLayout);
1133 }
1134 }
1135
1136 doMergeLayoutPrototypeLayout(group, layout);
1137 }
1138
1139
1143 @Deprecated
1144 @Override
1145 public void mergeLayoutProtypeLayout(Group group, Layout layout)
1146 throws Exception {
1147
1148 mergeLayoutPrototypeLayout(group, layout);
1149 }
1150
1151 @Override
1152 public void mergeLayoutSetPrototypeLayouts(Group group, LayoutSet layoutSet)
1153 throws Exception {
1154
1155 if (!isLayoutSetMergeable(group, layoutSet)) {
1156 return;
1157 }
1158
1159 UnicodeProperties settingsProperties =
1160 layoutSet.getSettingsProperties();
1161
1162 long lastMergeTime = GetterUtil.getLong(
1163 settingsProperties.getProperty(LAST_MERGE_TIME));
1164
1165 LayoutSetPrototype layoutSetPrototype =
1166 LayoutSetPrototypeLocalServiceUtil.
1167 getLayoutSetPrototypeByUuidAndCompanyId(
1168 layoutSet.getLayoutSetPrototypeUuid(),
1169 layoutSet.getCompanyId());
1170
1171 LayoutSet layoutSetPrototypeLayoutSet =
1172 layoutSetPrototype.getLayoutSet();
1173
1174 UnicodeProperties layoutSetPrototypeSettingsProperties =
1175 layoutSetPrototypeLayoutSet.getSettingsProperties();
1176
1177 int mergeFailCount = GetterUtil.getInteger(
1178 layoutSetPrototypeSettingsProperties.getProperty(MERGE_FAIL_COUNT));
1179
1180 String owner = PortalUUIDUtil.generate();
1181
1182 try {
1183 Lock lock = LockLocalServiceUtil.lock(
1184 LayoutLocalServiceVirtualLayoutsAdvice.class.getName(),
1185 String.valueOf(layoutSet.getLayoutSetId()), owner);
1186
1187
1188
1189 if (!owner.equals(lock.getOwner())) {
1190 Date createDate = lock.getCreateDate();
1191
1192 if ((System.currentTimeMillis() - createDate.getTime()) >=
1193 PropsValues.LAYOUT_SET_PROTOTYPE_MERGE_LOCK_MAX_TIME) {
1194
1195
1196
1197 lock = LockLocalServiceUtil.lock(
1198 LayoutLocalServiceVirtualLayoutsAdvice.class.getName(),
1199 String.valueOf(layoutSet.getLayoutSetId()),
1200 lock.getOwner(), owner);
1201
1202
1203
1204
1205 if (!owner.equals(lock.getOwner())) {
1206 return;
1207 }
1208 }
1209 else {
1210 return;
1211 }
1212 }
1213 }
1214 catch (Exception e) {
1215 return;
1216 }
1217
1218 try {
1219 MergeLayoutPrototypesThreadLocal.setInProgress(true);
1220
1221 boolean importData = true;
1222
1223 long lastResetTime = GetterUtil.getLong(
1224 settingsProperties.getProperty(LAST_RESET_TIME));
1225
1226 if ((lastMergeTime > 0) || (lastResetTime > 0)) {
1227 importData = false;
1228 }
1229
1230 Map<String, String[]> parameterMap =
1231 getLayoutSetPrototypesParameters(importData);
1232
1233 layoutSet = LayoutSetLocalServiceUtil.getLayoutSet(
1234 layoutSet.getLayoutSetId());
1235
1236 removeMergeFailFriendlyURLLayouts(layoutSet);
1237
1238 importLayoutSetPrototype(
1239 layoutSetPrototype, layoutSet.getGroupId(),
1240 layoutSet.isPrivateLayout(), parameterMap, importData);
1241 }
1242 catch (Exception e) {
1243 _log.error(e, e);
1244
1245 layoutSetPrototypeSettingsProperties.setProperty(
1246 MERGE_FAIL_COUNT, String.valueOf(++mergeFailCount));
1247
1248
1249
1250 LayoutSetUtil.updateImpl(layoutSetPrototypeLayoutSet);
1251 }
1252 finally {
1253 MergeLayoutPrototypesThreadLocal.setInProgress(false);
1254
1255 LockLocalServiceUtil.unlock(
1256 LayoutLocalServiceVirtualLayoutsAdvice.class.getName(),
1257 String.valueOf(layoutSet.getLayoutSetId()), owner);
1258 }
1259 }
1260
1261
1265 @Deprecated
1266 @Override
1267 public void mergeLayoutSetProtypeLayouts(Group group, LayoutSet layoutSet)
1268 throws Exception {
1269
1270 mergeLayoutSetPrototypeLayouts(group, layoutSet);
1271 }
1272
1273 @Override
1274 public void removeMergeFailFriendlyURLLayouts(LayoutSet layoutSet) {
1275 UnicodeProperties settingsProperties =
1276 layoutSet.getSettingsProperties();
1277
1278 settingsProperties.remove(MERGE_FAIL_FRIENDLY_URL_LAYOUTS);
1279
1280 LayoutSetLocalServiceUtil.updateLayoutSet(layoutSet);
1281 }
1282
1283
1292 @Override
1293 public void resetPrototype(Layout layout) throws PortalException {
1294 checkResetPrototypePermissions(layout.getGroup(), layout);
1295
1296 doResetPrototype(layout);
1297 }
1298
1299
1308 @Override
1309 public void resetPrototype(LayoutSet layoutSet) throws PortalException {
1310 checkResetPrototypePermissions(layoutSet.getGroup(), null);
1311
1312 doResetPrototype(layoutSet);
1313 }
1314
1315
1325 @Override
1326 public void setMergeFailCount(
1327 LayoutPrototype layoutPrototype, int newMergeFailCount)
1328 throws PortalException {
1329
1330 Layout layoutPrototypeLayout = layoutPrototype.getLayout();
1331
1332 UnicodeProperties prototypeTypeSettingsProperties =
1333 layoutPrototypeLayout.getTypeSettingsProperties();
1334
1335 if (newMergeFailCount == 0) {
1336 prototypeTypeSettingsProperties.remove(MERGE_FAIL_COUNT);
1337 }
1338 else {
1339 prototypeTypeSettingsProperties.setProperty(
1340 MERGE_FAIL_COUNT, String.valueOf(newMergeFailCount));
1341 }
1342
1343 LayoutServiceUtil.updateLayout(
1344 layoutPrototypeLayout.getGroupId(),
1345 layoutPrototypeLayout.getPrivateLayout(),
1346 layoutPrototypeLayout.getLayoutId(),
1347 layoutPrototypeLayout.getTypeSettings());
1348 }
1349
1350
1360 @Override
1361 public void setMergeFailCount(
1362 LayoutSetPrototype layoutSetPrototype, int newMergeFailCount)
1363 throws PortalException {
1364
1365 LayoutSet layoutSetPrototypeLayoutSet =
1366 layoutSetPrototype.getLayoutSet();
1367
1368 UnicodeProperties layoutSetPrototypeSettingsProperties =
1369 layoutSetPrototypeLayoutSet.getSettingsProperties();
1370
1371 if (newMergeFailCount == 0) {
1372 layoutSetPrototypeSettingsProperties.remove(MERGE_FAIL_COUNT);
1373 }
1374 else {
1375 layoutSetPrototypeSettingsProperties.setProperty(
1376 MERGE_FAIL_COUNT, String.valueOf(newMergeFailCount));
1377 }
1378
1379 LayoutSetServiceUtil.updateSettings(
1380 layoutSetPrototypeLayoutSet.getGroupId(),
1381 layoutSetPrototypeLayoutSet.getPrivateLayout(),
1382 layoutSetPrototypeLayoutSet.getSettings());
1383 }
1384
1385 @Override
1386 public void updateLayoutScopes(
1387 long userId, Layout sourceLayout, Layout targetLayout,
1388 PortletPreferences sourcePreferences,
1389 PortletPreferences targetPreferences, String sourcePortletId,
1390 String languageId)
1391 throws Exception {
1392
1393 String scopeType = GetterUtil.getString(
1394 sourcePreferences.getValue("lfrScopeType", null));
1395
1396 if (Validator.isNull(scopeType) || !scopeType.equals("layout")) {
1397 return;
1398 }
1399
1400 Layout targetScopeLayout =
1401 LayoutLocalServiceUtil.getLayoutByUuidAndGroupId(
1402 targetLayout.getUuid(), targetLayout.getGroupId(),
1403 targetLayout.isPrivateLayout());
1404
1405 if (!targetScopeLayout.hasScopeGroup()) {
1406 GroupLocalServiceUtil.addGroup(
1407 userId, GroupConstants.DEFAULT_PARENT_GROUP_ID,
1408 Layout.class.getName(), targetLayout.getPlid(),
1409 GroupConstants.DEFAULT_LIVE_GROUP_ID,
1410 targetLayout.getName(languageId), null, 0, true,
1411 GroupConstants.DEFAULT_MEMBERSHIP_RESTRICTION, null, false,
1412 true, null);
1413 }
1414
1415 String portletTitle = PortalUtil.getPortletTitle(
1416 sourcePortletId, languageId);
1417
1418 String newPortletTitle = PortalUtil.getNewPortletTitle(
1419 portletTitle, String.valueOf(sourceLayout.getLayoutId()),
1420 targetLayout.getName(languageId));
1421
1422 targetPreferences.setValue(
1423 "groupId", String.valueOf(targetLayout.getGroupId()));
1424 targetPreferences.setValue("lfrScopeType", "layout");
1425 targetPreferences.setValue(
1426 "lfrScopeLayoutUuid", targetLayout.getUuid());
1427 targetPreferences.setValue(
1428 "portletSetupTitle_" + languageId, newPortletTitle);
1429 targetPreferences.setValue(
1430 "portletSetupUseCustomTitle", Boolean.TRUE.toString());
1431
1432 targetPreferences.store();
1433 }
1434
1435 @Override
1436 public void updateLayoutSetPrototypesLinks(
1437 Group group, long publicLayoutSetPrototypeId,
1438 long privateLayoutSetPrototypeId,
1439 boolean publicLayoutSetPrototypeLinkEnabled,
1440 boolean privateLayoutSetPrototypeLinkEnabled)
1441 throws Exception {
1442
1443 updateLayoutSetPrototypeLink(
1444 group.getGroupId(), true, privateLayoutSetPrototypeId,
1445 privateLayoutSetPrototypeLinkEnabled);
1446 updateLayoutSetPrototypeLink(
1447 group.getGroupId(), false, publicLayoutSetPrototypeId,
1448 publicLayoutSetPrototypeLinkEnabled);
1449 }
1450
1451
1462 protected void checkResetPrototypePermissions(Group group, Layout layout)
1463 throws PortalException {
1464
1465 PermissionChecker permissionChecker =
1466 PermissionThreadLocal.getPermissionChecker();
1467
1468 if ((layout != null) &&
1469 !LayoutPermissionUtil.contains(
1470 permissionChecker, layout, ActionKeys.UPDATE)) {
1471
1472 throw new PrincipalException();
1473 }
1474 else if (!group.isUser() &&
1475 !GroupPermissionUtil.contains(
1476 permissionChecker, group, ActionKeys.UPDATE)) {
1477
1478 throw new PrincipalException();
1479 }
1480 else if (group.isUser() &&
1481 (permissionChecker.getUserId() != group.getClassPK())) {
1482
1483 throw new PrincipalException();
1484 }
1485 }
1486
1487 protected void doMergeLayoutPrototypeLayout(Group group, Layout layout)
1488 throws Exception {
1489
1490 if (!layout.isLayoutPrototypeLinkActive() ||
1491 group.isLayoutPrototype() || group.hasStagingGroup()) {
1492
1493 return;
1494 }
1495
1496 long lastMergeTime = GetterUtil.getLong(
1497 layout.getTypeSettingsProperty(LAST_MERGE_TIME));
1498
1499 LayoutPrototype layoutPrototype =
1500 LayoutPrototypeLocalServiceUtil.
1501 getLayoutPrototypeByUuidAndCompanyId(
1502 layout.getLayoutPrototypeUuid(), layout.getCompanyId());
1503
1504 Layout layoutPrototypeLayout = layoutPrototype.getLayout();
1505
1506 Date modifiedDate = layoutPrototypeLayout.getModifiedDate();
1507
1508 if (lastMergeTime >= modifiedDate.getTime()) {
1509 return;
1510 }
1511
1512 UnicodeProperties prototypeTypeSettingsProperties =
1513 layoutPrototypeLayout.getTypeSettingsProperties();
1514
1515 int mergeFailCount = GetterUtil.getInteger(
1516 prototypeTypeSettingsProperties.getProperty(MERGE_FAIL_COUNT));
1517
1518 if (mergeFailCount >
1519 PropsValues.LAYOUT_PROTOTYPE_MERGE_FAIL_THRESHOLD) {
1520
1521 if (_log.isWarnEnabled()) {
1522 StringBundler sb = new StringBundler(6);
1523
1524 sb.append("Merge not performed because the fail threshold ");
1525 sb.append("was reached for layoutPrototypeId ");
1526 sb.append(layoutPrototype.getLayoutPrototypeId());
1527 sb.append(" and layoutId ");
1528 sb.append(layoutPrototypeLayout.getLayoutId());
1529 sb.append(". Update the count in the database to try again.");
1530
1531 _log.warn(sb.toString());
1532 }
1533
1534 return;
1535 }
1536
1537 String owner = PortalUUIDUtil.generate();
1538
1539 try {
1540 Lock lock = LockLocalServiceUtil.lock(
1541 LayoutLocalServiceVirtualLayoutsAdvice.class.getName(),
1542 String.valueOf(layout.getPlid()), owner);
1543
1544 if (!owner.equals(lock.getOwner())) {
1545 Date createDate = lock.getCreateDate();
1546
1547 if ((System.currentTimeMillis() - createDate.getTime()) >=
1548 PropsValues.LAYOUT_PROTOTYPE_MERGE_LOCK_MAX_TIME) {
1549
1550
1551
1552 lock = LockLocalServiceUtil.lock(
1553 LayoutLocalServiceVirtualLayoutsAdvice.class.getName(),
1554 String.valueOf(layout.getPlid()), lock.getOwner(),
1555 owner);
1556
1557
1558
1559
1560 if (!owner.equals(lock.getOwner())) {
1561 return;
1562 }
1563 }
1564 else {
1565 return;
1566 }
1567 }
1568 }
1569 catch (Exception e) {
1570 return;
1571 }
1572
1573 try {
1574 MergeLayoutPrototypesThreadLocal.setInProgress(true);
1575
1576 applyLayoutPrototype(layoutPrototype, layout, true);
1577 }
1578 catch (Exception e) {
1579 _log.error(e, e);
1580
1581 prototypeTypeSettingsProperties.setProperty(
1582 MERGE_FAIL_COUNT, String.valueOf(++mergeFailCount));
1583
1584
1585
1586 LayoutUtil.updateImpl(layoutPrototypeLayout);
1587 }
1588 finally {
1589 MergeLayoutPrototypesThreadLocal.setInProgress(false);
1590
1591 LockLocalServiceUtil.unlock(
1592 LayoutLocalServiceVirtualLayoutsAdvice.class.getName(),
1593 String.valueOf(layout.getPlid()), owner);
1594 }
1595 }
1596
1597
1612 protected void doResetPrototype(Layout layout) throws PortalException {
1613 layout.setModifiedDate(null);
1614
1615 LayoutLocalServiceUtil.updateLayout(layout);
1616
1617 LayoutSet layoutSet = layout.getLayoutSet();
1618
1619 doResetPrototype(layoutSet);
1620 }
1621
1622
1632 protected void doResetPrototype(LayoutSet layoutSet) {
1633 UnicodeProperties settingsProperties =
1634 layoutSet.getSettingsProperties();
1635
1636 settingsProperties.remove(LAST_MERGE_TIME);
1637
1638 settingsProperties.setProperty(
1639 LAST_RESET_TIME, String.valueOf(System.currentTimeMillis()));
1640
1641 LayoutSetLocalServiceUtil.updateLayoutSet(layoutSet);
1642 }
1643
1644 protected Map<String, String[]> getLayoutSetPrototypesParameters(
1645 boolean importData) {
1646
1647 Map<String, String[]> parameterMap =
1648 new LinkedHashMap<String, String[]>();
1649
1650 parameterMap.put(
1651 PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS,
1652 new String[] {Boolean.FALSE.toString()});
1653 parameterMap.put(
1654 PortletDataHandlerKeys.DELETE_PORTLET_DATA,
1655 new String[] {Boolean.FALSE.toString()});
1656 parameterMap.put(
1657 PortletDataHandlerKeys.IGNORE_LAST_PUBLISH_DATE,
1658 new String[] {Boolean.TRUE.toString()});
1659 parameterMap.put(
1660 PortletDataHandlerKeys.LAYOUT_SET_SETTINGS,
1661 new String[] {Boolean.TRUE.toString()});
1662 parameterMap.put(
1663 PortletDataHandlerKeys.LAYOUT_SET_PROTOTYPE_LINK_ENABLED,
1664 new String[] {Boolean.TRUE.toString()});
1665 parameterMap.put(
1666 PortletDataHandlerKeys.LAYOUTS_IMPORT_MODE,
1667 new String[] {
1668 PortletDataHandlerKeys.
1669 LAYOUTS_IMPORT_MODE_CREATED_FROM_PROTOTYPE
1670 });
1671 parameterMap.put(
1672 PortletDataHandlerKeys.PERMISSIONS,
1673 new String[] {Boolean.TRUE.toString()});
1674 parameterMap.put(
1675 PortletDataHandlerKeys.PORTLET_CONFIGURATION,
1676 new String[] {Boolean.TRUE.toString()});
1677 parameterMap.put(
1678 PortletDataHandlerKeys.PORTLET_CONFIGURATION_ALL,
1679 new String[] {Boolean.TRUE.toString()});
1680 parameterMap.put(
1681 PortletDataHandlerKeys.PORTLET_DATA + StringPool.UNDERLINE +
1682 PortletKeys.ASSET_CATEGORIES_ADMIN,
1683 new String[] {Boolean.TRUE.toString()});
1684 parameterMap.put(
1685 PortletDataHandlerKeys.PORTLET_SETUP_ALL,
1686 new String[] {Boolean.TRUE.toString()});
1687 parameterMap.put(
1688 PortletDataHandlerKeys.THEME_REFERENCE,
1689 new String[] {Boolean.TRUE.toString()});
1690 parameterMap.put(
1691 PortletDataHandlerKeys.UPDATE_LAST_PUBLISH_DATE,
1692 new String[] {Boolean.FALSE.toString()});
1693 parameterMap.put(
1694 PortletDataHandlerKeys.USER_ID_STRATEGY,
1695 new String[] {UserIdStrategy.CURRENT_USER_ID});
1696
1697 if (importData) {
1698 parameterMap.put(
1699 PortletDataHandlerKeys.DATA_STRATEGY,
1700 new String[] {PortletDataHandlerKeys.DATA_STRATEGY_MIRROR});
1701 parameterMap.put(
1702 PortletDataHandlerKeys.LOGO,
1703 new String[] {Boolean.TRUE.toString()});
1704 parameterMap.put(
1705 PortletDataHandlerKeys.PORTLET_DATA,
1706 new String[] {Boolean.TRUE.toString()});
1707 parameterMap.put(
1708 PortletDataHandlerKeys.PORTLET_DATA_ALL,
1709 new String[] {Boolean.TRUE.toString()});
1710 }
1711 else {
1712 if (PropsValues.LAYOUT_SET_PROTOTYPE_PROPAGATE_LOGO) {
1713 parameterMap.put(
1714 PortletDataHandlerKeys.LOGO,
1715 new String[] {Boolean.TRUE.toString()});
1716 }
1717 else {
1718 parameterMap.put(
1719 PortletDataHandlerKeys.LOGO,
1720 new String[] {Boolean.FALSE.toString()});
1721 }
1722
1723 parameterMap.put(
1724 PortletDataHandlerKeys.PORTLET_DATA,
1725 new String[] {Boolean.FALSE.toString()});
1726 parameterMap.put(
1727 PortletDataHandlerKeys.PORTLET_DATA_ALL,
1728 new String[] {Boolean.FALSE.toString()});
1729 }
1730
1731 return parameterMap;
1732 }
1733
1734 protected void importLayoutSetPrototype(
1735 LayoutSetPrototype layoutSetPrototype, long groupId,
1736 boolean privateLayout, Map<String, String[]> parameterMap,
1737 boolean importData)
1738 throws PortalException {
1739
1740 File file = null;
1741
1742 StringBundler sb = new StringBundler(importData ? 4 : 3);
1743
1744 sb.append(_TEMP_DIR);
1745 sb.append(layoutSetPrototype.getUuid());
1746
1747 if (importData) {
1748 sb.append("-data");
1749 }
1750
1751 sb.append(".lar");
1752
1753 File cacheFile = new File(sb.toString());
1754
1755 if (cacheFile.exists()) {
1756 Date modifiedDate = layoutSetPrototype.getModifiedDate();
1757
1758 if (cacheFile.lastModified() >= modifiedDate.getTime()) {
1759 if (_log.isDebugEnabled()) {
1760 _log.debug(
1761 "Using cached layout set prototype LAR file " +
1762 cacheFile.getAbsolutePath());
1763 }
1764
1765 file = cacheFile;
1766 }
1767 }
1768
1769 boolean newFile = false;
1770
1771 if (file == null) {
1772 file = LayoutLocalServiceUtil.exportLayoutsAsFile(
1773 layoutSetPrototype.getGroupId(), true, null, parameterMap, null,
1774 null);
1775
1776 newFile = true;
1777 }
1778
1779 long userId = UserLocalServiceUtil.getDefaultUserId(
1780 layoutSetPrototype.getCompanyId());
1781
1782 LayoutLocalServiceUtil.importLayouts(
1783 userId, groupId, privateLayout, parameterMap, file);
1784
1785 if (newFile) {
1786 try {
1787 FileUtil.copyFile(file, cacheFile);
1788
1789 if (_log.isDebugEnabled()) {
1790 _log.debug(
1791 "Copied " + file.getAbsolutePath() + " to " +
1792 cacheFile.getAbsolutePath());
1793 }
1794 }
1795 catch (Exception e) {
1796 _log.error(
1797 "Unable to copy file " + file.getAbsolutePath() + " to " +
1798 cacheFile.getAbsolutePath(),
1799 e);
1800 }
1801 }
1802 }
1803
1804 protected void setLayoutSetPrototypeLinkEnabledParameter(
1805 Map<String, String[]> parameterMap, LayoutSet targetLayoutSet,
1806 ServiceContext serviceContext) {
1807
1808 PermissionChecker permissionChecker =
1809 PermissionThreadLocal.getPermissionChecker();
1810
1811 if ((permissionChecker == null) ||
1812 !PortalPermissionUtil.contains(
1813 permissionChecker, ActionKeys.UNLINK_LAYOUT_SET_PROTOTYPE)) {
1814
1815 return;
1816 }
1817
1818 if (targetLayoutSet.isPrivateLayout()) {
1819 boolean privateLayoutSetPrototypeLinkEnabled = ParamUtil.getBoolean(
1820 serviceContext, "privateLayoutSetPrototypeLinkEnabled", true);
1821
1822 if (!privateLayoutSetPrototypeLinkEnabled) {
1823 privateLayoutSetPrototypeLinkEnabled = ParamUtil.getBoolean(
1824 serviceContext, "layoutSetPrototypeLinkEnabled");
1825 }
1826
1827 parameterMap.put(
1828 PortletDataHandlerKeys.LAYOUT_SET_PROTOTYPE_LINK_ENABLED,
1829 new String[] {
1830 String.valueOf(privateLayoutSetPrototypeLinkEnabled)
1831 });
1832 }
1833 else {
1834 boolean publicLayoutSetPrototypeLinkEnabled = ParamUtil.getBoolean(
1835 serviceContext, "publicLayoutSetPrototypeLinkEnabled");
1836
1837 if (!publicLayoutSetPrototypeLinkEnabled) {
1838 publicLayoutSetPrototypeLinkEnabled = ParamUtil.getBoolean(
1839 serviceContext, "layoutSetPrototypeLinkEnabled", true);
1840 }
1841
1842 parameterMap.put(
1843 PortletDataHandlerKeys.LAYOUT_SET_PROTOTYPE_LINK_ENABLED,
1844 new String[] {
1845 String.valueOf(publicLayoutSetPrototypeLinkEnabled)
1846 });
1847 }
1848 }
1849
1850 protected void updateLayoutSetPrototypeLink(
1851 long groupId, boolean privateLayout, long layoutSetPrototypeId,
1852 boolean layoutSetPrototypeLinkEnabled)
1853 throws Exception {
1854
1855 String layoutSetPrototypeUuid = null;
1856
1857 if (layoutSetPrototypeId > 0) {
1858 LayoutSetPrototype layoutSetPrototype =
1859 LayoutSetPrototypeLocalServiceUtil.fetchLayoutSetPrototype(
1860 layoutSetPrototypeId);
1861
1862 if (layoutSetPrototype != null) {
1863 layoutSetPrototypeUuid = layoutSetPrototype.getUuid();
1864
1865
1866
1867 if (!layoutSetPrototypeLinkEnabled &&
1868 (layoutSetPrototypeId > 0)) {
1869
1870 Map<String, String[]> parameterMap =
1871 getLayoutSetPrototypesParameters(true);
1872
1873 importLayoutSetPrototype(
1874 layoutSetPrototype, groupId, privateLayout,
1875 parameterMap, true);
1876 }
1877 }
1878 }
1879
1880 LayoutSetServiceUtil.updateLayoutSetPrototypeLinkEnabled(
1881 groupId, privateLayout, layoutSetPrototypeLinkEnabled,
1882 layoutSetPrototypeUuid);
1883
1884 LayoutLocalServiceUtil.updatePriorities(groupId, privateLayout);
1885
1886
1887
1888 Group group = GroupLocalServiceUtil.getGroup(groupId);
1889
1890 LayoutSet layoutSet = LayoutSetLocalServiceUtil.getLayoutSet(
1891 groupId, privateLayout);
1892
1893 mergeLayoutSetPrototypeLayouts(group, layoutSet);
1894 }
1895
1896 private static final String _TEMP_DIR =
1897 SystemProperties.get(SystemProperties.TMP_DIR) +
1898 "/liferay/layout_set_prototype/";
1899
1900 private static Log _log = LogFactoryUtil.getLog(SitesImpl.class);
1901
1902 }