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