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(Layout layout, LayoutRevision layoutRevision) {
116 _layout = layout;
117
118 try {
119 _layoutRevision = _getLayoutRevision(layout, layoutRevision);
120 }
121 catch (Exception e) {
122 _log.error(e, e);
123
124 throw new IllegalStateException(e);
125 }
126 }
127
128 private Object _clone() {
129 return ProxyUtil.newProxyInstance(
130 PortalClassLoaderUtil.getClassLoader(), new Class[] {Layout.class},
131 new LayoutStagingHandler(_layout, _layoutRevision));
132 }
133
134 private LayoutRevision _getLayoutRevision(
135 Layout layout, LayoutRevision layoutRevision)
136 throws PortalException, SystemException {
137
138 if (layoutRevision != null) {
139 return layoutRevision;
140 }
141
142 ServiceContext serviceContext =
143 ServiceContextThreadLocal.getServiceContext();
144
145 if (!serviceContext.isSignedIn()) {
146 return layoutRevision;
147 }
148
149 long layoutSetBranchId = ParamUtil.getLong(
150 serviceContext, "layoutSetBranchId");
151
152 LayoutSetBranch layoutSetBranch =
153 LayoutSetBranchLocalServiceUtil.getUserLayoutSetBranch(
154 serviceContext.getUserId(), layout.getGroupId(),
155 layout.isPrivateLayout(), layoutSetBranchId);
156
157 layoutSetBranchId = layoutSetBranch.getLayoutSetBranchId();
158
159 long layoutRevisionId = ParamUtil.getLong(
160 serviceContext, "layoutRevisionId");
161
162 if (layoutSetBranchId > 0) {
163 if (layoutRevisionId <= 0) {
164 User user = UserLocalServiceUtil.getUser(
165 serviceContext.getUserId());
166
167 layoutRevisionId = StagingUtil.getRecentLayoutRevisionId(
168 user, layoutSetBranchId, layout.getPlid());
169
170 if (layoutRevisionId > 0) {
171 try {
172 layoutRevision =
173 LayoutRevisionLocalServiceUtil.getLayoutRevision(
174 layoutRevisionId);
175
176 if (layoutRevision.getStatus() !=
177 WorkflowConstants.STATUS_INACTIVE) {
178
179 return layoutRevision;
180 }
181
182 StagingUtil.setRecentLayoutRevisionId(
183 user, layoutSetBranchId, layout.getPlid(),
184 LayoutRevisionConstants.
185 DEFAULT_PARENT_LAYOUT_REVISION_ID);
186
187 layoutRevisionId =
188 StagingUtil.getRecentLayoutRevisionId(
189 user, layoutSetBranchId, layout.getPlid());
190 }
191 catch (NoSuchLayoutRevisionException nslre) {
192 }
193 }
194 }
195
196 try {
197 return LayoutRevisionLocalServiceUtil.getLayoutRevision(
198 layoutSetBranchId, layout.getPlid(), true);
199 }
200 catch (NoSuchLayoutRevisionException nslre) {
201 List<LayoutRevision> layoutRevisions =
202 LayoutRevisionLocalServiceUtil.getChildLayoutRevisions(
203 layoutSetBranchId,
204 LayoutRevisionConstants.
205 DEFAULT_PARENT_LAYOUT_REVISION_ID,
206 layout.getPlid());
207
208 if (!layoutRevisions.isEmpty()) {
209 return layoutRevisions.get(0);
210 }
211 }
212 }
213
214 if (layoutRevisionId > 0) {
215 try {
216 return LayoutRevisionLocalServiceUtil.getLayoutRevision(
217 layoutRevisionId);
218 }
219 catch (NoSuchLayoutRevisionException nslre) {
220 }
221 }
222
223 LayoutBranch layoutBranch = null;
224
225 try {
226 layoutBranch = LayoutBranchLocalServiceUtil.getMasterLayoutBranch(
227 layoutSetBranchId, layout.getPlid());
228 }
229 catch (NoSuchLayoutBranchException nslbe) {
230 layoutBranch = LayoutBranchLocalServiceUtil.addLayoutBranch(
231 layoutSetBranchId, layout.getPlid(),
232 LayoutBranchConstants.MASTER_BRANCH_NAME,
233 LayoutBranchConstants.MASTER_BRANCH_DESCRIPTION, true,
234 serviceContext);
235 }
236
237 serviceContext.setWorkflowAction(WorkflowConstants.ACTION_SAVE_DRAFT);
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 }