001
014
015 package com.liferay.portal.service.impl;
016
017 import com.liferay.portal.kernel.log.Log;
018 import com.liferay.portal.kernel.log.LogFactoryUtil;
019 import com.liferay.portal.kernel.staging.MergeLayoutPrototypesThreadLocal;
020 import com.liferay.portal.kernel.util.AutoResetThreadLocal;
021 import com.liferay.portal.kernel.util.ListUtil;
022 import com.liferay.portal.kernel.util.Validator;
023 import com.liferay.portal.kernel.workflow.WorkflowThreadLocal;
024 import com.liferay.portal.model.Group;
025 import com.liferay.portal.model.GroupConstants;
026 import com.liferay.portal.model.Layout;
027 import com.liferay.portal.model.LayoutConstants;
028 import com.liferay.portal.model.LayoutSet;
029 import com.liferay.portal.model.UserGroup;
030 import com.liferay.portal.model.impl.VirtualLayout;
031 import com.liferay.portal.service.GroupLocalServiceUtil;
032 import com.liferay.portal.service.LayoutLocalServiceUtil;
033 import com.liferay.portal.service.LayoutSetLocalServiceUtil;
034 import com.liferay.portal.service.UserGroupLocalServiceUtil;
035 import com.liferay.portal.util.PropsValues;
036 import com.liferay.portlet.sites.util.SitesUtil;
037
038 import java.lang.reflect.Method;
039
040 import java.util.ArrayList;
041 import java.util.Arrays;
042 import java.util.List;
043
044 import org.aopalliance.intercept.MethodInterceptor;
045 import org.aopalliance.intercept.MethodInvocation;
046
047 import org.springframework.core.annotation.Order;
048
049
053 @Order(2)
054 public class LayoutLocalServiceVirtualLayoutsAdvice
055 implements MethodInterceptor {
056
057 public Object invoke(MethodInvocation methodInvocation) throws Throwable {
058 if (MergeLayoutPrototypesThreadLocal.isInProgress()) {
059 return methodInvocation.proceed();
060 }
061
062 Method method = methodInvocation.getMethod();
063
064 String methodName = method.getName();
065
066 Object[] arguments = methodInvocation.getArguments();
067
068 Class<?>[] parameterTypes = method.getParameterTypes();
069
070 boolean workflowEnabled = WorkflowThreadLocal.isEnabled();
071
072 if (methodName.equals("getLayout") &&
073 (Arrays.equals(parameterTypes, _TYPES_L) ||
074 Arrays.equals(parameterTypes, _TYPES_L_B_L))) {
075
076 Layout layout = (Layout)methodInvocation.proceed();
077
078 if (Validator.isNull(layout.getLayoutPrototypeUuid()) &&
079 Validator.isNull(layout.getSourcePrototypeLayoutUuid())) {
080
081 return layout;
082 }
083
084 Group group = layout.getGroup();
085 LayoutSet layoutSet = layout.getLayoutSet();
086
087 try {
088 MergeLayoutPrototypesThreadLocal.setInProgress(true);
089 WorkflowThreadLocal.setEnabled(false);
090
091 SitesUtil.mergeLayoutProtypeLayout(group, layout);
092
093 if (Validator.isNotNull(
094 layout.getSourcePrototypeLayoutUuid())) {
095
096 if (!SitesUtil.isLayoutModifiedSinceLastMerge(layout)) {
097 SitesUtil.mergeLayoutSetProtypeLayouts(
098 group, layoutSet);
099 }
100 }
101 }
102 finally {
103 MergeLayoutPrototypesThreadLocal.setInProgress(false);
104 WorkflowThreadLocal.setEnabled(workflowEnabled);
105 }
106 }
107 else if (methodName.equals("getLayouts") &&
108 (Arrays.equals(parameterTypes, _TYPES_L_B_L) ||
109 Arrays.equals(parameterTypes, _TYPES_L_B_L_B_I_I))) {
110
111 long groupId = (Long)arguments[0];
112 boolean privateLayout = (Boolean)arguments[1];
113 long parentLayoutId = (Long)arguments[2];
114
115 try {
116 Group group = GroupLocalServiceUtil.getGroup(groupId);
117
118 LayoutSet layoutSet = LayoutSetLocalServiceUtil.getLayoutSet(
119 groupId, privateLayout);
120
121 try {
122 MergeLayoutPrototypesThreadLocal.setInProgress(true);
123 WorkflowThreadLocal.setEnabled(false);
124
125 List<Layout> layouts = LayoutLocalServiceUtil.getLayouts(
126 groupId, privateLayout);
127
128 if (layouts.isEmpty()) {
129 SitesUtil.mergeLayoutSetProtypeLayouts(
130 group, layoutSet);
131 }
132
133 boolean modified = false;
134
135 for (Layout layout : layouts) {
136 if (SitesUtil.isLayoutModifiedSinceLastMerge(layout)) {
137 modified = true;
138
139 break;
140 }
141 }
142
143 if (!modified) {
144 SitesUtil.mergeLayoutSetProtypeLayouts(
145 group, layoutSet);
146 }
147 }
148 finally {
149 MergeLayoutPrototypesThreadLocal.setInProgress(false);
150 WorkflowThreadLocal.setEnabled(workflowEnabled);
151 }
152
153 List<Layout> layouts = (List<Layout>)methodInvocation.proceed();
154
155 if (PropsValues.
156 USER_GROUPS_COPY_LAYOUTS_TO_USER_PERSONAL_SITE) {
157
158 return layouts;
159 }
160
161 if (group.isUser()) {
162 _virtualLayoutTargetGroupId.set(group.getGroupId());
163
164 if (parentLayoutId ==
165 LayoutConstants.DEFAULT_PARENT_LAYOUT_ID) {
166
167 return addUserGroupLayouts(
168 group, layoutSet, layouts, parentLayoutId);
169 }
170 else {
171 return addChildUserGroupLayouts(group, layouts);
172 }
173 }
174 else if (group.isUserGroup() &&
175 (parentLayoutId !=
176 LayoutConstants.DEFAULT_PARENT_LAYOUT_ID)) {
177
178 long targetGroupId = _virtualLayoutTargetGroupId.get();
179
180 if (targetGroupId != GroupConstants.DEFAULT_LIVE_GROUP_ID) {
181 Group targetGroup = GroupLocalServiceUtil.getGroup(
182 targetGroupId);
183
184 return addChildUserGroupLayouts(targetGroup, layouts);
185 }
186 }
187
188 return layouts;
189 }
190 catch (Exception e) {
191 _log.error(e, e);
192
193 throw e;
194 }
195 }
196
197 return methodInvocation.proceed();
198 }
199
200 protected List<Layout> addChildUserGroupLayouts(
201 Group group, List<Layout> layouts)
202 throws Exception {
203
204 layouts = ListUtil.copy(layouts);
205
206 List<Layout> childLayouts = new ArrayList<Layout>();
207
208 for (Layout layout : layouts) {
209 Layout childLayout = layout;
210
211 Group layoutGroup = layout.getGroup();
212
213 if (layoutGroup.isUserGroup()) {
214 childLayout = new VirtualLayout(layout, group);
215 }
216
217 childLayouts.add(childLayout);
218 }
219
220 return childLayouts;
221 }
222
223 protected List<Layout> addUserGroupLayouts(
224 Group group, LayoutSet layoutSet, List<Layout> layouts,
225 long parentLayoutId)
226 throws Exception {
227
228 layouts = ListUtil.copy(layouts);
229
230 List<UserGroup> userUserGroups =
231 UserGroupLocalServiceUtil.getUserUserGroups(group.getClassPK());
232
233 for (UserGroup userGroup : userUserGroups) {
234 Group userGroupGroup = userGroup.getGroup();
235
236 List<Layout> userGroupLayouts = LayoutLocalServiceUtil.getLayouts(
237 userGroupGroup.getGroupId(), layoutSet.isPrivateLayout(),
238 parentLayoutId);
239
240 for (Layout userGroupLayout : userGroupLayouts) {
241 Layout virtualLayout = new VirtualLayout(
242 userGroupLayout, group);
243
244 layouts.add(virtualLayout);
245 }
246 }
247
248 return layouts;
249 }
250
251 private static final Class<?>[] _TYPES_L = {Long.TYPE};
252
253 private static final Class<?>[] _TYPES_L_B_L = {
254 Long.TYPE, Boolean.TYPE, Long.TYPE
255 };
256
257 private static final Class<?>[] _TYPES_L_B_L_B_I_I = {
258 Long.TYPE, Boolean.TYPE, Long.TYPE, Boolean.TYPE, Integer.TYPE,
259 Integer.TYPE
260 };
261
262 private static Log _log = LogFactoryUtil.getLog(
263 LayoutLocalServiceVirtualLayoutsAdvice.class);
264
265 private static ThreadLocal<Long> _virtualLayoutTargetGroupId =
266 new AutoResetThreadLocal<Long>(
267 LayoutLocalServiceVirtualLayoutsAdvice.class +
268 "._virtualLayoutTargetGroupId",
269 GroupConstants.DEFAULT_LIVE_GROUP_ID);
270
271 }