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.getPageCount() == 1)) {
525 throw new RequiredLayoutException(
526 RequiredLayoutException.AT_LEAST_ONE);
527 }
528
529 ServiceContext serviceContext = ServiceContextFactory.getInstance(
530 request);
531
532 LayoutServiceUtil.deleteLayout(
533 groupId, privateLayout, layoutId, serviceContext);
534
535 long newPlid = layout.getParentPlid();
536
537 if (newPlid <= 0) {
538 Layout firstLayout = LayoutLocalServiceUtil.fetchFirstLayout(
539 layoutSet.getGroupId(), layoutSet.isPrivateLayout(),
540 LayoutConstants.DEFAULT_PARENT_LAYOUT_ID);
541
542 if (firstLayout != null) {
543 newPlid = firstLayout.getPlid();
544 }
545 }
546
547 return new Object[] {group, oldFriendlyURL, newPlid};
548 }
549
550 @Override
551 public void deleteLayout(
552 RenderRequest renderRequest, RenderResponse renderResponse)
553 throws Exception {
554
555 HttpServletRequest request = PortalUtil.getHttpServletRequest(
556 renderRequest);
557 HttpServletResponse response = PortalUtil.getHttpServletResponse(
558 renderResponse);
559
560 deleteLayout(request, response);
561 }
562
563 @Override
564 public File exportLayoutSetPrototype(
565 LayoutSetPrototype layoutSetPrototype,
566 ServiceContext serviceContext)
567 throws PortalException, SystemException {
568
569 LayoutSet layoutSet = layoutSetPrototype.getLayoutSet();
570
571 Map<String, String[]> parameterMap = getLayoutSetPrototypeParameters(
572 serviceContext);
573
574 return LayoutLocalServiceUtil.exportLayoutsAsFile(
575 layoutSet.getGroupId(), layoutSet.isPrivateLayout(), null,
576 parameterMap, null, null);
577 }
578
579 @Override
580 public Long[] filterGroups(List<Group> groups, String[] names) {
581 List<Long> groupIds = new ArrayList<Long>();
582
583 for (Group group : groups) {
584 if (!ArrayUtil.contains(names, group.getName())) {
585 groupIds.add(group.getGroupId());
586 }
587 }
588
589 return ArrayUtil.toArray(ArrayUtil.toLongArray(groupIds));
590 }
591
592 @Override
593 public Layout getLayoutSetPrototypeLayout(Layout layout) {
594 try {
595 LayoutSet layoutSet = layout.getLayoutSet();
596
597 if (!layoutSet.isLayoutSetPrototypeLinkActive()) {
598 return null;
599 }
600
601 LayoutSetPrototype layoutSetPrototype =
602 LayoutSetPrototypeLocalServiceUtil.
603 getLayoutSetPrototypeByUuidAndCompanyId(
604 layoutSet.getLayoutSetPrototypeUuid(),
605 layout.getCompanyId());
606
607 return LayoutLocalServiceUtil.fetchLayoutByUuidAndGroupId(
608 layout.getSourcePrototypeLayoutUuid(),
609 layoutSetPrototype.getGroupId(), true);
610 }
611 catch (Exception e) {
612 _log.error(
613 "Unable to fetch the the layout set prototype's layout", e);
614 }
615
616 return null;
617 }
618
619 @Override
620 public Map<String, String[]> getLayoutSetPrototypeParameters(
621 ServiceContext serviceContext) {
622
623 Map<String, String[]> parameterMap =
624 new LinkedHashMap<String, String[]>();
625
626 parameterMap.put(
627 PortletDataHandlerKeys.CATEGORIES,
628 new String[] {Boolean.TRUE.toString()});
629 parameterMap.put(
630 PortletDataHandlerKeys.DATA_STRATEGY,
631 new String[] {PortletDataHandlerKeys.DATA_STRATEGY_MIRROR});
632 parameterMap.put(
633 PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS,
634 new String[] {Boolean.TRUE.toString()});
635 parameterMap.put(
636 PortletDataHandlerKeys.DELETE_PORTLET_DATA,
637 new String[] {Boolean.FALSE.toString()});
638 parameterMap.put(
639 PortletDataHandlerKeys.LAYOUT_SET_PROTOTYPE_LINK_ENABLED,
640 new String[] {Boolean.TRUE.toString()});
641 parameterMap.put(
642 PortletDataHandlerKeys.LAYOUT_SET_SETTINGS,
643 new String[] {Boolean.TRUE.toString()});
644 parameterMap.put(
645 PortletDataHandlerKeys.LAYOUTS_IMPORT_MODE,
646 new String[] {
647 PortletDataHandlerKeys.
648 LAYOUTS_IMPORT_MODE_CREATED_FROM_PROTOTYPE
649 });
650 parameterMap.put(
651 PortletDataHandlerKeys.LOGO,
652 new String[] {Boolean.TRUE.toString()});
653 parameterMap.put(
654 PortletDataHandlerKeys.PERFORM_DIRECT_BINARY_IMPORT,
655 new String[] {Boolean.TRUE.toString()});
656 parameterMap.put(
657 PortletDataHandlerKeys.PERMISSIONS,
658 new String[] {Boolean.TRUE.toString()});
659 parameterMap.put(
660 PortletDataHandlerKeys.PORTLET_CONFIGURATION,
661 new String[] {Boolean.TRUE.toString()});
662 parameterMap.put(
663 PortletDataHandlerKeys.PORTLET_CONFIGURATION_ALL,
664 new String[] {Boolean.TRUE.toString()});
665 parameterMap.put(
666 PortletDataHandlerKeys.PORTLET_DATA,
667 new String[] {Boolean.TRUE.toString()});
668 parameterMap.put(
669 PortletDataHandlerKeys.PORTLET_DATA_ALL,
670 new String[] {Boolean.TRUE.toString()});
671 parameterMap.put(
672 PortletDataHandlerKeys.PORTLET_SETUP_ALL,
673 new String[] {Boolean.TRUE.toString()});
674 parameterMap.put(
675 PortletDataHandlerKeys.THEME_REFERENCE,
676 new String[] {Boolean.TRUE.toString()});
677 parameterMap.put(
678 PortletDataHandlerKeys.USER_ID_STRATEGY,
679 new String[] {UserIdStrategy.CURRENT_USER_ID});
680
681 return parameterMap;
682 }
683
684
695 @Override
696 public int getMergeFailCount(LayoutPrototype layoutPrototype)
697 throws PortalException, SystemException {
698
699 if ((layoutPrototype == null) ||
700 (layoutPrototype.getLayoutPrototypeId() == 0)) {
701
702 return 0;
703 }
704
705 Layout layoutPrototypeLayout = layoutPrototype.getLayout();
706
707 UnicodeProperties prototypeTypeSettingsProperties =
708 layoutPrototypeLayout.getTypeSettingsProperties();
709
710 return GetterUtil.getInteger(
711 prototypeTypeSettingsProperties.getProperty(MERGE_FAIL_COUNT));
712 }
713
714
725 @Override
726 public int getMergeFailCount(LayoutSetPrototype layoutSetPrototype)
727 throws PortalException, SystemException {
728
729 if ((layoutSetPrototype == null) ||
730 (layoutSetPrototype.getLayoutSetPrototypeId() == 0)) {
731
732 return 0;
733 }
734
735 LayoutSet layoutSetPrototypeLayoutSet =
736 layoutSetPrototype.getLayoutSet();
737
738 UnicodeProperties layoutSetPrototypeSettingsProperties =
739 layoutSetPrototypeLayoutSet.getSettingsProperties();
740
741 return GetterUtil.getInteger(
742 layoutSetPrototypeSettingsProperties.getProperty(MERGE_FAIL_COUNT));
743 }
744
745 @Override
746 public List<Layout> getMergeFailFriendlyURLLayouts(LayoutSet layoutSet)
747 throws PortalException, SystemException {
748
749 if (layoutSet == null) {
750 return Collections.emptyList();
751 }
752
753 UnicodeProperties settingsProperties =
754 layoutSet.getSettingsProperties();
755
756 String uuids = settingsProperties.getProperty(
757 MERGE_FAIL_FRIENDLY_URL_LAYOUTS);
758
759 if (Validator.isNotNull(uuids)) {
760 List<Layout> layouts = new ArrayList<Layout>();
761
762 for (String uuid : StringUtil.split(uuids)) {
763 Layout layout =
764 LayoutLocalServiceUtil.getLayoutByUuidAndGroupId(
765 uuid, layoutSet.getGroupId(),
766 layoutSet.isPrivateLayout());
767
768 layouts.add(layout);
769 }
770
771 return layouts;
772 }
773
774 return Collections.emptyList();
775 }
776
777 @Override
778 public void importLayoutSetPrototype(
779 LayoutSetPrototype layoutSetPrototype, InputStream inputStream,
780 ServiceContext serviceContext)
781 throws PortalException, SystemException {
782
783 LayoutSet layoutSet = layoutSetPrototype.getLayoutSet();
784
785 Map<String, String[]> parameterMap = getLayoutSetPrototypeParameters(
786 serviceContext);
787
788 setLayoutSetPrototypeLinkEnabledParameter(
789 parameterMap, layoutSet, serviceContext);
790
791 LayoutServiceUtil.importLayouts(
792 layoutSet.getGroupId(), layoutSet.isPrivateLayout(), parameterMap,
793 inputStream);
794 }
795
796 @Override
797 public boolean isContentSharingWithChildrenEnabled(Group group)
798 throws SystemException {
799
800 UnicodeProperties typeSettingsProperties =
801 group.getParentLiveGroupTypeSettingsProperties();
802
803 int companyContentSharingEnabled = PrefsPropsUtil.getInteger(
804 group.getCompanyId(),
805 PropsKeys.SITES_CONTENT_SHARING_WITH_CHILDREN_ENABLED);
806
807 if (companyContentSharingEnabled ==
808 CONTENT_SHARING_WITH_CHILDREN_DISABLED) {
809
810 return false;
811 }
812
813 int groupContentSharingEnabled = GetterUtil.getInteger(
814 typeSettingsProperties.getProperty(
815 "contentSharingWithChildrenEnabled"),
816 CONTENT_SHARING_WITH_CHILDREN_DEFAULT_VALUE);
817
818 if ((groupContentSharingEnabled ==
819 CONTENT_SHARING_WITH_CHILDREN_ENABLED) ||
820 ((companyContentSharingEnabled ==
821 CONTENT_SHARING_WITH_CHILDREN_ENABLED_BY_DEFAULT) &&
822 (groupContentSharingEnabled ==
823 CONTENT_SHARING_WITH_CHILDREN_DEFAULT_VALUE))) {
824
825 return true;
826 }
827
828 return false;
829 }
830
831 @Override
832 public boolean isFirstLayout(
833 long groupId, boolean privateLayout, long layoutId)
834 throws SystemException {
835
836 Layout firstLayout = LayoutLocalServiceUtil.fetchFirstLayout(
837 groupId, privateLayout, LayoutConstants.DEFAULT_PARENT_LAYOUT_ID);
838
839 if ((firstLayout != null) && (firstLayout.getLayoutId() == layoutId )) {
840 return true;
841 }
842
843 return false;
844 }
845
846 @Override
847 public boolean isLayoutDeleteable(Layout layout) {
848 try {
849 if (layout instanceof VirtualLayout) {
850 return false;
851 }
852
853 if (Validator.isNull(layout.getSourcePrototypeLayoutUuid())) {
854 return true;
855 }
856
857 LayoutSet layoutSet = layout.getLayoutSet();
858
859 if (!layoutSet.isLayoutSetPrototypeLinkActive()) {
860 return true;
861 }
862
863 if (LayoutLocalServiceUtil.hasLayoutSetPrototypeLayout(
864 layoutSet.getLayoutSetPrototypeUuid(),
865 layout.getCompanyId(),
866 layout.getSourcePrototypeLayoutUuid())) {
867
868 return false;
869 }
870 }
871 catch (Exception e) {
872 if (_log.isDebugEnabled()) {
873 _log.debug(e, e);
874 }
875 }
876
877 return true;
878 }
879
880 @Override
881 public boolean isLayoutModifiedSinceLastMerge(Layout layout) {
882 if ((layout == null) ||
883 Validator.isNull(layout.getSourcePrototypeLayoutUuid()) ||
884 layout.isLayoutPrototypeLinkActive() ||
885 !isLayoutUpdateable(layout)) {
886
887 return false;
888 }
889
890 long lastMergeTime = GetterUtil.getLong(
891 layout.getTypeSettingsProperty(LAST_MERGE_TIME));
892
893 Date existingLayoutModifiedDate = layout.getModifiedDate();
894
895 if ((existingLayoutModifiedDate != null) &&
896 (existingLayoutModifiedDate.getTime() > lastMergeTime)) {
897
898 return true;
899 }
900
901 return false;
902 }
903
904
920 @Override
921 public boolean isLayoutSetMergeable(Group group, LayoutSet layoutSet)
922 throws PortalException, SystemException {
923
924 if (!layoutSet.isLayoutSetPrototypeLinkActive() ||
925 group.isLayoutPrototype() || group.isLayoutSetPrototype()) {
926
927 return false;
928 }
929
930 UnicodeProperties settingsProperties =
931 layoutSet.getSettingsProperties();
932
933 long lastMergeTime = GetterUtil.getLong(
934 settingsProperties.getProperty(LAST_MERGE_TIME));
935
936 LayoutSetPrototype layoutSetPrototype =
937 LayoutSetPrototypeLocalServiceUtil.
938 getLayoutSetPrototypeByUuidAndCompanyId(
939 layoutSet.getLayoutSetPrototypeUuid(),
940 layoutSet.getCompanyId());
941
942 Date modifiedDate = layoutSetPrototype.getModifiedDate();
943
944 if (lastMergeTime >= modifiedDate.getTime()) {
945 return false;
946 }
947
948 LayoutSet layoutSetPrototypeLayoutSet =
949 layoutSetPrototype.getLayoutSet();
950
951 UnicodeProperties layoutSetPrototypeSettingsProperties =
952 layoutSetPrototypeLayoutSet.getSettingsProperties();
953
954 int mergeFailCount = GetterUtil.getInteger(
955 layoutSetPrototypeSettingsProperties.getProperty(MERGE_FAIL_COUNT));
956
957 if (mergeFailCount >
958 PropsValues.LAYOUT_SET_PROTOTYPE_MERGE_FAIL_THRESHOLD) {
959
960 if (_log.isWarnEnabled()) {
961 StringBundler sb = new StringBundler(6);
962
963 sb.append("Merge not performed because the fail threshold ");
964 sb.append("was reached for layoutSetPrototypeId ");
965 sb.append(layoutSetPrototype.getLayoutSetPrototypeId());
966 sb.append(" and layoutId ");
967 sb.append(layoutSetPrototypeLayoutSet.getLayoutSetId());
968 sb.append(". Update the count in the database to try again.");
969
970 _log.warn(sb.toString());
971 }
972
973 return false;
974 }
975
976 return true;
977 }
978
979 @Override
980 public boolean isLayoutSetPrototypeUpdateable(LayoutSet layoutSet) {
981 if (!layoutSet.isLayoutSetPrototypeLinkActive()) {
982 return true;
983 }
984
985 try {
986 LayoutSetPrototype layoutSetPrototype =
987 LayoutSetPrototypeLocalServiceUtil.
988 getLayoutSetPrototypeByUuidAndCompanyId(
989 layoutSet.getLayoutSetPrototypeUuid(),
990 layoutSet.getCompanyId());
991
992 String layoutsUpdateable = layoutSetPrototype.getSettingsProperty(
993 "layoutsUpdateable");
994
995 if (Validator.isNotNull(layoutsUpdateable)) {
996 return GetterUtil.getBoolean(layoutsUpdateable, true);
997 }
998 }
999 catch (Exception e) {
1000 if (_log.isDebugEnabled()) {
1001 _log.debug(e, e);
1002 }
1003 }
1004
1005 return true;
1006 }
1007
1008 @Override
1009 public boolean isLayoutSortable(Layout layout) {
1010 return isLayoutDeleteable(layout);
1011 }
1012
1013 @Override
1014 public boolean isLayoutUpdateable(Layout layout) {
1015 try {
1016 if (layout instanceof VirtualLayout) {
1017 return false;
1018 }
1019
1020 if (Validator.isNull(layout.getLayoutPrototypeUuid()) &&
1021 Validator.isNull(layout.getSourcePrototypeLayoutUuid())) {
1022
1023 return true;
1024 }
1025
1026 LayoutSet layoutSet = layout.getLayoutSet();
1027
1028 if (layoutSet.isLayoutSetPrototypeLinkActive()) {
1029 boolean layoutSetPrototypeUpdateable =
1030 isLayoutSetPrototypeUpdateable(layoutSet);
1031
1032 if (!layoutSetPrototypeUpdateable) {
1033 return false;
1034 }
1035
1036 Layout layoutSetPrototypeLayout = getLayoutSetPrototypeLayout(
1037 layout);
1038
1039 String layoutUpdateable =
1040 layoutSetPrototypeLayout.getTypeSettingsProperty(
1041 LAYOUT_UPDATEABLE);
1042
1043 if (Validator.isNull(layoutUpdateable)) {
1044 return true;
1045 }
1046
1047 return GetterUtil.getBoolean(layoutUpdateable);
1048 }
1049 }
1050 catch (Exception e) {
1051 if (_log.isDebugEnabled()) {
1052 _log.debug(e, e);
1053 }
1054 }
1055
1056 return true;
1057 }
1058
1059 @Override
1060 public boolean isOrganizationUser(
1061 long companyId, Group group, User user,
1062 List<String> organizationNames)
1063 throws Exception {
1064
1065 boolean organizationUser = false;
1066
1067 LinkedHashMap<String, Object> organizationParams =
1068 new LinkedHashMap<String, Object>();
1069
1070 organizationParams.put(
1071 "groupOrganization", new Long(group.getGroupId()));
1072 organizationParams.put(
1073 "organizationsGroups", new Long(group.getGroupId()));
1074
1075 List<Organization> organizationsGroups =
1076 OrganizationLocalServiceUtil.search(
1077 companyId, OrganizationConstants.ANY_PARENT_ORGANIZATION_ID,
1078 null, null, null, null, organizationParams, QueryUtil.ALL_POS,
1079 QueryUtil.ALL_POS);
1080
1081 for (Organization organization : organizationsGroups) {
1082 for (long userOrganizationId : user.getOrganizationIds()) {
1083 if (userOrganizationId == organization.getOrganizationId()) {
1084 organizationNames.add(organization.getName());
1085
1086 organizationUser = true;
1087 }
1088 }
1089 }
1090
1091 return organizationUser;
1092 }
1093
1094 @Override
1095 public boolean isUserGroupLayoutSetViewable(
1096 PermissionChecker permissionChecker, Group userGroupGroup)
1097 throws PortalException, SystemException {
1098
1099 if (!userGroupGroup.isUserGroup()) {
1100 return false;
1101 }
1102
1103 if (GroupPermissionUtil.contains(
1104 permissionChecker, userGroupGroup.getGroupId(),
1105 ActionKeys.VIEW)) {
1106
1107 return true;
1108 }
1109
1110 UserGroup userGroup = UserGroupLocalServiceUtil.getUserGroup(
1111 userGroupGroup.getClassPK());
1112
1113 if (UserLocalServiceUtil.hasUserGroupUser(
1114 userGroup.getUserGroupId(), permissionChecker.getUserId())) {
1115
1116 return true;
1117 }
1118 else {
1119 return false;
1120 }
1121 }
1122
1123 @Override
1124 public boolean isUserGroupUser(
1125 long companyId, Group group, User user, List<String> userGroupNames)
1126 throws Exception {
1127
1128 boolean userGroupUser = false;
1129
1130 LinkedHashMap<String, Object> userGroupParams =
1131 new LinkedHashMap<String, Object>();
1132
1133 userGroupParams.put("userGroupsGroups", new Long(group.getGroupId()));
1134
1135 List<UserGroup> userGroupsGroups = UserGroupLocalServiceUtil.search(
1136 companyId, null, userGroupParams, QueryUtil.ALL_POS,
1137 QueryUtil.ALL_POS, (OrderByComparator)null);
1138
1139 for (UserGroup userGroup : userGroupsGroups) {
1140 for (long userGroupId : user.getUserGroupIds()) {
1141 if (userGroupId == userGroup.getUserGroupId()) {
1142 userGroupNames.add(userGroup.getName());
1143
1144 userGroupUser = true;
1145 }
1146 }
1147 }
1148
1149 return userGroupUser;
1150 }
1151
1152 @Override
1153 public void mergeLayoutPrototypeLayout(Group group, Layout layout)
1154 throws Exception {
1155
1156 String sourcePrototypeLayoutUuid =
1157 layout.getSourcePrototypeLayoutUuid();
1158
1159 if (Validator.isNull(sourcePrototypeLayoutUuid)) {
1160 doMergeLayoutPrototypeLayout(group, layout);
1161
1162 return;
1163 }
1164
1165 LayoutSet layoutSet = layout.getLayoutSet();
1166
1167 long layoutSetPrototypeId = layoutSet.getLayoutSetPrototypeId();
1168
1169 if (layoutSetPrototypeId > 0) {
1170 Group layoutSetPrototypeGroup =
1171 GroupLocalServiceUtil.getLayoutSetPrototypeGroup(
1172 layout.getCompanyId(), layoutSetPrototypeId);
1173
1174 Layout sourcePrototypeLayout =
1175 LayoutLocalServiceUtil.fetchLayoutByUuidAndGroupId(
1176 sourcePrototypeLayoutUuid,
1177 layoutSetPrototypeGroup.getGroupId(), true);
1178
1179 if (sourcePrototypeLayout != null) {
1180 doMergeLayoutPrototypeLayout(
1181 layoutSetPrototypeGroup, sourcePrototypeLayout);
1182 }
1183 }
1184
1185 doMergeLayoutPrototypeLayout(group, layout);
1186 }
1187
1188
1192 @Override
1193 public void mergeLayoutProtypeLayout(Group group, Layout layout)
1194 throws Exception {
1195
1196 mergeLayoutPrototypeLayout(group, layout);
1197 }
1198
1199 @Override
1200 public void mergeLayoutSetPrototypeLayouts(Group group, LayoutSet layoutSet)
1201 throws Exception {
1202
1203 if (!isLayoutSetMergeable(group, layoutSet)) {
1204 return;
1205 }
1206
1207 UnicodeProperties settingsProperties =
1208 layoutSet.getSettingsProperties();
1209
1210 long lastMergeTime = GetterUtil.getLong(
1211 settingsProperties.getProperty(LAST_MERGE_TIME));
1212
1213 LayoutSetPrototype layoutSetPrototype =
1214 LayoutSetPrototypeLocalServiceUtil.
1215 getLayoutSetPrototypeByUuidAndCompanyId(
1216 layoutSet.getLayoutSetPrototypeUuid(),
1217 layoutSet.getCompanyId());
1218
1219 LayoutSet layoutSetPrototypeLayoutSet =
1220 layoutSetPrototype.getLayoutSet();
1221
1222 UnicodeProperties layoutSetPrototypeSettingsProperties =
1223 layoutSetPrototypeLayoutSet.getSettingsProperties();
1224
1225 int mergeFailCount = GetterUtil.getInteger(
1226 layoutSetPrototypeSettingsProperties.getProperty(MERGE_FAIL_COUNT));
1227
1228 String owner = PortalUUIDUtil.generate();
1229
1230 try {
1231 Lock lock = LockLocalServiceUtil.lock(
1232 LayoutLocalServiceVirtualLayoutsAdvice.class.getName(),
1233 String.valueOf(layoutSet.getLayoutSetId()), owner);
1234
1235
1236
1237 if (!owner.equals(lock.getOwner())) {
1238 Date createDate = lock.getCreateDate();
1239
1240 if ((System.currentTimeMillis() - createDate.getTime()) >=
1241 PropsValues.LAYOUT_SET_PROTOTYPE_MERGE_LOCK_MAX_TIME) {
1242
1243
1244
1245 lock = LockLocalServiceUtil.lock(
1246 LayoutLocalServiceVirtualLayoutsAdvice.class.getName(),
1247 String.valueOf(layoutSet.getLayoutSetId()),
1248 lock.getOwner(), owner);
1249
1250
1251
1252
1253 if (!owner.equals(lock.getOwner())) {
1254 return;
1255 }
1256 }
1257 else {
1258 return;
1259 }
1260 }
1261 }
1262 catch (Exception e) {
1263 return;
1264 }
1265
1266 try {
1267 boolean importData = true;
1268
1269 long lastResetTime = GetterUtil.getLong(
1270 settingsProperties.getProperty(LAST_RESET_TIME));
1271
1272 if ((lastMergeTime > 0) || (lastResetTime > 0)) {
1273 importData = false;
1274 }
1275
1276 Map<String, String[]> parameterMap =
1277 getLayoutSetPrototypesParameters(importData);
1278
1279 removeMergeFailFriendlyURLLayouts(layoutSet);
1280
1281 importLayoutSetPrototype(
1282 layoutSetPrototype, layoutSet.getGroupId(),
1283 layoutSet.isPrivateLayout(), parameterMap, importData);
1284 }
1285 catch (Exception e) {
1286 _log.error(e, e);
1287
1288 layoutSetPrototypeSettingsProperties.setProperty(
1289 MERGE_FAIL_COUNT, String.valueOf(++mergeFailCount));
1290
1291
1292
1293 LayoutSetUtil.updateImpl(layoutSetPrototypeLayoutSet);
1294 }
1295 finally {
1296 LockLocalServiceUtil.unlock(
1297 LayoutLocalServiceVirtualLayoutsAdvice.class.getName(),
1298 String.valueOf(layoutSet.getLayoutSetId()), owner);
1299 }
1300 }
1301
1302
1306 @Override
1307 public void mergeLayoutSetProtypeLayouts(Group group, LayoutSet layoutSet)
1308 throws Exception {
1309
1310 mergeLayoutSetPrototypeLayouts(group, layoutSet);
1311 }
1312
1313 @Override
1314 public void removeMergeFailFriendlyURLLayouts(LayoutSet layoutSet)
1315 throws SystemException {
1316
1317 UnicodeProperties settingsProperties =
1318 layoutSet.getSettingsProperties();
1319
1320 settingsProperties.remove(MERGE_FAIL_FRIENDLY_URL_LAYOUTS);
1321
1322 LayoutSetLocalServiceUtil.updateLayoutSet(layoutSet);
1323 }
1324
1325
1335 @Override
1336 public void resetPrototype(Layout layout)
1337 throws PortalException, SystemException {
1338
1339 checkResetPrototypePermissions(layout.getGroup(), layout);
1340
1341 doResetPrototype(layout);
1342 }
1343
1344
1354 @Override
1355 public void resetPrototype(LayoutSet layoutSet)
1356 throws PortalException, SystemException {
1357
1358 checkResetPrototypePermissions(layoutSet.getGroup(), null);
1359
1360 doResetPrototype(layoutSet);
1361 }
1362
1363
1374 @Override
1375 public void setMergeFailCount(
1376 LayoutPrototype layoutPrototype, int newMergeFailCount)
1377 throws PortalException, SystemException {
1378
1379 Layout layoutPrototypeLayout = layoutPrototype.getLayout();
1380
1381 UnicodeProperties prototypeTypeSettingsProperties =
1382 layoutPrototypeLayout.getTypeSettingsProperties();
1383
1384 if (newMergeFailCount == 0) {
1385 prototypeTypeSettingsProperties.remove(MERGE_FAIL_COUNT);
1386 }
1387 else {
1388 prototypeTypeSettingsProperties.setProperty(
1389 MERGE_FAIL_COUNT, String.valueOf(newMergeFailCount));
1390 }
1391
1392 LayoutServiceUtil.updateLayout(
1393 layoutPrototypeLayout.getGroupId(),
1394 layoutPrototypeLayout.getPrivateLayout(),
1395 layoutPrototypeLayout.getLayoutId(),
1396 layoutPrototypeLayout.getTypeSettings());
1397 }
1398
1399
1410 @Override
1411 public void setMergeFailCount(
1412 LayoutSetPrototype layoutSetPrototype, int newMergeFailCount)
1413 throws PortalException, SystemException {
1414
1415 LayoutSet layoutSetPrototypeLayoutSet =
1416 layoutSetPrototype.getLayoutSet();
1417
1418 UnicodeProperties layoutSetPrototypeSettingsProperties =
1419 layoutSetPrototypeLayoutSet.getSettingsProperties();
1420
1421 if (newMergeFailCount == 0) {
1422 layoutSetPrototypeSettingsProperties.remove(MERGE_FAIL_COUNT);
1423 }
1424 else {
1425 layoutSetPrototypeSettingsProperties.setProperty(
1426 MERGE_FAIL_COUNT, String.valueOf(newMergeFailCount));
1427 }
1428
1429 LayoutSetServiceUtil.updateSettings(
1430 layoutSetPrototypeLayoutSet.getGroupId(),
1431 layoutSetPrototypeLayoutSet.getPrivateLayout(),
1432 layoutSetPrototypeLayoutSet.getSettings());
1433 }
1434
1435 @Override
1436 public void updateLayoutScopes(
1437 long userId, Layout sourceLayout, Layout targetLayout,
1438 PortletPreferences sourcePreferences,
1439 PortletPreferences targetPreferences, String sourcePortletId,
1440 String languageId)
1441 throws Exception {
1442
1443 String scopeType = GetterUtil.getString(
1444 sourcePreferences.getValue("lfrScopeType", null));
1445
1446 if (Validator.isNull(scopeType) || !scopeType.equals("layout")) {
1447 return;
1448 }
1449
1450 Layout targetScopeLayout =
1451 LayoutLocalServiceUtil.getLayoutByUuidAndGroupId(
1452 targetLayout.getUuid(), targetLayout.getGroupId(),
1453 targetLayout.isPrivateLayout());
1454
1455 if (!targetScopeLayout.hasScopeGroup()) {
1456 GroupLocalServiceUtil.addGroup(
1457 userId, GroupConstants.DEFAULT_PARENT_GROUP_ID,
1458 Layout.class.getName(), targetLayout.getPlid(),
1459 GroupConstants.DEFAULT_LIVE_GROUP_ID,
1460 targetLayout.getName(languageId), null, 0, true,
1461 GroupConstants.DEFAULT_MEMBERSHIP_RESTRICTION, null, false,
1462 true, null);
1463 }
1464
1465 String portletTitle = PortalUtil.getPortletTitle(
1466 sourcePortletId, languageId);
1467
1468 String newPortletTitle = PortalUtil.getNewPortletTitle(
1469 portletTitle, String.valueOf(sourceLayout.getLayoutId()),
1470 targetLayout.getName(languageId));
1471
1472 targetPreferences.setValue(
1473 "groupId", String.valueOf(targetLayout.getGroupId()));
1474 targetPreferences.setValue("lfrScopeType", "layout");
1475 targetPreferences.setValue(
1476 "lfrScopeLayoutUuid", targetLayout.getUuid());
1477 targetPreferences.setValue(
1478 "portletSetupTitle_" + languageId, newPortletTitle);
1479 targetPreferences.setValue(
1480 "portletSetupUseCustomTitle", Boolean.TRUE.toString());
1481
1482 targetPreferences.store();
1483 }
1484
1485 @Override
1486 public void updateLayoutSetPrototypesLinks(
1487 Group group, long publicLayoutSetPrototypeId,
1488 long privateLayoutSetPrototypeId,
1489 boolean publicLayoutSetPrototypeLinkEnabled,
1490 boolean privateLayoutSetPrototypeLinkEnabled)
1491 throws Exception {
1492
1493 updateLayoutSetPrototypeLink(
1494 group.getGroupId(), true, privateLayoutSetPrototypeId,
1495 privateLayoutSetPrototypeLinkEnabled);
1496 updateLayoutSetPrototypeLink(
1497 group.getGroupId(), false, publicLayoutSetPrototypeId,
1498 publicLayoutSetPrototypeLinkEnabled);
1499 }
1500
1501
1513 protected void checkResetPrototypePermissions(Group group, Layout layout)
1514 throws PortalException, SystemException {
1515
1516 PermissionChecker permissionChecker =
1517 PermissionThreadLocal.getPermissionChecker();
1518
1519 if ((layout != null) &&
1520 !LayoutPermissionUtil.contains(
1521 permissionChecker, layout, ActionKeys.UPDATE)) {
1522
1523 throw new PrincipalException();
1524 }
1525 else if (!group.isUser() &&
1526 !GroupPermissionUtil.contains(
1527 permissionChecker, group, ActionKeys.UPDATE)) {
1528
1529 throw new PrincipalException();
1530 }
1531 else if (group.isUser() &&
1532 (permissionChecker.getUserId() != group.getClassPK())) {
1533
1534 throw new PrincipalException();
1535 }
1536 }
1537
1538 protected void doMergeLayoutPrototypeLayout(Group group, Layout layout)
1539 throws Exception {
1540
1541 if (!layout.isLayoutPrototypeLinkActive() ||
1542 group.isLayoutPrototype() || group.hasStagingGroup()) {
1543
1544 return;
1545 }
1546
1547 long lastMergeTime = GetterUtil.getLong(
1548 layout.getTypeSettingsProperty(LAST_MERGE_TIME));
1549
1550 LayoutPrototype layoutPrototype =
1551 LayoutPrototypeLocalServiceUtil.
1552 getLayoutPrototypeByUuidAndCompanyId(
1553 layout.getLayoutPrototypeUuid(), layout.getCompanyId());
1554
1555 Layout layoutPrototypeLayout = layoutPrototype.getLayout();
1556
1557 Date modifiedDate = layoutPrototypeLayout.getModifiedDate();
1558
1559 if (lastMergeTime >= modifiedDate.getTime()) {
1560 return;
1561 }
1562
1563 UnicodeProperties prototypeTypeSettingsProperties =
1564 layoutPrototypeLayout.getTypeSettingsProperties();
1565
1566 int mergeFailCount = GetterUtil.getInteger(
1567 prototypeTypeSettingsProperties.getProperty(MERGE_FAIL_COUNT));
1568
1569 if (mergeFailCount >
1570 PropsValues.LAYOUT_PROTOTYPE_MERGE_FAIL_THRESHOLD) {
1571
1572 if (_log.isWarnEnabled()) {
1573 StringBundler sb = new StringBundler(6);
1574
1575 sb.append("Merge not performed because the fail threshold ");
1576 sb.append("was reached for layoutPrototypeId ");
1577 sb.append(layoutPrototype.getLayoutPrototypeId());
1578 sb.append(" and layoutId ");
1579 sb.append(layoutPrototypeLayout.getLayoutId());
1580 sb.append(". Update the count in the database to try again.");
1581
1582 _log.warn(sb.toString());
1583 }
1584
1585 return;
1586 }
1587
1588 String owner = PortalUUIDUtil.generate();
1589
1590 try {
1591 Lock lock = LockLocalServiceUtil.lock(
1592 LayoutLocalServiceVirtualLayoutsAdvice.class.getName(),
1593 String.valueOf(layout.getPlid()), owner);
1594
1595 if (!owner.equals(lock.getOwner())) {
1596 Date createDate = lock.getCreateDate();
1597
1598 if ((System.currentTimeMillis() - createDate.getTime()) >=
1599 PropsValues.LAYOUT_PROTOTYPE_MERGE_LOCK_MAX_TIME) {
1600
1601
1602
1603 lock = LockLocalServiceUtil.lock(
1604 LayoutLocalServiceVirtualLayoutsAdvice.class.getName(),
1605 String.valueOf(layout.getPlid()), lock.getOwner(),
1606 owner);
1607
1608
1609
1610
1611 if (!owner.equals(lock.getOwner())) {
1612 return;
1613 }
1614 }
1615 else {
1616 return;
1617 }
1618 }
1619 }
1620 catch (Exception e) {
1621 return;
1622 }
1623
1624 try {
1625 applyLayoutPrototype(layoutPrototype, layout, true);
1626 }
1627 catch (Exception e) {
1628 _log.error(e, e);
1629
1630 prototypeTypeSettingsProperties.setProperty(
1631 MERGE_FAIL_COUNT, String.valueOf(++mergeFailCount));
1632
1633
1634
1635 LayoutUtil.updateImpl(layoutPrototypeLayout);
1636 }
1637 finally {
1638 LockLocalServiceUtil.unlock(
1639 LayoutLocalServiceVirtualLayoutsAdvice.class.getName(),
1640 String.valueOf(layout.getPlid()), owner);
1641 }
1642 }
1643
1644
1660 protected void doResetPrototype(Layout layout)
1661 throws PortalException, SystemException {
1662
1663 layout.setModifiedDate(null);
1664
1665 LayoutLocalServiceUtil.updateLayout(layout);
1666
1667 LayoutSet layoutSet = layout.getLayoutSet();
1668
1669 doResetPrototype(layoutSet);
1670 }
1671
1672
1683 protected void doResetPrototype(LayoutSet layoutSet)
1684 throws SystemException {
1685
1686 UnicodeProperties settingsProperties =
1687 layoutSet.getSettingsProperties();
1688
1689 settingsProperties.remove(LAST_MERGE_TIME);
1690
1691 settingsProperties.setProperty(
1692 LAST_RESET_TIME, String.valueOf(System.currentTimeMillis()));
1693
1694 LayoutSetLocalServiceUtil.updateLayoutSet(layoutSet);
1695 }
1696
1697 protected Map<String, String[]> getLayoutSetPrototypesParameters(
1698 boolean importData) {
1699
1700 Map<String, String[]> parameterMap =
1701 new LinkedHashMap<String, String[]>();
1702
1703 parameterMap.put(
1704 PortletDataHandlerKeys.CATEGORIES,
1705 new String[] {Boolean.TRUE.toString()});
1706 parameterMap.put(
1707 PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS,
1708 new String[] {Boolean.FALSE.toString()});
1709 parameterMap.put(
1710 PortletDataHandlerKeys.DELETE_PORTLET_DATA,
1711 new String[] {Boolean.FALSE.toString()});
1712 parameterMap.put(
1713 PortletDataHandlerKeys.IGNORE_LAST_PUBLISH_DATE,
1714 new String[] {Boolean.TRUE.toString()});
1715 parameterMap.put(
1716 PortletDataHandlerKeys.LAYOUT_SET_SETTINGS,
1717 new String[] {Boolean.TRUE.toString()});
1718 parameterMap.put(
1719 PortletDataHandlerKeys.LAYOUT_SET_PROTOTYPE_LINK_ENABLED,
1720 new String[] {Boolean.TRUE.toString()});
1721 parameterMap.put(
1722 PortletDataHandlerKeys.LAYOUTS_IMPORT_MODE,
1723 new String[] {
1724 PortletDataHandlerKeys.
1725 LAYOUTS_IMPORT_MODE_CREATED_FROM_PROTOTYPE
1726 });
1727 parameterMap.put(
1728 PortletDataHandlerKeys.PERMISSIONS,
1729 new String[] {Boolean.TRUE.toString()});
1730 parameterMap.put(
1731 PortletDataHandlerKeys.PORTLET_CONFIGURATION,
1732 new String[] {Boolean.TRUE.toString()});
1733 parameterMap.put(
1734 PortletDataHandlerKeys.PORTLET_CONFIGURATION_ALL,
1735 new String[] {Boolean.TRUE.toString()});
1736 parameterMap.put(
1737 PortletDataHandlerKeys.PORTLET_SETUP_ALL,
1738 new String[] {Boolean.TRUE.toString()});
1739 parameterMap.put(
1740 PortletDataHandlerKeys.THEME_REFERENCE,
1741 new String[] {Boolean.TRUE.toString()});
1742 parameterMap.put(
1743 PortletDataHandlerKeys.UPDATE_LAST_PUBLISH_DATE,
1744 new String[] {Boolean.FALSE.toString()});
1745 parameterMap.put(
1746 PortletDataHandlerKeys.USER_ID_STRATEGY,
1747 new String[] {UserIdStrategy.CURRENT_USER_ID});
1748
1749 if (importData) {
1750 parameterMap.put(
1751 PortletDataHandlerKeys.DATA_STRATEGY,
1752 new String[] {PortletDataHandlerKeys.DATA_STRATEGY_MIRROR});
1753 parameterMap.put(
1754 PortletDataHandlerKeys.LOGO,
1755 new String[] {Boolean.TRUE.toString()});
1756 parameterMap.put(
1757 PortletDataHandlerKeys.PORTLET_DATA,
1758 new String[] {Boolean.TRUE.toString()});
1759 parameterMap.put(
1760 PortletDataHandlerKeys.PORTLET_DATA_ALL,
1761 new String[] {Boolean.TRUE.toString()});
1762 }
1763 else {
1764 if (LAYOUT_SET_PROTOTYPE_PROPAGATE_LOGO) {
1765 parameterMap.put(
1766 PortletDataHandlerKeys.LOGO,
1767 new String[] {Boolean.TRUE.toString()});
1768 }
1769 else {
1770 parameterMap.put(
1771 PortletDataHandlerKeys.LOGO,
1772 new String[] {Boolean.FALSE.toString()});
1773 }
1774
1775 parameterMap.put(
1776 PortletDataHandlerKeys.PORTLET_DATA,
1777 new String[] {Boolean.FALSE.toString()});
1778 parameterMap.put(
1779 PortletDataHandlerKeys.PORTLET_DATA_ALL,
1780 new String[] {Boolean.FALSE.toString()});
1781 }
1782
1783 return parameterMap;
1784 }
1785
1786 protected void importLayoutSetPrototype(
1787 LayoutSetPrototype layoutSetPrototype, long groupId,
1788 boolean privateLayout, Map<String, String[]> parameterMap,
1789 boolean importData)
1790 throws PortalException, SystemException {
1791
1792 File file = null;
1793
1794 StringBundler sb = new StringBundler(importData ? 4 : 3);
1795
1796 sb.append(_TEMP_DIR);
1797 sb.append(layoutSetPrototype.getUuid());
1798
1799 if (importData) {
1800 sb.append("-data");
1801 }
1802
1803 sb.append(".lar");
1804
1805 File cacheFile = new File(sb.toString());
1806
1807 if (cacheFile.exists()) {
1808 Date modifiedDate = layoutSetPrototype.getModifiedDate();
1809
1810 if (cacheFile.lastModified() >= modifiedDate.getTime()) {
1811 if (_log.isDebugEnabled()) {
1812 _log.debug(
1813 "Using cached layout set prototype LAR file " +
1814 cacheFile.getAbsolutePath());
1815 }
1816
1817 file = cacheFile;
1818 }
1819 }
1820
1821 boolean newFile = false;
1822
1823 if (file == null) {
1824 file = LayoutLocalServiceUtil.exportLayoutsAsFile(
1825 layoutSetPrototype.getGroupId(), true, null, parameterMap, null,
1826 null);
1827
1828 newFile = true;
1829 }
1830
1831 long userId = UserLocalServiceUtil.getDefaultUserId(
1832 layoutSetPrototype.getCompanyId());
1833
1834 LayoutLocalServiceUtil.importLayouts(
1835 userId, groupId, privateLayout, parameterMap, file);
1836
1837 if (newFile) {
1838 try {
1839 FileUtil.copyFile(file, cacheFile);
1840
1841 if (_log.isDebugEnabled()) {
1842 _log.debug(
1843 "Copied " + file.getAbsolutePath() + " to " +
1844 cacheFile.getAbsolutePath());
1845 }
1846 }
1847 catch (Exception e) {
1848 _log.error(
1849 "Unable to copy file " + file.getAbsolutePath() + " to " +
1850 cacheFile.getAbsolutePath(),
1851 e);
1852 }
1853 }
1854 }
1855
1856 protected void setLayoutSetPrototypeLinkEnabledParameter(
1857 Map<String, String[]> parameterMap, LayoutSet targetLayoutSet,
1858 ServiceContext serviceContext) {
1859
1860 PermissionChecker permissionChecker =
1861 PermissionThreadLocal.getPermissionChecker();
1862
1863 if ((permissionChecker == null) ||
1864 !PortalPermissionUtil.contains(
1865 permissionChecker, ActionKeys.UNLINK_LAYOUT_SET_PROTOTYPE)) {
1866
1867 return;
1868 }
1869
1870 if (targetLayoutSet.isPrivateLayout()) {
1871 boolean privateLayoutSetPrototypeLinkEnabled = ParamUtil.getBoolean(
1872 serviceContext, "privateLayoutSetPrototypeLinkEnabled", true);
1873
1874 if (!privateLayoutSetPrototypeLinkEnabled) {
1875 privateLayoutSetPrototypeLinkEnabled = ParamUtil.getBoolean(
1876 serviceContext, "layoutSetPrototypeLinkEnabled");
1877 }
1878
1879 parameterMap.put(
1880 PortletDataHandlerKeys.LAYOUT_SET_PROTOTYPE_LINK_ENABLED,
1881 new String[] {
1882 String.valueOf(privateLayoutSetPrototypeLinkEnabled)
1883 });
1884 }
1885 else {
1886 boolean publicLayoutSetPrototypeLinkEnabled = ParamUtil.getBoolean(
1887 serviceContext, "publicLayoutSetPrototypeLinkEnabled");
1888
1889 if (!publicLayoutSetPrototypeLinkEnabled) {
1890 publicLayoutSetPrototypeLinkEnabled = ParamUtil.getBoolean(
1891 serviceContext, "layoutSetPrototypeLinkEnabled", true);
1892 }
1893
1894 parameterMap.put(
1895 PortletDataHandlerKeys.LAYOUT_SET_PROTOTYPE_LINK_ENABLED,
1896 new String[] {
1897 String.valueOf(publicLayoutSetPrototypeLinkEnabled)
1898 });
1899 }
1900 }
1901
1902 protected void updateLayoutSetPrototypeLink(
1903 long groupId, boolean privateLayout, long layoutSetPrototypeId,
1904 boolean layoutSetPrototypeLinkEnabled)
1905 throws Exception {
1906
1907 String layoutSetPrototypeUuid = null;
1908
1909 if (layoutSetPrototypeId > 0) {
1910 LayoutSetPrototype layoutSetPrototype =
1911 LayoutSetPrototypeLocalServiceUtil.fetchLayoutSetPrototype(
1912 layoutSetPrototypeId);
1913
1914 if (layoutSetPrototype != null) {
1915 layoutSetPrototypeUuid = layoutSetPrototype.getUuid();
1916
1917
1918
1919 if (!layoutSetPrototypeLinkEnabled &&
1920 (layoutSetPrototypeId > 0)) {
1921
1922 Map<String, String[]> parameterMap =
1923 getLayoutSetPrototypesParameters(true);
1924
1925 importLayoutSetPrototype(
1926 layoutSetPrototype, groupId, privateLayout,
1927 parameterMap, true);
1928 }
1929 }
1930 }
1931
1932 LayoutSetServiceUtil.updateLayoutSetPrototypeLinkEnabled(
1933 groupId, privateLayout, layoutSetPrototypeLinkEnabled,
1934 layoutSetPrototypeUuid);
1935
1936 LayoutLocalServiceUtil.updatePriorities(groupId, privateLayout);
1937 }
1938
1939 private static final String _TEMP_DIR =
1940 SystemProperties.get(SystemProperties.TMP_DIR) +
1941 "/liferay/layout_set_prototype/";
1942
1943 private static Log _log = LogFactoryUtil.getLog(SitesImpl.class);
1944
1945 }