001
014
015 package com.liferay.portal.model;
016
017 import com.liferay.portal.NoSuchLayoutBranchException;
018 import com.liferay.portal.NoSuchLayoutRevisionException;
019 import com.liferay.portal.kernel.exception.PortalException;
020 import com.liferay.portal.kernel.exception.SystemException;
021 import com.liferay.portal.kernel.log.Log;
022 import com.liferay.portal.kernel.log.LogFactoryUtil;
023 import com.liferay.portal.kernel.staging.MergeLayoutPrototypesThreadLocal;
024 import com.liferay.portal.kernel.staging.StagingUtil;
025 import com.liferay.portal.kernel.util.ParamUtil;
026 import com.liferay.portal.kernel.util.PortalClassLoaderUtil;
027 import com.liferay.portal.kernel.util.ProxyUtil;
028 import com.liferay.portal.kernel.util.ReflectionUtil;
029 import com.liferay.portal.kernel.workflow.WorkflowConstants;
030 import com.liferay.portal.service.LayoutBranchLocalServiceUtil;
031 import com.liferay.portal.service.LayoutRevisionLocalServiceUtil;
032 import com.liferay.portal.service.LayoutSetBranchLocalServiceUtil;
033 import com.liferay.portal.service.ServiceContext;
034 import com.liferay.portal.service.ServiceContextThreadLocal;
035 import com.liferay.portal.service.UserLocalServiceUtil;
036 import com.liferay.portal.util.LayoutTypePortletFactoryUtil;
037
038 import java.io.Serializable;
039
040 import java.lang.reflect.InvocationHandler;
041 import java.lang.reflect.InvocationTargetException;
042 import java.lang.reflect.Method;
043
044 import java.util.HashSet;
045 import java.util.List;
046 import java.util.Set;
047
048
052 public class LayoutStagingHandler implements InvocationHandler, Serializable {
053
054 public LayoutStagingHandler(Layout layout) {
055 this(layout, null);
056 }
057
058 public Layout getLayout() {
059 return _layout;
060 }
061
062 public LayoutRevision getLayoutRevision() {
063 return _layoutRevision;
064 }
065
066 public Object invoke(Object proxy, Method method, Object[] arguments)
067 throws Throwable {
068
069 try {
070 if (_layoutRevision == null) {
071 return method.invoke(_layout, arguments);
072 }
073
074 String methodName = method.getName();
075
076 if (methodName.equals("getLayoutType")) {
077 return _getLayoutType();
078 }
079 else if (methodName.equals("toEscapedModel")) {
080 if (_layout.isEscapedModel()) {
081 return this;
082 }
083
084 return _toEscapedModel();
085 }
086
087 if (methodName.equals("clone")) {
088 return _clone();
089 }
090
091 Object bean = _layout;
092
093 if (_layoutRevisionMethodNames.contains(methodName)) {
094 try {
095 Class<?> layoutRevisionClass = _layoutRevision.getClass();
096
097 method = layoutRevisionClass.getMethod(
098 methodName,
099 ReflectionUtil.getParameterTypes(arguments));
100
101 bean = _layoutRevision;
102 }
103 catch (NoSuchMethodException nsme) {
104 _log.error(nsme, nsme);
105 }
106 }
107
108 return method.invoke(bean, arguments);
109 }
110 catch (InvocationTargetException ite) {
111 throw ite.getTargetException();
112 }
113 }
114
115 public void setLayoutRevision(LayoutRevision layoutRevision) {
116 _layoutRevision = layoutRevision;
117 }
118
119 private LayoutStagingHandler(Layout layout, LayoutRevision layoutRevision) {
120 _layout = layout;
121
122 try {
123 _layoutRevision = _getLayoutRevision(layout, layoutRevision);
124 }
125 catch (Exception e) {
126 _log.error(e, e);
127
128 throw new IllegalStateException(e);
129 }
130 }
131
132 private Object _clone() {
133 return ProxyUtil.newProxyInstance(
134 PortalClassLoaderUtil.getClassLoader(), new Class[] {Layout.class},
135 new LayoutStagingHandler(_layout, _layoutRevision));
136 }
137
138 private LayoutRevision _getLayoutRevision(
139 Layout layout, LayoutRevision layoutRevision)
140 throws PortalException, SystemException {
141
142 if (layoutRevision != null) {
143 return layoutRevision;
144 }
145
146 ServiceContext serviceContext =
147 ServiceContextThreadLocal.getServiceContext();
148
149 if (!serviceContext.isSignedIn()) {
150 LayoutRevision lastLayoutRevision = null;
151
152 lastLayoutRevision =
153 LayoutRevisionLocalServiceUtil.fetchLastLayoutRevision(
154 layout.getPlid(), true);
155
156 if (lastLayoutRevision == null) {
157 lastLayoutRevision =
158 LayoutRevisionLocalServiceUtil.fetchLastLayoutRevision(
159 layout.getPlid(), false);
160 }
161
162 return lastLayoutRevision;
163 }
164
165 long layoutSetBranchId = ParamUtil.getLong(
166 serviceContext, "layoutSetBranchId");
167
168 LayoutSet layoutSet = layout.getLayoutSet();
169
170 LayoutSetBranch layoutSetBranch =
171 LayoutSetBranchLocalServiceUtil.getUserLayoutSetBranch(
172 serviceContext.getUserId(), layout.getGroupId(),
173 layout.isPrivateLayout(), layoutSet.getLayoutSetId(),
174 layoutSetBranchId);
175
176 layoutSetBranchId = layoutSetBranch.getLayoutSetBranchId();
177
178 long layoutRevisionId = ParamUtil.getLong(
179 serviceContext, "layoutRevisionId");
180
181 if (layoutSetBranchId > 0) {
182 if (layoutRevisionId <= 0) {
183 User user = UserLocalServiceUtil.getUser(
184 serviceContext.getUserId());
185
186 layoutRevisionId = StagingUtil.getRecentLayoutRevisionId(
187 user, layoutSetBranchId, layout.getPlid());
188
189 if (layoutRevisionId > 0) {
190 try {
191 layoutRevision =
192 LayoutRevisionLocalServiceUtil.getLayoutRevision(
193 layoutRevisionId);
194
195 if (layoutRevision.getStatus() !=
196 WorkflowConstants.STATUS_INACTIVE) {
197
198 return layoutRevision;
199 }
200
201 StagingUtil.setRecentLayoutRevisionId(
202 user, layoutSetBranchId, layout.getPlid(),
203 LayoutRevisionConstants.
204 DEFAULT_PARENT_LAYOUT_REVISION_ID);
205
206 layoutRevisionId =
207 StagingUtil.getRecentLayoutRevisionId(
208 user, layoutSetBranchId, layout.getPlid());
209 }
210 catch (NoSuchLayoutRevisionException nslre) {
211 }
212 }
213 }
214
215 if (layoutRevisionId > 0) {
216 try {
217 return LayoutRevisionLocalServiceUtil.getLayoutRevision(
218 layoutRevisionId);
219 }
220 catch (NoSuchLayoutRevisionException nslre) {
221 }
222 }
223
224 try {
225 return LayoutRevisionLocalServiceUtil.getLayoutRevision(
226 layoutSetBranchId, layout.getPlid(), true);
227 }
228 catch (NoSuchLayoutRevisionException nslre) {
229 List<LayoutRevision> layoutRevisions =
230 LayoutRevisionLocalServiceUtil.getChildLayoutRevisions(
231 layoutSetBranchId,
232 LayoutRevisionConstants.
233 DEFAULT_PARENT_LAYOUT_REVISION_ID,
234 layout.getPlid());
235
236 if (!layoutRevisions.isEmpty()) {
237 return layoutRevisions.get(0);
238 }
239 }
240 }
241
242 LayoutBranch layoutBranch = null;
243
244 try {
245 layoutBranch = LayoutBranchLocalServiceUtil.getMasterLayoutBranch(
246 layoutSetBranchId, layout.getPlid());
247 }
248 catch (NoSuchLayoutBranchException nslbe) {
249 layoutBranch = LayoutBranchLocalServiceUtil.addLayoutBranch(
250 layoutSetBranchId, layout.getPlid(),
251 LayoutBranchConstants.MASTER_BRANCH_NAME,
252 LayoutBranchConstants.MASTER_BRANCH_DESCRIPTION, true,
253 serviceContext);
254 }
255
256 if (!MergeLayoutPrototypesThreadLocal.isInProgress()) {
257 serviceContext.setWorkflowAction(
258 WorkflowConstants.ACTION_SAVE_DRAFT);
259 }
260
261 layoutRevision = LayoutRevisionLocalServiceUtil.addLayoutRevision(
262 serviceContext.getUserId(), layoutSetBranchId,
263 layoutBranch.getLayoutBranchId(),
264 LayoutRevisionConstants.DEFAULT_PARENT_LAYOUT_REVISION_ID, false,
265 layout.getPlid(), LayoutConstants.DEFAULT_PLID,
266 layout.isPrivateLayout(), layout.getName(), layout.getTitle(),
267 layout.getDescription(), layout.getKeywords(), layout.getRobots(),
268 layout.getTypeSettings(), layout.getIconImage(),
269 layout.getIconImageId(), layout.getThemeId(),
270 layout.getColorSchemeId(), layout.getWapThemeId(),
271 layout.getWapColorSchemeId(), layout.getCss(), serviceContext);
272
273 boolean explicitCreation = ParamUtil.getBoolean(
274 serviceContext, "explicitCreation");
275
276 if (!explicitCreation) {
277 LayoutRevisionLocalServiceUtil.updateStatus(
278 serviceContext.getUserId(),
279 layoutRevision.getLayoutRevisionId(),
280 WorkflowConstants.STATUS_INCOMPLETE, serviceContext);
281 }
282
283 return layoutRevision;
284 }
285
286 private LayoutType _getLayoutType() {
287 return LayoutTypePortletFactoryUtil.create(
288 (Layout)ProxyUtil.newProxyInstance(
289 PortalClassLoaderUtil.getClassLoader(),
290 new Class[] {Layout.class},
291 new LayoutStagingHandler(_layout, _layoutRevision)));
292 }
293
294 private Object _toEscapedModel() {
295 return ProxyUtil.newProxyInstance(
296 PortalClassLoaderUtil.getClassLoader(), new Class[] {Layout.class},
297 new LayoutStagingHandler(
298 _layout.toEscapedModel(), _layoutRevision.toEscapedModel()));
299 }
300
301 private static Log _log = LogFactoryUtil.getLog(LayoutStagingHandler.class);
302
303 private static Set<String> _layoutRevisionMethodNames =
304 new HashSet<String>();
305
306 static {
307 _layoutRevisionMethodNames.add("getColorScheme");
308 _layoutRevisionMethodNames.add("getColorSchemeId");
309 _layoutRevisionMethodNames.add("getCss");
310 _layoutRevisionMethodNames.add("getCssText");
311 _layoutRevisionMethodNames.add("getDescription");
312 _layoutRevisionMethodNames.add("getHTMLTitle");
313 _layoutRevisionMethodNames.add("getIconImage");
314 _layoutRevisionMethodNames.add("getIconImageId");
315 _layoutRevisionMethodNames.add("getKeywords");
316 _layoutRevisionMethodNames.add("getName");
317 _layoutRevisionMethodNames.add("getRobots");
318 _layoutRevisionMethodNames.add("getTheme");
319 _layoutRevisionMethodNames.add("getThemeId");
320 _layoutRevisionMethodNames.add("getTitle");
321 _layoutRevisionMethodNames.add("getTypeSettings");
322 _layoutRevisionMethodNames.add("getTypeSettingsProperties");
323 _layoutRevisionMethodNames.add("getWapColorScheme");
324 _layoutRevisionMethodNames.add("getWapColorSchemeId");
325 _layoutRevisionMethodNames.add("getWapTheme");
326 _layoutRevisionMethodNames.add("getWapThemeId");
327 _layoutRevisionMethodNames.add("isEscapedModel");
328 _layoutRevisionMethodNames.add("isIconImage");
329 _layoutRevisionMethodNames.add("isInheritLookAndFeel");
330 _layoutRevisionMethodNames.add("isInheritWapLookAndFeel");
331 _layoutRevisionMethodNames.add("setColorSchemeId");
332 _layoutRevisionMethodNames.add("setCss");
333 _layoutRevisionMethodNames.add("setDescription");
334 _layoutRevisionMethodNames.add("setDescriptionMap");
335 _layoutRevisionMethodNames.add("setEscapedModel");
336 _layoutRevisionMethodNames.add("setIconImage");
337 _layoutRevisionMethodNames.add("setIconImageId");
338 _layoutRevisionMethodNames.add("setKeywords");
339 _layoutRevisionMethodNames.add("setKeywordsMap");
340 _layoutRevisionMethodNames.add("setName");
341 _layoutRevisionMethodNames.add("setNameMap");
342 _layoutRevisionMethodNames.add("setRobots");
343 _layoutRevisionMethodNames.add("setRobotsMap");
344 _layoutRevisionMethodNames.add("setThemeId");
345 _layoutRevisionMethodNames.add("setTitle");
346 _layoutRevisionMethodNames.add("setTitleMap");
347 _layoutRevisionMethodNames.add("setTypeSettings");
348 _layoutRevisionMethodNames.add("setTypeSettingsProperties");
349 _layoutRevisionMethodNames.add("setWapColorSchemeId");
350 _layoutRevisionMethodNames.add("setWapThemeId");
351 }
352
353 private Layout _layout;
354 private LayoutRevision _layoutRevision;
355
356 }