001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.service.impl;
016    
017    import com.liferay.portal.NoSuchLayoutRevisionException;
018    import com.liferay.portal.NoSuchPortletPreferencesException;
019    import com.liferay.portal.kernel.exception.PortalException;
020    import com.liferay.portal.kernel.exception.SystemException;
021    import com.liferay.portal.kernel.staging.MergeLayoutPrototypesThreadLocal;
022    import com.liferay.portal.kernel.staging.StagingUtil;
023    import com.liferay.portal.kernel.util.AutoResetThreadLocal;
024    import com.liferay.portal.kernel.util.OrderByComparator;
025    import com.liferay.portal.kernel.util.ParamUtil;
026    import com.liferay.portal.kernel.workflow.WorkflowConstants;
027    import com.liferay.portal.kernel.workflow.WorkflowHandlerRegistryUtil;
028    import com.liferay.portal.model.LayoutConstants;
029    import com.liferay.portal.model.LayoutRevision;
030    import com.liferay.portal.model.LayoutRevisionConstants;
031    import com.liferay.portal.model.LayoutSetBranch;
032    import com.liferay.portal.model.PortletPreferences;
033    import com.liferay.portal.model.User;
034    import com.liferay.portal.service.ServiceContext;
035    import com.liferay.portal.service.base.LayoutRevisionLocalServiceBaseImpl;
036    import com.liferay.portal.util.comparator.LayoutRevisionCreateDateComparator;
037    
038    import java.util.Date;
039    import java.util.List;
040    
041    /**
042     * @author Raymond Augé
043     * @author Brian Wing Shun Chan
044     */
045    public class LayoutRevisionLocalServiceImpl
046            extends LayoutRevisionLocalServiceBaseImpl {
047    
048            public LayoutRevision addLayoutRevision(
049                            long userId, long layoutSetBranchId, long layoutBranchId,
050                            long parentLayoutRevisionId, boolean head, long plid,
051                            long portletPreferencesPlid, boolean privateLayout, String name,
052                            String title, String description, String keywords, String robots,
053                            String typeSettings, boolean iconImage, long iconImageId,
054                            String themeId, String colorSchemeId, String wapThemeId,
055                            String wapColorSchemeId, String css, ServiceContext serviceContext)
056                    throws PortalException, SystemException {
057    
058                    // Layout revision
059    
060                    User user = userPersistence.findByPrimaryKey(userId);
061                    LayoutSetBranch layoutSetBranch =
062                            layoutSetBranchPersistence.findByPrimaryKey(layoutSetBranchId);
063                    parentLayoutRevisionId = getParentLayoutRevisionId(
064                            layoutSetBranchId, parentLayoutRevisionId, plid);
065                    Date now = new Date();
066    
067                    long layoutRevisionId = counterLocalService.increment();
068    
069                    LayoutRevision layoutRevision = layoutRevisionPersistence.create(
070                            layoutRevisionId);
071    
072                    layoutRevision.setGroupId(layoutSetBranch.getGroupId());
073                    layoutRevision.setCompanyId(user.getCompanyId());
074                    layoutRevision.setUserId(user.getUserId());
075                    layoutRevision.setUserName(user.getFullName());
076                    layoutRevision.setCreateDate(serviceContext.getCreateDate(now));
077                    layoutRevision.setModifiedDate(serviceContext.getModifiedDate(now));
078                    layoutRevision.setLayoutSetBranchId(layoutSetBranchId);
079                    layoutRevision.setLayoutBranchId(layoutBranchId);
080                    layoutRevision.setParentLayoutRevisionId(parentLayoutRevisionId);
081                    layoutRevision.setHead(head);
082                    layoutRevision.setPlid(plid);
083                    layoutRevision.setPrivateLayout(privateLayout);
084                    layoutRevision.setName(name);
085                    layoutRevision.setTitle(title);
086                    layoutRevision.setDescription(description);
087                    layoutRevision.setKeywords(keywords);
088                    layoutRevision.setRobots(robots);
089                    layoutRevision.setTypeSettings(typeSettings);
090    
091                    if (iconImage) {
092                            layoutRevision.setIconImage(iconImage);
093                            layoutRevision.setIconImageId(iconImageId);
094                    }
095    
096                    layoutRevision.setThemeId(themeId);
097                    layoutRevision.setColorSchemeId(colorSchemeId);
098                    layoutRevision.setWapThemeId(wapThemeId);
099                    layoutRevision.setWapColorSchemeId(wapColorSchemeId);
100                    layoutRevision.setCss(css);
101                    layoutRevision.setStatus(WorkflowConstants.STATUS_DRAFT);
102                    layoutRevision.setStatusDate(serviceContext.getModifiedDate(now));
103    
104                    layoutRevisionPersistence.update(layoutRevision, false);
105    
106                    _layoutRevisionId.set(layoutRevision.getLayoutRevisionId());
107    
108                    // Portlet preferences
109    
110                    if (portletPreferencesPlid == LayoutConstants.DEFAULT_PLID) {
111                            portletPreferencesPlid = plid;
112                    }
113    
114                    copyPortletPreferences(
115                            layoutRevision, portletPreferencesPlid, serviceContext);
116    
117                    // Workflow
118    
119                    WorkflowHandlerRegistryUtil.startWorkflowInstance(
120                            user.getCompanyId(), layoutRevision.getGroupId(), user.getUserId(),
121                            LayoutRevision.class.getName(),
122                            layoutRevision.getLayoutRevisionId(), layoutRevision,
123                            serviceContext);
124    
125                    return layoutRevision;
126            }
127    
128            public void deleteLayoutLayoutRevisions(long plid)
129                    throws PortalException, SystemException {
130    
131                    for (LayoutRevision layoutRevision : getLayoutRevisions(plid)) {
132                            layoutRevisionLocalService.deleteLayoutRevision(layoutRevision);
133                    }
134            }
135    
136            @Override
137            public void deleteLayoutRevision(LayoutRevision layoutRevision)
138                    throws PortalException, SystemException {
139    
140                    if (layoutRevision.hasChildren()) {
141                            for (LayoutRevision curLayoutRevision :
142                                            layoutRevision.getChildren()) {
143    
144                                    curLayoutRevision.setParentLayoutRevisionId(
145                                            layoutRevision.getParentLayoutRevisionId());
146    
147                                    layoutRevisionPersistence.update(curLayoutRevision, false);
148                            }
149                    }
150    
151                    List<PortletPreferences> portletPreferencesList =
152                            portletPreferencesLocalService.getPortletPreferencesByPlid(
153                                    layoutRevision.getLayoutRevisionId());
154    
155                    for (PortletPreferences portletPreferences : portletPreferencesList) {
156                            try {
157                                    portletPreferencesLocalService.deletePortletPreferences(
158                                            portletPreferences.getPortletPreferencesId());
159                            }
160                            catch (NoSuchPortletPreferencesException nsppe) {
161                            }
162                    }
163    
164                    layoutRevisionPersistence.remove(layoutRevision);
165            }
166    
167            @Override
168            public void deleteLayoutRevision(long layoutRevisionId)
169                    throws PortalException, SystemException {
170    
171                    LayoutRevision layoutRevision =
172                            layoutRevisionPersistence.findByPrimaryKey(layoutRevisionId);
173    
174                    layoutRevisionLocalService.deleteLayoutRevision(layoutRevision);
175            }
176    
177            public void deleteLayoutRevisions(long layoutSetBranchId, long plid)
178                    throws PortalException, SystemException {
179    
180                    for (LayoutRevision layoutRevision : getLayoutRevisions(
181                                    layoutSetBranchId, plid)) {
182    
183                            layoutRevisionLocalService.deleteLayoutRevision(layoutRevision);
184                    }
185            }
186    
187            public void deleteLayoutRevisions(
188                            long layoutSetBranchId, long layoutBranchId, long plid)
189                    throws PortalException, SystemException {
190    
191                    List<LayoutRevision> layoutRevisions =
192                            layoutRevisionPersistence.findByL_L_P(
193                                    layoutSetBranchId, layoutBranchId, plid);
194    
195                    for (LayoutRevision layoutRevision : layoutRevisions) {
196                            layoutRevisionLocalService.deleteLayoutRevision(layoutRevision);
197                    }
198            }
199    
200            public void deleteLayoutSetBranchLayoutRevisions(long layoutSetBranchId)
201                    throws PortalException, SystemException {
202    
203                    List<LayoutRevision> layoutRevisions =
204                            layoutRevisionPersistence.findByLayoutSetBranchId(
205                                    layoutSetBranchId);
206    
207                    for (LayoutRevision layoutRevision : layoutRevisions) {
208                            layoutRevisionLocalService.deleteLayoutRevision(layoutRevision);
209                    }
210            }
211    
212            public LayoutRevision fetchLastLayoutRevision(long plid, boolean head)
213                    throws SystemException {
214    
215                    try {
216                            return layoutRevisionPersistence.findByH_P_Last(
217                                    head, plid, new LayoutRevisionCreateDateComparator(true));
218                    }
219                    catch (NoSuchLayoutRevisionException nslre) {
220                            return null;
221                    }
222            }
223    
224            public List<LayoutRevision> getChildLayoutRevisions(
225                            long layoutSetBranchId, long parentLayoutRevisionId, long plid)
226                    throws SystemException {
227    
228                    return layoutRevisionPersistence.findByL_P_P(
229                            layoutSetBranchId, parentLayoutRevisionId, plid);
230            }
231    
232            public List<LayoutRevision> getChildLayoutRevisions(
233                            long layoutSetBranchId, long parentLayoutRevision, long plid,
234                            int start, int end, OrderByComparator orderByComparator)
235                    throws SystemException {
236    
237                    return layoutRevisionPersistence.findByL_P_P(
238                            layoutSetBranchId, parentLayoutRevision, plid, start, end,
239                            orderByComparator);
240            }
241    
242            public int getChildLayoutRevisionsCount(
243                            long layoutSetBranchId, long parentLayoutRevision, long plid)
244                    throws SystemException {
245    
246                    return layoutRevisionPersistence.countByL_P_P(
247                            layoutSetBranchId, parentLayoutRevision, plid);
248            }
249    
250            @Override
251            public LayoutRevision getLayoutRevision(long layoutRevisionId)
252                    throws PortalException, SystemException {
253    
254                    return layoutRevisionPersistence.findByPrimaryKey(layoutRevisionId);
255            }
256    
257            public LayoutRevision getLayoutRevision(
258                            long layoutSetBranchId, long plid, boolean head)
259                    throws PortalException, SystemException {
260    
261                    return layoutRevisionPersistence.findByL_H_P(
262                            layoutSetBranchId, head, plid);
263            }
264    
265            public LayoutRevision getLayoutRevision(
266                            long layoutSetBranchId, long layoutBranchId, long plid)
267                    throws PortalException, SystemException {
268    
269                    List<LayoutRevision> layoutRevisions =
270                            layoutRevisionPersistence.findByL_L_P(
271                                    layoutSetBranchId, layoutBranchId, plid, 0, 1,
272                                    new LayoutRevisionCreateDateComparator(false));
273    
274                    if (!layoutRevisions.isEmpty()) {
275                            return layoutRevisions.get(0);
276                    }
277    
278                    throw new NoSuchLayoutRevisionException();
279            }
280    
281            public List<LayoutRevision> getLayoutRevisions(long plid)
282                    throws SystemException {
283    
284                    return layoutRevisionPersistence.findByPlid(plid);
285            }
286    
287            public List<LayoutRevision> getLayoutRevisions(
288                            long layoutSetBranchId, boolean head)
289                    throws SystemException {
290    
291                    return layoutRevisionPersistence.findByL_H(layoutSetBranchId, head);
292            }
293    
294            public List<LayoutRevision> getLayoutRevisions(
295                            long layoutSetBranchId, int status)
296                    throws SystemException {
297    
298                    return layoutRevisionPersistence.findByL_S(layoutSetBranchId, status);
299            }
300    
301            public List<LayoutRevision> getLayoutRevisions(
302                            long layoutSetBranchId, long plid)
303                    throws SystemException {
304    
305                    return layoutRevisionPersistence.findByL_P(layoutSetBranchId, plid);
306            }
307    
308            public List<LayoutRevision> getLayoutRevisions(
309                            long layoutSetBranchId, long plid, int status)
310                    throws SystemException {
311    
312                    return layoutRevisionPersistence.findByL_P_S(
313                            layoutSetBranchId, plid, status);
314            }
315    
316            public List<LayoutRevision> getLayoutRevisions(
317                            long layoutSetBranchId, long layoutBranchId, long plid, int start,
318                            int end, OrderByComparator orderByComparator)
319                    throws SystemException {
320    
321                    return layoutRevisionPersistence.findByL_L_P(
322                            layoutSetBranchId, layoutBranchId, plid, start, end,
323                            orderByComparator);
324            }
325    
326            public int getLayoutRevisionsCount(
327                            long layoutSetBranchId, long layoutBranchId, long plid)
328                    throws SystemException {
329    
330                    return layoutRevisionPersistence.countByL_L_P(
331                            layoutSetBranchId, layoutBranchId, plid);
332            }
333    
334            public LayoutRevision updateLayoutRevision(
335                            long userId, long layoutRevisionId, long layoutBranchId,
336                            String name, String title, String description, String keywords,
337                            String robots, String typeSettings, boolean iconImage,
338                            long iconImageId, String themeId, String colorSchemeId,
339                            String wapThemeId, String wapColorSchemeId, String css,
340                            ServiceContext serviceContext)
341                    throws PortalException, SystemException {
342    
343                    // Layout revision
344    
345                    User user = userPersistence.findByPrimaryKey(userId);
346                    LayoutRevision oldLayoutRevision =
347                            layoutRevisionPersistence.findByPrimaryKey(layoutRevisionId);
348                    Date now = new Date();
349    
350                    LayoutRevision layoutRevision = null;
351    
352                    int workflowAction = serviceContext.getWorkflowAction();
353    
354                    if (!MergeLayoutPrototypesThreadLocal.isInProgress() &&
355                            (workflowAction != WorkflowConstants.ACTION_PUBLISH) &&
356                            (_layoutRevisionId.get() <= 0)) {
357    
358                            long newLayoutRevisionId = counterLocalService.increment();
359    
360                            layoutRevision = layoutRevisionPersistence.create(
361                                    newLayoutRevisionId);
362    
363                            layoutRevision.setGroupId(oldLayoutRevision.getGroupId());
364                            layoutRevision.setCompanyId(oldLayoutRevision.getCompanyId());
365                            layoutRevision.setUserId(user.getUserId());
366                            layoutRevision.setUserName(user.getFullName());
367                            layoutRevision.setCreateDate(serviceContext.getCreateDate(now));
368                            layoutRevision.setModifiedDate(serviceContext.getModifiedDate(now));
369                            layoutRevision.setLayoutSetBranchId(
370                                    oldLayoutRevision.getLayoutSetBranchId());
371                            layoutRevision.setParentLayoutRevisionId(
372                                    oldLayoutRevision.getLayoutRevisionId());
373                            layoutRevision.setHead(false);
374                            layoutRevision.setLayoutBranchId(layoutBranchId);
375                            layoutRevision.setPlid(oldLayoutRevision.getPlid());
376                            layoutRevision.setPrivateLayout(
377                                    oldLayoutRevision.isPrivateLayout());
378                            layoutRevision.setName(name);
379                            layoutRevision.setTitle(title);
380                            layoutRevision.setDescription(description);
381                            layoutRevision.setKeywords(keywords);
382                            layoutRevision.setRobots(robots);
383                            layoutRevision.setTypeSettings(typeSettings);
384    
385                            if (iconImage) {
386                                    layoutRevision.setIconImage(iconImage);
387                                    layoutRevision.setIconImageId(iconImageId);
388                            }
389    
390                            layoutRevision.setThemeId(themeId);
391                            layoutRevision.setColorSchemeId(colorSchemeId);
392                            layoutRevision.setWapThemeId(wapThemeId);
393                            layoutRevision.setWapColorSchemeId(wapColorSchemeId);
394                            layoutRevision.setCss(css);
395                            layoutRevision.setStatus(WorkflowConstants.STATUS_DRAFT);
396                            layoutRevision.setStatusDate(serviceContext.getModifiedDate(now));
397    
398                            layoutRevisionPersistence.update(layoutRevision, false);
399    
400                            _layoutRevisionId.set(layoutRevision.getLayoutRevisionId());
401    
402                            // Portlet preferences
403    
404                            copyPortletPreferences(
405                                    layoutRevision, layoutRevision.getParentLayoutRevisionId(),
406                                    serviceContext);
407    
408                            StagingUtil.deleteRecentLayoutRevisionId(
409                                    user, layoutRevision.getLayoutSetBranchId(),
410                                    layoutRevision.getPlid());
411    
412                            StagingUtil.setRecentLayoutBranchId(
413                                    user, layoutRevision.getLayoutSetBranchId(),
414                                    layoutRevision.getPlid(), layoutRevision.getLayoutBranchId());
415                    }
416                    else {
417                            layoutRevision = oldLayoutRevision;
418    
419                            layoutRevision.setName(name);
420                            layoutRevision.setTitle(title);
421                            layoutRevision.setDescription(description);
422                            layoutRevision.setKeywords(keywords);
423                            layoutRevision.setRobots(robots);
424                            layoutRevision.setTypeSettings(typeSettings);
425    
426                            if (iconImage) {
427                                    layoutRevision.setIconImage(iconImage);
428                                    layoutRevision.setIconImageId(iconImageId);
429                            }
430    
431                            layoutRevision.setThemeId(themeId);
432                            layoutRevision.setColorSchemeId(colorSchemeId);
433                            layoutRevision.setWapThemeId(wapThemeId);
434                            layoutRevision.setWapColorSchemeId(wapColorSchemeId);
435                            layoutRevision.setCss(css);
436    
437                            layoutRevisionPersistence.update(layoutRevision, false);
438    
439                            _layoutRevisionId.set(layoutRevision.getLayoutRevisionId());
440                    }
441    
442                    boolean major = ParamUtil.getBoolean(serviceContext, "major");
443    
444                    if (major) {
445                            updateMajor(layoutRevision);
446                    }
447    
448                    // Workflow
449    
450                    WorkflowHandlerRegistryUtil.startWorkflowInstance(
451                            layoutRevision.getCompanyId(), layoutRevision.getGroupId(), userId,
452                            LayoutRevision.class.getName(),
453                            layoutRevision.getLayoutRevisionId(), layoutRevision,
454                            serviceContext);
455    
456                    return layoutRevision;
457            }
458    
459            public LayoutRevision updateStatus(
460                            long userId, long layoutRevisionId, int status,
461                            ServiceContext serviceContext)
462                    throws PortalException, SystemException {
463    
464                    User user = userPersistence.findByPrimaryKey(userId);
465    
466                    LayoutRevision layoutRevision =
467                            layoutRevisionPersistence.findByPrimaryKey(layoutRevisionId);
468    
469                    layoutRevision.setStatus(status);
470                    layoutRevision.setStatusByUserId(user.getUserId());
471                    layoutRevision.setStatusByUserName(user.getFullName());
472                    layoutRevision.setStatusDate(new Date());
473    
474                    if (status == WorkflowConstants.STATUS_APPROVED) {
475                            layoutRevision.setHead(true);
476    
477                            List<LayoutRevision> layoutRevisions =
478                                    layoutRevisionPersistence.findByL_P(
479                                            layoutRevision.getLayoutSetBranchId(),
480                                            layoutRevision.getPlid());
481    
482                            for (LayoutRevision curLayoutRevision : layoutRevisions) {
483                                    if (curLayoutRevision.getLayoutRevisionId() !=
484                                                    layoutRevision.getLayoutRevisionId()) {
485    
486                                            curLayoutRevision.setHead(false);
487    
488                                            layoutRevisionPersistence.update(curLayoutRevision, false);
489                                    }
490                            }
491                    }
492                    else {
493                            layoutRevision.setHead(false);
494    
495                            List<LayoutRevision> layoutRevisions =
496                                    layoutRevisionPersistence.findByL_P_S(
497                                            layoutRevision.getLayoutSetBranchId(),
498                                            layoutRevision.getPlid(),
499                                            WorkflowConstants.STATUS_APPROVED);
500    
501                            for (LayoutRevision curLayoutRevision : layoutRevisions) {
502                                    if (curLayoutRevision.getLayoutRevisionId() !=
503                                                    layoutRevision.getLayoutRevisionId()) {
504    
505                                            curLayoutRevision.setHead(true);
506    
507                                            layoutRevisionPersistence.update(curLayoutRevision, false);
508    
509                                            break;
510                                    }
511                            }
512                    }
513    
514                    layoutRevisionPersistence.update(layoutRevision, false);
515    
516                    return layoutRevision;
517            }
518    
519            protected void copyPortletPreferences(
520                            LayoutRevision layoutRevision, long parentLayoutRevisionId,
521                            ServiceContext serviceContext)
522                    throws SystemException {
523    
524                    List<PortletPreferences> portletPreferencesList =
525                            portletPreferencesLocalService.getPortletPreferencesByPlid(
526                                    parentLayoutRevisionId);
527    
528                    for (PortletPreferences portletPreferences : portletPreferencesList) {
529                            portletPreferencesLocalService.addPortletPreferences(
530                                    layoutRevision.getCompanyId(), portletPreferences.getOwnerId(),
531                                    portletPreferences.getOwnerType(),
532                                    layoutRevision.getLayoutRevisionId(),
533                                    portletPreferences.getPortletId(), null,
534                                    portletPreferences.getPreferences());
535                    }
536            }
537    
538            protected long getParentLayoutRevisionId(
539                            long layoutSetBranchId, long parentLayoutRevisionId, long plid)
540                    throws SystemException {
541    
542                    LayoutRevision parentLayoutRevision = null;
543    
544                    if (parentLayoutRevisionId > 0) {
545                            parentLayoutRevision = layoutRevisionPersistence.fetchByPrimaryKey(
546                                    parentLayoutRevisionId);
547    
548                            if (parentLayoutRevision == null) {
549                                    List<LayoutRevision> layoutRevisions =
550                                            layoutRevisionPersistence.findByL_P(
551                                                    layoutSetBranchId, plid, 0, 1);
552    
553                                    if (!layoutRevisions.isEmpty()) {
554                                            parentLayoutRevision = layoutRevisions.get(0);
555                                    }
556                            }
557                    }
558    
559                    if (parentLayoutRevision != null) {
560                            return parentLayoutRevision.getLayoutRevisionId();
561                    }
562    
563                    return LayoutRevisionConstants.DEFAULT_PARENT_LAYOUT_REVISION_ID;
564            }
565    
566            protected LayoutRevision updateMajor(LayoutRevision layoutRevision)
567                    throws PortalException, SystemException {
568    
569                    long parentLayoutRevisionId =
570                            layoutRevision.getParentLayoutRevisionId();
571    
572                    boolean fork = false;
573    
574                    while (parentLayoutRevisionId !=
575                                            LayoutRevisionConstants.DEFAULT_PARENT_LAYOUT_REVISION_ID) {
576    
577                            LayoutRevision parentLayoutRevision =
578                                    layoutRevisionPersistence.findByPrimaryKey(
579                                            parentLayoutRevisionId);
580    
581                            if (parentLayoutRevision.isMajor()) {
582                                    break;
583                            }
584    
585                            parentLayoutRevisionId =
586                                    parentLayoutRevision.getParentLayoutRevisionId();
587    
588                            if (parentLayoutRevision.getChildren().size() > 1) {
589                                    fork = true;
590                            }
591    
592                            if (!fork) {
593                                    layoutRevisionLocalService.deleteLayoutRevision(
594                                            parentLayoutRevision);
595                            }
596                    }
597    
598                    layoutRevision.setParentLayoutRevisionId(parentLayoutRevisionId);
599                    layoutRevision.setMajor(true);
600    
601                    layoutRevisionPersistence.update(layoutRevision, false);
602    
603                    return layoutRevision;
604            }
605    
606            private static ThreadLocal<Long> _layoutRevisionId =
607                    new AutoResetThreadLocal<Long>(
608                            LayoutRevisionLocalServiceImpl.class + "._layoutRevisionId", 0L);
609    
610    }