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.mergeLayoutPrototypeLayout(group, layout);
092
093 if (Validator.isNotNull(
094 layout.getSourcePrototypeLayoutUuid())) {
095
096 if (!SitesUtil.isLayoutModifiedSinceLastMerge(layout)) {
097 SitesUtil.mergeLayoutSetPrototypeLayouts(
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.mergeLayoutSetPrototypeLayouts(
130 group, layoutSet);
131 }
132 else {
133 boolean modified = false;
134
135 for (Layout layout : layouts) {
136 if (SitesUtil.isLayoutModifiedSinceLastMerge(
137 layout)) {
138
139 modified = true;
140
141 break;
142 }
143 }
144
145 if (!modified) {
146 SitesUtil.mergeLayoutSetPrototypeLayouts(
147 group, layoutSet);
148 }
149 }
150 }
151 finally {
152 MergeLayoutPrototypesThreadLocal.setInProgress(false);
153 WorkflowThreadLocal.setEnabled(workflowEnabled);
154 }
155
156 List<Layout> layouts = (List<Layout>)methodInvocation.proceed();
157
158 if (PropsValues.
159 USER_GROUPS_COPY_LAYOUTS_TO_USER_PERSONAL_SITE) {
160
161 return layouts;
162 }
163
164 if (group.isUser()) {
165 _virtualLayoutTargetGroupId.set(group.getGroupId());
166
167 if (parentLayoutId ==
168 LayoutConstants.DEFAULT_PARENT_LAYOUT_ID) {
169
170 return addUserGroupLayouts(
171 group, layoutSet, layouts, parentLayoutId);
172 }
173 else {
174 return addChildUserGroupLayouts(group, layouts);
175 }
176 }
177 else if (group.isUserGroup() &&
178 (parentLayoutId !=
179 LayoutConstants.DEFAULT_PARENT_LAYOUT_ID)) {
180
181 long targetGroupId = _virtualLayoutTargetGroupId.get();
182
183 if (targetGroupId != GroupConstants.DEFAULT_LIVE_GROUP_ID) {
184 Group targetGroup = GroupLocalServiceUtil.getGroup(
185 targetGroupId);
186
187 return addChildUserGroupLayouts(targetGroup, layouts);
188 }
189 }
190
191 return layouts;
192 }
193 catch (Exception e) {
194 _log.error(e, e);
195
196 throw e;
197 }
198 }
199
200 return methodInvocation.proceed();
201 }
202
203 protected List<Layout> addChildUserGroupLayouts(
204 Group group, List<Layout> layouts)
205 throws Exception {
206
207 layouts = ListUtil.copy(layouts);
208
209 List<Layout> childLayouts = new ArrayList<Layout>();
210
211 for (Layout layout : layouts) {
212 Layout childLayout = layout;
213
214 Group layoutGroup = layout.getGroup();
215
216 if (layoutGroup.isUserGroup()) {
217 childLayout = new VirtualLayout(layout, group);
218 }
219
220 childLayouts.add(childLayout);
221 }
222
223 return childLayouts;
224 }
225
226 protected List<Layout> addUserGroupLayouts(
227 Group group, LayoutSet layoutSet, List<Layout> layouts,
228 long parentLayoutId)
229 throws Exception {
230
231 layouts = ListUtil.copy(layouts);
232
233 List<UserGroup> userUserGroups =
234 UserGroupLocalServiceUtil.getUserUserGroups(group.getClassPK());
235
236 for (UserGroup userGroup : userUserGroups) {
237 Group userGroupGroup = userGroup.getGroup();
238
239 List<Layout> userGroupLayouts = LayoutLocalServiceUtil.getLayouts(
240 userGroupGroup.getGroupId(), layoutSet.isPrivateLayout(),
241 parentLayoutId);
242
243 for (Layout userGroupLayout : userGroupLayouts) {
244 Layout virtualLayout = new VirtualLayout(
245 userGroupLayout, group);
246
247 layouts.add(virtualLayout);
248 }
249 }
250
251 return layouts;
252 }
253
254 private static final Class<?>[] _TYPES_L = {Long.TYPE};
255
256 private static final Class<?>[] _TYPES_L_B_L = {
257 Long.TYPE, Boolean.TYPE, Long.TYPE
258 };
259
260 private static final Class<?>[] _TYPES_L_B_L_B_I_I = {
261 Long.TYPE, Boolean.TYPE, Long.TYPE, Boolean.TYPE, Integer.TYPE,
262 Integer.TYPE
263 };
264
265 private static Log _log = LogFactoryUtil.getLog(
266 LayoutLocalServiceVirtualLayoutsAdvice.class);
267
268 private static ThreadLocal<Long> _virtualLayoutTargetGroupId =
269 new AutoResetThreadLocal<Long>(
270 LayoutLocalServiceVirtualLayoutsAdvice.class +
271 "._virtualLayoutTargetGroupId",
272 GroupConstants.DEFAULT_LIVE_GROUP_ID);
273
274 }