001    /**
002     * Copyright (c) 2000-2011 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.StagingUtil;
022    import com.liferay.portal.kernel.util.AutoResetThreadLocal;
023    import com.liferay.portal.kernel.util.OrderByComparator;
024    import com.liferay.portal.kernel.util.ParamUtil;
025    import com.liferay.portal.kernel.workflow.WorkflowConstants;
026    import com.liferay.portal.kernel.workflow.WorkflowHandlerRegistryUtil;
027    import com.liferay.portal.model.LayoutRevision;
028    import com.liferay.portal.model.LayoutRevisionConstants;
029    import com.liferay.portal.model.LayoutSetBranch;
030    import com.liferay.portal.model.PortletPreferences;
031    import com.liferay.portal.model.User;
032    import com.liferay.portal.service.ServiceContext;
033    import com.liferay.portal.service.base.LayoutRevisionLocalServiceBaseImpl;
034    import com.liferay.portal.util.comparator.LayoutRevisionCreateDateComparator;
035    
036    import java.util.Date;
037    import java.util.List;
038    
039    /**
040     * @author Raymond Augé
041     * @author Brian Wing Shun Chan
042     */
043    public class LayoutRevisionLocalServiceImpl
044            extends LayoutRevisionLocalServiceBaseImpl {
045    
046            public LayoutRevision addLayoutRevision(
047                            long userId, long layoutSetBranchId, long layoutBranchId,
048                            long parentLayoutRevisionId, boolean head, long plid,
049                            boolean privateLayout, String name, String title,
050                            String description, String keywords, String robots,
051                            String typeSettings, boolean iconImage, long iconImageId,
052                            String themeId, String colorSchemeId, String wapThemeId,
053                            String wapColorSchemeId, String css, ServiceContext serviceContext)
054                    throws PortalException, SystemException {
055    
056                    // Layout revision
057    
058                    User user = userPersistence.findByPrimaryKey(userId);
059                    LayoutSetBranch layoutSetBranch =
060                            layoutSetBranchPersistence.findByPrimaryKey(layoutSetBranchId);
061                    parentLayoutRevisionId = getParentLayoutRevisionId(
062                            layoutSetBranchId, parentLayoutRevisionId, plid);
063                    Date now = new Date();
064    
065                    long layoutRevisionId = counterLocalService.increment();
066    
067                    LayoutRevision layoutRevision = layoutRevisionPersistence.create(
068                            layoutRevisionId);
069    
070                    layoutRevision.setGroupId(layoutSetBranch.getGroupId());
071                    layoutRevision.setCompanyId(user.getCompanyId());
072                    layoutRevision.setUserId(user.getUserId());
073                    layoutRevision.setUserName(user.getFullName());
074                    layoutRevision.setCreateDate(serviceContext.getCreateDate(now));
075                    layoutRevision.setModifiedDate(serviceContext.getModifiedDate(now));
076                    layoutRevision.setLayoutSetBranchId(layoutSetBranchId);
077                    layoutRevision.setLayoutBranchId(layoutBranchId);
078                    layoutRevision.setParentLayoutRevisionId(parentLayoutRevisionId);
079                    layoutRevision.setHead(head);
080    
081                    long mergeLayoutRevisionId = ParamUtil.getLong(
082                            serviceContext, "mergeLayoutRevisionId");
083    
084                    if (mergeLayoutRevisionId > 0) {
085                            layoutRevision.setMajor(true);
086                    }
087    
088                    layoutRevision.setPlid(plid);
089                    layoutRevision.setPrivateLayout(privateLayout);
090                    layoutRevision.setName(name);
091                    layoutRevision.setTitle(title);
092                    layoutRevision.setDescription(description);
093                    layoutRevision.setKeywords(keywords);
094                    layoutRevision.setRobots(robots);
095                    layoutRevision.setTypeSettings(typeSettings);
096    
097                    if (iconImage) {
098                            layoutRevision.setIconImage(iconImage);
099                            layoutRevision.setIconImageId(iconImageId);
100                    }
101    
102                    layoutRevision.setThemeId(themeId);
103                    layoutRevision.setColorSchemeId(colorSchemeId);
104                    layoutRevision.setWapThemeId(wapThemeId);
105                    layoutRevision.setWapColorSchemeId(wapColorSchemeId);
106                    layoutRevision.setCss(css);
107                    layoutRevision.setStatus(WorkflowConstants.STATUS_DRAFT);
108                    layoutRevision.setStatusDate(serviceContext.getModifiedDate(now));
109    
110                    layoutRevisionPersistence.update(layoutRevision, false);
111    
112                    // Portlet preferences
113    
114                    if (parentLayoutRevisionId ==
115                                    LayoutRevisionConstants.DEFAULT_PARENT_LAYOUT_REVISION_ID) {
116    
117                            parentLayoutRevisionId = layoutRevision.getPlid();
118                    }
119    
120                    long sourceParentLayoutRevisionId = parentLayoutRevisionId;
121    
122                    if (mergeLayoutRevisionId > 0) {
123                            sourceParentLayoutRevisionId = mergeLayoutRevisionId;
124                    }
125    
126                    copyPortletPreferences(
127                            layoutRevision, sourceParentLayoutRevisionId, serviceContext);
128    
129                    // Workflow
130    
131                    WorkflowHandlerRegistryUtil.startWorkflowInstance(
132                            user.getCompanyId(), layoutRevision.getGroupId(), user.getUserId(),
133                            LayoutRevision.class.getName(),
134                            layoutRevision.getLayoutRevisionId(), layoutRevision,
135                            serviceContext);
136    
137                    return layoutRevision;
138            }
139    
140            public void deleteLayoutLayoutRevisions(long plid)
141                    throws PortalException, SystemException {
142    
143                    for (LayoutRevision layoutRevision : getLayoutRevisions(plid)) {
144                            layoutRevisionLocalService.deleteLayoutRevision(layoutRevision);
145                    }
146            }
147    
148            @Override
149            public void deleteLayoutRevision(LayoutRevision layoutRevision)
150                    throws PortalException, SystemException {
151    
152                    if (layoutRevision.hasChildren()) {
153                            for (LayoutRevision curLayoutRevision :
154                                            layoutRevision.getChildren()) {
155    
156                                    curLayoutRevision.setParentLayoutRevisionId(
157                                            layoutRevision.getParentLayoutRevisionId());
158    
159                                    layoutRevisionPersistence.update(curLayoutRevision, false);
160                            }
161                    }
162    
163                    List<PortletPreferences> portletPreferencesList =
164                            portletPreferencesLocalService.getPortletPreferencesByPlid(
165                                    layoutRevision.getLayoutRevisionId());
166    
167                    for (PortletPreferences portletPreferences : portletPreferencesList) {
168                            try {
169                                    portletPreferencesLocalService.deletePortletPreferences(
170                                            portletPreferences.getPortletPreferencesId());
171                            }
172                            catch (NoSuchPortletPreferencesException nsppe) {
173                            }
174                    }
175    
176                    layoutRevisionPersistence.remove(layoutRevision);
177            }
178    
179            @Override
180            public void deleteLayoutRevision(long layoutRevisionId)
181                    throws PortalException, SystemException {
182    
183                    LayoutRevision layoutRevision =
184                            layoutRevisionPersistence.findByPrimaryKey(layoutRevisionId);
185    
186                    layoutRevisionLocalService.deleteLayoutRevision(layoutRevision);
187            }
188    
189            public void deleteLayoutRevisions(long layoutSetBranchId, long plid)
190                    throws PortalException, SystemException {
191    
192                    for (LayoutRevision layoutRevision : getLayoutRevisions(
193                                    layoutSetBranchId, plid)) {
194    
195                            layoutRevisionLocalService.deleteLayoutRevision(layoutRevision);
196                    }
197            }
198    
199            public void deleteLayoutRevisions(
200                            long layoutSetBranchId, long layoutBranchId, long plid)
201                    throws PortalException, SystemException {
202    
203                    List<LayoutRevision> layoutRevisions =
204                            layoutRevisionPersistence.findByL_L_P(
205                                    layoutSetBranchId, layoutBranchId, plid);
206    
207                    for (LayoutRevision layoutRevision : layoutRevisions) {
208                            layoutRevisionLocalService.deleteLayoutRevision(layoutRevision);
209                    }
210            }
211    
212            public void deleteLayoutSetBranchLayoutRevisions(long layoutSetBranchId)
213                    throws PortalException, SystemException {
214    
215                    List<LayoutRevision> layoutRevisions =
216                            layoutRevisionPersistence.findByLayoutSetBranchId(
217                                    layoutSetBranchId);
218    
219                    for (LayoutRevision layoutRevision : layoutRevisions) {
220                            layoutRevisionLocalService.deleteLayoutRevision(layoutRevision);
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,
318                            int start, 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 ((workflowAction != WorkflowConstants.ACTION_PUBLISH) &&
355                            (_layoutRevisionId.get() <= 0)) {
356    
357                            long newLayoutRevisionId = counterLocalService.increment();
358    
359                            layoutRevision = layoutRevisionPersistence.create(
360                                    newLayoutRevisionId);
361    
362                            layoutRevision.setGroupId(oldLayoutRevision.getGroupId());
363                            layoutRevision.setCompanyId(oldLayoutRevision.getCompanyId());
364                            layoutRevision.setUserId(user.getUserId());
365                            layoutRevision.setUserName(user.getFullName());
366                            layoutRevision.setCreateDate(serviceContext.getCreateDate(now));
367                            layoutRevision.setModifiedDate(serviceContext.getModifiedDate(now));
368                            layoutRevision.setLayoutSetBranchId(
369                                    oldLayoutRevision.getLayoutSetBranchId());
370                            layoutRevision.setParentLayoutRevisionId(
371                                    oldLayoutRevision.getLayoutRevisionId());
372                            layoutRevision.setHead(false);
373                            layoutRevision.setLayoutBranchId(layoutBranchId);
374                            layoutRevision.setPlid(oldLayoutRevision.getPlid());
375                            layoutRevision.setPrivateLayout(
376                                    oldLayoutRevision.isPrivateLayout());
377                            layoutRevision.setName(name);
378                            layoutRevision.setTitle(title);
379                            layoutRevision.setDescription(description);
380                            layoutRevision.setKeywords(keywords);
381                            layoutRevision.setRobots(robots);
382                            layoutRevision.setTypeSettings(typeSettings);
383    
384                            if (iconImage) {
385                                    layoutRevision.setIconImage(iconImage);
386                                    layoutRevision.setIconImageId(iconImageId);
387                            }
388    
389                            layoutRevision.setThemeId(themeId);
390                            layoutRevision.setColorSchemeId(colorSchemeId);
391                            layoutRevision.setWapThemeId(wapThemeId);
392                            layoutRevision.setWapColorSchemeId(wapColorSchemeId);
393                            layoutRevision.setCss(css);
394                            layoutRevision.setStatus(WorkflowConstants.STATUS_DRAFT);
395                            layoutRevision.setStatusDate(serviceContext.getModifiedDate(now));
396    
397                            layoutRevisionPersistence.update(layoutRevision, false);
398    
399                            _layoutRevisionId.set(layoutRevision.getLayoutRevisionId());
400    
401                            // Portlet preferences
402    
403                            copyPortletPreferences(
404                                    layoutRevision, layoutRevision.getParentLayoutRevisionId(),
405                                    serviceContext);
406    
407                            StagingUtil.deleteRecentLayoutRevisionId(
408                                    user, layoutRevision.getLayoutSetBranchId(),
409                                    layoutRevision.getPlid());
410    
411                            StagingUtil.setRecentLayoutBranchId(
412                                    user, layoutRevision.getLayoutSetBranchId(),
413                                    layoutRevision.getPlid(), layoutRevision.getLayoutBranchId());
414                    }
415                    else {
416                            layoutRevision = oldLayoutRevision;
417                    }
418    
419                    boolean major = ParamUtil.getBoolean(serviceContext, "major");
420    
421                    if (major) {
422                            updateMajor(layoutRevision);
423                    }
424    
425                    // Workflow
426    
427                    WorkflowHandlerRegistryUtil.startWorkflowInstance(
428                            layoutRevision.getCompanyId(), layoutRevision.getGroupId(),
429                            userId, LayoutRevision.class.getName(),
430                            layoutRevision.getLayoutRevisionId(), layoutRevision,
431                            serviceContext);
432    
433                    return layoutRevision;
434            }
435    
436            public LayoutRevision updateStatus(
437                            long userId, long layoutRevisionId, int status,
438                            ServiceContext serviceContext)
439                    throws PortalException, SystemException {
440    
441                    User user = userPersistence.findByPrimaryKey(userId);
442    
443                    LayoutRevision layoutRevision =
444                            layoutRevisionPersistence.findByPrimaryKey(layoutRevisionId);
445    
446                    layoutRevision.setStatus(status);
447                    layoutRevision.setStatusByUserId(user.getUserId());
448                    layoutRevision.setStatusByUserName(user.getFullName());
449                    layoutRevision.setStatusDate(new Date());
450    
451                    if (status == WorkflowConstants.STATUS_APPROVED) {
452                            layoutRevision.setHead(true);
453    
454                            List<LayoutRevision> layoutRevisions =
455                                    layoutRevisionPersistence.findByL_P(
456                                            layoutRevision.getLayoutSetBranchId(),
457                                            layoutRevision.getPlid());
458    
459                            for (LayoutRevision curLayoutRevision : layoutRevisions) {
460                                    if (curLayoutRevision.getLayoutRevisionId() !=
461                                                    layoutRevision.getLayoutRevisionId()) {
462    
463                                            curLayoutRevision.setHead(false);
464    
465                                            layoutRevisionPersistence.update(curLayoutRevision, false);
466                                    }
467                            }
468                    }
469                    else {
470                            layoutRevision.setHead(false);
471    
472                            List<LayoutRevision> layoutRevisions =
473                                    layoutRevisionPersistence.findByL_P_S(
474                                            layoutRevision.getLayoutSetBranchId(),
475                                            layoutRevision.getPlid(),
476                                            WorkflowConstants.STATUS_APPROVED);
477    
478                            for (LayoutRevision curLayoutRevision : layoutRevisions) {
479                                    if (curLayoutRevision.getLayoutRevisionId() !=
480                                                    layoutRevision.getLayoutRevisionId()) {
481    
482                                            curLayoutRevision.setHead(true);
483    
484                                            layoutRevisionPersistence.update(curLayoutRevision, false);
485    
486                                            break;
487                                    }
488                            }
489                    }
490    
491                    layoutRevisionPersistence.update(layoutRevision, false);
492    
493                    return layoutRevision;
494            }
495    
496            protected void copyPortletPreferences(
497                            LayoutRevision layoutRevision, long parentLayoutRevisionId,
498                            ServiceContext serviceContext)
499                    throws SystemException {
500    
501                    List<PortletPreferences> portletPreferencesList =
502                            portletPreferencesLocalService.getPortletPreferencesByPlid(
503                                    parentLayoutRevisionId);
504    
505                    for (PortletPreferences portletPreferences : portletPreferencesList) {
506                            portletPreferencesLocalService.addPortletPreferences(
507                                    layoutRevision.getCompanyId(), portletPreferences.getOwnerId(),
508                                    portletPreferences.getOwnerType(),
509                                    layoutRevision.getLayoutRevisionId(),
510                                    portletPreferences.getPortletId(), null,
511                                    portletPreferences.getPreferences());
512                    }
513            }
514    
515            protected long getParentLayoutRevisionId(
516                            long layoutSetBranchId, long parentLayoutRevisionId, long plid)
517                    throws SystemException {
518    
519                    LayoutRevision parentLayoutRevision = null;
520    
521                    if (parentLayoutRevisionId > 0) {
522                            parentLayoutRevision = layoutRevisionPersistence.fetchByPrimaryKey(
523                                    parentLayoutRevisionId);
524    
525                            if (parentLayoutRevision == null) {
526                                    List<LayoutRevision> layoutRevisions =
527                                            layoutRevisionPersistence.findByL_P(
528                                                    layoutSetBranchId, plid, 0, 1);
529    
530                                    if (!layoutRevisions.isEmpty()) {
531                                            parentLayoutRevision = layoutRevisions.get(0);
532                                    }
533                            }
534                    }
535    
536                    if (parentLayoutRevision != null) {
537                            return parentLayoutRevision.getLayoutRevisionId();
538                    }
539    
540                    return LayoutRevisionConstants.DEFAULT_PARENT_LAYOUT_REVISION_ID;
541            }
542    
543            protected LayoutRevision updateMajor(LayoutRevision layoutRevision)
544                    throws PortalException, SystemException {
545    
546                    long parentLayoutRevisionId =
547                            layoutRevision.getParentLayoutRevisionId();
548    
549                    boolean fork = false;
550    
551                    while (parentLayoutRevisionId !=
552                                            LayoutRevisionConstants.DEFAULT_PARENT_LAYOUT_REVISION_ID) {
553    
554                            LayoutRevision parentLayoutRevision =
555                                    layoutRevisionPersistence.findByPrimaryKey(
556                                            parentLayoutRevisionId);
557    
558                            if (parentLayoutRevision.isMajor()) {
559                                    break;
560                            }
561    
562                            parentLayoutRevisionId =
563                                    parentLayoutRevision.getParentLayoutRevisionId();
564    
565                            if (parentLayoutRevision.getChildren().size() > 1) {
566                                    fork = true;
567                            }
568    
569                            if (!fork) {
570                                    layoutRevisionLocalService.deleteLayoutRevision(
571                                            parentLayoutRevision);
572                            }
573                    }
574    
575                    layoutRevision.setParentLayoutRevisionId(parentLayoutRevisionId);
576                    layoutRevision.setMajor(true);
577    
578                    layoutRevisionPersistence.update(layoutRevision, false);
579    
580                    return layoutRevision;
581            }
582    
583            private static ThreadLocal<Long> _layoutRevisionId =
584                    new AutoResetThreadLocal<Long>(
585                            LayoutRevisionLocalServiceImpl.class + "._layoutRevisionId", 0L);
586    
587    }