001
014
015 package com.liferay.portal.service.impl;
016
017 import com.liferay.portal.kernel.exception.PortalException;
018 import com.liferay.portal.kernel.exception.SystemException;
019 import com.liferay.portal.kernel.staging.LayoutStagingUtil;
020 import com.liferay.portal.kernel.staging.MergeLayoutPrototypesThreadLocal;
021 import com.liferay.portal.kernel.staging.StagingUtil;
022 import com.liferay.portal.kernel.util.GetterUtil;
023 import com.liferay.portal.kernel.util.LocaleUtil;
024 import com.liferay.portal.kernel.util.ParamUtil;
025 import com.liferay.portal.kernel.util.ProxyUtil;
026 import com.liferay.portal.kernel.util.StringPool;
027 import com.liferay.portal.kernel.workflow.WorkflowConstants;
028 import com.liferay.portal.model.Layout;
029 import com.liferay.portal.model.LayoutRevision;
030 import com.liferay.portal.model.LayoutSet;
031 import com.liferay.portal.model.LayoutStagingHandler;
032 import com.liferay.portal.model.User;
033 import com.liferay.portal.security.auth.PrincipalThreadLocal;
034 import com.liferay.portal.security.pacl.PACLClassLoaderUtil;
035 import com.liferay.portal.service.ServiceContext;
036 import com.liferay.portal.service.ServiceContextThreadLocal;
037 import com.liferay.portal.service.UserLocalServiceUtil;
038 import com.liferay.portal.staging.StagingAdvicesThreadLocal;
039 import com.liferay.portlet.expando.model.ExpandoBridge;
040
041 import java.lang.reflect.InvocationTargetException;
042 import java.lang.reflect.Method;
043
044 import java.util.ArrayList;
045 import java.util.HashSet;
046 import java.util.List;
047 import java.util.Locale;
048 import java.util.Map;
049 import java.util.Set;
050
051 import org.aopalliance.intercept.MethodInterceptor;
052 import org.aopalliance.intercept.MethodInvocation;
053
054 import org.springframework.core.annotation.Order;
055
056
060 @Order(1)
061 public class LayoutLocalServiceStagingAdvice
062 extends LayoutLocalServiceImpl implements MethodInterceptor {
063
064 @Override
065 public void deleteLayout(
066 Layout layout, boolean updateLayoutSet,
067 ServiceContext serviceContext)
068 throws PortalException, SystemException {
069
070 long layoutSetBranchId = ParamUtil.getLong(
071 serviceContext, "layoutSetBranchId");
072
073 if (layoutSetBranchId > 0) {
074 layoutRevisionLocalService.deleteLayoutRevisions(
075 layoutSetBranchId, layout.getPlid());
076
077 List<LayoutRevision> notIncompleteLayoutRevisions =
078 layoutRevisionPersistence.findByP_NotS(
079 layout.getPlid(), WorkflowConstants.STATUS_INCOMPLETE);
080
081 if (notIncompleteLayoutRevisions.isEmpty()) {
082 layoutRevisionLocalService.deleteLayoutLayoutRevisions(
083 layout.getPlid());
084
085 super.deleteLayout(layout, updateLayoutSet, serviceContext);
086 }
087 }
088 else {
089 super.deleteLayout(layout, updateLayoutSet, serviceContext);
090 }
091 }
092
093 public Object invoke(MethodInvocation methodInvocation) throws Throwable {
094 if (!StagingAdvicesThreadLocal.isEnabled()) {
095 return methodInvocation.proceed();
096 }
097
098 Method method = methodInvocation.getMethod();
099
100 String methodName = method.getName();
101
102 Object[] arguments = methodInvocation.getArguments();
103
104 boolean showIncomplete = false;
105
106 if (!_layoutLocalServiceStagingAdviceMethodNames.contains(methodName)) {
107 return wrapReturnValue(methodInvocation.proceed(), showIncomplete);
108 }
109
110 Object returnValue = null;
111
112 if (methodName.equals("deleteLayout") && (arguments.length == 3)) {
113 deleteLayout(
114 (Layout)arguments[0], (Boolean)arguments[1],
115 (ServiceContext)arguments[2]);
116 }
117 else if (methodName.equals("getLayouts")) {
118 if (arguments.length == 6) {
119 showIncomplete = (Boolean)arguments[3];
120 }
121
122 return wrapReturnValue(methodInvocation.proceed(), showIncomplete);
123 }
124 else if (methodName.equals("updateLayout") &&
125 (arguments.length == 15)) {
126
127 returnValue = updateLayout(
128 (Long)arguments[0], (Boolean)arguments[1], (Long)arguments[2],
129 (Long)arguments[3], (Map<Locale, String>)arguments[4],
130 (Map<Locale, String>)arguments[5],
131 (Map<Locale, String>)arguments[6],
132 (Map<Locale, String>)arguments[7],
133 (Map<Locale, String>)arguments[8], (String)arguments[9],
134 (Boolean)arguments[10], (String)arguments[11],
135 (Boolean)arguments[12], (byte[])arguments[13],
136 (ServiceContext)arguments[14]);
137 }
138 else {
139 try {
140 Class<?> clazz = getClass();
141
142 Method localMethod = clazz.getMethod(
143 methodName, method.getParameterTypes());
144
145 returnValue = localMethod.invoke(this, arguments);
146 }
147 catch (InvocationTargetException ite) {
148 throw ite.getTargetException();
149 }
150 catch (NoSuchMethodException nsme) {
151 throw new SystemException(nsme);
152 }
153 }
154
155 returnValue = wrapReturnValue(returnValue, showIncomplete);
156
157 return returnValue;
158 }
159
160 @Override
161 public Layout updateLayout(
162 long groupId, boolean privateLayout, long layoutId,
163 long parentLayoutId, Map<Locale, String> nameMap,
164 Map<Locale, String> titleMap, Map<Locale, String> descriptionMap,
165 Map<Locale, String> keywordsMap, Map<Locale, String> robotsMap,
166 String type, boolean hidden, String friendlyURL, Boolean iconImage,
167 byte[] iconBytes, ServiceContext serviceContext)
168 throws PortalException, SystemException {
169
170
171
172 parentLayoutId = getParentLayoutId(
173 groupId, privateLayout, parentLayoutId);
174 String name = nameMap.get(LocaleUtil.getDefault());
175 friendlyURL = getFriendlyURL(
176 groupId, privateLayout, layoutId, StringPool.BLANK, friendlyURL);
177
178 validate(
179 groupId, privateLayout, layoutId, parentLayoutId, name, type,
180 hidden, friendlyURL);
181
182 validateParentLayoutId(
183 groupId, privateLayout, layoutId, parentLayoutId);
184
185 Layout originalLayout = layoutPersistence.findByG_P_L(
186 groupId, privateLayout, layoutId);
187
188 Layout layout = wrapLayout(originalLayout);
189
190 LayoutRevision layoutRevision = LayoutStagingUtil.getLayoutRevision(
191 layout);
192
193 if (layoutRevision == null) {
194 return super.updateLayout(
195 groupId, privateLayout, layoutId, parentLayoutId, nameMap,
196 titleMap, descriptionMap, keywordsMap, robotsMap, type, hidden,
197 friendlyURL, iconImage, iconBytes, serviceContext);
198 }
199
200 if (parentLayoutId != originalLayout.getParentLayoutId()) {
201 int priority = getNextPriority(
202 groupId, privateLayout, parentLayoutId,
203 originalLayout.getSourcePrototypeLayoutUuid(), -1);
204
205 originalLayout.setPriority(priority);
206 }
207
208 originalLayout.setParentLayoutId(parentLayoutId);
209 layoutRevision.setNameMap(nameMap);
210 layoutRevision.setTitleMap(titleMap);
211 layoutRevision.setDescriptionMap(descriptionMap);
212 layoutRevision.setKeywordsMap(keywordsMap);
213 layoutRevision.setRobotsMap(robotsMap);
214 originalLayout.setType(type);
215 originalLayout.setHidden(hidden);
216 originalLayout.setFriendlyURL(friendlyURL);
217
218 if (iconImage != null) {
219 originalLayout.setIconImage(iconImage.booleanValue());
220
221 if (iconImage.booleanValue()) {
222 long iconImageId = originalLayout.getIconImageId();
223
224 if (iconImageId <= 0) {
225 iconImageId = counterLocalService.increment();
226
227 originalLayout.setIconImageId(iconImageId);
228 }
229 }
230 }
231
232 boolean layoutPrototypeLinkEnabled = ParamUtil.getBoolean(
233 serviceContext, "layoutPrototypeLinkEnabled", true);
234
235 originalLayout.setLayoutPrototypeLinkEnabled(
236 layoutPrototypeLinkEnabled);
237
238 layoutPersistence.update(originalLayout, false);
239
240 boolean hasWorkflowTask = StagingUtil.hasWorkflowTask(
241 serviceContext.getUserId(), layoutRevision);
242
243 serviceContext.setAttribute("revisionInProgress", hasWorkflowTask);
244
245 serviceContext.setWorkflowAction(WorkflowConstants.ACTION_SAVE_DRAFT);
246
247 layoutRevisionLocalService.updateLayoutRevision(
248 serviceContext.getUserId(), layoutRevision.getLayoutRevisionId(),
249 layoutRevision.getLayoutBranchId(), layoutRevision.getName(),
250 layoutRevision.getTitle(), layoutRevision.getDescription(),
251 layoutRevision.getKeywords(), layoutRevision.getRobots(),
252 layoutRevision.getTypeSettings(), layoutRevision.getIconImage(),
253 layoutRevision.getIconImageId(), layoutRevision.getThemeId(),
254 layoutRevision.getColorSchemeId(), layoutRevision.getWapThemeId(),
255 layoutRevision.getWapColorSchemeId(), layoutRevision.getCss(),
256 serviceContext);
257
258
259
260 if (iconImage != null) {
261 if ((iconBytes != null) && (iconBytes.length > 0)) {
262 imageLocalService.updateImage(
263 originalLayout.getIconImageId(), iconBytes);
264 }
265 }
266
267
268
269 ExpandoBridge expandoBridge = originalLayout.getExpandoBridge();
270
271 expandoBridge.setAttributes(serviceContext);
272
273 return layout;
274 }
275
276 @Override
277 public Layout updateLayout(
278 long groupId, boolean privateLayout, long layoutId,
279 String typeSettings)
280 throws PortalException, SystemException {
281
282 Layout layout = layoutPersistence.findByG_P_L(
283 groupId, privateLayout, layoutId);
284
285 layout = wrapLayout(layout);
286
287 LayoutRevision layoutRevision = LayoutStagingUtil.getLayoutRevision(
288 layout);
289
290 if (layoutRevision == null) {
291 return super.updateLayout(
292 groupId, privateLayout, layoutId, typeSettings);
293 }
294
295 layout.setTypeSettings(typeSettings);
296
297 ServiceContext serviceContext =
298 ServiceContextThreadLocal.getServiceContext();
299
300 boolean hasWorkflowTask = StagingUtil.hasWorkflowTask(
301 serviceContext.getUserId(), layoutRevision);
302
303 serviceContext.setAttribute("revisionInProgress", hasWorkflowTask);
304
305 if (!MergeLayoutPrototypesThreadLocal.isInProgress()) {
306 serviceContext.setWorkflowAction(
307 WorkflowConstants.ACTION_SAVE_DRAFT);
308 }
309
310 layoutRevisionLocalService.updateLayoutRevision(
311 serviceContext.getUserId(), layoutRevision.getLayoutRevisionId(),
312 layoutRevision.getLayoutBranchId(), layoutRevision.getName(),
313 layoutRevision.getTitle(), layoutRevision.getDescription(),
314 layoutRevision.getKeywords(), layoutRevision.getRobots(),
315 layoutRevision.getTypeSettings(), layoutRevision.getIconImage(),
316 layoutRevision.getIconImageId(), layoutRevision.getThemeId(),
317 layoutRevision.getColorSchemeId(), layoutRevision.getWapThemeId(),
318 layoutRevision.getWapColorSchemeId(), layoutRevision.getCss(),
319 serviceContext);
320
321 return layout;
322 }
323
324 @Override
325 public Layout updateLookAndFeel(
326 long groupId, boolean privateLayout, long layoutId, String themeId,
327 String colorSchemeId, String css, boolean wapTheme)
328 throws PortalException, SystemException {
329
330 Layout layout = layoutPersistence.findByG_P_L(
331 groupId, privateLayout, layoutId);
332
333 layout = wrapLayout(layout);
334
335 LayoutRevision layoutRevision = LayoutStagingUtil.getLayoutRevision(
336 layout);
337
338 if (layoutRevision == null) {
339 return super.updateLookAndFeel(
340 groupId, privateLayout, layoutId, themeId, colorSchemeId, css,
341 wapTheme);
342 }
343
344 if (wapTheme) {
345 layout.setWapThemeId(themeId);
346 layout.setWapColorSchemeId(colorSchemeId);
347 }
348 else {
349 layout.setThemeId(themeId);
350 layout.setColorSchemeId(colorSchemeId);
351 layout.setCss(css);
352 }
353
354 ServiceContext serviceContext =
355 ServiceContextThreadLocal.getServiceContext();
356
357 boolean hasWorkflowTask = StagingUtil.hasWorkflowTask(
358 serviceContext.getUserId(), layoutRevision);
359
360 serviceContext.setAttribute("revisionInProgress", hasWorkflowTask);
361
362 if (!MergeLayoutPrototypesThreadLocal.isInProgress()) {
363 serviceContext.setWorkflowAction(
364 WorkflowConstants.ACTION_SAVE_DRAFT);
365 }
366
367 layoutRevisionLocalService.updateLayoutRevision(
368 serviceContext.getUserId(), layoutRevision.getLayoutRevisionId(),
369 layoutRevision.getLayoutBranchId(), layoutRevision.getName(),
370 layoutRevision.getTitle(), layoutRevision.getDescription(),
371 layoutRevision.getKeywords(), layoutRevision.getRobots(),
372 layoutRevision.getTypeSettings(), layoutRevision.getIconImage(),
373 layoutRevision.getIconImageId(), layoutRevision.getThemeId(),
374 layoutRevision.getColorSchemeId(), layoutRevision.getWapThemeId(),
375 layoutRevision.getWapColorSchemeId(), layoutRevision.getCss(),
376 serviceContext);
377
378 return layout;
379 }
380
381 @Override
382 public Layout updateName(Layout layout, String name, String languageId)
383 throws PortalException, SystemException {
384
385 layout = wrapLayout(layout);
386
387 LayoutRevision layoutRevision = LayoutStagingUtil.getLayoutRevision(
388 layout);
389
390 if (layoutRevision == null) {
391 return super.updateName(layout, name, languageId);
392 }
393
394 validateName(name, languageId);
395
396 layout.setName(name, LocaleUtil.fromLanguageId(languageId));
397
398 ServiceContext serviceContext =
399 ServiceContextThreadLocal.getServiceContext();
400
401 boolean hasWorkflowTask = StagingUtil.hasWorkflowTask(
402 serviceContext.getUserId(), layoutRevision);
403
404 serviceContext.setAttribute("revisionInProgress", hasWorkflowTask);
405
406 serviceContext.setWorkflowAction(WorkflowConstants.ACTION_SAVE_DRAFT);
407
408 layoutRevisionLocalService.updateLayoutRevision(
409 serviceContext.getUserId(), layoutRevision.getLayoutRevisionId(),
410 layoutRevision.getLayoutBranchId(), layoutRevision.getName(),
411 layoutRevision.getTitle(), layoutRevision.getDescription(),
412 layoutRevision.getKeywords(), layoutRevision.getRobots(),
413 layoutRevision.getTypeSettings(), layoutRevision.getIconImage(),
414 layoutRevision.getIconImageId(), layoutRevision.getThemeId(),
415 layoutRevision.getColorSchemeId(), layoutRevision.getWapThemeId(),
416 layoutRevision.getWapColorSchemeId(), layoutRevision.getCss(),
417 serviceContext);
418
419 return layout;
420 }
421
422 protected Layout unwrapLayout(Layout layout) {
423 LayoutStagingHandler layoutStagingHandler =
424 LayoutStagingUtil.getLayoutStagingHandler(layout);
425
426 if (layoutStagingHandler == null) {
427 return layout;
428 }
429
430 return layoutStagingHandler.getLayout();
431 }
432
433 protected Layout wrapLayout(Layout layout) {
434 LayoutStagingHandler layoutStagingHandler =
435 LayoutStagingUtil.getLayoutStagingHandler(layout);
436
437 if (layoutStagingHandler != null) {
438 return layout;
439 }
440
441 if (!LayoutStagingUtil.isBranchingLayout(layout)) {
442 return layout;
443 }
444
445 return (Layout)ProxyUtil.newProxyInstance(
446 PACLClassLoaderUtil.getPortalClassLoader(),
447 new Class[] {Layout.class}, new LayoutStagingHandler(layout));
448 }
449
450 protected List<Layout> wrapLayouts(
451 List<Layout> layouts, boolean showIncomplete) {
452
453 if (layouts.isEmpty()) {
454 return layouts;
455 }
456
457 Layout firstLayout = layouts.get(0);
458
459 Layout wrappedFirstLayout = wrapLayout(firstLayout);
460
461 if (wrappedFirstLayout == firstLayout) {
462 return layouts;
463 }
464
465 long layoutSetBranchId = 0;
466
467 if (!showIncomplete) {
468 try {
469 long userId = GetterUtil.getLong(
470 PrincipalThreadLocal.getName());
471
472 if (userId > 0) {
473 User user = UserLocalServiceUtil.getUser(userId);
474
475 LayoutSet layoutSet = firstLayout.getLayoutSet();
476
477 layoutSetBranchId = StagingUtil.getRecentLayoutSetBranchId(
478 user, layoutSet.getLayoutSetId());
479 }
480 }
481 catch (Exception e) {
482 }
483 }
484
485 List<Layout> wrappedLayouts = new ArrayList<Layout>(layouts.size());
486
487 for (int i = 0; i < layouts.size(); i++) {
488 Layout wrappedLayout = wrapLayout(layouts.get(i));
489
490 if (showIncomplete ||
491 !StagingUtil.isIncomplete(wrappedLayout, layoutSetBranchId)) {
492
493 wrappedLayouts.add(wrappedLayout);
494 }
495 }
496
497 return wrappedLayouts;
498 }
499
500 protected Object wrapReturnValue(
501 Object returnValue, boolean showIncomplete) {
502
503 if (returnValue instanceof Layout) {
504 returnValue = wrapLayout((Layout)returnValue);
505 }
506 else if (returnValue instanceof List<?>) {
507 returnValue = wrapLayouts(
508 (List<Layout>)returnValue, showIncomplete);
509 }
510
511 return returnValue;
512 }
513
514 private static Set<String> _layoutLocalServiceStagingAdviceMethodNames =
515 new HashSet<String>();
516
517 static {
518 _layoutLocalServiceStagingAdviceMethodNames.add("deleteLayout");
519 _layoutLocalServiceStagingAdviceMethodNames.add("getLayouts");
520 _layoutLocalServiceStagingAdviceMethodNames.add("updateLayout");
521 _layoutLocalServiceStagingAdviceMethodNames.add("updateLookAndFeel");
522 _layoutLocalServiceStagingAdviceMethodNames.add("updateName");
523 }
524
525 }