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.dao.orm.QueryUtil;
020 import com.liferay.portal.kernel.exception.PortalException;
021 import com.liferay.portal.kernel.exception.SystemException;
022 import com.liferay.portal.kernel.language.LanguageUtil;
023 import com.liferay.portal.kernel.lar.PortletDataHandlerKeys;
024 import com.liferay.portal.kernel.lar.UserIdStrategy;
025 import com.liferay.portal.kernel.log.Log;
026 import com.liferay.portal.kernel.log.LogFactoryUtil;
027 import com.liferay.portal.kernel.util.ArrayUtil;
028 import com.liferay.portal.kernel.util.FileUtil;
029 import com.liferay.portal.kernel.util.GetterUtil;
030 import com.liferay.portal.kernel.util.OrderByComparator;
031 import com.liferay.portal.kernel.util.ParamUtil;
032 import com.liferay.portal.kernel.util.PrefsPropsUtil;
033 import com.liferay.portal.kernel.util.PropsKeys;
034 import com.liferay.portal.kernel.util.StringBundler;
035 import com.liferay.portal.kernel.util.StringPool;
036 import com.liferay.portal.kernel.util.StringUtil;
037 import com.liferay.portal.kernel.util.SystemProperties;
038 import com.liferay.portal.kernel.util.UnicodeProperties;
039 import com.liferay.portal.kernel.util.Validator;
040 import com.liferay.portal.kernel.uuid.PortalUUIDUtil;
041 import com.liferay.portal.model.Group;
042 import com.liferay.portal.model.GroupConstants;
043 import com.liferay.portal.model.Layout;
044 import com.liferay.portal.model.LayoutConstants;
045 import com.liferay.portal.model.LayoutPrototype;
046 import com.liferay.portal.model.LayoutSet;
047 import com.liferay.portal.model.LayoutSetPrototype;
048 import com.liferay.portal.model.LayoutTypePortlet;
049 import com.liferay.portal.model.Lock;
050 import com.liferay.portal.model.Organization;
051 import com.liferay.portal.model.OrganizationConstants;
052 import com.liferay.portal.model.PortletConstants;
053 import com.liferay.portal.model.ResourceConstants;
054 import com.liferay.portal.model.Role;
055 import com.liferay.portal.model.RoleConstants;
056 import com.liferay.portal.model.User;
057 import com.liferay.portal.model.UserGroup;
058 import com.liferay.portal.model.impl.VirtualLayout;
059 import com.liferay.portal.security.auth.PrincipalException;
060 import com.liferay.portal.security.permission.ActionKeys;
061 import com.liferay.portal.security.permission.PermissionChecker;
062 import com.liferay.portal.security.permission.PermissionThreadLocal;
063 import com.liferay.portal.security.permission.ResourceActionsUtil;
064 import com.liferay.portal.service.GroupLocalServiceUtil;
065 import com.liferay.portal.service.GroupServiceUtil;
066 import com.liferay.portal.service.LayoutLocalServiceUtil;
067 import com.liferay.portal.service.LayoutPrototypeLocalServiceUtil;
068 import com.liferay.portal.service.LayoutServiceUtil;
069 import com.liferay.portal.service.LayoutSetLocalServiceUtil;
070 import com.liferay.portal.service.LayoutSetPrototypeLocalServiceUtil;
071 import com.liferay.portal.service.LayoutSetServiceUtil;
072 import com.liferay.portal.service.LockLocalServiceUtil;
073 import com.liferay.portal.service.OrganizationLocalServiceUtil;
074 import com.liferay.portal.service.PortletPreferencesLocalServiceUtil;
075 import com.liferay.portal.service.ResourcePermissionLocalServiceUtil;
076 import com.liferay.portal.service.RoleLocalServiceUtil;
077 import com.liferay.portal.service.ServiceContext;
078 import com.liferay.portal.service.ServiceContextFactory;
079 import com.liferay.portal.service.ServiceContextThreadLocal;
080 import com.liferay.portal.service.UserGroupLocalServiceUtil;
081 import com.liferay.portal.service.UserLocalServiceUtil;
082 import com.liferay.portal.service.impl.LayoutLocalServiceVirtualLayoutsAdvice;
083 import com.liferay.portal.service.permission.GroupPermissionUtil;
084 import com.liferay.portal.service.permission.LayoutPermissionUtil;
085 import com.liferay.portal.service.permission.PortalPermissionUtil;
086 import com.liferay.portal.service.permission.PortletPermissionUtil;
087 import com.liferay.portal.service.persistence.LayoutSetUtil;
088 import com.liferay.portal.service.persistence.LayoutUtil;
089 import com.liferay.portal.theme.PortletDisplay;
090 import com.liferay.portal.theme.ThemeDisplay;
091 import com.liferay.portal.util.LayoutSettings;
092 import com.liferay.portal.util.PortalUtil;
093 import com.liferay.portal.util.PortletKeys;
094 import com.liferay.portal.util.PropsValues;
095 import com.liferay.portal.util.WebKeys;
096 import com.liferay.portlet.PortletPreferencesFactoryUtil;
097 import com.liferay.portlet.PortletPreferencesImpl;
098
099 import java.io.File;
100 import java.io.InputStream;
101
102 import java.util.ArrayList;
103 import java.util.Collections;
104 import java.util.Date;
105 import java.util.LinkedHashMap;
106 import java.util.List;
107 import java.util.Locale;
108 import java.util.Map;
109
110 import javax.portlet.ActionRequest;
111 import javax.portlet.ActionResponse;
112 import javax.portlet.PortletPreferences;
113 import javax.portlet.PortletURL;
114 import javax.portlet.RenderRequest;
115 import javax.portlet.RenderResponse;
116
117 import javax.servlet.http.HttpServletRequest;
118 import javax.servlet.http.HttpServletResponse;
119
120
125 public class SitesImpl implements Sites {
126
127 @Override
128 public void addMergeFailFriendlyURLLayout(Layout layout)
129 throws PortalException, SystemException {
130
131 LayoutSet layoutSet = layout.getLayoutSet();
132
133 layoutSet = LayoutSetLocalServiceUtil.getLayoutSet(
134 layoutSet.getGroupId(), layoutSet.isPrivateLayout());
135
136 UnicodeProperties settingsProperties =
137 layoutSet.getSettingsProperties();
138
139 String mergeFailFriendlyURLLayouts =
140 settingsProperties.getProperty(
141 MERGE_FAIL_FRIENDLY_URL_LAYOUTS, StringPool.BLANK);
142
143 mergeFailFriendlyURLLayouts = StringUtil.add(
144 mergeFailFriendlyURLLayouts, layout.getUuid());
145
146 settingsProperties.setProperty(
147 MERGE_FAIL_FRIENDLY_URL_LAYOUTS, mergeFailFriendlyURLLayouts);
148
149 LayoutSetLocalServiceUtil.updateLayoutSet(layoutSet);
150 }
151
152 @Override
153 public void addPortletBreadcrumbEntries(
154 Group group, HttpServletRequest request,
155 RenderResponse renderResponse)
156 throws Exception {
157
158 PortletURL portletURL = renderResponse.createRenderURL();
159
160 portletURL.setParameter("struts_action", "/sites_admin/view");
161
162 List<Group> ancestorGroups = group.getAncestors();
163
164 Collections.reverse(ancestorGroups);
165
166 for (Group ancestorGroup : ancestorGroups) {
167 portletURL.setParameter(
168 "groupId", String.valueOf(ancestorGroup.getGroupId()));
169
170 PortalUtil.addPortletBreadcrumbEntry(
171 request, ancestorGroup.getDescriptiveName(),
172 portletURL.toString());
173 }
174
175 Group unescapedGroup = group.toUnescapedModel();
176
177 portletURL.setParameter(
178 "groupId", String.valueOf(unescapedGroup.getGroupId()));
179
180 PortalUtil.addPortletBreadcrumbEntry(
181 request, unescapedGroup.getDescriptiveName(),
182 portletURL.toString());
183 }
184
185 @Override
186 public void addPortletBreadcrumbEntries(
187 Group group, String pagesName, PortletURL redirectURL,
188 HttpServletRequest request, RenderResponse renderResponse)
189 throws Exception {
190
191 ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
192 com.liferay.portal.kernel.util.WebKeys.THEME_DISPLAY);
193
194 PortletDisplay portletDisplay = themeDisplay.getPortletDisplay();
195
196 String portletName = portletDisplay.getPortletName();
197
198 if ((renderResponse == null) ||
199 portletName.equals(PortletKeys.GROUP_PAGES) ||
200 portletName.equals(PortletKeys.MY_PAGES)) {
201
202 return;
203 }
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 Map<String, String[]> parameterMap = getLayoutSetPrototypeParameters(
290 serviceContext);
291
292 parameterMap.put(
293 PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS,
294 new String[] {Boolean.FALSE.toString()});
295
296 File file = LayoutLocalServiceUtil.exportLayoutsAsFile(
297 sourceLayout.getGroupId(), sourceLayout.isPrivateLayout(),
298 new long[] {sourceLayout.getLayoutId()}, parameterMap, null, null);
299
300 try {
301 LayoutLocalServiceUtil.importLayouts(
302 userId, targetLayout.getGroupId(),
303 targetLayout.isPrivateLayout(), parameterMap, file);
304 }
305 finally {
306 file.delete();
307 }
308 }
309
310 @Override
311 public void copyLookAndFeel(Layout targetLayout, Layout sourceLayout)
312 throws Exception {
313
314 LayoutLocalServiceUtil.updateLookAndFeel(
315 targetLayout.getGroupId(), targetLayout.isPrivateLayout(),
316 targetLayout.getLayoutId(), sourceLayout.getThemeId(),
317 sourceLayout.getColorSchemeId(), sourceLayout.getCss(), false);
318
319 LayoutLocalServiceUtil.updateLookAndFeel(
320 targetLayout.getGroupId(), targetLayout.isPrivateLayout(),
321 targetLayout.getLayoutId(), sourceLayout.getWapThemeId(),
322 sourceLayout.getWapColorSchemeId(), sourceLayout.getCss(), true);
323 }
324
325 @Override
326 public void copyPortletPermissions(Layout targetLayout, Layout sourceLayout)
327 throws Exception {
328
329 long companyId = targetLayout.getCompanyId();
330
331 List<Role> roles = RoleLocalServiceUtil.getRoles(companyId);
332
333 LayoutTypePortlet sourceLayoutTypePortlet =
334 (LayoutTypePortlet)sourceLayout.getLayoutType();
335
336 List<String> sourcePortletIds = sourceLayoutTypePortlet.getPortletIds();
337
338 for (String sourcePortletId : sourcePortletIds) {
339 String resourceName = PortletConstants.getRootPortletId(
340 sourcePortletId);
341
342 String sourceResourcePrimKey = PortletPermissionUtil.getPrimaryKey(
343 sourceLayout.getPlid(), sourcePortletId);
344
345 String targetResourcePrimKey = PortletPermissionUtil.getPrimaryKey(
346 targetLayout.getPlid(), sourcePortletId);
347
348 List<String> actionIds =
349 ResourceActionsUtil.getPortletResourceActions(resourceName);
350
351 for (Role role : roles) {
352 String roleName = role.getName();
353
354 if (roleName.equals(RoleConstants.ADMINISTRATOR) ||
355 (targetLayout.isPrivateLayout() &&
356 roleName.equals(RoleConstants.GUEST))) {
357
358 continue;
359 }
360
361 List<String> actions =
362 ResourcePermissionLocalServiceUtil.
363 getAvailableResourcePermissionActionIds(
364 companyId, resourceName,
365 ResourceConstants.SCOPE_INDIVIDUAL,
366 sourceResourcePrimKey, role.getRoleId(), actionIds);
367
368 ResourcePermissionLocalServiceUtil.setResourcePermissions(
369 companyId, resourceName, ResourceConstants.SCOPE_INDIVIDUAL,
370 targetResourcePrimKey, role.getRoleId(),
371 actions.toArray(new String[actions.size()]));
372 }
373 }
374 }
375
376 @Override
377 public void copyPortletSetups(Layout sourceLayout, Layout targetLayout)
378 throws Exception {
379
380 LayoutTypePortlet sourceLayoutTypePortlet =
381 (LayoutTypePortlet)sourceLayout.getLayoutType();
382
383 List<String> sourcePortletIds = sourceLayoutTypePortlet.getPortletIds();
384
385 for (String sourcePortletId : sourcePortletIds) {
386 PortletPreferences sourcePreferences =
387 PortletPreferencesFactoryUtil.getPortletSetup(
388 sourceLayout, sourcePortletId, null);
389
390 PortletPreferencesImpl sourcePreferencesImpl =
391 (PortletPreferencesImpl)sourcePreferences;
392
393 PortletPreferences targetPreferences =
394 PortletPreferencesFactoryUtil.getPortletSetup(
395 targetLayout, sourcePortletId, null);
396
397 PortletPreferencesImpl targetPreferencesImpl =
398 (PortletPreferencesImpl)targetPreferences;
399
400 PortletPreferencesLocalServiceUtil.updatePreferences(
401 targetPreferencesImpl.getOwnerId(),
402 targetPreferencesImpl.getOwnerType(),
403 targetPreferencesImpl.getPlid(), sourcePortletId,
404 sourcePreferences);
405
406 if ((sourcePreferencesImpl.getOwnerId() !=
407 PortletKeys.PREFS_OWNER_ID_DEFAULT) &&
408 (sourcePreferencesImpl.getOwnerType() !=
409 PortletKeys.PREFS_OWNER_TYPE_LAYOUT)) {
410
411 sourcePreferences =
412 PortletPreferencesFactoryUtil.getLayoutPortletSetup(
413 sourceLayout, sourcePortletId);
414
415 sourcePreferencesImpl =
416 (PortletPreferencesImpl)sourcePreferences;
417
418 targetPreferences =
419 PortletPreferencesFactoryUtil.getLayoutPortletSetup(
420 targetLayout, sourcePortletId);
421
422 targetPreferencesImpl =
423 (PortletPreferencesImpl)targetPreferences;
424
425 PortletPreferencesLocalServiceUtil.updatePreferences(
426 targetPreferencesImpl.getOwnerId(),
427 targetPreferencesImpl.getOwnerType(),
428 targetPreferencesImpl.getPlid(), sourcePortletId,
429 sourcePreferences);
430 }
431
432 ServiceContext serviceContext =
433 ServiceContextThreadLocal.getServiceContext();
434
435 updateLayoutScopes(
436 serviceContext.getUserId(), sourceLayout, targetLayout,
437 sourcePreferences, targetPreferences, sourcePortletId,
438 serviceContext.getLanguageId());
439 }
440 }
441
442 @Override
443 public void copyTypeSettings(Group sourceGroup, Group targetGroup)
444 throws Exception {
445
446 GroupServiceUtil.updateGroup(
447 targetGroup.getGroupId(), sourceGroup.getTypeSettings());
448 }
449
450 @Override
451 public Object[] deleteLayout(
452 ActionRequest actionRequest, ActionResponse actionResponse)
453 throws Exception {
454
455 HttpServletRequest request = PortalUtil.getHttpServletRequest(
456 actionRequest);
457 HttpServletResponse response = PortalUtil.getHttpServletResponse(
458 actionResponse);
459
460 return deleteLayout(request, response);
461 }
462
463 @Override
464 public Object[] deleteLayout(
465 HttpServletRequest request, HttpServletResponse response)
466 throws Exception {
467
468 ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
469 WebKeys.THEME_DISPLAY);
470
471 PermissionChecker permissionChecker =
472 themeDisplay.getPermissionChecker();
473
474 long plid = ParamUtil.getLong(request, "plid");
475
476 long groupId = ParamUtil.getLong(request, "groupId");
477 boolean privateLayout = ParamUtil.getBoolean(request, "privateLayout");
478 long layoutId = ParamUtil.getLong(request, "layoutId");
479
480 Layout layout = null;
481
482 if (plid <= 0) {
483 layout = LayoutLocalServiceUtil.getLayout(
484 groupId, privateLayout, layoutId);
485 }
486 else {
487 layout = LayoutLocalServiceUtil.getLayout(plid);
488
489 groupId = layout.getGroupId();
490 privateLayout = layout.isPrivateLayout();
491 layoutId = layout.getLayoutId();
492 }
493
494 Group group = layout.getGroup();
495 String oldFriendlyURL = layout.getFriendlyURL(themeDisplay.getLocale());
496
497 if (group.isStagingGroup() &&
498 !GroupPermissionUtil.contains(
499 permissionChecker, groupId, ActionKeys.MANAGE_STAGING) &&
500 !GroupPermissionUtil.contains(
501 permissionChecker, groupId, ActionKeys.PUBLISH_STAGING)) {
502
503 throw new PrincipalException();
504 }
505
506 if (LayoutPermissionUtil.contains(
507 permissionChecker, layout, ActionKeys.DELETE)) {
508
509 LayoutSettings layoutSettings = LayoutSettings.getInstance(layout);
510
511 EventsProcessorUtil.process(
512 PropsKeys.LAYOUT_CONFIGURATION_ACTION_DELETE,
513 layoutSettings.getConfigurationActionDelete(), request,
514 response);
515 }
516
517 LayoutSet layoutSet = layout.getLayoutSet();
518
519 if (group.isGuest() && (layoutSet.getPageCount() == 1)) {
520 throw new RequiredLayoutException(
521 RequiredLayoutException.AT_LEAST_ONE);
522 }
523
524 ServiceContext serviceContext = ServiceContextFactory.getInstance(
525 request);
526
527 LayoutServiceUtil.deleteLayout(
528 groupId, privateLayout, layoutId, serviceContext);
529
530 long newPlid = layout.getParentPlid();
531
532 if (newPlid <= 0) {
533 Layout firstLayout = LayoutLocalServiceUtil.fetchFirstLayout(
534 layoutSet.getGroupId(), layoutSet.isPrivateLayout(),
535 LayoutConstants.DEFAULT_PARENT_LAYOUT_ID);
536
537 if (firstLayout != null) {
538 newPlid = firstLayout.getPlid();
539 }
540 }
541
542 return new Object[] {group, oldFriendlyURL, newPlid};
543 }
544
545 @Override
546 public void deleteLayout(
547 RenderRequest renderRequest, RenderResponse renderResponse)
548 throws Exception {
549
550 HttpServletRequest request = PortalUtil.getHttpServletRequest(
551 renderRequest);
552 HttpServletResponse response = PortalUtil.getHttpServletResponse(
553 renderResponse);
554
555 deleteLayout(request, response);
556 }
557
558 @Override
559 public File exportLayoutSetPrototype(
560 LayoutSetPrototype layoutSetPrototype,
561 ServiceContext serviceContext)
562 throws PortalException, SystemException {
563
564 LayoutSet layoutSet = layoutSetPrototype.getLayoutSet();
565
566 Map<String, String[]> parameterMap = getLayoutSetPrototypeParameters(
567 serviceContext);
568
569 return LayoutLocalServiceUtil.exportLayoutsAsFile(
570 layoutSet.getGroupId(), layoutSet.isPrivateLayout(), null,
571 parameterMap, null, null);
572 }
573
574 @Override
575 public Long[] filterGroups(List<Group> groups, String[] names) {
576 List<Long> groupIds = new ArrayList<Long>();
577
578 for (Group group : groups) {
579 if (!ArrayUtil.contains(names, group.getName())) {
580 groupIds.add(group.getGroupId());
581 }
582 }
583
584 return ArrayUtil.toArray(ArrayUtil.toLongArray(groupIds));
585 }
586
587 @Override
588 public Layout getLayoutSetPrototypeLayout(Layout layout) {
589 try {
590 LayoutSet layoutSet = layout.getLayoutSet();
591
592 if (!layoutSet.isLayoutSetPrototypeLinkActive()) {
593 return null;
594 }
595
596 LayoutSetPrototype layoutSetPrototype =
597 LayoutSetPrototypeLocalServiceUtil.
598 getLayoutSetPrototypeByUuidAndCompanyId(
599 layoutSet.getLayoutSetPrototypeUuid(),
600 layout.getCompanyId());
601
602 return LayoutLocalServiceUtil.fetchLayoutByUuidAndGroupId(
603 layout.getSourcePrototypeLayoutUuid(),
604 layoutSetPrototype.getGroupId(), true);
605 }
606 catch (Exception e) {
607 _log.error(
608 "Unable to fetch the the layout set prototype's layout", e);
609 }
610
611 return null;
612 }
613
614 @Override
615 public Map<String, String[]> getLayoutSetPrototypeParameters(
616 ServiceContext serviceContext) {
617
618 Map<String, String[]> parameterMap =
619 new LinkedHashMap<String, String[]>();
620
621 parameterMap.put(
622 PortletDataHandlerKeys.CATEGORIES,
623 new String[] {Boolean.TRUE.toString()});
624 parameterMap.put(
625 PortletDataHandlerKeys.DATA_STRATEGY,
626 new String[] {PortletDataHandlerKeys.DATA_STRATEGY_MIRROR});
627 parameterMap.put(
628 PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS,
629 new String[] {Boolean.TRUE.toString()});
630 parameterMap.put(
631 PortletDataHandlerKeys.DELETE_PORTLET_DATA,
632 new String[] {Boolean.FALSE.toString()});
633 parameterMap.put(
634 PortletDataHandlerKeys.LAYOUT_SET_PROTOTYPE_LINK_ENABLED,
635 new String[] {Boolean.TRUE.toString()});
636 parameterMap.put(
637 PortletDataHandlerKeys.LAYOUT_SET_SETTINGS,
638 new String[] {Boolean.TRUE.toString()});
639 parameterMap.put(
640 PortletDataHandlerKeys.LAYOUTS_IMPORT_MODE,
641 new String[] {
642 PortletDataHandlerKeys.
643 LAYOUTS_IMPORT_MODE_CREATED_FROM_PROTOTYPE
644 });
645 parameterMap.put(
646 PortletDataHandlerKeys.LOGO,
647 new String[] {Boolean.TRUE.toString()});
648 parameterMap.put(
649 PortletDataHandlerKeys.PERFORM_DIRECT_BINARY_IMPORT,
650 new String[] {Boolean.TRUE.toString()});
651 parameterMap.put(
652 PortletDataHandlerKeys.PERMISSIONS,
653 new String[] {Boolean.TRUE.toString()});
654 parameterMap.put(
655 PortletDataHandlerKeys.PORTLET_CONFIGURATION,
656 new String[] {Boolean.TRUE.toString()});
657 parameterMap.put(
658 PortletDataHandlerKeys.PORTLET_CONFIGURATION_ALL,
659 new String[] {Boolean.TRUE.toString()});
660 parameterMap.put(
661 PortletDataHandlerKeys.PORTLET_DATA,
662 new String[] {Boolean.TRUE.toString()});
663 parameterMap.put(
664 PortletDataHandlerKeys.PORTLET_DATA_ALL,
665 new String[] {Boolean.TRUE.toString()});
666 parameterMap.put(
667 PortletDataHandlerKeys.PORTLET_SETUP_ALL,
668 new String[] {Boolean.TRUE.toString()});
669 parameterMap.put(
670 PortletDataHandlerKeys.THEME,
671 new String[] {Boolean.FALSE.toString()});
672 parameterMap.put(
673 PortletDataHandlerKeys.THEME_REFERENCE,
674 new String[] {Boolean.TRUE.toString()});
675 parameterMap.put(
676 PortletDataHandlerKeys.USER_ID_STRATEGY,
677 new String[] {UserIdStrategy.CURRENT_USER_ID});
678
679 return parameterMap;
680 }
681
682
693 @Override
694 public int getMergeFailCount(LayoutPrototype layoutPrototype)
695 throws PortalException, SystemException {
696
697 if ((layoutPrototype == null) ||
698 (layoutPrototype.getLayoutPrototypeId() == 0)) {
699
700 return 0;
701 }
702
703 Layout layoutPrototypeLayout = layoutPrototype.getLayout();
704
705 UnicodeProperties prototypeTypeSettingsProperties =
706 layoutPrototypeLayout.getTypeSettingsProperties();
707
708 return GetterUtil.getInteger(
709 prototypeTypeSettingsProperties.getProperty(MERGE_FAIL_COUNT));
710 }
711
712
723 @Override
724 public int getMergeFailCount(LayoutSetPrototype layoutSetPrototype)
725 throws PortalException, SystemException {
726
727 if ((layoutSetPrototype == null) ||
728 (layoutSetPrototype.getLayoutSetPrototypeId() == 0)) {
729
730 return 0;
731 }
732
733 LayoutSet layoutSetPrototypeLayoutSet =
734 layoutSetPrototype.getLayoutSet();
735
736 UnicodeProperties layoutSetPrototypeSettingsProperties =
737 layoutSetPrototypeLayoutSet.getSettingsProperties();
738
739 return GetterUtil.getInteger(
740 layoutSetPrototypeSettingsProperties.getProperty(MERGE_FAIL_COUNT));
741 }
742
743 @Override
744 public List<Layout> getMergeFailFriendlyURLLayouts(LayoutSet layoutSet)
745 throws PortalException, SystemException {
746
747 if (layoutSet == null) {
748 return Collections.emptyList();
749 }
750
751 UnicodeProperties settingsProperties =
752 layoutSet.getSettingsProperties();
753
754 String uuids = settingsProperties.getProperty(
755 MERGE_FAIL_FRIENDLY_URL_LAYOUTS);
756
757 if (Validator.isNotNull(uuids)) {
758 List<Layout> layouts = new ArrayList<Layout>();
759
760 for (String uuid : StringUtil.split(uuids)) {
761 Layout layout =
762 LayoutLocalServiceUtil.getLayoutByUuidAndGroupId(
763 uuid, layoutSet.getGroupId(),
764 layoutSet.isPrivateLayout());
765
766 layouts.add(layout);
767 }
768
769 return layouts;
770 }
771
772 return Collections.emptyList();
773 }
774
775 @Override
776 public void importLayoutSetPrototype(
777 LayoutSetPrototype layoutSetPrototype, InputStream inputStream,
778 ServiceContext serviceContext)
779 throws PortalException, SystemException {
780
781 LayoutSet layoutSet = layoutSetPrototype.getLayoutSet();
782
783 Map<String, String[]> parameterMap = getLayoutSetPrototypeParameters(
784 serviceContext);
785
786 setLayoutSetPrototypeLinkEnabledParameter(
787 parameterMap, layoutSet, serviceContext);
788
789 LayoutServiceUtil.importLayouts(
790 layoutSet.getGroupId(), layoutSet.isPrivateLayout(), parameterMap,
791 inputStream);
792 }
793
794 @Override
795 public boolean isContentSharingWithChildrenEnabled(Group group)
796 throws SystemException {
797
798 UnicodeProperties typeSettingsProperties =
799 group.getParentLiveGroupTypeSettingsProperties();
800
801 int companyContentSharingEnabled = PrefsPropsUtil.getInteger(
802 group.getCompanyId(),
803 PropsKeys.SITES_CONTENT_SHARING_WITH_CHILDREN_ENABLED);
804
805 if (companyContentSharingEnabled ==
806 CONTENT_SHARING_WITH_CHILDREN_DISABLED) {
807
808 return false;
809 }
810
811 int groupContentSharingEnabled = GetterUtil.getInteger(
812 typeSettingsProperties.getProperty(
813 "contentSharingWithChildrenEnabled"),
814 CONTENT_SHARING_WITH_CHILDREN_DEFAULT_VALUE);
815
816 if ((groupContentSharingEnabled ==
817 CONTENT_SHARING_WITH_CHILDREN_ENABLED) ||
818 ((companyContentSharingEnabled ==
819 CONTENT_SHARING_WITH_CHILDREN_ENABLED_BY_DEFAULT) &&
820 (groupContentSharingEnabled ==
821 CONTENT_SHARING_WITH_CHILDREN_DEFAULT_VALUE))) {
822
823 return true;
824 }
825
826 return false;
827 }
828
829 @Override
830 public boolean isLayoutDeleteable(Layout layout) {
831 try {
832 if (layout instanceof VirtualLayout) {
833 return false;
834 }
835
836 if (Validator.isNull(layout.getSourcePrototypeLayoutUuid())) {
837 return true;
838 }
839
840 LayoutSet layoutSet = layout.getLayoutSet();
841
842 if (!layoutSet.isLayoutSetPrototypeLinkActive()) {
843 return true;
844 }
845
846 if (LayoutLocalServiceUtil.hasLayoutSetPrototypeLayout(
847 layoutSet.getLayoutSetPrototypeUuid(),
848 layout.getCompanyId(),
849 layout.getSourcePrototypeLayoutUuid())) {
850
851 return false;
852 }
853 }
854 catch (Exception e) {
855 if (_log.isDebugEnabled()) {
856 _log.debug(e, e);
857 }
858 }
859
860 return true;
861 }
862
863 @Override
864 public boolean isLayoutModifiedSinceLastMerge(Layout layout) {
865 if ((layout == null) ||
866 Validator.isNull(layout.getSourcePrototypeLayoutUuid()) ||
867 layout.isLayoutPrototypeLinkActive() ||
868 !isLayoutUpdateable(layout)) {
869
870 return false;
871 }
872
873 long lastMergeTime = GetterUtil.getLong(
874 layout.getTypeSettingsProperty(LAST_MERGE_TIME));
875
876 Date existingLayoutModifiedDate = layout.getModifiedDate();
877
878 if ((existingLayoutModifiedDate != null) &&
879 (existingLayoutModifiedDate.getTime() > lastMergeTime)) {
880
881 return true;
882 }
883
884 return false;
885 }
886
887
903 @Override
904 public boolean isLayoutSetMergeable(Group group, LayoutSet layoutSet)
905 throws PortalException, SystemException {
906
907 if (!layoutSet.isLayoutSetPrototypeLinkActive() ||
908 group.isLayoutPrototype() || group.isLayoutSetPrototype()) {
909
910 return false;
911 }
912
913 UnicodeProperties settingsProperties =
914 layoutSet.getSettingsProperties();
915
916 long lastMergeTime = GetterUtil.getLong(
917 settingsProperties.getProperty(LAST_MERGE_TIME));
918
919 LayoutSetPrototype layoutSetPrototype =
920 LayoutSetPrototypeLocalServiceUtil.
921 getLayoutSetPrototypeByUuidAndCompanyId(
922 layoutSet.getLayoutSetPrototypeUuid(),
923 layoutSet.getCompanyId());
924
925 Date modifiedDate = layoutSetPrototype.getModifiedDate();
926
927 if (lastMergeTime >= modifiedDate.getTime()) {
928 return false;
929 }
930
931 LayoutSet layoutSetPrototypeLayoutSet =
932 layoutSetPrototype.getLayoutSet();
933
934 UnicodeProperties layoutSetPrototypeSettingsProperties =
935 layoutSetPrototypeLayoutSet.getSettingsProperties();
936
937 int mergeFailCount = GetterUtil.getInteger(
938 layoutSetPrototypeSettingsProperties.getProperty(MERGE_FAIL_COUNT));
939
940 if (mergeFailCount >
941 PropsValues.LAYOUT_SET_PROTOTYPE_MERGE_FAIL_THRESHOLD) {
942
943 if (_log.isWarnEnabled()) {
944 StringBundler sb = new StringBundler(6);
945
946 sb.append("Merge not performed because the fail threshold ");
947 sb.append("was reached for layoutSetPrototypeId ");
948 sb.append(layoutSetPrototype.getLayoutSetPrototypeId());
949 sb.append(" and layoutId ");
950 sb.append(layoutSetPrototypeLayoutSet.getLayoutSetId());
951 sb.append(". Update the count in the database to try again.");
952
953 _log.warn(sb.toString());
954 }
955
956 return false;
957 }
958
959 return true;
960 }
961
962 @Override
963 public boolean isLayoutSetPrototypeUpdateable(LayoutSet layoutSet) {
964 if (!layoutSet.isLayoutSetPrototypeLinkActive()) {
965 return true;
966 }
967
968 try {
969 LayoutSetPrototype layoutSetPrototype =
970 LayoutSetPrototypeLocalServiceUtil.
971 getLayoutSetPrototypeByUuidAndCompanyId(
972 layoutSet.getLayoutSetPrototypeUuid(),
973 layoutSet.getCompanyId());
974
975 String layoutsUpdateable = layoutSetPrototype.getSettingsProperty(
976 "layoutsUpdateable");
977
978 if (Validator.isNotNull(layoutsUpdateable)) {
979 return GetterUtil.getBoolean(layoutsUpdateable, true);
980 }
981 }
982 catch (Exception e) {
983 if (_log.isDebugEnabled()) {
984 _log.debug(e, e);
985 }
986 }
987
988 return true;
989 }
990
991 @Override
992 public boolean isLayoutSortable(Layout layout) {
993 return isLayoutDeleteable(layout);
994 }
995
996 @Override
997 public boolean isLayoutUpdateable(Layout layout) {
998 try {
999 if (layout instanceof VirtualLayout) {
1000 return false;
1001 }
1002
1003 if (Validator.isNull(layout.getLayoutPrototypeUuid()) &&
1004 Validator.isNull(layout.getSourcePrototypeLayoutUuid())) {
1005
1006 return true;
1007 }
1008
1009 LayoutSet layoutSet = layout.getLayoutSet();
1010
1011 if (layoutSet.isLayoutSetPrototypeLinkActive()) {
1012 boolean layoutSetPrototypeUpdateable =
1013 isLayoutSetPrototypeUpdateable(layoutSet);
1014
1015 if (!layoutSetPrototypeUpdateable) {
1016 return false;
1017 }
1018
1019 Layout layoutSetPrototypeLayout = getLayoutSetPrototypeLayout(
1020 layout);
1021
1022 String layoutUpdateable =
1023 layoutSetPrototypeLayout.getTypeSettingsProperty(
1024 LAYOUT_UPDATEABLE);
1025
1026 if (Validator.isNull(layoutUpdateable)) {
1027 return true;
1028 }
1029
1030 return GetterUtil.getBoolean(layoutUpdateable);
1031 }
1032 }
1033 catch (Exception e) {
1034 if (_log.isDebugEnabled()) {
1035 _log.debug(e, e);
1036 }
1037 }
1038
1039 return true;
1040 }
1041
1042 @Override
1043 public boolean isOrganizationUser(
1044 long companyId, Group group, User user,
1045 List<String> organizationNames)
1046 throws Exception {
1047
1048 boolean organizationUser = false;
1049
1050 LinkedHashMap<String, Object> organizationParams =
1051 new LinkedHashMap<String, Object>();
1052
1053 organizationParams.put(
1054 "groupOrganization", new Long(group.getGroupId()));
1055 organizationParams.put(
1056 "organizationsGroups", new Long(group.getGroupId()));
1057
1058 List<Organization> organizationsGroups =
1059 OrganizationLocalServiceUtil.search(
1060 companyId, OrganizationConstants.ANY_PARENT_ORGANIZATION_ID,
1061 null, null, null, null, organizationParams, QueryUtil.ALL_POS,
1062 QueryUtil.ALL_POS);
1063
1064 for (Organization organization : organizationsGroups) {
1065 for (long userOrganizationId : user.getOrganizationIds()) {
1066 if (userOrganizationId == organization.getOrganizationId()) {
1067 organizationNames.add(organization.getName());
1068
1069 organizationUser = true;
1070 }
1071 }
1072 }
1073
1074 return organizationUser;
1075 }
1076
1077 @Override
1078 public boolean isUserGroupLayoutSetViewable(
1079 PermissionChecker permissionChecker, Group userGroupGroup)
1080 throws PortalException, SystemException {
1081
1082 if (!userGroupGroup.isUserGroup()) {
1083 return false;
1084 }
1085
1086 if (GroupPermissionUtil.contains(
1087 permissionChecker, userGroupGroup.getGroupId(),
1088 ActionKeys.VIEW)) {
1089
1090 return true;
1091 }
1092
1093 UserGroup userGroup = UserGroupLocalServiceUtil.getUserGroup(
1094 userGroupGroup.getClassPK());
1095
1096 if (UserLocalServiceUtil.hasUserGroupUser(
1097 userGroup.getUserGroupId(), permissionChecker.getUserId())) {
1098
1099 return true;
1100 }
1101 else {
1102 return false;
1103 }
1104 }
1105
1106 @Override
1107 public boolean isUserGroupUser(
1108 long companyId, Group group, User user, List<String> userGroupNames)
1109 throws Exception {
1110
1111 boolean userGroupUser = false;
1112
1113 LinkedHashMap<String, Object> userGroupParams =
1114 new LinkedHashMap<String, Object>();
1115
1116 userGroupParams.put("userGroupsGroups", new Long(group.getGroupId()));
1117
1118 List<UserGroup> userGroupsGroups = UserGroupLocalServiceUtil.search(
1119 companyId, null, userGroupParams, QueryUtil.ALL_POS,
1120 QueryUtil.ALL_POS, (OrderByComparator)null);
1121
1122 for (UserGroup userGroup : userGroupsGroups) {
1123 for (long userGroupId : user.getUserGroupIds()) {
1124 if (userGroupId == userGroup.getUserGroupId()) {
1125 userGroupNames.add(userGroup.getName());
1126
1127 userGroupUser = true;
1128 }
1129 }
1130 }
1131
1132 return userGroupUser;
1133 }
1134
1135 @Override
1136 public void mergeLayoutPrototypeLayout(Group group, Layout layout)
1137 throws Exception {
1138
1139 String sourcePrototypeLayoutUuid =
1140 layout.getSourcePrototypeLayoutUuid();
1141
1142 if (Validator.isNull(sourcePrototypeLayoutUuid)) {
1143 doMergeLayoutPrototypeLayout(group, layout);
1144
1145 return;
1146 }
1147
1148 LayoutSet layoutSet = layout.getLayoutSet();
1149
1150 long layoutSetPrototypeId = layoutSet.getLayoutSetPrototypeId();
1151
1152 if (layoutSetPrototypeId > 0) {
1153 Group layoutSetPrototypeGroup =
1154 GroupLocalServiceUtil.getLayoutSetPrototypeGroup(
1155 layout.getCompanyId(), layoutSetPrototypeId);
1156
1157 Layout sourcePrototypeLayout =
1158 LayoutLocalServiceUtil.getLayoutByUuidAndGroupId(
1159 sourcePrototypeLayoutUuid,
1160 layoutSetPrototypeGroup.getGroupId(), true);
1161
1162 doMergeLayoutPrototypeLayout(
1163 layoutSetPrototypeGroup, sourcePrototypeLayout);
1164 }
1165
1166 doMergeLayoutPrototypeLayout(group, layout);
1167 }
1168
1169
1173 @Override
1174 public void mergeLayoutProtypeLayout(Group group, Layout layout)
1175 throws Exception {
1176
1177 mergeLayoutPrototypeLayout(group, layout);
1178 }
1179
1180 @Override
1181 public void mergeLayoutSetPrototypeLayouts(Group group, LayoutSet layoutSet)
1182 throws Exception {
1183
1184 if (!isLayoutSetMergeable(group, layoutSet)) {
1185 return;
1186 }
1187
1188 UnicodeProperties settingsProperties =
1189 layoutSet.getSettingsProperties();
1190
1191 long lastMergeTime = GetterUtil.getLong(
1192 settingsProperties.getProperty(LAST_MERGE_TIME));
1193
1194 LayoutSetPrototype layoutSetPrototype =
1195 LayoutSetPrototypeLocalServiceUtil.
1196 getLayoutSetPrototypeByUuidAndCompanyId(
1197 layoutSet.getLayoutSetPrototypeUuid(),
1198 layoutSet.getCompanyId());
1199
1200 LayoutSet layoutSetPrototypeLayoutSet =
1201 layoutSetPrototype.getLayoutSet();
1202
1203 UnicodeProperties layoutSetPrototypeSettingsProperties =
1204 layoutSetPrototypeLayoutSet.getSettingsProperties();
1205
1206 int mergeFailCount = GetterUtil.getInteger(
1207 layoutSetPrototypeSettingsProperties.getProperty(MERGE_FAIL_COUNT));
1208
1209 String owner = PortalUUIDUtil.generate();
1210
1211 try {
1212 Lock lock = LockLocalServiceUtil.lock(
1213 LayoutLocalServiceVirtualLayoutsAdvice.class.getName(),
1214 String.valueOf(layoutSet.getLayoutSetId()), owner);
1215
1216
1217
1218 if (!owner.equals(lock.getOwner())) {
1219 Date createDate = lock.getCreateDate();
1220
1221 if ((System.currentTimeMillis() - createDate.getTime()) >=
1222 PropsValues.LAYOUT_SET_PROTOTYPE_MERGE_LOCK_MAX_TIME) {
1223
1224
1225
1226 lock = LockLocalServiceUtil.lock(
1227 LayoutLocalServiceVirtualLayoutsAdvice.class.getName(),
1228 String.valueOf(layoutSet.getLayoutSetId()),
1229 lock.getOwner(), owner);
1230
1231
1232
1233
1234 if (!owner.equals(lock.getOwner())) {
1235 return;
1236 }
1237 }
1238 else {
1239 return;
1240 }
1241 }
1242 }
1243 catch (Exception e) {
1244 return;
1245 }
1246
1247 try {
1248 boolean importData = true;
1249
1250 long lastResetTime = GetterUtil.getLong(
1251 settingsProperties.getProperty(LAST_RESET_TIME));
1252
1253 if ((lastMergeTime > 0) || (lastResetTime > 0)) {
1254 importData = false;
1255 }
1256
1257 Map<String, String[]> parameterMap =
1258 getLayoutSetPrototypesParameters(importData);
1259
1260 removeMergeFailFriendlyURLLayouts(layoutSet);
1261
1262 importLayoutSetPrototype(
1263 layoutSetPrototype, layoutSet.getGroupId(),
1264 layoutSet.isPrivateLayout(), parameterMap, importData);
1265 }
1266 catch (Exception e) {
1267 _log.error(e, e);
1268
1269 layoutSetPrototypeSettingsProperties.setProperty(
1270 MERGE_FAIL_COUNT, String.valueOf(++mergeFailCount));
1271
1272
1273
1274 LayoutSetUtil.updateImpl(layoutSetPrototypeLayoutSet);
1275 }
1276 finally {
1277 LockLocalServiceUtil.unlock(
1278 LayoutLocalServiceVirtualLayoutsAdvice.class.getName(),
1279 String.valueOf(layoutSet.getLayoutSetId()), owner);
1280 }
1281 }
1282
1283
1287 @Override
1288 public void mergeLayoutSetProtypeLayouts(Group group, LayoutSet layoutSet)
1289 throws Exception {
1290
1291 mergeLayoutSetPrototypeLayouts(group, layoutSet);
1292 }
1293
1294 @Override
1295 public void removeMergeFailFriendlyURLLayouts(LayoutSet layoutSet)
1296 throws SystemException {
1297
1298 UnicodeProperties settingsProperties =
1299 layoutSet.getSettingsProperties();
1300
1301 settingsProperties.remove(MERGE_FAIL_FRIENDLY_URL_LAYOUTS);
1302
1303 LayoutSetLocalServiceUtil.updateLayoutSet(layoutSet);
1304 }
1305
1306
1316 @Override
1317 public void resetPrototype(Layout layout)
1318 throws PortalException, SystemException {
1319
1320 checkResetPrototypePermissions(layout.getGroup(), layout);
1321
1322 doResetPrototype(layout);
1323 }
1324
1325
1335 @Override
1336 public void resetPrototype(LayoutSet layoutSet)
1337 throws PortalException, SystemException {
1338
1339 checkResetPrototypePermissions(layoutSet.getGroup(), null);
1340
1341 doResetPrototype(layoutSet);
1342 }
1343
1344
1355 @Override
1356 public void setMergeFailCount(
1357 LayoutPrototype layoutPrototype, int newMergeFailCount)
1358 throws PortalException, SystemException {
1359
1360 Layout layoutPrototypeLayout = layoutPrototype.getLayout();
1361
1362 UnicodeProperties prototypeTypeSettingsProperties =
1363 layoutPrototypeLayout.getTypeSettingsProperties();
1364
1365 if (newMergeFailCount == 0) {
1366 prototypeTypeSettingsProperties.remove(MERGE_FAIL_COUNT);
1367 }
1368 else {
1369 prototypeTypeSettingsProperties.setProperty(
1370 MERGE_FAIL_COUNT, String.valueOf(newMergeFailCount));
1371 }
1372
1373 LayoutServiceUtil.updateLayout(
1374 layoutPrototypeLayout.getGroupId(),
1375 layoutPrototypeLayout.getPrivateLayout(),
1376 layoutPrototypeLayout.getLayoutId(),
1377 layoutPrototypeLayout.getTypeSettings());
1378 }
1379
1380
1391 @Override
1392 public void setMergeFailCount(
1393 LayoutSetPrototype layoutSetPrototype, int newMergeFailCount)
1394 throws PortalException, SystemException {
1395
1396 LayoutSet layoutSetPrototypeLayoutSet =
1397 layoutSetPrototype.getLayoutSet();
1398
1399 UnicodeProperties layoutSetPrototypeSettingsProperties =
1400 layoutSetPrototypeLayoutSet.getSettingsProperties();
1401
1402 if (newMergeFailCount == 0) {
1403 layoutSetPrototypeSettingsProperties.remove(MERGE_FAIL_COUNT);
1404 }
1405 else {
1406 layoutSetPrototypeSettingsProperties.setProperty(
1407 MERGE_FAIL_COUNT, String.valueOf(newMergeFailCount));
1408 }
1409
1410 LayoutSetServiceUtil.updateSettings(
1411 layoutSetPrototypeLayoutSet.getGroupId(),
1412 layoutSetPrototypeLayoutSet.getPrivateLayout(),
1413 layoutSetPrototypeLayoutSet.getSettings());
1414 }
1415
1416 @Override
1417 public void updateLayoutScopes(
1418 long userId, Layout sourceLayout, Layout targetLayout,
1419 PortletPreferences sourcePreferences,
1420 PortletPreferences targetPreferences, String sourcePortletId,
1421 String languageId)
1422 throws Exception {
1423
1424 String scopeType = GetterUtil.getString(
1425 sourcePreferences.getValue("lfrScopeType", null));
1426
1427 if (Validator.isNull(scopeType) || !scopeType.equals("layout")) {
1428 return;
1429 }
1430
1431 Layout targetScopeLayout =
1432 LayoutLocalServiceUtil.getLayoutByUuidAndGroupId(
1433 targetLayout.getUuid(), targetLayout.getGroupId(),
1434 targetLayout.isPrivateLayout());
1435
1436 if (!targetScopeLayout.hasScopeGroup()) {
1437 GroupLocalServiceUtil.addGroup(
1438 userId, GroupConstants.DEFAULT_PARENT_GROUP_ID,
1439 Layout.class.getName(), targetLayout.getPlid(),
1440 GroupConstants.DEFAULT_LIVE_GROUP_ID,
1441 targetLayout.getName(languageId), null, 0, true,
1442 GroupConstants.DEFAULT_MEMBERSHIP_RESTRICTION, null, false,
1443 true, null);
1444 }
1445
1446 String portletTitle = PortalUtil.getPortletTitle(
1447 sourcePortletId, languageId);
1448
1449 String newPortletTitle = PortalUtil.getNewPortletTitle(
1450 portletTitle, String.valueOf(sourceLayout.getLayoutId()),
1451 targetLayout.getName(languageId));
1452
1453 targetPreferences.setValue(
1454 "groupId", String.valueOf(targetLayout.getGroupId()));
1455 targetPreferences.setValue("lfrScopeType", "layout");
1456 targetPreferences.setValue(
1457 "lfrScopeLayoutUuid", targetLayout.getUuid());
1458 targetPreferences.setValue(
1459 "portletSetupTitle_" + languageId, newPortletTitle);
1460 targetPreferences.setValue(
1461 "portletSetupUseCustomTitle", Boolean.TRUE.toString());
1462
1463 targetPreferences.store();
1464 }
1465
1466 @Override
1467 public void updateLayoutSetPrototypesLinks(
1468 Group group, long publicLayoutSetPrototypeId,
1469 long privateLayoutSetPrototypeId,
1470 boolean publicLayoutSetPrototypeLinkEnabled,
1471 boolean privateLayoutSetPrototypeLinkEnabled)
1472 throws Exception {
1473
1474 updateLayoutSetPrototypeLink(
1475 group.getGroupId(), true, privateLayoutSetPrototypeId,
1476 privateLayoutSetPrototypeLinkEnabled);
1477 updateLayoutSetPrototypeLink(
1478 group.getGroupId(), false, publicLayoutSetPrototypeId,
1479 publicLayoutSetPrototypeLinkEnabled);
1480 }
1481
1482
1494 protected void checkResetPrototypePermissions(Group group, Layout layout)
1495 throws PortalException, SystemException {
1496
1497 PermissionChecker permissionChecker =
1498 PermissionThreadLocal.getPermissionChecker();
1499
1500 if ((layout != null) &&
1501 !LayoutPermissionUtil.contains(
1502 permissionChecker, layout, ActionKeys.UPDATE)) {
1503
1504 throw new PrincipalException();
1505 }
1506 else if (!group.isUser() &&
1507 !GroupPermissionUtil.contains(
1508 permissionChecker, group, ActionKeys.UPDATE)) {
1509
1510 throw new PrincipalException();
1511 }
1512 else if (group.isUser() &&
1513 (permissionChecker.getUserId() != group.getClassPK())) {
1514
1515 throw new PrincipalException();
1516 }
1517 }
1518
1519 protected void doMergeLayoutPrototypeLayout(Group group, Layout layout)
1520 throws Exception {
1521
1522 if (!layout.isLayoutPrototypeLinkActive() ||
1523 group.isLayoutPrototype() || group.hasStagingGroup()) {
1524
1525 return;
1526 }
1527
1528 long lastMergeTime = GetterUtil.getLong(
1529 layout.getTypeSettingsProperty(LAST_MERGE_TIME));
1530
1531 LayoutPrototype layoutPrototype =
1532 LayoutPrototypeLocalServiceUtil.
1533 getLayoutPrototypeByUuidAndCompanyId(
1534 layout.getLayoutPrototypeUuid(), layout.getCompanyId());
1535
1536 Layout layoutPrototypeLayout = layoutPrototype.getLayout();
1537
1538 Date modifiedDate = layoutPrototypeLayout.getModifiedDate();
1539
1540 if (lastMergeTime >= modifiedDate.getTime()) {
1541 return;
1542 }
1543
1544 UnicodeProperties prototypeTypeSettingsProperties =
1545 layoutPrototypeLayout.getTypeSettingsProperties();
1546
1547 int mergeFailCount = GetterUtil.getInteger(
1548 prototypeTypeSettingsProperties.getProperty(MERGE_FAIL_COUNT));
1549
1550 if (mergeFailCount >
1551 PropsValues.LAYOUT_PROTOTYPE_MERGE_FAIL_THRESHOLD) {
1552
1553 if (_log.isWarnEnabled()) {
1554 StringBundler sb = new StringBundler(6);
1555
1556 sb.append("Merge not performed because the fail threshold ");
1557 sb.append("was reached for layoutPrototypeId ");
1558 sb.append(layoutPrototype.getLayoutPrototypeId());
1559 sb.append(" and layoutId ");
1560 sb.append(layoutPrototypeLayout.getLayoutId());
1561 sb.append(". Update the count in the database to try again.");
1562
1563 _log.warn(sb.toString());
1564 }
1565
1566 return;
1567 }
1568
1569 String owner = PortalUUIDUtil.generate();
1570
1571 try {
1572 Lock lock = LockLocalServiceUtil.lock(
1573 LayoutLocalServiceVirtualLayoutsAdvice.class.getName(),
1574 String.valueOf(layout.getPlid()), owner);
1575
1576 if (!owner.equals(lock.getOwner())) {
1577 Date createDate = lock.getCreateDate();
1578
1579 if ((System.currentTimeMillis() - createDate.getTime()) >=
1580 PropsValues.LAYOUT_PROTOTYPE_MERGE_LOCK_MAX_TIME) {
1581
1582
1583
1584 lock = LockLocalServiceUtil.lock(
1585 LayoutLocalServiceVirtualLayoutsAdvice.class.getName(),
1586 String.valueOf(layout.getPlid()), lock.getOwner(),
1587 owner);
1588
1589
1590
1591
1592 if (!owner.equals(lock.getOwner())) {
1593 return;
1594 }
1595 }
1596 else {
1597 return;
1598 }
1599 }
1600 }
1601 catch (Exception e) {
1602 return;
1603 }
1604
1605 try {
1606 applyLayoutPrototype(layoutPrototype, layout, true);
1607 }
1608 catch (Exception e) {
1609 _log.error(e, e);
1610
1611 prototypeTypeSettingsProperties.setProperty(
1612 MERGE_FAIL_COUNT, String.valueOf(++mergeFailCount));
1613
1614
1615
1616 LayoutUtil.updateImpl(layoutPrototypeLayout);
1617 }
1618 finally {
1619 LockLocalServiceUtil.unlock(
1620 LayoutLocalServiceVirtualLayoutsAdvice.class.getName(),
1621 String.valueOf(layout.getPlid()), owner);
1622 }
1623 }
1624
1625
1641 protected void doResetPrototype(Layout layout)
1642 throws PortalException, SystemException {
1643
1644 layout.setModifiedDate(null);
1645
1646 LayoutLocalServiceUtil.updateLayout(layout);
1647
1648 LayoutSet layoutSet = layout.getLayoutSet();
1649
1650 doResetPrototype(layoutSet);
1651 }
1652
1653
1664 protected void doResetPrototype(LayoutSet layoutSet)
1665 throws SystemException {
1666
1667 UnicodeProperties settingsProperties =
1668 layoutSet.getSettingsProperties();
1669
1670 settingsProperties.remove(LAST_MERGE_TIME);
1671
1672 settingsProperties.setProperty(
1673 LAST_RESET_TIME, String.valueOf(System.currentTimeMillis()));
1674
1675 LayoutSetLocalServiceUtil.updateLayoutSet(layoutSet);
1676 }
1677
1678 protected Map<String, String[]> getLayoutSetPrototypesParameters(
1679 boolean importData) {
1680
1681 Map<String, String[]> parameterMap =
1682 new LinkedHashMap<String, String[]>();
1683
1684 parameterMap.put(
1685 PortletDataHandlerKeys.CATEGORIES,
1686 new String[] {Boolean.TRUE.toString()});
1687 parameterMap.put(
1688 PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS,
1689 new String[] {Boolean.FALSE.toString()});
1690 parameterMap.put(
1691 PortletDataHandlerKeys.DELETE_PORTLET_DATA,
1692 new String[] {Boolean.FALSE.toString()});
1693 parameterMap.put(
1694 PortletDataHandlerKeys.IGNORE_LAST_PUBLISH_DATE,
1695 new String[] {Boolean.TRUE.toString()});
1696 parameterMap.put(
1697 PortletDataHandlerKeys.LAYOUT_SET_SETTINGS,
1698 new String[] {Boolean.TRUE.toString()});
1699 parameterMap.put(
1700 PortletDataHandlerKeys.LAYOUT_SET_PROTOTYPE_LINK_ENABLED,
1701 new String[] {Boolean.TRUE.toString()});
1702 parameterMap.put(
1703 PortletDataHandlerKeys.LAYOUTS_IMPORT_MODE,
1704 new String[] {
1705 PortletDataHandlerKeys.
1706 LAYOUTS_IMPORT_MODE_CREATED_FROM_PROTOTYPE
1707 });
1708 parameterMap.put(
1709 PortletDataHandlerKeys.LOGO,
1710 new String[] {Boolean.TRUE.toString()});
1711 parameterMap.put(
1712 PortletDataHandlerKeys.PERMISSIONS,
1713 new String[] {Boolean.TRUE.toString()});
1714 parameterMap.put(
1715 PortletDataHandlerKeys.PORTLET_CONFIGURATION,
1716 new String[] {Boolean.TRUE.toString()});
1717 parameterMap.put(
1718 PortletDataHandlerKeys.PORTLET_CONFIGURATION_ALL,
1719 new String[] {Boolean.TRUE.toString()});
1720 parameterMap.put(
1721 PortletDataHandlerKeys.PORTLET_SETUP_ALL,
1722 new String[] {Boolean.TRUE.toString()});
1723 parameterMap.put(
1724 PortletDataHandlerKeys.THEME,
1725 new String[] {Boolean.FALSE.toString()});
1726 parameterMap.put(
1727 PortletDataHandlerKeys.THEME_REFERENCE,
1728 new String[] {Boolean.TRUE.toString()});
1729 parameterMap.put(
1730 PortletDataHandlerKeys.UPDATE_LAST_PUBLISH_DATE,
1731 new String[] {Boolean.FALSE.toString()});
1732 parameterMap.put(
1733 PortletDataHandlerKeys.USER_ID_STRATEGY,
1734 new String[] {UserIdStrategy.CURRENT_USER_ID});
1735
1736 if (importData) {
1737 parameterMap.put(
1738 PortletDataHandlerKeys.DATA_STRATEGY,
1739 new String[] {PortletDataHandlerKeys.DATA_STRATEGY_MIRROR});
1740 parameterMap.put(
1741 PortletDataHandlerKeys.PORTLET_DATA,
1742 new String[] {Boolean.TRUE.toString()});
1743 parameterMap.put(
1744 PortletDataHandlerKeys.PORTLET_DATA_ALL,
1745 new String[] {Boolean.TRUE.toString()});
1746 }
1747 else {
1748 parameterMap.put(
1749 PortletDataHandlerKeys.PORTLET_DATA,
1750 new String[] {Boolean.FALSE.toString()});
1751 parameterMap.put(
1752 PortletDataHandlerKeys.PORTLET_DATA_ALL,
1753 new String[] {Boolean.FALSE.toString()});
1754 }
1755
1756 return parameterMap;
1757 }
1758
1759 protected void importLayoutSetPrototype(
1760 LayoutSetPrototype layoutSetPrototype, long groupId,
1761 boolean privateLayout, Map<String, String[]> parameterMap,
1762 boolean importData)
1763 throws PortalException, SystemException {
1764
1765 File file = null;
1766
1767 StringBundler sb = new StringBundler(importData ? 4 : 3);
1768
1769 sb.append(_TEMP_DIR);
1770 sb.append(layoutSetPrototype.getUuid());
1771
1772 if (importData) {
1773 sb.append("-data");
1774 }
1775
1776 sb.append(".lar");
1777
1778 File cacheFile = new File(sb.toString());
1779
1780 if (cacheFile.exists()) {
1781 Date modifiedDate = layoutSetPrototype.getModifiedDate();
1782
1783 if (cacheFile.lastModified() >= modifiedDate.getTime()) {
1784 if (_log.isDebugEnabled()) {
1785 _log.debug(
1786 "Using cached layout set prototype LAR file " +
1787 cacheFile.getAbsolutePath());
1788 }
1789
1790 file = cacheFile;
1791 }
1792 }
1793
1794 boolean newFile = false;
1795
1796 if (file == null) {
1797 file = LayoutLocalServiceUtil.exportLayoutsAsFile(
1798 layoutSetPrototype.getGroupId(), true, null, parameterMap, null,
1799 null);
1800
1801 newFile = true;
1802 }
1803
1804 long userId = UserLocalServiceUtil.getDefaultUserId(
1805 layoutSetPrototype.getCompanyId());
1806
1807 LayoutLocalServiceUtil.importLayouts(
1808 userId, groupId, privateLayout, parameterMap, file);
1809
1810 if (newFile) {
1811 try {
1812 FileUtil.copyFile(file, cacheFile);
1813
1814 if (_log.isDebugEnabled()) {
1815 _log.debug(
1816 "Copied " + file.getAbsolutePath() + " to " +
1817 cacheFile.getAbsolutePath());
1818 }
1819 }
1820 catch (Exception e) {
1821 _log.error(
1822 "Unable to copy file " + file.getAbsolutePath() + " to " +
1823 cacheFile.getAbsolutePath(),
1824 e);
1825 }
1826 }
1827 }
1828
1829 protected void setLayoutSetPrototypeLinkEnabledParameter(
1830 Map<String, String[]> parameterMap, LayoutSet targetLayoutSet,
1831 ServiceContext serviceContext) {
1832
1833 PermissionChecker permissionChecker =
1834 PermissionThreadLocal.getPermissionChecker();
1835
1836 if ((permissionChecker == null) ||
1837 !PortalPermissionUtil.contains(
1838 permissionChecker, ActionKeys.UNLINK_LAYOUT_SET_PROTOTYPE)) {
1839
1840 return;
1841 }
1842
1843 if (targetLayoutSet.isPrivateLayout()) {
1844 boolean privateLayoutSetPrototypeLinkEnabled = ParamUtil.getBoolean(
1845 serviceContext, "privateLayoutSetPrototypeLinkEnabled", true);
1846
1847 if (!privateLayoutSetPrototypeLinkEnabled) {
1848 privateLayoutSetPrototypeLinkEnabled = ParamUtil.getBoolean(
1849 serviceContext, "layoutSetPrototypeLinkEnabled");
1850 }
1851
1852 parameterMap.put(
1853 PortletDataHandlerKeys.LAYOUT_SET_PROTOTYPE_LINK_ENABLED,
1854 new String[] {
1855 String.valueOf(privateLayoutSetPrototypeLinkEnabled)
1856 });
1857 }
1858 else {
1859 boolean publicLayoutSetPrototypeLinkEnabled = ParamUtil.getBoolean(
1860 serviceContext, "publicLayoutSetPrototypeLinkEnabled");
1861
1862 if (!publicLayoutSetPrototypeLinkEnabled) {
1863 publicLayoutSetPrototypeLinkEnabled = ParamUtil.getBoolean(
1864 serviceContext, "layoutSetPrototypeLinkEnabled", true);
1865 }
1866
1867 parameterMap.put(
1868 PortletDataHandlerKeys.LAYOUT_SET_PROTOTYPE_LINK_ENABLED,
1869 new String[] {
1870 String.valueOf(publicLayoutSetPrototypeLinkEnabled)
1871 });
1872 }
1873 }
1874
1875 protected void updateLayoutSetPrototypeLink(
1876 long groupId, boolean privateLayout, long layoutSetPrototypeId,
1877 boolean layoutSetPrototypeLinkEnabled)
1878 throws Exception {
1879
1880 String layoutSetPrototypeUuid = null;
1881
1882 if (layoutSetPrototypeId > 0) {
1883 LayoutSetPrototype layoutSetPrototype =
1884 LayoutSetPrototypeLocalServiceUtil.fetchLayoutSetPrototype(
1885 layoutSetPrototypeId);
1886
1887 if (layoutSetPrototype != null) {
1888 layoutSetPrototypeUuid = layoutSetPrototype.getUuid();
1889
1890
1891
1892 if (!layoutSetPrototypeLinkEnabled &&
1893 (layoutSetPrototypeId > 0)) {
1894
1895 Map<String, String[]> parameterMap =
1896 getLayoutSetPrototypesParameters(true);
1897
1898 importLayoutSetPrototype(
1899 layoutSetPrototype, groupId, privateLayout,
1900 parameterMap, true);
1901 }
1902 }
1903 }
1904
1905 LayoutSetServiceUtil.updateLayoutSetPrototypeLinkEnabled(
1906 groupId, privateLayout, layoutSetPrototypeLinkEnabled,
1907 layoutSetPrototypeUuid);
1908
1909 LayoutLocalServiceUtil.updatePriorities(groupId, privateLayout);
1910 }
1911
1912 private static final String _TEMP_DIR =
1913 SystemProperties.get(SystemProperties.TMP_DIR) +
1914 "/liferay/layout_set_prototype/";
1915
1916 private static Log _log = LogFactoryUtil.getLog(SitesImpl.class);
1917
1918 }