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