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