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