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