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