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