View Javadoc

1   /**
2    * This file Copyright (c) 2011-2013 Magnolia International
3    * Ltd.  (http://www.magnolia-cms.com). All rights reserved.
4    *
5    *
6    * This file is dual-licensed under both the Magnolia
7    * Network Agreement and the GNU General Public License.
8    * You may elect to use one or the other of these licenses.
9    *
10   * This file is distributed in the hope that it will be
11   * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the
12   * implied warranty of MERCHANTABILITY or FITNESS FOR A
13   * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
14   * Redistribution, except as permitted by whichever of the GPL
15   * or MNA you select, is prohibited.
16   *
17   * 1. For the GPL license (GPL), you can redistribute and/or
18   * modify this file under the terms of the GNU General
19   * Public License, Version 3, as published by the Free Software
20   * Foundation.  You should have received a copy of the GNU
21   * General Public License, Version 3 along with this program;
22   * if not, write to the Free Software Foundation, Inc., 51
23   * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24   *
25   * 2. For the Magnolia Network Agreement (MNA), this file
26   * and the accompanying materials are made available under the
27   * terms of the MNA which accompanies this distribution, and
28   * is available at http://www.magnolia-cms.com/mna.html
29   *
30   * Any modifications to this file must keep this entire header
31   * intact.
32   *
33   */
34  package info.magnolia.jcr.util;
35  
36  import info.magnolia.cms.core.version.ContentVersion;
37  import info.magnolia.cms.core.version.VersionInfo;
38  import info.magnolia.cms.core.version.VersionManager;
39  import info.magnolia.cms.util.ContentUtil;
40  import info.magnolia.jcr.wrapper.JCRPropertiesFilteringNodeWrapper;
41  import info.magnolia.objectfactory.Components;
42  
43  import java.util.ArrayList;
44  import java.util.Collections;
45  import java.util.List;
46  
47  import javax.jcr.Node;
48  import javax.jcr.RepositoryException;
49  import javax.jcr.UnsupportedRepositoryOperationException;
50  import javax.jcr.version.Version;
51  import javax.jcr.version.VersionException;
52  import javax.jcr.version.VersionHistory;
53  import javax.jcr.version.VersionIterator;
54  
55  import org.apache.commons.lang.StringUtils;
56  import org.apache.jackrabbit.JcrConstants;
57  import org.slf4j.Logger;
58  import org.slf4j.LoggerFactory;
59  
60  /**
61   * Various utility methods useful for JCR-Versioning.
62   */
63  public class VersionUtil {
64  
65      private static final Logger log = LoggerFactory.getLogger(VersionUtil.class);
66  
67      /**
68       * Return the NodeType-name for the provided Node. It it's a JCPropertiesFilteringNodeWrapper the unwrapped node will be used for retrieving the property from.
69       * As it's about versioning, the frozen primary type if existing (else primary type) will be returned.
70       */
71      public static String getNodeTypeName(Node node) throws RepositoryException {
72          node = NodeUtil.deepUnwrap(node, JCRPropertiesFilteringNodeWrapper.class);
73  
74          if (node.hasProperty(JcrConstants.JCR_FROZENPRIMARYTYPE)) {
75              return node.getProperty(JcrConstants.JCR_FROZENPRIMARYTYPE).getString();
76          }
77          return node.getProperty(JcrConstants.JCR_PRIMARYTYPE).getString();
78      }
79  
80      /**
81       * Returns version history of a content as a List of {@link info.magnolia.cms.core.version.VersionInfo}s.
82       *
83       * @param node Node
84       * @return list of version info
85       * @see info.magnolia.cms.core.version.VersionInfo
86       */
87      public static List<VersionInfo> getVersionInfoList(Node node) {
88          List<VersionInfo> versionList = new ArrayList<VersionInfo>();
89          VersionManager versionManager = Components.getComponent(VersionManager.class);
90  
91          try {
92              VersionHistory versionHistory = versionManager.getVersionHistory(node);
93  
94              if (versionHistory != null) {
95                  VersionIterator versionIterator = versionHistory.getAllVersions();
96                  while (versionIterator.hasNext()) {
97                      final Version version = versionIterator.nextVersion();
98                      final String versionName = version.getName();
99  
100                     // We do not want to read the version user from system root node
101                     if (StringUtils.isNotBlank(versionName) && !StringUtils.equals(versionName, "jcr:rootVersion")) {
102                         final String versionComment = NodeTypes.Versionable.getComment(version.getFrozenNode());
103                         final ContentVersion contentVersion = new ContentVersion(version, ContentUtil.asContent(node));
104                         final String versionUser = contentVersion.getUserName();
105 
106                         versionList.add(new VersionInfo(versionName, version.getCreated().getTime(), versionUser, versionComment));
107                     }
108                 }
109             }
110         } catch (RepositoryException e) {
111             log.warn("Unable to get version history of node [{}].", new Object[] {node, e});
112         }
113 
114         Collections.reverse(versionList);
115 
116         return versionList;
117     }
118 
119     /**
120      * Returns the version object of a labelled version.
121      * @return version object or null if the requested version doesn't exist.
122      */
123     public static Version getVersion(Node node, String versionLabel) throws RepositoryException {
124         if (StringUtils.isEmpty(versionLabel)) {
125             return null;
126         }
127 
128         VersionManager versionManager = Components.getComponent(VersionManager.class);
129 
130         try {
131             VersionHistory versionHistory = versionManager.getVersionHistory(node);
132             if (versionHistory == null) {
133                 return null;
134             }
135             return versionHistory.getVersion(versionLabel);
136         } catch (VersionException e) {
137             log.warn("The version '{}' of the node '{}' doesn't exists.", new Object[] {versionLabel, node, e});
138             return null;
139         } catch (UnsupportedRepositoryOperationException e) {
140             return null;
141         }
142     }
143 
144     /**
145      * @return the label of the first predecessor version or null if no previous version exists.
146      */
147     public static String getPreviousVersionLabel(Node node, String versionLabel) throws RepositoryException {
148         if (node == null) {
149             return null;
150         }
151         Version previousVersion = getPreviousVersion(getVersion(node, versionLabel));
152         if (previousVersion != null){
153             return previousVersion.getName();
154         }
155         return null;
156     }
157 
158     /**
159      * Checks if a version label of a {@link Node} has a previous version.
160      */
161     public static boolean hasPreviousVersion(Node node, String versionLabel) {
162         Version previousVersion;
163         String previousVersionName;
164 
165         try {
166             previousVersion = getPreviousVersion(getVersion(node, versionLabel));
167             previousVersionName = previousVersion.getName();
168         } catch (RepositoryException e) {
169             return false;
170         }
171 
172         if (previousVersion != null && !StringUtils.equals(previousVersionName, "jcr:rootVersion")) {
173             return true;
174         }
175         return false;
176     }
177 
178     /**
179      * @return Latest version or null if not found.
180      */
181     public static Version getLatestVersion(Node node) throws RepositoryException {
182         VersionManager versionManager = Components.getComponent(VersionManager.class);
183         VersionIterator versionIterator = versionManager.getAllVersions(node);
184 
185         Version latest = null;
186         // Check.
187         if (versionIterator == null) {
188             return latest;
189         }
190         // Get last Version.
191         while (versionIterator.hasNext()) {
192             latest = versionIterator.nextVersion();
193         }
194         return latest;
195     }
196 
197     /**
198      * @return the first predecessor or null if no previous version exists.
199      */
200     public static Version getPreviousVersion(Version version) throws RepositoryException {
201         if (version == null) {
202             return null;
203         }
204         Version[] predecessors = version.getPredecessors();
205         if (predecessors.length > 0) {
206             return predecessors[0];
207         }
208         return null;
209     }
210 
211     /**
212      * @return the label of the next successor version or null if no next version exists.
213      */
214     public static String getNextVersionLabel(Node node, String versionLabel) throws RepositoryException {
215         if (node == null) {
216             return null;
217         }
218         Version nextVersion = getNextVersion(getVersion(node, versionLabel));
219         if (nextVersion != null){
220             return nextVersion.getName();
221         }
222         return null;
223     }
224 
225     /**
226      * @return the first successor or null if no next version exists.
227      */
228     public static Version getNextVersion(Version version) throws RepositoryException {
229         if (version == null) {
230             return null;
231         }
232         Version[] successors = version.getSuccessors();
233         if (successors.length > 0) {
234             return successors[0];
235         }
236         return null;
237     }
238 
239 }