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 List<Role> roles = RoleLocalServiceUtil.getGroupRelatedRoles(
330 targetLayout.getGroupId());
331
332 LayoutTypePortlet sourceLayoutTypePortlet =
333 (LayoutTypePortlet)sourceLayout.getLayoutType();
334
335 List<String> sourcePortletIds = sourceLayoutTypePortlet.getPortletIds();
336
337 for (String sourcePortletId : sourcePortletIds) {
338 String resourceName = PortletConstants.getRootPortletId(
339 sourcePortletId);
340
341 String sourceResourcePrimKey = PortletPermissionUtil.getPrimaryKey(
342 sourceLayout.getPlid(), sourcePortletId);
343
344 String targetResourcePrimKey = PortletPermissionUtil.getPrimaryKey(
345 targetLayout.getPlid(), sourcePortletId);
346
347 List<String> actionIds =
348 ResourceActionsUtil.getPortletResourceActions(resourceName);
349
350 for (Role role : roles) {
351 String roleName = role.getName();
352
353 if (roleName.equals(RoleConstants.ADMINISTRATOR) ||
354 (targetLayout.isPrivateLayout() &&
355 roleName.equals(RoleConstants.GUEST))) {
356
357 continue;
358 }
359
360 List<String> actions =
361 ResourcePermissionLocalServiceUtil.
362 getAvailableResourcePermissionActionIds(
363 targetLayout.getCompanyId(), resourceName,
364 ResourceConstants.SCOPE_INDIVIDUAL,
365 sourceResourcePrimKey, role.getRoleId(), actionIds);
366
367 ResourcePermissionLocalServiceUtil.setResourcePermissions(
368 targetLayout.getCompanyId(), resourceName,
369 ResourceConstants.SCOPE_INDIVIDUAL, targetResourcePrimKey,
370 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 isFirstLayout(
831 long groupId, boolean privateLayout, long layoutId)
832 throws SystemException {
833
834 Layout firstLayout = LayoutLocalServiceUtil.fetchFirstLayout(
835 groupId, privateLayout, LayoutConstants.DEFAULT_PARENT_LAYOUT_ID);
836
837 if ((firstLayout != null) && (firstLayout.getLayoutId() == layoutId )) {
838 return true;
839 }
840
841 return false;
842 }
843
844 @Override
845 public boolean isLayoutDeleteable(Layout layout) {
846 try {
847 if (layout instanceof VirtualLayout) {
848 return false;
849 }
850
851 if (Validator.isNull(layout.getSourcePrototypeLayoutUuid())) {
852 return true;
853 }
854
855 LayoutSet layoutSet = layout.getLayoutSet();
856
857 if (!layoutSet.isLayoutSetPrototypeLinkActive()) {
858 return true;
859 }
860
861 if (LayoutLocalServiceUtil.hasLayoutSetPrototypeLayout(
862 layoutSet.getLayoutSetPrototypeUuid(),
863 layout.getCompanyId(),
864 layout.getSourcePrototypeLayoutUuid())) {
865
866 return false;
867 }
868 }
869 catch (Exception e) {
870 if (_log.isDebugEnabled()) {
871 _log.debug(e, e);
872 }
873 }
874
875 return true;
876 }
877
878 @Override
879 public boolean isLayoutModifiedSinceLastMerge(Layout layout) {
880 if ((layout == null) ||
881 Validator.isNull(layout.getSourcePrototypeLayoutUuid()) ||
882 layout.isLayoutPrototypeLinkActive() ||
883 !isLayoutUpdateable(layout)) {
884
885 return false;
886 }
887
888 long lastMergeTime = GetterUtil.getLong(
889 layout.getTypeSettingsProperty(LAST_MERGE_TIME));
890
891 Date existingLayoutModifiedDate = layout.getModifiedDate();
892
893 if ((existingLayoutModifiedDate != null) &&
894 (existingLayoutModifiedDate.getTime() > lastMergeTime)) {
895
896 return true;
897 }
898
899 return false;
900 }
901
902
918 @Override
919 public boolean isLayoutSetMergeable(Group group, LayoutSet layoutSet)
920 throws PortalException, SystemException {
921
922 if (!layoutSet.isLayoutSetPrototypeLinkActive() ||
923 group.isLayoutPrototype() || group.isLayoutSetPrototype()) {
924
925 return false;
926 }
927
928 UnicodeProperties settingsProperties =
929 layoutSet.getSettingsProperties();
930
931 long lastMergeTime = GetterUtil.getLong(
932 settingsProperties.getProperty(LAST_MERGE_TIME));
933
934 LayoutSetPrototype layoutSetPrototype =
935 LayoutSetPrototypeLocalServiceUtil.
936 getLayoutSetPrototypeByUuidAndCompanyId(
937 layoutSet.getLayoutSetPrototypeUuid(),
938 layoutSet.getCompanyId());
939
940 Date modifiedDate = layoutSetPrototype.getModifiedDate();
941
942 if (lastMergeTime >= modifiedDate.getTime()) {
943 return false;
944 }
945
946 LayoutSet layoutSetPrototypeLayoutSet =
947 layoutSetPrototype.getLayoutSet();
948
949 UnicodeProperties layoutSetPrototypeSettingsProperties =
950 layoutSetPrototypeLayoutSet.getSettingsProperties();
951
952 int mergeFailCount = GetterUtil.getInteger(
953 layoutSetPrototypeSettingsProperties.getProperty(MERGE_FAIL_COUNT));
954
955 if (mergeFailCount >
956 PropsValues.LAYOUT_SET_PROTOTYPE_MERGE_FAIL_THRESHOLD) {
957
958 if (_log.isWarnEnabled()) {
959 StringBundler sb = new StringBundler(6);
960
961 sb.append("Merge not performed because the fail threshold ");
962 sb.append("was reached for layoutSetPrototypeId ");
963 sb.append(layoutSetPrototype.getLayoutSetPrototypeId());
964 sb.append(" and layoutId ");
965 sb.append(layoutSetPrototypeLayoutSet.getLayoutSetId());
966 sb.append(". Update the count in the database to try again.");
967
968 _log.warn(sb.toString());
969 }
970
971 return false;
972 }
973
974 return true;
975 }
976
977 @Override
978 public boolean isLayoutSetPrototypeUpdateable(LayoutSet layoutSet) {
979 if (!layoutSet.isLayoutSetPrototypeLinkActive()) {
980 return true;
981 }
982
983 try {
984 LayoutSetPrototype layoutSetPrototype =
985 LayoutSetPrototypeLocalServiceUtil.
986 getLayoutSetPrototypeByUuidAndCompanyId(
987 layoutSet.getLayoutSetPrototypeUuid(),
988 layoutSet.getCompanyId());
989
990 String layoutsUpdateable = layoutSetPrototype.getSettingsProperty(
991 "layoutsUpdateable");
992
993 if (Validator.isNotNull(layoutsUpdateable)) {
994 return GetterUtil.getBoolean(layoutsUpdateable, true);
995 }
996 }
997 catch (Exception e) {
998 if (_log.isDebugEnabled()) {
999 _log.debug(e, e);
1000 }
1001 }
1002
1003 return true;
1004 }
1005
1006 @Override
1007 public boolean isLayoutSortable(Layout layout) {
1008 return isLayoutDeleteable(layout);
1009 }
1010
1011 @Override
1012 public boolean isLayoutUpdateable(Layout layout) {
1013 try {
1014 if (layout instanceof VirtualLayout) {
1015 return false;
1016 }
1017
1018 if (Validator.isNull(layout.getLayoutPrototypeUuid()) &&
1019 Validator.isNull(layout.getSourcePrototypeLayoutUuid())) {
1020
1021 return true;
1022 }
1023
1024 LayoutSet layoutSet = layout.getLayoutSet();
1025
1026 if (layoutSet.isLayoutSetPrototypeLinkActive()) {
1027 boolean layoutSetPrototypeUpdateable =
1028 isLayoutSetPrototypeUpdateable(layoutSet);
1029
1030 if (!layoutSetPrototypeUpdateable) {
1031 return false;
1032 }
1033
1034 Layout layoutSetPrototypeLayout = getLayoutSetPrototypeLayout(
1035 layout);
1036
1037 String layoutUpdateable =
1038 layoutSetPrototypeLayout.getTypeSettingsProperty(
1039 LAYOUT_UPDATEABLE);
1040
1041 if (Validator.isNull(layoutUpdateable)) {
1042 return true;
1043 }
1044
1045 return GetterUtil.getBoolean(layoutUpdateable);
1046 }
1047 }
1048 catch (Exception e) {
1049 if (_log.isDebugEnabled()) {
1050 _log.debug(e, e);
1051 }
1052 }
1053
1054 return true;
1055 }
1056
1057 @Override
1058 public boolean isOrganizationUser(
1059 long companyId, Group group, User user,
1060 List<String> organizationNames)
1061 throws Exception {
1062
1063 boolean organizationUser = false;
1064
1065 LinkedHashMap<String, Object> organizationParams =
1066 new LinkedHashMap<String, Object>();
1067
1068 organizationParams.put(
1069 "groupOrganization", new Long(group.getGroupId()));
1070 organizationParams.put(
1071 "organizationsGroups", new Long(group.getGroupId()));
1072
1073 List<Organization> organizationsGroups =
1074 OrganizationLocalServiceUtil.search(
1075 companyId, OrganizationConstants.ANY_PARENT_ORGANIZATION_ID,
1076 null, null, null, null, organizationParams, QueryUtil.ALL_POS,
1077 QueryUtil.ALL_POS);
1078
1079 for (Organization organization : organizationsGroups) {
1080 for (long userOrganizationId : user.getOrganizationIds()) {
1081 if (userOrganizationId == organization.getOrganizationId()) {
1082 organizationNames.add(organization.getName());
1083
1084 organizationUser = true;
1085 }
1086 }
1087 }
1088
1089 return organizationUser;
1090 }
1091
1092 @Override
1093 public boolean isUserGroupLayoutSetViewable(
1094 PermissionChecker permissionChecker, Group userGroupGroup)
1095 throws PortalException, SystemException {
1096
1097 if (!userGroupGroup.isUserGroup()) {
1098 return false;
1099 }
1100
1101 if (GroupPermissionUtil.contains(
1102 permissionChecker, userGroupGroup.getGroupId(),
1103 ActionKeys.VIEW)) {
1104
1105 return true;
1106 }
1107
1108 UserGroup userGroup = UserGroupLocalServiceUtil.getUserGroup(
1109 userGroupGroup.getClassPK());
1110
1111 if (UserLocalServiceUtil.hasUserGroupUser(
1112 userGroup.getUserGroupId(), permissionChecker.getUserId())) {
1113
1114 return true;
1115 }
1116 else {
1117 return false;
1118 }
1119 }
1120
1121 @Override
1122 public boolean isUserGroupUser(
1123 long companyId, Group group, User user, List<String> userGroupNames)
1124 throws Exception {
1125
1126 boolean userGroupUser = false;
1127
1128 LinkedHashMap<String, Object> userGroupParams =
1129 new LinkedHashMap<String, Object>();
1130
1131 userGroupParams.put("userGroupsGroups", new Long(group.getGroupId()));
1132
1133 List<UserGroup> userGroupsGroups = UserGroupLocalServiceUtil.search(
1134 companyId, null, userGroupParams, QueryUtil.ALL_POS,
1135 QueryUtil.ALL_POS, (OrderByComparator)null);
1136
1137 for (UserGroup userGroup : userGroupsGroups) {
1138 for (long userGroupId : user.getUserGroupIds()) {
1139 if (userGroupId == userGroup.getUserGroupId()) {
1140 userGroupNames.add(userGroup.getName());
1141
1142 userGroupUser = true;
1143 }
1144 }
1145 }
1146
1147 return userGroupUser;
1148 }
1149
1150 @Override
1151 public void mergeLayoutPrototypeLayout(Group group, Layout layout)
1152 throws Exception {
1153
1154 String sourcePrototypeLayoutUuid =
1155 layout.getSourcePrototypeLayoutUuid();
1156
1157 if (Validator.isNull(sourcePrototypeLayoutUuid)) {
1158 doMergeLayoutPrototypeLayout(group, layout);
1159
1160 return;
1161 }
1162
1163 LayoutSet layoutSet = layout.getLayoutSet();
1164
1165 long layoutSetPrototypeId = layoutSet.getLayoutSetPrototypeId();
1166
1167 if (layoutSetPrototypeId > 0) {
1168 Group layoutSetPrototypeGroup =
1169 GroupLocalServiceUtil.getLayoutSetPrototypeGroup(
1170 layout.getCompanyId(), layoutSetPrototypeId);
1171
1172 Layout sourcePrototypeLayout =
1173 LayoutLocalServiceUtil.getLayoutByUuidAndGroupId(
1174 sourcePrototypeLayoutUuid,
1175 layoutSetPrototypeGroup.getGroupId(), true);
1176
1177 doMergeLayoutPrototypeLayout(
1178 layoutSetPrototypeGroup, sourcePrototypeLayout);
1179 }
1180
1181 doMergeLayoutPrototypeLayout(group, layout);
1182 }
1183
1184
1188 @Override
1189 public void mergeLayoutProtypeLayout(Group group, Layout layout)
1190 throws Exception {
1191
1192 mergeLayoutPrototypeLayout(group, layout);
1193 }
1194
1195 @Override
1196 public void mergeLayoutSetPrototypeLayouts(Group group, LayoutSet layoutSet)
1197 throws Exception {
1198
1199 if (!isLayoutSetMergeable(group, layoutSet)) {
1200 return;
1201 }
1202
1203 UnicodeProperties settingsProperties =
1204 layoutSet.getSettingsProperties();
1205
1206 long lastMergeTime = GetterUtil.getLong(
1207 settingsProperties.getProperty(LAST_MERGE_TIME));
1208
1209 LayoutSetPrototype layoutSetPrototype =
1210 LayoutSetPrototypeLocalServiceUtil.
1211 getLayoutSetPrototypeByUuidAndCompanyId(
1212 layoutSet.getLayoutSetPrototypeUuid(),
1213 layoutSet.getCompanyId());
1214
1215 LayoutSet layoutSetPrototypeLayoutSet =
1216 layoutSetPrototype.getLayoutSet();
1217
1218 UnicodeProperties layoutSetPrototypeSettingsProperties =
1219 layoutSetPrototypeLayoutSet.getSettingsProperties();
1220
1221 int mergeFailCount = GetterUtil.getInteger(
1222 layoutSetPrototypeSettingsProperties.getProperty(MERGE_FAIL_COUNT));
1223
1224 String owner = PortalUUIDUtil.generate();
1225
1226 try {
1227 Lock lock = LockLocalServiceUtil.lock(
1228 LayoutLocalServiceVirtualLayoutsAdvice.class.getName(),
1229 String.valueOf(layoutSet.getLayoutSetId()), owner);
1230
1231
1232
1233 if (!owner.equals(lock.getOwner())) {
1234 Date createDate = lock.getCreateDate();
1235
1236 if ((System.currentTimeMillis() - createDate.getTime()) >=
1237 PropsValues.LAYOUT_SET_PROTOTYPE_MERGE_LOCK_MAX_TIME) {
1238
1239
1240
1241 lock = LockLocalServiceUtil.lock(
1242 LayoutLocalServiceVirtualLayoutsAdvice.class.getName(),
1243 String.valueOf(layoutSet.getLayoutSetId()),
1244 lock.getOwner(), owner);
1245
1246
1247
1248
1249 if (!owner.equals(lock.getOwner())) {
1250 return;
1251 }
1252 }
1253 else {
1254 return;
1255 }
1256 }
1257 }
1258 catch (Exception e) {
1259 return;
1260 }
1261
1262 try {
1263 boolean importData = true;
1264
1265 long lastResetTime = GetterUtil.getLong(
1266 settingsProperties.getProperty(LAST_RESET_TIME));
1267
1268 if ((lastMergeTime > 0) || (lastResetTime > 0)) {
1269 importData = false;
1270 }
1271
1272 Map<String, String[]> parameterMap =
1273 getLayoutSetPrototypesParameters(importData);
1274
1275 removeMergeFailFriendlyURLLayouts(layoutSet);
1276
1277 importLayoutSetPrototype(
1278 layoutSetPrototype, layoutSet.getGroupId(),
1279 layoutSet.isPrivateLayout(), parameterMap, importData);
1280 }
1281 catch (Exception e) {
1282 _log.error(e, e);
1283
1284 layoutSetPrototypeSettingsProperties.setProperty(
1285 MERGE_FAIL_COUNT, String.valueOf(++mergeFailCount));
1286
1287
1288
1289 LayoutSetUtil.updateImpl(layoutSetPrototypeLayoutSet);
1290 }
1291 finally {
1292 LockLocalServiceUtil.unlock(
1293 LayoutLocalServiceVirtualLayoutsAdvice.class.getName(),
1294 String.valueOf(layoutSet.getLayoutSetId()), owner);
1295 }
1296 }
1297
1298
1302 @Override
1303 public void mergeLayoutSetProtypeLayouts(Group group, LayoutSet layoutSet)
1304 throws Exception {
1305
1306 mergeLayoutSetPrototypeLayouts(group, layoutSet);
1307 }
1308
1309 @Override
1310 public void removeMergeFailFriendlyURLLayouts(LayoutSet layoutSet)
1311 throws SystemException {
1312
1313 UnicodeProperties settingsProperties =
1314 layoutSet.getSettingsProperties();
1315
1316 settingsProperties.remove(MERGE_FAIL_FRIENDLY_URL_LAYOUTS);
1317
1318 LayoutSetLocalServiceUtil.updateLayoutSet(layoutSet);
1319 }
1320
1321
1331 @Override
1332 public void resetPrototype(Layout layout)
1333 throws PortalException, SystemException {
1334
1335 checkResetPrototypePermissions(layout.getGroup(), layout);
1336
1337 doResetPrototype(layout);
1338 }
1339
1340
1350 @Override
1351 public void resetPrototype(LayoutSet layoutSet)
1352 throws PortalException, SystemException {
1353
1354 checkResetPrototypePermissions(layoutSet.getGroup(), null);
1355
1356 doResetPrototype(layoutSet);
1357 }
1358
1359
1370 @Override
1371 public void setMergeFailCount(
1372 LayoutPrototype layoutPrototype, int newMergeFailCount)
1373 throws PortalException, SystemException {
1374
1375 Layout layoutPrototypeLayout = layoutPrototype.getLayout();
1376
1377 UnicodeProperties prototypeTypeSettingsProperties =
1378 layoutPrototypeLayout.getTypeSettingsProperties();
1379
1380 if (newMergeFailCount == 0) {
1381 prototypeTypeSettingsProperties.remove(MERGE_FAIL_COUNT);
1382 }
1383 else {
1384 prototypeTypeSettingsProperties.setProperty(
1385 MERGE_FAIL_COUNT, String.valueOf(newMergeFailCount));
1386 }
1387
1388 LayoutServiceUtil.updateLayout(
1389 layoutPrototypeLayout.getGroupId(),
1390 layoutPrototypeLayout.getPrivateLayout(),
1391 layoutPrototypeLayout.getLayoutId(),
1392 layoutPrototypeLayout.getTypeSettings());
1393 }
1394
1395
1406 @Override
1407 public void setMergeFailCount(
1408 LayoutSetPrototype layoutSetPrototype, int newMergeFailCount)
1409 throws PortalException, SystemException {
1410
1411 LayoutSet layoutSetPrototypeLayoutSet =
1412 layoutSetPrototype.getLayoutSet();
1413
1414 UnicodeProperties layoutSetPrototypeSettingsProperties =
1415 layoutSetPrototypeLayoutSet.getSettingsProperties();
1416
1417 if (newMergeFailCount == 0) {
1418 layoutSetPrototypeSettingsProperties.remove(MERGE_FAIL_COUNT);
1419 }
1420 else {
1421 layoutSetPrototypeSettingsProperties.setProperty(
1422 MERGE_FAIL_COUNT, String.valueOf(newMergeFailCount));
1423 }
1424
1425 LayoutSetServiceUtil.updateSettings(
1426 layoutSetPrototypeLayoutSet.getGroupId(),
1427 layoutSetPrototypeLayoutSet.getPrivateLayout(),
1428 layoutSetPrototypeLayoutSet.getSettings());
1429 }
1430
1431 @Override
1432 public void updateLayoutScopes(
1433 long userId, Layout sourceLayout, Layout targetLayout,
1434 PortletPreferences sourcePreferences,
1435 PortletPreferences targetPreferences, String sourcePortletId,
1436 String languageId)
1437 throws Exception {
1438
1439 String scopeType = GetterUtil.getString(
1440 sourcePreferences.getValue("lfrScopeType", null));
1441
1442 if (Validator.isNull(scopeType) || !scopeType.equals("layout")) {
1443 return;
1444 }
1445
1446 Layout targetScopeLayout =
1447 LayoutLocalServiceUtil.getLayoutByUuidAndGroupId(
1448 targetLayout.getUuid(), targetLayout.getGroupId(),
1449 targetLayout.isPrivateLayout());
1450
1451 if (!targetScopeLayout.hasScopeGroup()) {
1452 GroupLocalServiceUtil.addGroup(
1453 userId, GroupConstants.DEFAULT_PARENT_GROUP_ID,
1454 Layout.class.getName(), targetLayout.getPlid(),
1455 GroupConstants.DEFAULT_LIVE_GROUP_ID,
1456 targetLayout.getName(languageId), null, 0, true,
1457 GroupConstants.DEFAULT_MEMBERSHIP_RESTRICTION, null, false,
1458 true, null);
1459 }
1460
1461 String portletTitle = PortalUtil.getPortletTitle(
1462 sourcePortletId, languageId);
1463
1464 String newPortletTitle = PortalUtil.getNewPortletTitle(
1465 portletTitle, String.valueOf(sourceLayout.getLayoutId()),
1466 targetLayout.getName(languageId));
1467
1468 targetPreferences.setValue(
1469 "groupId", String.valueOf(targetLayout.getGroupId()));
1470 targetPreferences.setValue("lfrScopeType", "layout");
1471 targetPreferences.setValue(
1472 "lfrScopeLayoutUuid", targetLayout.getUuid());
1473 targetPreferences.setValue(
1474 "portletSetupTitle_" + languageId, newPortletTitle);
1475 targetPreferences.setValue(
1476 "portletSetupUseCustomTitle", Boolean.TRUE.toString());
1477
1478 targetPreferences.store();
1479 }
1480
1481 @Override
1482 public void updateLayoutSetPrototypesLinks(
1483 Group group, long publicLayoutSetPrototypeId,
1484 long privateLayoutSetPrototypeId,
1485 boolean publicLayoutSetPrototypeLinkEnabled,
1486 boolean privateLayoutSetPrototypeLinkEnabled)
1487 throws Exception {
1488
1489 updateLayoutSetPrototypeLink(
1490 group.getGroupId(), true, privateLayoutSetPrototypeId,
1491 privateLayoutSetPrototypeLinkEnabled);
1492 updateLayoutSetPrototypeLink(
1493 group.getGroupId(), false, publicLayoutSetPrototypeId,
1494 publicLayoutSetPrototypeLinkEnabled);
1495 }
1496
1497
1509 protected void checkResetPrototypePermissions(Group group, Layout layout)
1510 throws PortalException, SystemException {
1511
1512 PermissionChecker permissionChecker =
1513 PermissionThreadLocal.getPermissionChecker();
1514
1515 if ((layout != null) &&
1516 !LayoutPermissionUtil.contains(
1517 permissionChecker, layout, ActionKeys.UPDATE)) {
1518
1519 throw new PrincipalException();
1520 }
1521 else if (!group.isUser() &&
1522 !GroupPermissionUtil.contains(
1523 permissionChecker, group, ActionKeys.UPDATE)) {
1524
1525 throw new PrincipalException();
1526 }
1527 else if (group.isUser() &&
1528 (permissionChecker.getUserId() != group.getClassPK())) {
1529
1530 throw new PrincipalException();
1531 }
1532 }
1533
1534 protected void doMergeLayoutPrototypeLayout(Group group, Layout layout)
1535 throws Exception {
1536
1537 if (!layout.isLayoutPrototypeLinkActive() ||
1538 group.isLayoutPrototype() || group.hasStagingGroup()) {
1539
1540 return;
1541 }
1542
1543 long lastMergeTime = GetterUtil.getLong(
1544 layout.getTypeSettingsProperty(LAST_MERGE_TIME));
1545
1546 LayoutPrototype layoutPrototype =
1547 LayoutPrototypeLocalServiceUtil.
1548 getLayoutPrototypeByUuidAndCompanyId(
1549 layout.getLayoutPrototypeUuid(), layout.getCompanyId());
1550
1551 Layout layoutPrototypeLayout = layoutPrototype.getLayout();
1552
1553 Date modifiedDate = layoutPrototypeLayout.getModifiedDate();
1554
1555 if (lastMergeTime >= modifiedDate.getTime()) {
1556 return;
1557 }
1558
1559 UnicodeProperties prototypeTypeSettingsProperties =
1560 layoutPrototypeLayout.getTypeSettingsProperties();
1561
1562 int mergeFailCount = GetterUtil.getInteger(
1563 prototypeTypeSettingsProperties.getProperty(MERGE_FAIL_COUNT));
1564
1565 if (mergeFailCount >
1566 PropsValues.LAYOUT_PROTOTYPE_MERGE_FAIL_THRESHOLD) {
1567
1568 if (_log.isWarnEnabled()) {
1569 StringBundler sb = new StringBundler(6);
1570
1571 sb.append("Merge not performed because the fail threshold ");
1572 sb.append("was reached for layoutPrototypeId ");
1573 sb.append(layoutPrototype.getLayoutPrototypeId());
1574 sb.append(" and layoutId ");
1575 sb.append(layoutPrototypeLayout.getLayoutId());
1576 sb.append(". Update the count in the database to try again.");
1577
1578 _log.warn(sb.toString());
1579 }
1580
1581 return;
1582 }
1583
1584 String owner = PortalUUIDUtil.generate();
1585
1586 try {
1587 Lock lock = LockLocalServiceUtil.lock(
1588 LayoutLocalServiceVirtualLayoutsAdvice.class.getName(),
1589 String.valueOf(layout.getPlid()), owner);
1590
1591 if (!owner.equals(lock.getOwner())) {
1592 Date createDate = lock.getCreateDate();
1593
1594 if ((System.currentTimeMillis() - createDate.getTime()) >=
1595 PropsValues.LAYOUT_PROTOTYPE_MERGE_LOCK_MAX_TIME) {
1596
1597
1598
1599 lock = LockLocalServiceUtil.lock(
1600 LayoutLocalServiceVirtualLayoutsAdvice.class.getName(),
1601 String.valueOf(layout.getPlid()), lock.getOwner(),
1602 owner);
1603
1604
1605
1606
1607 if (!owner.equals(lock.getOwner())) {
1608 return;
1609 }
1610 }
1611 else {
1612 return;
1613 }
1614 }
1615 }
1616 catch (Exception e) {
1617 return;
1618 }
1619
1620 try {
1621 applyLayoutPrototype(layoutPrototype, layout, true);
1622 }
1623 catch (Exception e) {
1624 _log.error(e, e);
1625
1626 prototypeTypeSettingsProperties.setProperty(
1627 MERGE_FAIL_COUNT, String.valueOf(++mergeFailCount));
1628
1629
1630
1631 LayoutUtil.updateImpl(layoutPrototypeLayout);
1632 }
1633 finally {
1634 LockLocalServiceUtil.unlock(
1635 LayoutLocalServiceVirtualLayoutsAdvice.class.getName(),
1636 String.valueOf(layout.getPlid()), owner);
1637 }
1638 }
1639
1640
1656 protected void doResetPrototype(Layout layout)
1657 throws PortalException, SystemException {
1658
1659 layout.setModifiedDate(null);
1660
1661 LayoutLocalServiceUtil.updateLayout(layout);
1662
1663 LayoutSet layoutSet = layout.getLayoutSet();
1664
1665 doResetPrototype(layoutSet);
1666 }
1667
1668
1679 protected void doResetPrototype(LayoutSet layoutSet)
1680 throws SystemException {
1681
1682 UnicodeProperties settingsProperties =
1683 layoutSet.getSettingsProperties();
1684
1685 settingsProperties.remove(LAST_MERGE_TIME);
1686
1687 settingsProperties.setProperty(
1688 LAST_RESET_TIME, String.valueOf(System.currentTimeMillis()));
1689
1690 LayoutSetLocalServiceUtil.updateLayoutSet(layoutSet);
1691 }
1692
1693 protected Map<String, String[]> getLayoutSetPrototypesParameters(
1694 boolean importData) {
1695
1696 Map<String, String[]> parameterMap =
1697 new LinkedHashMap<String, String[]>();
1698
1699 parameterMap.put(
1700 PortletDataHandlerKeys.CATEGORIES,
1701 new String[] {Boolean.TRUE.toString()});
1702 parameterMap.put(
1703 PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS,
1704 new String[] {Boolean.FALSE.toString()});
1705 parameterMap.put(
1706 PortletDataHandlerKeys.DELETE_PORTLET_DATA,
1707 new String[] {Boolean.FALSE.toString()});
1708 parameterMap.put(
1709 PortletDataHandlerKeys.IGNORE_LAST_PUBLISH_DATE,
1710 new String[] {Boolean.TRUE.toString()});
1711 parameterMap.put(
1712 PortletDataHandlerKeys.LAYOUT_SET_SETTINGS,
1713 new String[] {Boolean.TRUE.toString()});
1714 parameterMap.put(
1715 PortletDataHandlerKeys.LAYOUT_SET_PROTOTYPE_LINK_ENABLED,
1716 new String[] {Boolean.TRUE.toString()});
1717 parameterMap.put(
1718 PortletDataHandlerKeys.LAYOUTS_IMPORT_MODE,
1719 new String[] {
1720 PortletDataHandlerKeys.
1721 LAYOUTS_IMPORT_MODE_CREATED_FROM_PROTOTYPE
1722 });
1723 parameterMap.put(
1724 PortletDataHandlerKeys.LOGO,
1725 new String[] {Boolean.TRUE.toString()});
1726 parameterMap.put(
1727 PortletDataHandlerKeys.PERMISSIONS,
1728 new String[] {Boolean.TRUE.toString()});
1729 parameterMap.put(
1730 PortletDataHandlerKeys.PORTLET_CONFIGURATION,
1731 new String[] {Boolean.TRUE.toString()});
1732 parameterMap.put(
1733 PortletDataHandlerKeys.PORTLET_CONFIGURATION_ALL,
1734 new String[] {Boolean.TRUE.toString()});
1735 parameterMap.put(
1736 PortletDataHandlerKeys.PORTLET_SETUP_ALL,
1737 new String[] {Boolean.TRUE.toString()});
1738 parameterMap.put(
1739 PortletDataHandlerKeys.THEME,
1740 new String[] {Boolean.FALSE.toString()});
1741 parameterMap.put(
1742 PortletDataHandlerKeys.THEME_REFERENCE,
1743 new String[] {Boolean.TRUE.toString()});
1744 parameterMap.put(
1745 PortletDataHandlerKeys.UPDATE_LAST_PUBLISH_DATE,
1746 new String[] {Boolean.FALSE.toString()});
1747 parameterMap.put(
1748 PortletDataHandlerKeys.USER_ID_STRATEGY,
1749 new String[] {UserIdStrategy.CURRENT_USER_ID});
1750
1751 if (importData) {
1752 parameterMap.put(
1753 PortletDataHandlerKeys.DATA_STRATEGY,
1754 new String[] {PortletDataHandlerKeys.DATA_STRATEGY_MIRROR});
1755 parameterMap.put(
1756 PortletDataHandlerKeys.PORTLET_DATA,
1757 new String[] {Boolean.TRUE.toString()});
1758 parameterMap.put(
1759 PortletDataHandlerKeys.PORTLET_DATA_ALL,
1760 new String[] {Boolean.TRUE.toString()});
1761 }
1762 else {
1763 parameterMap.put(
1764 PortletDataHandlerKeys.PORTLET_DATA,
1765 new String[] {Boolean.FALSE.toString()});
1766 parameterMap.put(
1767 PortletDataHandlerKeys.PORTLET_DATA_ALL,
1768 new String[] {Boolean.FALSE.toString()});
1769 }
1770
1771 return parameterMap;
1772 }
1773
1774 protected void importLayoutSetPrototype(
1775 LayoutSetPrototype layoutSetPrototype, long groupId,
1776 boolean privateLayout, Map<String, String[]> parameterMap,
1777 boolean importData)
1778 throws PortalException, SystemException {
1779
1780 File file = null;
1781
1782 StringBundler sb = new StringBundler(importData ? 4 : 3);
1783
1784 sb.append(_TEMP_DIR);
1785 sb.append(layoutSetPrototype.getUuid());
1786
1787 if (importData) {
1788 sb.append("-data");
1789 }
1790
1791 sb.append(".lar");
1792
1793 File cacheFile = new File(sb.toString());
1794
1795 if (cacheFile.exists()) {
1796 Date modifiedDate = layoutSetPrototype.getModifiedDate();
1797
1798 if (cacheFile.lastModified() >= modifiedDate.getTime()) {
1799 if (_log.isDebugEnabled()) {
1800 _log.debug(
1801 "Using cached layout set prototype LAR file " +
1802 cacheFile.getAbsolutePath());
1803 }
1804
1805 file = cacheFile;
1806 }
1807 }
1808
1809 boolean newFile = false;
1810
1811 if (file == null) {
1812 file = LayoutLocalServiceUtil.exportLayoutsAsFile(
1813 layoutSetPrototype.getGroupId(), true, null, parameterMap, null,
1814 null);
1815
1816 newFile = true;
1817 }
1818
1819 long userId = UserLocalServiceUtil.getDefaultUserId(
1820 layoutSetPrototype.getCompanyId());
1821
1822 LayoutLocalServiceUtil.importLayouts(
1823 userId, groupId, privateLayout, parameterMap, file);
1824
1825 if (newFile) {
1826 try {
1827 FileUtil.copyFile(file, cacheFile);
1828
1829 if (_log.isDebugEnabled()) {
1830 _log.debug(
1831 "Copied " + file.getAbsolutePath() + " to " +
1832 cacheFile.getAbsolutePath());
1833 }
1834 }
1835 catch (Exception e) {
1836 _log.error(
1837 "Unable to copy file " + file.getAbsolutePath() + " to " +
1838 cacheFile.getAbsolutePath(),
1839 e);
1840 }
1841 }
1842 }
1843
1844 protected void setLayoutSetPrototypeLinkEnabledParameter(
1845 Map<String, String[]> parameterMap, LayoutSet targetLayoutSet,
1846 ServiceContext serviceContext) {
1847
1848 PermissionChecker permissionChecker =
1849 PermissionThreadLocal.getPermissionChecker();
1850
1851 if ((permissionChecker == null) ||
1852 !PortalPermissionUtil.contains(
1853 permissionChecker, ActionKeys.UNLINK_LAYOUT_SET_PROTOTYPE)) {
1854
1855 return;
1856 }
1857
1858 if (targetLayoutSet.isPrivateLayout()) {
1859 boolean privateLayoutSetPrototypeLinkEnabled = ParamUtil.getBoolean(
1860 serviceContext, "privateLayoutSetPrototypeLinkEnabled", true);
1861
1862 if (!privateLayoutSetPrototypeLinkEnabled) {
1863 privateLayoutSetPrototypeLinkEnabled = ParamUtil.getBoolean(
1864 serviceContext, "layoutSetPrototypeLinkEnabled");
1865 }
1866
1867 parameterMap.put(
1868 PortletDataHandlerKeys.LAYOUT_SET_PROTOTYPE_LINK_ENABLED,
1869 new String[] {
1870 String.valueOf(privateLayoutSetPrototypeLinkEnabled)
1871 });
1872 }
1873 else {
1874 boolean publicLayoutSetPrototypeLinkEnabled = ParamUtil.getBoolean(
1875 serviceContext, "publicLayoutSetPrototypeLinkEnabled");
1876
1877 if (!publicLayoutSetPrototypeLinkEnabled) {
1878 publicLayoutSetPrototypeLinkEnabled = ParamUtil.getBoolean(
1879 serviceContext, "layoutSetPrototypeLinkEnabled", true);
1880 }
1881
1882 parameterMap.put(
1883 PortletDataHandlerKeys.LAYOUT_SET_PROTOTYPE_LINK_ENABLED,
1884 new String[] {
1885 String.valueOf(publicLayoutSetPrototypeLinkEnabled)
1886 });
1887 }
1888 }
1889
1890 protected void updateLayoutSetPrototypeLink(
1891 long groupId, boolean privateLayout, long layoutSetPrototypeId,
1892 boolean layoutSetPrototypeLinkEnabled)
1893 throws Exception {
1894
1895 String layoutSetPrototypeUuid = null;
1896
1897 if (layoutSetPrototypeId > 0) {
1898 LayoutSetPrototype layoutSetPrototype =
1899 LayoutSetPrototypeLocalServiceUtil.fetchLayoutSetPrototype(
1900 layoutSetPrototypeId);
1901
1902 if (layoutSetPrototype != null) {
1903 layoutSetPrototypeUuid = layoutSetPrototype.getUuid();
1904
1905
1906
1907 if (!layoutSetPrototypeLinkEnabled &&
1908 (layoutSetPrototypeId > 0)) {
1909
1910 Map<String, String[]> parameterMap =
1911 getLayoutSetPrototypesParameters(true);
1912
1913 importLayoutSetPrototype(
1914 layoutSetPrototype, groupId, privateLayout,
1915 parameterMap, true);
1916 }
1917 }
1918 }
1919
1920 LayoutSetServiceUtil.updateLayoutSetPrototypeLinkEnabled(
1921 groupId, privateLayout, layoutSetPrototypeLinkEnabled,
1922 layoutSetPrototypeUuid);
1923
1924 LayoutLocalServiceUtil.updatePriorities(groupId, privateLayout);
1925 }
1926
1927 private static final String _TEMP_DIR =
1928 SystemProperties.get(SystemProperties.TMP_DIR) +
1929 "/liferay/layout_set_prototype/";
1930
1931 private static Log _log = LogFactoryUtil.getLog(SitesImpl.class);
1932
1933 }