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