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