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