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