View Javadoc
1   /*
2    * Copyright (C) 2003-2013 eXo Platform SAS.
3    *
4    * This program is free software: you can redistribute it and/or modify
5    * it under the terms of the GNU Affero General Public License as published by
6    * the Free Software Foundation, either version 3 of the License, or
7    * (at your option) any later version.
8    *
9    * This program is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   * GNU Affero General Public License for more details.
13   *
14   * You should have received a copy of the GNU Affero General Public License
15   * along with this program. If not, see <http://www.gnu.org/licenses/>.
16   */
17  package org.exoplatform.services.wcm.extensions.deployment;
18  
19  import java.io.InputStream;
20  import java.util.Date;
21  import java.util.Iterator;
22  import java.util.Map;
23  
24  import javax.jcr.ImportUUIDBehavior;
25  import javax.jcr.Node;
26  import javax.jcr.NodeIterator;
27  import javax.jcr.Session;
28  
29  
30  import org.exoplatform.container.configuration.ConfigurationManager;
31  import org.exoplatform.container.xml.InitParams;
32  import org.exoplatform.container.xml.ObjectParameter;
33  import org.exoplatform.services.cms.documents.TrashService;
34  import org.exoplatform.services.deployment.DeploymentPlugin;
35  import org.exoplatform.services.deployment.Utils;
36  import org.exoplatform.services.deployment.DeploymentUtils;
37  import org.exoplatform.services.ecm.publication.NotInPublicationLifecycleException;
38  import org.exoplatform.services.ecm.publication.PublicationService;
39  import org.exoplatform.services.jcr.RepositoryService;
40  import org.exoplatform.services.jcr.core.ManageableRepository;
41  import org.exoplatform.services.jcr.ext.common.SessionProvider;
42  import org.exoplatform.services.log.ExoLogger;
43  import org.exoplatform.services.log.Log;
44  import org.exoplatform.services.wcm.publication.WCMPublicationService;
45  
46  /**
47   * Created by The eXo Platform SAS
48   * Author : eXoPlatform
49   *          tanhq@exoplatform.com
50   * Oct 3, 2013  
51   */
52  public class WCMPublicationDeploymentPlugin extends DeploymentPlugin{
53    
54    /** The configuration manager. */
55    private ConfigurationManager configurationManager;
56  
57    /** The repository service. */
58    private RepositoryService repositoryService;
59    
60    /** The publication service */
61    private PublicationService publicationService;
62    
63    /** The publication service */
64    private WCMPublicationService wcmPublicationService;
65    
66    private TrashService trashService;
67  
68    /** The log. */
69    private static final Log LOG = ExoLogger.getLogger(WCMPublicationDeploymentPlugin.class.getName());
70    
71    private static final String CLEAN_PUBLICATION             = "clean-publication";
72    private static final String PUBLISH_FIRST_PUBLICATION     = "publish-first-publication";
73    private static final String KEEP_PUBLICATION              = "keep-publication";
74    
75    /**
76     * Instantiates a new xML deployment plugin.
77     *
78     * @param initParams the init params
79     * @param configurationManager the configuration manager
80     * @param repositoryService the repository service
81     * @param publicationService the publication service
82     */
83    public WCMPublicationDeploymentPlugin(InitParams initParams,
84                               ConfigurationManager configurationManager,
85                               RepositoryService repositoryService,
86                               PublicationService publicationService,
87                               WCMPublicationService wcmPublicationService,
88                               TrashService trashService) {
89      super(initParams);
90      this.configurationManager = configurationManager;
91      this.repositoryService = repositoryService;
92      this.publicationService = publicationService;
93      this.wcmPublicationService = wcmPublicationService;
94      this.trashService = trashService;
95    }
96    
97    /*
98     * (non-Javadoc)
99     * @see
100    * org.exoplatform.services.deployment.DeploymentPlugin#deploy(org.exoplatform
101    * .services.jcr.ext.common.SessionProvider)
102    */
103   public void deploy(SessionProvider sessionProvider) throws Exception {
104     ManageableRepository repository = repositoryService.getCurrentRepository();
105     Iterator iterator = initParams.getObjectParamIterator();
106     WCMPublicationDeploymentDescriptor deploymentDescriptor = null;
107     while (iterator.hasNext()) {
108       try {
109         ObjectParameter objectParameter = (ObjectParameter) iterator.next();
110         deploymentDescriptor = (WCMPublicationDeploymentDescriptor) objectParameter.getObject();
111         String sourcePath = deploymentDescriptor.getSourcePath();
112         // sourcePath should start with: war:/, jar:/, classpath:/, file:/
113         String versionHistoryPath = deploymentDescriptor.getVersionHistoryPath();
114         String cleanupPublicationType = deploymentDescriptor.getCleanupPublicationType();
115 
116         InputStream inputStream = configurationManager.getInputStream(sourcePath);
117         Session session = sessionProvider.getSession(deploymentDescriptor.getTarget().getWorkspace(), repository);       
118         
119         String nodeName = DeploymentUtils.getNodeName(configurationManager.getInputStream(sourcePath));
120         //remove old resources
121         if (this.isOverride()) {
122           Node parent = (Node)session.getItem(deploymentDescriptor.getTarget().getNodePath());
123           if (parent.hasNode(nodeName)) {
124             trashService.moveToTrash(parent.getNode(nodeName), sessionProvider);
125           }
126         }
127         
128         session.importXML(deploymentDescriptor.getTarget().getNodePath(),
129                           inputStream,
130                           ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW);
131         if (CLEAN_PUBLICATION.equalsIgnoreCase(cleanupPublicationType) || 
132             PUBLISH_FIRST_PUBLICATION.equalsIgnoreCase(cleanupPublicationType)) {
133           /**
134            * This code allows to cleanup the publication lifecycle and publish the first version in the target
135            * folder after importing the data. By using this, the publication
136            * live revision property will be re-initialized and the content will
137            * be set as published directly. Thus, the content will be visible in
138            * front side.
139            */    
140           
141           Node parent = (Node)session.getItem(deploymentDescriptor.getTarget().getNodePath() + "/" + nodeName);
142           cleanPublication(parent, cleanupPublicationType, true);
143         } else if (versionHistoryPath != null && versionHistoryPath.length() > 0) {
144           // process import version history
145           Node currentNode = (Node) session.getItem(deploymentDescriptor.getTarget().getNodePath());
146 
147           Map<String, String> mapHistoryValue =
148             Utils.getMapImportHistory(configurationManager.getInputStream(versionHistoryPath));
149           Utils.processImportHistory(currentNode,
150                                      configurationManager.getInputStream(versionHistoryPath),
151                                      mapHistoryValue);
152         }
153         session.save();
154       } catch (Exception ex) {
155         if (LOG.isErrorEnabled()) {
156           LOG.error("deploy " + deploymentDescriptor.getSourcePath() + " into "
157                       + deploymentDescriptor.getTarget().getNodePath() + " is FAILURE at "
158                       + new Date().toString() + "\n",
159                   ex);
160         }      
161       }
162     }
163     if (LOG.isInfoEnabled()) {
164       LOG.info(deploymentDescriptor.getSourcePath() + " is deployed succesfully into "
165           + deploymentDescriptor.getTarget().getNodePath());
166     }
167   }
168   
169   /**
170    * This method implement cleaning publication based on cleanPublicationType. The cleanPublicationType can accept one of 
171      three values as following:
172      -  clean-publication: This code allows to cleanup the publication lifecycle.
173      -  keep-publication : This option allows to keep all current publications 
174      -  publish-first-publication: This option allows to cleanup the publication lifecycle and publish the first version in the 
175         target folder
176    * @param cleanupPublicationType the type of cleaning publication
177    * @throws Exception 
178    * @throws NotInPublicationLifecycleException 
179    */
180   private void cleanPublication(Node node, String cleanupPublicationType, boolean updateLifecycle) throws NotInPublicationLifecycleException, Exception  {
181     if (node.hasProperty("publication:liveRevision")
182         && node.hasProperty("publication:currentState")) {
183       if (LOG.isInfoEnabled()) {
184         LOG.info("\"" + node.getName() + "\" publication lifecycle has been cleaned up");
185       }
186       node.setProperty("publication:liveRevision", (javax.jcr.Value) null);
187       node.setProperty("publication:currentState", "published");
188     }
189     node.getSession().save();
190     if(updateLifecycle && PUBLISH_FIRST_PUBLICATION.equalsIgnoreCase(cleanupPublicationType) && 
191         org.exoplatform.services.cms.impl.Utils.isDocument(node)) {
192       if(publicationService.isNodeEnrolledInLifecycle(node)) publicationService.unsubcribeLifecycle(node);
193       wcmPublicationService.updateLifecyleOnChangeContent(node, "default", "__system", "published");
194       node.save();
195     }
196     NodeIterator iter = node.getNodes(); 
197     while (iter.hasNext()) {
198       Node childNode = iter.nextNode();
199       cleanPublication(childNode, cleanupPublicationType, false);
200     }
201   }  
202   
203 }