This project has retired. For details please refer to its Attic page.
JcrVersionBase xref

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  
20  package org.apache.chemistry.opencmis.jcr;
21  
22  import org.apache.chemistry.opencmis.commons.data.ContentStream;
23  import org.apache.chemistry.opencmis.commons.data.Properties;
24  import org.apache.chemistry.opencmis.commons.enums.Action;
25  import org.apache.chemistry.opencmis.commons.exceptions.CmisConstraintException;
26  import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
27  import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;
28  import org.apache.chemistry.opencmis.commons.exceptions.CmisStorageException;
29  import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertiesImpl;
30  import org.apache.chemistry.opencmis.commons.impl.server.ObjectInfoImpl;
31  import org.apache.chemistry.opencmis.jcr.type.JcrTypeHandlerManager;
32  import org.apache.commons.logging.Log;
33  import org.apache.commons.logging.LogFactory;
34  
35  import javax.jcr.Node;
36  import javax.jcr.RepositoryException;
37  import javax.jcr.UnsupportedRepositoryOperationException;
38  import javax.jcr.version.Version;
39  import javax.jcr.version.VersionException;
40  import javax.jcr.version.VersionHistory;
41  import javax.jcr.version.VersionIterator;
42  import java.util.Iterator;
43  import java.util.Set;
44  
45  /**
46   * Instances of this class represent a versionable cmis:document and its versions backed by an underlying
47   * JCR <code>Node</code>. 
48   */
49  public abstract class JcrVersionBase extends JcrDocument {
50      private static final Log log = LogFactory.getLog(JcrVersionBase.class);
51  
52      protected JcrVersionBase(Node node, JcrTypeManager typeManager, PathManager pathManager, JcrTypeHandlerManager typeHandlerManager) {
53          super(node, typeManager, pathManager, typeHandlerManager);
54      }
55  
56      /**
57       * See CMIS 1.0 section 2.2.7.6 getAllVersions
58       */
59      public Iterator<JcrVersion> getVersions() {
60          try {
61              VersionHistory versionHistory = getVersionHistory(getNode());
62              final VersionIterator versions = versionHistory.getAllLinearVersions();
63  
64              return new Iterator<JcrVersion>() {
65                  public boolean hasNext() {
66                      return versions.hasNext();
67                  }
68  
69                  public JcrVersion next() {
70                      return new JcrVersion(getNode(), versions.nextVersion(), typeManager, pathManager, typeHandlerManager);
71                  }
72  
73                  public void remove() {
74                      throw new UnsupportedOperationException();
75                  }
76              };
77          }
78          catch (RepositoryException e) {
79              log.debug(e.getMessage(), e);
80              throw new CmisRuntimeException(e.getMessage(), e);
81          }
82      }
83      
84      @Override
85      public void delete(boolean allVersions, boolean isPwc) {
86          Node node = getNode();
87          try {
88              if (node.isCheckedOut()) {
89                  if (isPwc) {
90                      cancelCheckout(node);
91                  }
92                  else {
93                      throw new CmisStorageException("Cannot delete checked out document: " + getId());
94                  }
95              }
96              else if (allVersions) {
97                  checkout(node);
98                  node.remove();
99                  node.getSession().save();
100             }
101             else {
102                 throw new CmisRuntimeException("Cannot delete a single version");
103             }
104         }
105         catch (RepositoryException e) {
106             log.debug(e.getMessage(), e);
107             throw new CmisRuntimeException(e.getMessage(), e);
108         }
109     }
110 
111     /**
112      * See CMIS 1.0 section 2.2.7.1 checkOut
113      *
114      * @throws CmisRuntimeException
115      */
116     public JcrPrivateWorkingCopy checkout() {
117         Node node = getNode();
118         try {
119             if (node.isCheckedOut()) {
120                 throw new CmisConstraintException("Document is already checked out " + getId());
121             }
122 
123             checkout(node);
124             return getPwc();
125         }
126         catch (RepositoryException e) {
127             log.debug(e.getMessage(), e);
128             throw new CmisRuntimeException(e.getMessage(), e);
129         }
130     }
131 
132     /**
133      * See CMIS 1.0 section 2.2.7.3 checkedIn
134      *
135      * @throws CmisRuntimeException
136      */
137     public JcrVersion checkin(Properties properties, ContentStream contentStream, String checkinComment) {
138         Node node = getNode();
139 
140         try {
141             if (!node.isCheckedOut()) {
142                 throw new CmisStorageException("Not checked out: " + getId());
143             }
144 
145             if (properties != null && !properties.getPropertyList().isEmpty()) {
146                 updateProperties(properties);
147             }
148 
149             if (contentStream != null) {
150                 setContentStream(contentStream, true);
151             }
152 
153             // todo handle checkinComment
154             checkin(node);
155             return (JcrVersion) create(node);
156         }
157         catch (RepositoryException e) {
158             log.debug(e.getMessage(), e);
159             throw new CmisRuntimeException(e.getMessage(), e);
160         }
161     }
162 
163     /**
164      * See CMIS 1.0 section 2.2.7.2 cancelCheckout
165      *
166      * @throws CmisRuntimeException
167      */
168     public void cancelCheckout() {
169         Node node = getNode();
170         try {
171             cancelCheckout(node);
172         }
173         catch (RepositoryException e) {
174             log.debug(e.getMessage(), e);
175             throw new CmisRuntimeException(e.getMessage(), e);
176         }
177     }
178 
179     /**
180      * Get the private working copy of the versions series or throw an exception if not checked out.
181      *
182      * @return  a {@link JcrPrivateWorkingCopy} instance
183      * @throws CmisObjectNotFoundException  if not checked out
184      * @throws CmisRuntimeException
185      */
186     public JcrPrivateWorkingCopy getPwc() {
187         try {
188             Node node = getNode();
189             if (node.isCheckedOut()) {
190                 return new JcrPrivateWorkingCopy(getNode(), typeManager, pathManager, typeHandlerManager);
191             }
192             else {
193                 throw new CmisObjectNotFoundException("Not checked out document has no private working copy");
194             }
195         }
196         catch (RepositoryException e) {
197             log.debug(e.getMessage(), e);
198             throw new CmisRuntimeException(e.getMessage(), e);
199         }
200     }
201 
202     /**
203      * Get a specific version by name
204      * @param name  name of the version to get
205      * @return  a {@link JcrVersion} instance for <code>name</code>
206      * @throws CmisObjectNotFoundException  if a version <code>name</code> does not exist
207      * @throws CmisRuntimeException
208      */
209     public JcrVersion getVersion(String name) {
210         try {
211             Node node = getNode();
212             VersionHistory versionHistory = getVersionHistory(node);
213             Version version = versionHistory.getVersion(name);
214             return new JcrVersion(node, version, typeManager, pathManager, typeHandlerManager);
215         }
216         catch (UnsupportedRepositoryOperationException e) {
217             log.debug(e.getMessage(), e);
218             throw new CmisObjectNotFoundException(e.getMessage(), e);
219         }
220         catch (VersionException e) {
221             log.debug(e.getMessage(), e);
222             throw new CmisObjectNotFoundException(e.getMessage(), e);
223         }
224         catch (RepositoryException e) {
225             log.debug(e.getMessage(), e);
226             throw new CmisRuntimeException(e.getMessage(), e);
227         }
228     }
229 
230     //------------------------------------------< protected >---
231 
232     /**
233      * @return  Id of the version representing the base of this versions series
234      * @throws RepositoryException
235      */
236     protected String getBaseNodeId() throws RepositoryException {
237         Version baseVersion = getBaseVersion(getNode());
238         JcrNode baseNode = new JcrVersion(getNode(), baseVersion, typeManager, pathManager, typeHandlerManager);
239         return baseNode.getId();
240     }
241 
242     /**
243      * @return  Id of the private working copy of this version series
244      * @throws RepositoryException
245      */
246     protected String getPwcId() throws RepositoryException {
247         return null;
248     }
249     
250     @Override
251     protected void compileProperties(PropertiesImpl properties, Set<String> filter, ObjectInfoImpl objectInfo)
252             throws RepositoryException {
253 
254         super.compileProperties(properties, filter, objectInfo);
255 
256         objectInfo.setWorkingCopyOriginalId(getBaseNodeId());
257         objectInfo.setWorkingCopyId(getPwcId());
258     }
259 
260     @Override
261     protected Set<Action> compileAllowableActions(Set<Action> aas) {
262         Set<Action> result = super.compileAllowableActions(aas);
263         setAction(result, Action.CAN_GET_ALL_VERSIONS, true);
264         setAction(result, Action.CAN_CHECK_OUT, true);
265         setAction(result, Action.CAN_CANCEL_CHECK_OUT, true);
266         setAction(result, Action.CAN_CHECK_IN, true);
267         return result;
268     }
269     
270     @Override
271     protected String getTypeIdInternal() {
272         return JcrTypeManager.DOCUMENT_TYPE_ID;
273     }
274 
275     @Override
276     protected boolean isCheckedOut() throws RepositoryException {
277         return getNode().isCheckedOut();
278     }
279 
280     @Override
281     protected String getCheckedOutId() throws RepositoryException {
282         return isCheckedOut()
283                 ? getVersionSeriesId() + "/pwc"
284                 : null;
285     }
286 
287     @Override
288     protected String getCheckedOutBy() throws RepositoryException {
289         return isCheckedOut()
290                 ? getNode().getSession().getUserID()
291                 : null;
292     }
293     
294     //------------------------------------------< private >---
295 
296     private static void checkout(Node node) throws RepositoryException {
297         getVersionManager(node).checkout(node.getPath());
298     }
299 
300     private static void checkin(Node node) throws RepositoryException {
301         getVersionManager(node).checkin(node.getPath());
302     }
303 
304     private static void cancelCheckout(Node node) throws RepositoryException {
305         Version base = getBaseVersion(node);
306         getVersionManager(node).restore(base, true);
307     }
308     
309 }