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