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.uuid.PortalUUIDUtil;
042 import com.liferay.portal.kernel.workflow.WorkflowConstants;
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.GroupLocalServiceUtil;
067 import com.liferay.portal.service.GroupServiceUtil;
068 import com.liferay.portal.service.LayoutLocalServiceUtil;
069 import com.liferay.portal.service.LayoutPrototypeLocalServiceUtil;
070 import com.liferay.portal.service.LayoutServiceUtil;
071 import com.liferay.portal.service.LayoutSetLocalServiceUtil;
072 import com.liferay.portal.service.LayoutSetPrototypeLocalServiceUtil;
073 import com.liferay.portal.service.LayoutSetServiceUtil;
074 import com.liferay.portal.service.OrganizationLocalServiceUtil;
075 import com.liferay.portal.service.PortletPreferencesLocalServiceUtil;
076 import com.liferay.portal.service.ResourcePermissionLocalServiceUtil;
077 import com.liferay.portal.service.RoleLocalServiceUtil;
078 import com.liferay.portal.service.ServiceContext;
079 import com.liferay.portal.service.ServiceContextFactory;
080 import com.liferay.portal.service.ServiceContextThreadLocal;
081 import com.liferay.portal.service.UserGroupLocalServiceUtil;
082 import com.liferay.portal.service.UserLocalServiceUtil;
083 import com.liferay.portal.service.impl.LayoutLocalServiceVirtualLayoutsAdvice;
084 import com.liferay.portal.service.permission.GroupPermissionUtil;
085 import com.liferay.portal.service.permission.LayoutPermissionUtil;
086 import com.liferay.portal.service.permission.PortalPermissionUtil;
087 import com.liferay.portal.service.permission.PortletPermissionUtil;
088 import com.liferay.portal.service.persistence.LayoutSetUtil;
089 import com.liferay.portal.service.persistence.LayoutUtil;
090 import com.liferay.portal.theme.ThemeDisplay;
091 import com.liferay.portal.util.PortalUtil;
092 import com.liferay.portal.util.PortletKeys;
093 import com.liferay.portal.util.PropsValues;
094 import com.liferay.portal.util.WebKeys;
095 import com.liferay.portlet.PortletPreferencesFactoryUtil;
096 import com.liferay.portlet.PortletPreferencesImpl;
097 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
753 @Override
754 public int getMergeFailCount(LayoutPrototype layoutPrototype)
755 throws PortalException {
756
757 if ((layoutPrototype == null) ||
758 (layoutPrototype.getLayoutPrototypeId() == 0)) {
759
760 return 0;
761 }
762
763 Layout layoutPrototypeLayout = layoutPrototype.getLayout();
764
765 UnicodeProperties prototypeTypeSettingsProperties =
766 layoutPrototypeLayout.getTypeSettingsProperties();
767
768 return GetterUtil.getInteger(
769 prototypeTypeSettingsProperties.getProperty(MERGE_FAIL_COUNT));
770 }
771
772
782 @Override
783 public int getMergeFailCount(LayoutSetPrototype layoutSetPrototype)
784 throws PortalException {
785
786 if ((layoutSetPrototype == null) ||
787 (layoutSetPrototype.getLayoutSetPrototypeId() == 0)) {
788
789 return 0;
790 }
791
792 LayoutSet layoutSetPrototypeLayoutSet =
793 layoutSetPrototype.getLayoutSet();
794
795 UnicodeProperties layoutSetPrototypeSettingsProperties =
796 layoutSetPrototypeLayoutSet.getSettingsProperties();
797
798 return GetterUtil.getInteger(
799 layoutSetPrototypeSettingsProperties.getProperty(MERGE_FAIL_COUNT));
800 }
801
802 @Override
803 public List<Layout> getMergeFailFriendlyURLLayouts(LayoutSet layoutSet)
804 throws PortalException {
805
806 if (layoutSet == null) {
807 return Collections.emptyList();
808 }
809
810 UnicodeProperties settingsProperties =
811 layoutSet.getSettingsProperties();
812
813 String uuids = settingsProperties.getProperty(
814 MERGE_FAIL_FRIENDLY_URL_LAYOUTS);
815
816 if (Validator.isNotNull(uuids)) {
817 List<Layout> layouts = new ArrayList<>();
818
819 for (String uuid : StringUtil.split(uuids)) {
820 Layout layout =
821 LayoutLocalServiceUtil.getLayoutByUuidAndGroupId(
822 uuid, layoutSet.getGroupId(),
823 layoutSet.isPrivateLayout());
824
825 layouts.add(layout);
826 }
827
828 return layouts;
829 }
830
831 return Collections.emptyList();
832 }
833
834 @Override
835 public List<String> getOrganizationNames(Group group, User user)
836 throws Exception {
837
838 List<Organization> organizations =
839 OrganizationLocalServiceUtil.getGroupUserOrganizations(
840 group.getGroupId(), user.getUserId());
841
842 return ListUtil.toList(organizations, Organization.NAME_ACCESSOR);
843 }
844
845 @Override
846 public List<String> getUserGroupNames(Group group, User user)
847 throws Exception {
848
849 List<UserGroup> userGroups =
850 UserGroupLocalServiceUtil.getGroupUserUserGroups(
851 group.getGroupId(), user.getUserId());
852
853 return ListUtil.toList(userGroups, UserGroup.NAME_ACCESSOR);
854 }
855
856 @Override
857 public void importLayoutSetPrototype(
858 LayoutSetPrototype layoutSetPrototype, InputStream inputStream,
859 ServiceContext serviceContext)
860 throws PortalException {
861
862 LayoutSet layoutSet = layoutSetPrototype.getLayoutSet();
863
864 Map<String, String[]> parameterMap = getLayoutSetPrototypeParameters(
865 serviceContext);
866
867 setLayoutSetPrototypeLinkEnabledParameter(
868 parameterMap, layoutSet, serviceContext);
869
870 User user = UserLocalServiceUtil.fetchUser(serviceContext.getUserId());
871
872 if (user == null) {
873 BackgroundTask backgroundTask =
874 BackgroundTaskManagerUtil.fetchBackgroundTask(
875 BackgroundTaskThreadLocal.getBackgroundTaskId());
876
877 if (backgroundTask != null) {
878 user = UserLocalServiceUtil.getUser(backgroundTask.getUserId());
879 }
880 }
881
882 if (user == null) {
883 user = UserLocalServiceUtil.getUser(
884 GetterUtil.getLong(PrincipalThreadLocal.getName()));
885 }
886
887 Map<String, Serializable> importLayoutSettingsMap =
888 ExportImportConfigurationSettingsMapFactory.
889 buildImportLayoutSettingsMap(
890 user.getUserId(), layoutSet.getGroupId(),
891 layoutSet.isPrivateLayout(), null, parameterMap,
892 user.getLocale(), user.getTimeZone());
893
894 ExportImportConfiguration exportImportConfiguration =
895 ExportImportConfigurationLocalServiceUtil.
896 addDraftExportImportConfiguration(
897 user.getUserId(),
898 ExportImportConfigurationConstants.TYPE_IMPORT_LAYOUT,
899 importLayoutSettingsMap);
900
901 ExportImportServiceUtil.importLayouts(
902 exportImportConfiguration, inputStream);
903 }
904
905 @Override
906 public boolean isContentSharingWithChildrenEnabled(Group group) {
907 UnicodeProperties typeSettingsProperties =
908 group.getParentLiveGroupTypeSettingsProperties();
909
910 int companyContentSharingEnabled = PrefsPropsUtil.getInteger(
911 group.getCompanyId(),
912 PropsKeys.SITES_CONTENT_SHARING_WITH_CHILDREN_ENABLED);
913
914 if (companyContentSharingEnabled ==
915 CONTENT_SHARING_WITH_CHILDREN_DISABLED) {
916
917 return false;
918 }
919
920 int groupContentSharingEnabled = GetterUtil.getInteger(
921 typeSettingsProperties.getProperty(
922 "contentSharingWithChildrenEnabled"),
923 CONTENT_SHARING_WITH_CHILDREN_DEFAULT_VALUE);
924
925 if ((groupContentSharingEnabled ==
926 CONTENT_SHARING_WITH_CHILDREN_ENABLED) ||
927 ((companyContentSharingEnabled ==
928 CONTENT_SHARING_WITH_CHILDREN_ENABLED_BY_DEFAULT) &&
929 (groupContentSharingEnabled ==
930 CONTENT_SHARING_WITH_CHILDREN_DEFAULT_VALUE))) {
931
932 return true;
933 }
934
935 return false;
936 }
937
938 @Override
939 public boolean isFirstLayout(
940 long groupId, boolean privateLayout, long layoutId) {
941
942 Layout firstLayout = LayoutLocalServiceUtil.fetchFirstLayout(
943 groupId, privateLayout, LayoutConstants.DEFAULT_PARENT_LAYOUT_ID);
944
945 if ((firstLayout != null) && (firstLayout.getLayoutId() == layoutId )) {
946 return true;
947 }
948
949 return false;
950 }
951
952 @Override
953 public boolean isLayoutDeleteable(Layout layout) {
954 try {
955 if (layout instanceof VirtualLayout) {
956 return false;
957 }
958
959 if (Validator.isNull(layout.getSourcePrototypeLayoutUuid())) {
960 return true;
961 }
962
963 LayoutSet layoutSet = layout.getLayoutSet();
964
965 if (!layoutSet.isLayoutSetPrototypeLinkActive()) {
966 return true;
967 }
968
969 if (LayoutLocalServiceUtil.hasLayoutSetPrototypeLayout(
970 layoutSet.getLayoutSetPrototypeUuid(),
971 layout.getCompanyId(),
972 layout.getSourcePrototypeLayoutUuid())) {
973
974 return false;
975 }
976 }
977 catch (Exception e) {
978 if (_log.isDebugEnabled()) {
979 _log.debug(e, e);
980 }
981 }
982
983 return true;
984 }
985
986 @Override
987 public boolean isLayoutModifiedSinceLastMerge(Layout layout) {
988 if ((layout == null) ||
989 Validator.isNull(layout.getSourcePrototypeLayoutUuid()) ||
990 layout.isLayoutPrototypeLinkActive() ||
991 !isLayoutUpdateable(layout)) {
992
993 return false;
994 }
995
996 long lastMergeTime = GetterUtil.getLong(
997 layout.getTypeSettingsProperty(LAST_MERGE_TIME));
998
999 if (lastMergeTime == 0) {
1000 return false;
1001 }
1002
1003 Date existingLayoutModifiedDate = layout.getModifiedDate();
1004
1005 if ((existingLayoutModifiedDate != null) &&
1006 (existingLayoutModifiedDate.getTime() > lastMergeTime)) {
1007
1008 return true;
1009 }
1010
1011 return false;
1012 }
1013
1014
1029 @Override
1030 public boolean isLayoutSetMergeable(Group group, LayoutSet layoutSet)
1031 throws PortalException {
1032
1033 if (!layoutSet.isLayoutSetPrototypeLinkActive() ||
1034 group.isLayoutPrototype() || group.isLayoutSetPrototype()) {
1035
1036 return false;
1037 }
1038
1039 UnicodeProperties settingsProperties =
1040 layoutSet.getSettingsProperties();
1041
1042 long lastMergeTime = GetterUtil.getLong(
1043 settingsProperties.getProperty(LAST_MERGE_TIME));
1044
1045 LayoutSetPrototype layoutSetPrototype =
1046 LayoutSetPrototypeLocalServiceUtil.
1047 getLayoutSetPrototypeByUuidAndCompanyId(
1048 layoutSet.getLayoutSetPrototypeUuid(),
1049 layoutSet.getCompanyId());
1050
1051 Date modifiedDate = layoutSetPrototype.getModifiedDate();
1052
1053 if (lastMergeTime >= modifiedDate.getTime()) {
1054 return false;
1055 }
1056
1057 LayoutSet layoutSetPrototypeLayoutSet =
1058 layoutSetPrototype.getLayoutSet();
1059
1060 UnicodeProperties layoutSetPrototypeSettingsProperties =
1061 layoutSetPrototypeLayoutSet.getSettingsProperties();
1062
1063 int mergeFailCount = GetterUtil.getInteger(
1064 layoutSetPrototypeSettingsProperties.getProperty(MERGE_FAIL_COUNT));
1065
1066 if (mergeFailCount >
1067 PropsValues.LAYOUT_SET_PROTOTYPE_MERGE_FAIL_THRESHOLD) {
1068
1069 if (_log.isWarnEnabled()) {
1070 StringBundler sb = new StringBundler(6);
1071
1072 sb.append("Merge not performed because the fail threshold ");
1073 sb.append("was reached for layoutSetPrototypeId ");
1074 sb.append(layoutSetPrototype.getLayoutSetPrototypeId());
1075 sb.append(" and layoutId ");
1076 sb.append(layoutSetPrototypeLayoutSet.getLayoutSetId());
1077 sb.append(". Update the count in the database to try again.");
1078
1079 _log.warn(sb.toString());
1080 }
1081
1082 return false;
1083 }
1084
1085 return true;
1086 }
1087
1088 @Override
1089 public boolean isLayoutSetPrototypeUpdateable(LayoutSet layoutSet) {
1090 if (!layoutSet.isLayoutSetPrototypeLinkActive()) {
1091 return true;
1092 }
1093
1094 try {
1095 LayoutSetPrototype layoutSetPrototype =
1096 LayoutSetPrototypeLocalServiceUtil.
1097 getLayoutSetPrototypeByUuidAndCompanyId(
1098 layoutSet.getLayoutSetPrototypeUuid(),
1099 layoutSet.getCompanyId());
1100
1101 String layoutsUpdateable = layoutSetPrototype.getSettingsProperty(
1102 "layoutsUpdateable");
1103
1104 if (Validator.isNotNull(layoutsUpdateable)) {
1105 return GetterUtil.getBoolean(layoutsUpdateable, true);
1106 }
1107 }
1108 catch (Exception e) {
1109 if (_log.isDebugEnabled()) {
1110 _log.debug(e, e);
1111 }
1112 }
1113
1114 return true;
1115 }
1116
1117 @Override
1118 public boolean isLayoutSortable(Layout layout) {
1119 return isLayoutDeleteable(layout);
1120 }
1121
1122 @Override
1123 public boolean isLayoutUpdateable(Layout layout) {
1124 try {
1125 if (layout instanceof VirtualLayout) {
1126 return false;
1127 }
1128
1129 if (Validator.isNull(layout.getLayoutPrototypeUuid()) &&
1130 Validator.isNull(layout.getSourcePrototypeLayoutUuid())) {
1131
1132 return true;
1133 }
1134
1135 LayoutSet layoutSet = layout.getLayoutSet();
1136
1137 if (layoutSet.isLayoutSetPrototypeLinkActive()) {
1138 boolean layoutSetPrototypeUpdateable =
1139 isLayoutSetPrototypeUpdateable(layoutSet);
1140
1141 if (!layoutSetPrototypeUpdateable) {
1142 return false;
1143 }
1144
1145 Layout layoutSetPrototypeLayout = getLayoutSetPrototypeLayout(
1146 layout);
1147
1148 String layoutUpdateable =
1149 layoutSetPrototypeLayout.getTypeSettingsProperty(
1150 LAYOUT_UPDATEABLE);
1151
1152 if (Validator.isNull(layoutUpdateable)) {
1153 return true;
1154 }
1155
1156 return GetterUtil.getBoolean(layoutUpdateable);
1157 }
1158 }
1159 catch (Exception e) {
1160 if (_log.isDebugEnabled()) {
1161 _log.debug(e, e);
1162 }
1163 }
1164
1165 return true;
1166 }
1167
1168 @Override
1169 public boolean isUserGroupLayout(Layout layout) throws PortalException {
1170 if (!(layout instanceof VirtualLayout)) {
1171 return false;
1172 }
1173
1174 VirtualLayout virtualLayout = (VirtualLayout)layout;
1175
1176 Layout sourceLayout = virtualLayout.getSourceLayout();
1177
1178 Group sourceGroup = sourceLayout.getGroup();
1179
1180 if (sourceGroup.isUserGroup()) {
1181 return true;
1182 }
1183
1184 return false;
1185 }
1186
1187 @Override
1188 public boolean isUserGroupLayoutSetViewable(
1189 PermissionChecker permissionChecker, Group userGroupGroup)
1190 throws PortalException {
1191
1192 if (!userGroupGroup.isUserGroup()) {
1193 return false;
1194 }
1195
1196 if (GroupPermissionUtil.contains(
1197 permissionChecker, userGroupGroup, ActionKeys.VIEW)) {
1198
1199 return true;
1200 }
1201
1202 UserGroup userGroup = UserGroupLocalServiceUtil.getUserGroup(
1203 userGroupGroup.getClassPK());
1204
1205 if (UserLocalServiceUtil.hasUserGroupUser(
1206 userGroup.getUserGroupId(), permissionChecker.getUserId())) {
1207
1208 return true;
1209 }
1210 else {
1211 return false;
1212 }
1213 }
1214
1215 @Override
1216 public void mergeLayoutPrototypeLayout(Group group, Layout layout)
1217 throws Exception {
1218
1219 String sourcePrototypeLayoutUuid =
1220 layout.getSourcePrototypeLayoutUuid();
1221
1222 if (Validator.isNull(sourcePrototypeLayoutUuid)) {
1223 doMergeLayoutPrototypeLayout(group, layout);
1224
1225 return;
1226 }
1227
1228 LayoutSet layoutSet = layout.getLayoutSet();
1229
1230 long layoutSetPrototypeId = layoutSet.getLayoutSetPrototypeId();
1231
1232 if (layoutSetPrototypeId > 0) {
1233 Group layoutSetPrototypeGroup =
1234 GroupLocalServiceUtil.getLayoutSetPrototypeGroup(
1235 layout.getCompanyId(), layoutSetPrototypeId);
1236
1237 Layout sourcePrototypeLayout =
1238 LayoutLocalServiceUtil.fetchLayoutByUuidAndGroupId(
1239 sourcePrototypeLayoutUuid,
1240 layoutSetPrototypeGroup.getGroupId(), true);
1241
1242 if (sourcePrototypeLayout != null) {
1243 doMergeLayoutPrototypeLayout(
1244 layoutSetPrototypeGroup, sourcePrototypeLayout);
1245 }
1246 }
1247
1248 doMergeLayoutPrototypeLayout(group, layout);
1249 }
1250
1251
1255 @Deprecated
1256 @Override
1257 public void mergeLayoutProtypeLayout(Group group, Layout layout)
1258 throws Exception {
1259
1260 mergeLayoutPrototypeLayout(group, layout);
1261 }
1262
1263 @Override
1264 public void mergeLayoutSetPrototypeLayouts(Group group, LayoutSet layoutSet)
1265 throws Exception {
1266
1267 if (!isLayoutSetMergeable(group, layoutSet)) {
1268 return;
1269 }
1270
1271 UnicodeProperties settingsProperties =
1272 layoutSet.getSettingsProperties();
1273
1274 long lastMergeTime = GetterUtil.getLong(
1275 settingsProperties.getProperty(LAST_MERGE_TIME));
1276
1277 LayoutSetPrototype layoutSetPrototype =
1278 LayoutSetPrototypeLocalServiceUtil.
1279 getLayoutSetPrototypeByUuidAndCompanyId(
1280 layoutSet.getLayoutSetPrototypeUuid(),
1281 layoutSet.getCompanyId());
1282
1283 LayoutSet layoutSetPrototypeLayoutSet =
1284 layoutSetPrototype.getLayoutSet();
1285
1286 UnicodeProperties layoutSetPrototypeSettingsProperties =
1287 layoutSetPrototypeLayoutSet.getSettingsProperties();
1288
1289 int mergeFailCount = GetterUtil.getInteger(
1290 layoutSetPrototypeSettingsProperties.getProperty(MERGE_FAIL_COUNT));
1291
1292 String owner = PortalUUIDUtil.generate();
1293
1294 try {
1295 Lock lock = LockManagerUtil.lock(
1296 LayoutLocalServiceVirtualLayoutsAdvice.class.getName(),
1297 String.valueOf(layoutSet.getLayoutSetId()), owner);
1298
1299
1300
1301 if (!owner.equals(lock.getOwner())) {
1302 Date createDate = lock.getCreateDate();
1303
1304 if ((System.currentTimeMillis() - createDate.getTime()) >=
1305 PropsValues.LAYOUT_SET_PROTOTYPE_MERGE_LOCK_MAX_TIME) {
1306
1307
1308
1309 lock = LockManagerUtil.lock(
1310 LayoutLocalServiceVirtualLayoutsAdvice.class.getName(),
1311 String.valueOf(layoutSet.getLayoutSetId()),
1312 lock.getOwner(), owner);
1313
1314
1315
1316
1317 if (!owner.equals(lock.getOwner())) {
1318 return;
1319 }
1320 }
1321 else {
1322 return;
1323 }
1324 }
1325 }
1326 catch (Exception e) {
1327 return;
1328 }
1329
1330 try {
1331 MergeLayoutPrototypesThreadLocal.setInProgress(true);
1332
1333 boolean importData = true;
1334
1335 long lastResetTime = GetterUtil.getLong(
1336 settingsProperties.getProperty(LAST_RESET_TIME));
1337
1338 if ((lastMergeTime > 0) || (lastResetTime > 0)) {
1339 importData = false;
1340 }
1341
1342 Map<String, String[]> parameterMap =
1343 getLayoutSetPrototypesParameters(importData);
1344
1345 layoutSet = LayoutSetLocalServiceUtil.getLayoutSet(
1346 layoutSet.getLayoutSetId());
1347
1348 removeMergeFailFriendlyURLLayouts(layoutSet);
1349
1350 importLayoutSetPrototype(
1351 layoutSetPrototype, layoutSet.getGroupId(),
1352 layoutSet.isPrivateLayout(), parameterMap, importData);
1353 }
1354 catch (Exception e) {
1355 _log.error(e, e);
1356
1357 layoutSetPrototypeSettingsProperties.setProperty(
1358 MERGE_FAIL_COUNT, String.valueOf(++mergeFailCount));
1359
1360
1361
1362 LayoutSetUtil.updateImpl(layoutSetPrototypeLayoutSet);
1363 }
1364 finally {
1365 MergeLayoutPrototypesThreadLocal.setInProgress(false);
1366
1367 LockManagerUtil.unlock(
1368 LayoutLocalServiceVirtualLayoutsAdvice.class.getName(),
1369 String.valueOf(layoutSet.getLayoutSetId()), owner);
1370 }
1371 }
1372
1373
1377 @Deprecated
1378 @Override
1379 public void mergeLayoutSetProtypeLayouts(Group group, LayoutSet layoutSet)
1380 throws Exception {
1381
1382 mergeLayoutSetPrototypeLayouts(group, layoutSet);
1383 }
1384
1385 @Override
1386 public void removeMergeFailFriendlyURLLayouts(LayoutSet layoutSet) {
1387 UnicodeProperties settingsProperties =
1388 layoutSet.getSettingsProperties();
1389
1390 settingsProperties.remove(MERGE_FAIL_FRIENDLY_URL_LAYOUTS);
1391
1392 LayoutSetLocalServiceUtil.updateLayoutSet(layoutSet);
1393 }
1394
1395
1404 @Override
1405 public void resetPrototype(Layout layout) throws PortalException {
1406 checkResetPrototypePermissions(layout.getGroup(), layout);
1407
1408 doResetPrototype(layout);
1409 }
1410
1411
1420 @Override
1421 public void resetPrototype(LayoutSet layoutSet) throws PortalException {
1422 checkResetPrototypePermissions(layoutSet.getGroup(), null);
1423
1424 doResetPrototype(layoutSet);
1425 }
1426
1427
1437 @Override
1438 public void setMergeFailCount(
1439 LayoutPrototype layoutPrototype, int newMergeFailCount)
1440 throws PortalException {
1441
1442 Layout layoutPrototypeLayout = layoutPrototype.getLayout();
1443
1444 UnicodeProperties prototypeTypeSettingsProperties =
1445 layoutPrototypeLayout.getTypeSettingsProperties();
1446
1447 if (newMergeFailCount == 0) {
1448 prototypeTypeSettingsProperties.remove(MERGE_FAIL_COUNT);
1449 }
1450 else {
1451 prototypeTypeSettingsProperties.setProperty(
1452 MERGE_FAIL_COUNT, String.valueOf(newMergeFailCount));
1453 }
1454
1455 LayoutServiceUtil.updateLayout(
1456 layoutPrototypeLayout.getGroupId(),
1457 layoutPrototypeLayout.getPrivateLayout(),
1458 layoutPrototypeLayout.getLayoutId(),
1459 layoutPrototypeLayout.getTypeSettings());
1460 }
1461
1462
1472 @Override
1473 public void setMergeFailCount(
1474 LayoutSetPrototype layoutSetPrototype, int newMergeFailCount)
1475 throws PortalException {
1476
1477 LayoutSet layoutSetPrototypeLayoutSet =
1478 layoutSetPrototype.getLayoutSet();
1479
1480 UnicodeProperties layoutSetPrototypeSettingsProperties =
1481 layoutSetPrototypeLayoutSet.getSettingsProperties();
1482
1483 if (newMergeFailCount == 0) {
1484 layoutSetPrototypeSettingsProperties.remove(MERGE_FAIL_COUNT);
1485 }
1486 else {
1487 layoutSetPrototypeSettingsProperties.setProperty(
1488 MERGE_FAIL_COUNT, String.valueOf(newMergeFailCount));
1489 }
1490
1491 LayoutSetServiceUtil.updateSettings(
1492 layoutSetPrototypeLayoutSet.getGroupId(),
1493 layoutSetPrototypeLayoutSet.getPrivateLayout(),
1494 layoutSetPrototypeLayoutSet.getSettings());
1495 }
1496
1497 @Override
1498 public void updateLayoutScopes(
1499 long userId, Layout sourceLayout, Layout targetLayout,
1500 PortletPreferences sourcePreferences,
1501 PortletPreferences targetPreferences, String sourcePortletId,
1502 String languageId)
1503 throws Exception {
1504
1505 String scopeType = GetterUtil.getString(
1506 sourcePreferences.getValue("lfrScopeType", null));
1507
1508 if (Validator.isNull(scopeType) || !scopeType.equals("layout")) {
1509 return;
1510 }
1511
1512 Layout targetScopeLayout =
1513 LayoutLocalServiceUtil.getLayoutByUuidAndGroupId(
1514 targetLayout.getUuid(), targetLayout.getGroupId(),
1515 targetLayout.isPrivateLayout());
1516
1517 if (!targetScopeLayout.hasScopeGroup()) {
1518 GroupLocalServiceUtil.addGroup(
1519 userId, GroupConstants.DEFAULT_PARENT_GROUP_ID,
1520 Layout.class.getName(), targetLayout.getPlid(),
1521 GroupConstants.DEFAULT_LIVE_GROUP_ID, targetLayout.getNameMap(),
1522 null, 0, true, GroupConstants.DEFAULT_MEMBERSHIP_RESTRICTION,
1523 null, false, true, null);
1524 }
1525
1526 String portletTitle = PortalUtil.getPortletTitle(
1527 PortletConstants.getRootPortletId(sourcePortletId), languageId);
1528
1529 String newPortletTitle = PortalUtil.getNewPortletTitle(
1530 portletTitle, String.valueOf(sourceLayout.getLayoutId()),
1531 targetLayout.getName(languageId));
1532
1533 targetPreferences.setValue(
1534 "groupId", String.valueOf(targetLayout.getGroupId()));
1535 targetPreferences.setValue("lfrScopeType", "layout");
1536 targetPreferences.setValue(
1537 "lfrScopeLayoutUuid", targetLayout.getUuid());
1538 targetPreferences.setValue(
1539 "portletSetupTitle_" + languageId, newPortletTitle);
1540 targetPreferences.setValue(
1541 "portletSetupUseCustomTitle", Boolean.TRUE.toString());
1542
1543 targetPreferences.store();
1544 }
1545
1546 @Override
1547 public void updateLayoutSetPrototypesLinks(
1548 Group group, long publicLayoutSetPrototypeId,
1549 long privateLayoutSetPrototypeId,
1550 boolean publicLayoutSetPrototypeLinkEnabled,
1551 boolean privateLayoutSetPrototypeLinkEnabled)
1552 throws Exception {
1553
1554 updateLayoutSetPrototypeLink(
1555 group.getGroupId(), true, privateLayoutSetPrototypeId,
1556 privateLayoutSetPrototypeLinkEnabled);
1557 updateLayoutSetPrototypeLink(
1558 group.getGroupId(), false, publicLayoutSetPrototypeId,
1559 publicLayoutSetPrototypeLinkEnabled);
1560 }
1561
1562
1573 protected void checkResetPrototypePermissions(Group group, Layout layout)
1574 throws PortalException {
1575
1576 PermissionChecker permissionChecker =
1577 PermissionThreadLocal.getPermissionChecker();
1578
1579 if ((layout != null) &&
1580 !LayoutPermissionUtil.contains(
1581 permissionChecker, layout, ActionKeys.UPDATE)) {
1582
1583 throw new PrincipalException.MustHavePermission(
1584 permissionChecker, layout.getName(), layout.getLayoutId(),
1585 ActionKeys.UPDATE);
1586 }
1587 else if (!group.isUser() &&
1588 !GroupPermissionUtil.contains(
1589 permissionChecker, group, ActionKeys.UPDATE)) {
1590
1591 throw new PrincipalException.MustHavePermission(
1592 permissionChecker, group.getName(), group.getGroupId(),
1593 ActionKeys.UPDATE);
1594 }
1595 else if (group.isUser() &&
1596 (permissionChecker.getUserId() != group.getClassPK())) {
1597
1598 throw new PrincipalException();
1599 }
1600 }
1601
1602 protected void doMergeLayoutPrototypeLayout(Group group, Layout layout)
1603 throws Exception {
1604
1605 if (!layout.isLayoutPrototypeLinkActive() ||
1606 group.isLayoutPrototype() || group.hasStagingGroup()) {
1607
1608 return;
1609 }
1610
1611 long lastMergeTime = GetterUtil.getLong(
1612 layout.getTypeSettingsProperty(LAST_MERGE_TIME));
1613
1614 LayoutPrototype layoutPrototype =
1615 LayoutPrototypeLocalServiceUtil.
1616 getLayoutPrototypeByUuidAndCompanyId(
1617 layout.getLayoutPrototypeUuid(), layout.getCompanyId());
1618
1619 Layout layoutPrototypeLayout = layoutPrototype.getLayout();
1620
1621 Date modifiedDate = layoutPrototypeLayout.getModifiedDate();
1622
1623 if (lastMergeTime >= modifiedDate.getTime()) {
1624 return;
1625 }
1626
1627 UnicodeProperties prototypeTypeSettingsProperties =
1628 layoutPrototypeLayout.getTypeSettingsProperties();
1629
1630 int mergeFailCount = GetterUtil.getInteger(
1631 prototypeTypeSettingsProperties.getProperty(MERGE_FAIL_COUNT));
1632
1633 if (mergeFailCount >
1634 PropsValues.LAYOUT_PROTOTYPE_MERGE_FAIL_THRESHOLD) {
1635
1636 if (_log.isWarnEnabled()) {
1637 StringBundler sb = new StringBundler(6);
1638
1639 sb.append("Merge not performed because the fail threshold ");
1640 sb.append("was reached for layoutPrototypeId ");
1641 sb.append(layoutPrototype.getLayoutPrototypeId());
1642 sb.append(" and layoutId ");
1643 sb.append(layoutPrototypeLayout.getLayoutId());
1644 sb.append(". Update the count in the database to try again.");
1645
1646 _log.warn(sb.toString());
1647 }
1648
1649 return;
1650 }
1651
1652 String owner = PortalUUIDUtil.generate();
1653
1654 try {
1655 Lock lock = LockManagerUtil.lock(
1656 LayoutLocalServiceVirtualLayoutsAdvice.class.getName(),
1657 String.valueOf(layout.getPlid()), owner);
1658
1659 if (!owner.equals(lock.getOwner())) {
1660 Date createDate = lock.getCreateDate();
1661
1662 if ((System.currentTimeMillis() - createDate.getTime()) >=
1663 PropsValues.LAYOUT_PROTOTYPE_MERGE_LOCK_MAX_TIME) {
1664
1665
1666
1667 lock = LockManagerUtil.lock(
1668 LayoutLocalServiceVirtualLayoutsAdvice.class.getName(),
1669 String.valueOf(layout.getPlid()), lock.getOwner(),
1670 owner);
1671
1672
1673
1674
1675 if (!owner.equals(lock.getOwner())) {
1676 return;
1677 }
1678 }
1679 else {
1680 return;
1681 }
1682 }
1683 }
1684 catch (Exception e) {
1685 return;
1686 }
1687
1688 try {
1689 MergeLayoutPrototypesThreadLocal.setInProgress(true);
1690
1691 applyLayoutPrototype(layoutPrototype, layout, true);
1692 }
1693 catch (Exception e) {
1694 _log.error(e, e);
1695
1696 prototypeTypeSettingsProperties.setProperty(
1697 MERGE_FAIL_COUNT, String.valueOf(++mergeFailCount));
1698
1699
1700
1701 LayoutUtil.updateImpl(layoutPrototypeLayout);
1702 }
1703 finally {
1704 MergeLayoutPrototypesThreadLocal.setInProgress(false);
1705
1706 LockManagerUtil.unlock(
1707 LayoutLocalServiceVirtualLayoutsAdvice.class.getName(),
1708 String.valueOf(layout.getPlid()), owner);
1709 }
1710 }
1711
1712
1727 protected void doResetPrototype(Layout layout) throws PortalException {
1728 layout.setModifiedDate(null);
1729
1730 LayoutLocalServiceUtil.updateLayout(layout);
1731
1732 LayoutSet layoutSet = layout.getLayoutSet();
1733
1734 doResetPrototype(layoutSet);
1735 }
1736
1737
1747 protected void doResetPrototype(LayoutSet layoutSet) {
1748 UnicodeProperties settingsProperties =
1749 layoutSet.getSettingsProperties();
1750
1751 settingsProperties.remove(LAST_MERGE_TIME);
1752
1753 settingsProperties.setProperty(
1754 LAST_RESET_TIME, String.valueOf(System.currentTimeMillis()));
1755
1756 LayoutSetLocalServiceUtil.updateLayoutSet(layoutSet);
1757 }
1758
1759 protected Map<String, String[]> getLayoutSetPrototypesParameters(
1760 boolean importData) {
1761
1762 Map<String, String[]> parameterMap = new LinkedHashMap<>();
1763
1764 parameterMap.put(
1765 PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS,
1766 new String[] {Boolean.FALSE.toString()});
1767 parameterMap.put(
1768 PortletDataHandlerKeys.DELETE_PORTLET_DATA,
1769 new String[] {Boolean.FALSE.toString()});
1770 parameterMap.put(
1771 PortletDataHandlerKeys.IGNORE_LAST_PUBLISH_DATE,
1772 new String[] {Boolean.TRUE.toString()});
1773 parameterMap.put(
1774 PortletDataHandlerKeys.LAYOUT_SET_SETTINGS,
1775 new String[] {Boolean.TRUE.toString()});
1776 parameterMap.put(
1777 PortletDataHandlerKeys.LAYOUT_SET_PROTOTYPE_LINK_ENABLED,
1778 new String[] {Boolean.TRUE.toString()});
1779 parameterMap.put(
1780 PortletDataHandlerKeys.LAYOUTS_IMPORT_MODE,
1781 new String[] {
1782 PortletDataHandlerKeys.
1783 LAYOUTS_IMPORT_MODE_CREATED_FROM_PROTOTYPE
1784 });
1785 parameterMap.put(
1786 PortletDataHandlerKeys.PERMISSIONS,
1787 new String[] {Boolean.TRUE.toString()});
1788 parameterMap.put(
1789 PortletDataHandlerKeys.PORTLET_CONFIGURATION,
1790 new String[] {Boolean.TRUE.toString()});
1791 parameterMap.put(
1792 PortletDataHandlerKeys.PORTLET_CONFIGURATION_ALL,
1793 new String[] {Boolean.TRUE.toString()});
1794 parameterMap.put(
1795 PortletDataHandlerKeys.PORTLET_SETUP_ALL,
1796 new String[] {Boolean.TRUE.toString()});
1797 parameterMap.put(
1798 PortletDataHandlerKeys.THEME_REFERENCE,
1799 new String[] {Boolean.TRUE.toString()});
1800 parameterMap.put(
1801 PortletDataHandlerKeys.UPDATE_LAST_PUBLISH_DATE,
1802 new String[] {Boolean.FALSE.toString()});
1803 parameterMap.put(
1804 PortletDataHandlerKeys.USER_ID_STRATEGY,
1805 new String[] {UserIdStrategy.CURRENT_USER_ID});
1806
1807 if (importData) {
1808 parameterMap.put(
1809 PortletDataHandlerKeys.DATA_STRATEGY,
1810 new String[] {PortletDataHandlerKeys.DATA_STRATEGY_MIRROR});
1811 parameterMap.put(
1812 PortletDataHandlerKeys.LOGO,
1813 new String[] {Boolean.TRUE.toString()});
1814 parameterMap.put(
1815 PortletDataHandlerKeys.PORTLET_DATA,
1816 new String[] {Boolean.TRUE.toString()});
1817 parameterMap.put(
1818 PortletDataHandlerKeys.PORTLET_DATA_ALL,
1819 new String[] {Boolean.TRUE.toString()});
1820 }
1821 else {
1822 if (PropsValues.LAYOUT_SET_PROTOTYPE_PROPAGATE_LOGO) {
1823 parameterMap.put(
1824 PortletDataHandlerKeys.LOGO,
1825 new String[] {Boolean.TRUE.toString()});
1826 }
1827 else {
1828 parameterMap.put(
1829 PortletDataHandlerKeys.LOGO,
1830 new String[] {Boolean.FALSE.toString()});
1831 }
1832
1833 parameterMap.put(
1834 PortletDataHandlerKeys.PORTLET_DATA,
1835 new String[] {Boolean.FALSE.toString()});
1836 parameterMap.put(
1837 PortletDataHandlerKeys.PORTLET_DATA_ALL,
1838 new String[] {Boolean.FALSE.toString()});
1839 }
1840
1841 return parameterMap;
1842 }
1843
1844 protected void importLayoutSetPrototype(
1845 LayoutSetPrototype layoutSetPrototype, long groupId,
1846 boolean privateLayout, Map<String, String[]> parameterMap,
1847 boolean importData)
1848 throws PortalException {
1849
1850 File file = null;
1851
1852 StringBundler sb = new StringBundler(importData ? 4 : 3);
1853
1854 sb.append(_TEMP_DIR);
1855 sb.append(layoutSetPrototype.getUuid());
1856
1857 if (importData) {
1858 sb.append("-data");
1859 }
1860
1861 sb.append(".lar");
1862
1863 File cacheFile = new File(sb.toString());
1864
1865 if (cacheFile.exists() && !importData) {
1866 Date modifiedDate = layoutSetPrototype.getModifiedDate();
1867
1868 if (cacheFile.lastModified() >= modifiedDate.getTime()) {
1869 if (_log.isDebugEnabled()) {
1870 _log.debug(
1871 "Using cached layout set prototype LAR file " +
1872 cacheFile.getAbsolutePath());
1873 }
1874
1875 file = cacheFile;
1876 }
1877 }
1878
1879 User user = UserLocalServiceUtil.getDefaultUser(
1880 layoutSetPrototype.getCompanyId());
1881
1882 boolean newFile = false;
1883
1884 if (file == null) {
1885 List<Layout> layoutSetPrototypeLayouts =
1886 LayoutLocalServiceUtil.getLayouts(
1887 layoutSetPrototype.getGroupId(), true);
1888
1889 Map<String, Serializable> exportLayoutSettingsMap =
1890 ExportImportConfigurationSettingsMapFactory.
1891 buildExportLayoutSettingsMap(
1892 user, layoutSetPrototype.getGroupId(), true,
1893 ExportImportHelperUtil.getLayoutIds(
1894 layoutSetPrototypeLayouts),
1895 parameterMap);
1896
1897 ExportImportConfiguration exportImportConfiguration =
1898 ExportImportConfigurationLocalServiceUtil.
1899 addDraftExportImportConfiguration(
1900 user.getUserId(),
1901 ExportImportConfigurationConstants.TYPE_EXPORT_LAYOUT,
1902 exportLayoutSettingsMap);
1903
1904 file = ExportImportLocalServiceUtil.exportLayoutsAsFile(
1905 exportImportConfiguration);
1906
1907 newFile = true;
1908 }
1909
1910 Map<String, Serializable> importLayoutSettingsMap =
1911 ExportImportConfigurationSettingsMapFactory.
1912 buildImportLayoutSettingsMap(
1913 user.getUserId(), groupId, privateLayout, null,
1914 parameterMap, user.getLocale(), user.getTimeZone());
1915
1916 ExportImportConfiguration exportImportConfiguration =
1917 ExportImportConfigurationLocalServiceUtil.
1918 addExportImportConfiguration(
1919 user.getUserId(), groupId, StringPool.BLANK,
1920 StringPool.BLANK,
1921 ExportImportConfigurationConstants.TYPE_IMPORT_LAYOUT,
1922 importLayoutSettingsMap, WorkflowConstants.STATUS_DRAFT,
1923 new ServiceContext());
1924
1925 ExportImportLocalServiceUtil.importLayouts(
1926 exportImportConfiguration, file);
1927
1928 if (newFile) {
1929 try {
1930 FileUtil.copyFile(file, cacheFile);
1931
1932 if (_log.isDebugEnabled()) {
1933 _log.debug(
1934 "Copied " + file.getAbsolutePath() + " to " +
1935 cacheFile.getAbsolutePath());
1936 }
1937 }
1938 catch (Exception e) {
1939 _log.error(
1940 "Unable to copy file " + file.getAbsolutePath() + " to " +
1941 cacheFile.getAbsolutePath(),
1942 e);
1943 }
1944 }
1945 }
1946
1947 protected void setLayoutSetPrototypeLinkEnabledParameter(
1948 Map<String, String[]> parameterMap, LayoutSet targetLayoutSet,
1949 ServiceContext serviceContext) {
1950
1951 PermissionChecker permissionChecker =
1952 PermissionThreadLocal.getPermissionChecker();
1953
1954 if ((permissionChecker == null) ||
1955 !PortalPermissionUtil.contains(
1956 permissionChecker, ActionKeys.UNLINK_LAYOUT_SET_PROTOTYPE)) {
1957
1958 return;
1959 }
1960
1961 if (targetLayoutSet.isPrivateLayout()) {
1962 boolean privateLayoutSetPrototypeLinkEnabled = ParamUtil.getBoolean(
1963 serviceContext, "privateLayoutSetPrototypeLinkEnabled", true);
1964
1965 if (!privateLayoutSetPrototypeLinkEnabled) {
1966 privateLayoutSetPrototypeLinkEnabled = ParamUtil.getBoolean(
1967 serviceContext, "layoutSetPrototypeLinkEnabled");
1968 }
1969
1970 parameterMap.put(
1971 PortletDataHandlerKeys.LAYOUT_SET_PROTOTYPE_LINK_ENABLED,
1972 new String[] {
1973 String.valueOf(privateLayoutSetPrototypeLinkEnabled)
1974 });
1975 }
1976 else {
1977 boolean publicLayoutSetPrototypeLinkEnabled = ParamUtil.getBoolean(
1978 serviceContext, "publicLayoutSetPrototypeLinkEnabled");
1979
1980 if (!publicLayoutSetPrototypeLinkEnabled) {
1981 publicLayoutSetPrototypeLinkEnabled = ParamUtil.getBoolean(
1982 serviceContext, "layoutSetPrototypeLinkEnabled", true);
1983 }
1984
1985 parameterMap.put(
1986 PortletDataHandlerKeys.LAYOUT_SET_PROTOTYPE_LINK_ENABLED,
1987 new String[] {
1988 String.valueOf(publicLayoutSetPrototypeLinkEnabled)
1989 });
1990 }
1991 }
1992
1993 protected void updateLayoutSetPrototypeLink(
1994 long groupId, boolean privateLayout, long layoutSetPrototypeId,
1995 boolean layoutSetPrototypeLinkEnabled)
1996 throws Exception {
1997
1998 String layoutSetPrototypeUuid = null;
1999
2000 if (layoutSetPrototypeId > 0) {
2001 LayoutSetPrototype layoutSetPrototype =
2002 LayoutSetPrototypeLocalServiceUtil.fetchLayoutSetPrototype(
2003 layoutSetPrototypeId);
2004
2005 if (layoutSetPrototype != null) {
2006 layoutSetPrototypeUuid = layoutSetPrototype.getUuid();
2007
2008
2009
2010 if (!layoutSetPrototypeLinkEnabled &&
2011 (layoutSetPrototypeId > 0)) {
2012
2013 Map<String, String[]> parameterMap =
2014 getLayoutSetPrototypesParameters(true);
2015
2016 importLayoutSetPrototype(
2017 layoutSetPrototype, groupId, privateLayout,
2018 parameterMap, true);
2019 }
2020 }
2021 }
2022
2023 LayoutSetServiceUtil.updateLayoutSetPrototypeLinkEnabled(
2024 groupId, privateLayout, layoutSetPrototypeLinkEnabled,
2025 layoutSetPrototypeUuid);
2026
2027 LayoutLocalServiceUtil.updatePriorities(groupId, privateLayout);
2028
2029
2030
2031 Group group = GroupLocalServiceUtil.getGroup(groupId);
2032
2033 LayoutSet layoutSet = LayoutSetLocalServiceUtil.getLayoutSet(
2034 groupId, privateLayout);
2035
2036 mergeLayoutSetPrototypeLayouts(group, layoutSet);
2037 }
2038
2039 private static final String _TEMP_DIR =
2040 SystemProperties.get(SystemProperties.TMP_DIR) +
2041 "/liferay/layout_set_prototype/";
2042
2043 private static final Log _log = LogFactoryUtil.getLog(SitesImpl.class);
2044
2045 }