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