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