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);
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 LayoutRevision 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);
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                    return layoutRevisionPersistence.remove(layoutRevision);
165            }
166    
167            @Override
168            public LayoutRevision deleteLayoutRevision(long layoutRevisionId)
169                    throws PortalException, SystemException {
170    
171                    LayoutRevision layoutRevision =
172                            layoutRevisionPersistence.findByPrimaryKey(layoutRevisionId);
173    
174                    return 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            public LayoutRevision getLayoutRevision(
251                            long layoutSetBranchId, long plid, boolean head)
252                    throws PortalException, SystemException {
253    
254                    return layoutRevisionPersistence.findByL_H_P(
255                            layoutSetBranchId, head, plid);
256            }
257    
258            public LayoutRevision getLayoutRevision(
259                            long layoutSetBranchId, long layoutBranchId, long plid)
260                    throws PortalException, SystemException {
261    
262                    List<LayoutRevision> layoutRevisions =
263                            layoutRevisionPersistence.findByL_L_P(
264                                    layoutSetBranchId, layoutBranchId, plid, 0, 1,
265                                    new LayoutRevisionCreateDateComparator(false));
266    
267                    if (!layoutRevisions.isEmpty()) {
268                            return layoutRevisions.get(0);
269                    }
270    
271                    throw new NoSuchLayoutRevisionException();
272            }
273    
274            public List<LayoutRevision> getLayoutRevisions(long plid)
275                    throws SystemException {
276    
277                    return layoutRevisionPersistence.findByPlid(plid);
278            }
279    
280            public List<LayoutRevision> getLayoutRevisions(
281                            long layoutSetBranchId, boolean head)
282                    throws SystemException {
283    
284                    return layoutRevisionPersistence.findByL_H(layoutSetBranchId, head);
285            }
286    
287            public List<LayoutRevision> getLayoutRevisions(
288                            long layoutSetBranchId, int status)
289                    throws SystemException {
290    
291                    return layoutRevisionPersistence.findByL_S(layoutSetBranchId, status);
292            }
293    
294            public List<LayoutRevision> getLayoutRevisions(
295                            long layoutSetBranchId, long plid)
296                    throws SystemException {
297    
298                    return layoutRevisionPersistence.findByL_P(layoutSetBranchId, plid);
299            }
300    
301            public List<LayoutRevision> getLayoutRevisions(
302                            long layoutSetBranchId, long plid, int status)
303                    throws SystemException {
304    
305                    return layoutRevisionPersistence.findByL_P_S(
306                            layoutSetBranchId, plid, status);
307            }
308    
309            public List<LayoutRevision> getLayoutRevisions(
310                            long layoutSetBranchId, long layoutBranchId, long plid, int start,
311                            int end, OrderByComparator orderByComparator)
312                    throws SystemException {
313    
314                    return layoutRevisionPersistence.findByL_L_P(
315                            layoutSetBranchId, layoutBranchId, plid, start, end,
316                            orderByComparator);
317            }
318    
319            public int getLayoutRevisionsCount(
320                            long layoutSetBranchId, long layoutBranchId, long plid)
321                    throws SystemException {
322    
323                    return layoutRevisionPersistence.countByL_L_P(
324                            layoutSetBranchId, layoutBranchId, plid);
325            }
326    
327            public LayoutRevision updateLayoutRevision(
328                            long userId, long layoutRevisionId, long layoutBranchId,
329                            String name, String title, String description, String keywords,
330                            String robots, String typeSettings, boolean iconImage,
331                            long iconImageId, String themeId, String colorSchemeId,
332                            String wapThemeId, String wapColorSchemeId, String css,
333                            ServiceContext serviceContext)
334                    throws PortalException, SystemException {
335    
336                    // Layout revision
337    
338                    User user = userPersistence.findByPrimaryKey(userId);
339                    LayoutRevision oldLayoutRevision =
340                            layoutRevisionPersistence.findByPrimaryKey(layoutRevisionId);
341                    Date now = new Date();
342    
343                    LayoutRevision layoutRevision = null;
344    
345                    int workflowAction = serviceContext.getWorkflowAction();
346    
347                    boolean revisionInProgress = ParamUtil.getBoolean(
348                            serviceContext, "revisionInProgress");
349    
350                    if (!MergeLayoutPrototypesThreadLocal.isInProgress() &&
351                            (workflowAction != WorkflowConstants.ACTION_PUBLISH) &&
352                            (_layoutRevisionId.get() <= 0) && !revisionInProgress) {
353    
354                            long newLayoutRevisionId = counterLocalService.increment();
355    
356                            layoutRevision = layoutRevisionPersistence.create(
357                                    newLayoutRevisionId);
358    
359                            layoutRevision.setGroupId(oldLayoutRevision.getGroupId());
360                            layoutRevision.setCompanyId(oldLayoutRevision.getCompanyId());
361                            layoutRevision.setUserId(user.getUserId());
362                            layoutRevision.setUserName(user.getFullName());
363                            layoutRevision.setCreateDate(serviceContext.getCreateDate(now));
364                            layoutRevision.setModifiedDate(serviceContext.getModifiedDate(now));
365                            layoutRevision.setLayoutSetBranchId(
366                                    oldLayoutRevision.getLayoutSetBranchId());
367                            layoutRevision.setParentLayoutRevisionId(
368                                    oldLayoutRevision.getLayoutRevisionId());
369                            layoutRevision.setHead(false);
370                            layoutRevision.setLayoutBranchId(layoutBranchId);
371                            layoutRevision.setPlid(oldLayoutRevision.getPlid());
372                            layoutRevision.setPrivateLayout(
373                                    oldLayoutRevision.isPrivateLayout());
374                            layoutRevision.setName(name);
375                            layoutRevision.setTitle(title);
376                            layoutRevision.setDescription(description);
377                            layoutRevision.setKeywords(keywords);
378                            layoutRevision.setRobots(robots);
379                            layoutRevision.setTypeSettings(typeSettings);
380    
381                            if (iconImage) {
382                                    layoutRevision.setIconImage(iconImage);
383                                    layoutRevision.setIconImageId(iconImageId);
384                            }
385    
386                            layoutRevision.setThemeId(themeId);
387                            layoutRevision.setColorSchemeId(colorSchemeId);
388                            layoutRevision.setWapThemeId(wapThemeId);
389                            layoutRevision.setWapColorSchemeId(wapColorSchemeId);
390                            layoutRevision.setCss(css);
391                            layoutRevision.setStatus(WorkflowConstants.STATUS_DRAFT);
392                            layoutRevision.setStatusDate(serviceContext.getModifiedDate(now));
393    
394                            layoutRevisionPersistence.update(layoutRevision);
395    
396                            _layoutRevisionId.set(layoutRevision.getLayoutRevisionId());
397    
398                            // Portlet preferences
399    
400                            copyPortletPreferences(
401                                    layoutRevision, layoutRevision.getParentLayoutRevisionId(),
402                                    serviceContext);
403    
404                            StagingUtil.deleteRecentLayoutRevisionId(
405                                    user, layoutRevision.getLayoutSetBranchId(),
406                                    layoutRevision.getPlid());
407    
408                            StagingUtil.setRecentLayoutBranchId(
409                                    user, layoutRevision.getLayoutSetBranchId(),
410                                    layoutRevision.getPlid(), layoutRevision.getLayoutBranchId());
411                    }
412                    else {
413                            layoutRevision = oldLayoutRevision;
414    
415                            layoutRevision.setName(name);
416                            layoutRevision.setTitle(title);
417                            layoutRevision.setDescription(description);
418                            layoutRevision.setKeywords(keywords);
419                            layoutRevision.setRobots(robots);
420                            layoutRevision.setTypeSettings(typeSettings);
421    
422                            if (iconImage) {
423                                    layoutRevision.setIconImage(iconImage);
424                                    layoutRevision.setIconImageId(iconImageId);
425                            }
426    
427                            layoutRevision.setThemeId(themeId);
428                            layoutRevision.setColorSchemeId(colorSchemeId);
429                            layoutRevision.setWapThemeId(wapThemeId);
430                            layoutRevision.setWapColorSchemeId(wapColorSchemeId);
431                            layoutRevision.setCss(css);
432    
433                            layoutRevisionPersistence.update(layoutRevision);
434    
435                            _layoutRevisionId.set(layoutRevision.getLayoutRevisionId());
436                    }
437    
438                    boolean major = ParamUtil.getBoolean(serviceContext, "major");
439    
440                    if (major) {
441                            updateMajor(layoutRevision);
442                    }
443    
444                    // Workflow
445    
446                    WorkflowHandlerRegistryUtil.startWorkflowInstance(
447                            layoutRevision.getCompanyId(), layoutRevision.getGroupId(), userId,
448                            LayoutRevision.class.getName(),
449                            layoutRevision.getLayoutRevisionId(), layoutRevision,
450                            serviceContext);
451    
452                    return layoutRevision;
453            }
454    
455            public LayoutRevision updateStatus(
456                            long userId, long layoutRevisionId, int status,
457                            ServiceContext serviceContext)
458                    throws PortalException, SystemException {
459    
460                    User user = userPersistence.findByPrimaryKey(userId);
461    
462                    LayoutRevision layoutRevision =
463                            layoutRevisionPersistence.findByPrimaryKey(layoutRevisionId);
464    
465                    layoutRevision.setStatus(status);
466                    layoutRevision.setStatusByUserId(user.getUserId());
467                    layoutRevision.setStatusByUserName(user.getFullName());
468                    layoutRevision.setStatusDate(new Date());
469    
470                    if (status == WorkflowConstants.STATUS_APPROVED) {
471                            layoutRevision.setHead(true);
472    
473                            List<LayoutRevision> layoutRevisions =
474                                    layoutRevisionPersistence.findByL_P(
475                                            layoutRevision.getLayoutSetBranchId(),
476                                            layoutRevision.getPlid());
477    
478                            for (LayoutRevision curLayoutRevision : layoutRevisions) {
479                                    if (curLayoutRevision.getLayoutRevisionId() !=
480                                                    layoutRevision.getLayoutRevisionId()) {
481    
482                                            curLayoutRevision.setHead(false);
483    
484                                            layoutRevisionPersistence.update(curLayoutRevision);
485                                    }
486                            }
487                    }
488                    else {
489                            layoutRevision.setHead(false);
490    
491                            List<LayoutRevision> layoutRevisions =
492                                    layoutRevisionPersistence.findByL_P_S(
493                                            layoutRevision.getLayoutSetBranchId(),
494                                            layoutRevision.getPlid(),
495                                            WorkflowConstants.STATUS_APPROVED);
496    
497                            for (LayoutRevision curLayoutRevision : layoutRevisions) {
498                                    if (curLayoutRevision.getLayoutRevisionId() !=
499                                                    layoutRevision.getLayoutRevisionId()) {
500    
501                                            curLayoutRevision.setHead(true);
502    
503                                            layoutRevisionPersistence.update(curLayoutRevision);
504    
505                                            break;
506                                    }
507                            }
508                    }
509    
510                    layoutRevisionPersistence.update(layoutRevision);
511    
512                    return layoutRevision;
513            }
514    
515            protected void copyPortletPreferences(
516                            LayoutRevision layoutRevision, long parentLayoutRevisionId,
517                            ServiceContext serviceContext)
518                    throws SystemException {
519    
520                    List<PortletPreferences> portletPreferencesList =
521                            portletPreferencesLocalService.getPortletPreferencesByPlid(
522                                    parentLayoutRevisionId);
523    
524                    for (PortletPreferences portletPreferences : portletPreferencesList) {
525                            portletPreferencesLocalService.addPortletPreferences(
526                                    layoutRevision.getCompanyId(), portletPreferences.getOwnerId(),
527                                    portletPreferences.getOwnerType(),
528                                    layoutRevision.getLayoutRevisionId(),
529                                    portletPreferences.getPortletId(), null,
530                                    portletPreferences.getPreferences());
531                    }
532            }
533    
534            protected long getParentLayoutRevisionId(
535                            long layoutSetBranchId, long parentLayoutRevisionId, long plid)
536                    throws SystemException {
537    
538                    LayoutRevision parentLayoutRevision = null;
539    
540                    if (parentLayoutRevisionId > 0) {
541                            parentLayoutRevision = layoutRevisionPersistence.fetchByPrimaryKey(
542                                    parentLayoutRevisionId);
543    
544                            if (parentLayoutRevision == null) {
545                                    List<LayoutRevision> layoutRevisions =
546                                            layoutRevisionPersistence.findByL_P(
547                                                    layoutSetBranchId, plid, 0, 1);
548    
549                                    if (!layoutRevisions.isEmpty()) {
550                                            parentLayoutRevision = layoutRevisions.get(0);
551                                    }
552                            }
553                    }
554    
555                    if (parentLayoutRevision != null) {
556                            return parentLayoutRevision.getLayoutRevisionId();
557                    }
558    
559                    return LayoutRevisionConstants.DEFAULT_PARENT_LAYOUT_REVISION_ID;
560            }
561    
562            protected LayoutRevision updateMajor(LayoutRevision layoutRevision)
563                    throws PortalException, SystemException {
564    
565                    long parentLayoutRevisionId =
566                            layoutRevision.getParentLayoutRevisionId();
567    
568                    boolean fork = false;
569    
570                    while (parentLayoutRevisionId !=
571                                            LayoutRevisionConstants.DEFAULT_PARENT_LAYOUT_REVISION_ID) {
572    
573                            LayoutRevision parentLayoutRevision =
574                                    layoutRevisionPersistence.findByPrimaryKey(
575                                            parentLayoutRevisionId);
576    
577                            if (parentLayoutRevision.isMajor()) {
578                                    break;
579                            }
580    
581                            parentLayoutRevisionId =
582                                    parentLayoutRevision.getParentLayoutRevisionId();
583    
584                            if (parentLayoutRevision.getChildren().size() > 1) {
585                                    fork = true;
586                            }
587    
588                            if (!fork) {
589                                    layoutRevisionLocalService.deleteLayoutRevision(
590                                            parentLayoutRevision);
591                            }
592                    }
593    
594                    layoutRevision.setParentLayoutRevisionId(parentLayoutRevisionId);
595                    layoutRevision.setMajor(true);
596    
597                    layoutRevisionPersistence.update(layoutRevision);
598    
599                    return layoutRevision;
600            }
601    
602            private static ThreadLocal<Long> _layoutRevisionId =
603                    new AutoResetThreadLocal<Long>(
604                            LayoutRevisionLocalServiceImpl.class + "._layoutRevisionId", 0L);
605    
606    }