This project has retired. For details please refer to its Attic page.
InMemoryVersioningServiceImpl 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  package org.apache.chemistry.opencmis.inmemory.server;
20  
21  import java.util.ArrayList;
22  import java.util.List;
23  
24  import org.apache.chemistry.opencmis.commons.data.Acl;
25  import org.apache.chemistry.opencmis.commons.data.ContentStream;
26  import org.apache.chemistry.opencmis.commons.data.ExtensionsData;
27  import org.apache.chemistry.opencmis.commons.data.ObjectData;
28  import org.apache.chemistry.opencmis.commons.data.Properties;
29  import org.apache.chemistry.opencmis.commons.definitions.DocumentTypeDefinition;
30  import org.apache.chemistry.opencmis.commons.definitions.TypeDefinition;
31  import org.apache.chemistry.opencmis.commons.enums.BaseTypeId;
32  import org.apache.chemistry.opencmis.commons.enums.IncludeRelationships;
33  import org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentException;
34  import org.apache.chemistry.opencmis.commons.exceptions.CmisNotSupportedException;
35  import org.apache.chemistry.opencmis.commons.exceptions.CmisUpdateConflictException;
36  import org.apache.chemistry.opencmis.commons.impl.server.ObjectInfoImpl;
37  import org.apache.chemistry.opencmis.commons.server.CallContext;
38  import org.apache.chemistry.opencmis.commons.server.ObjectInfoHandler;
39  import org.apache.chemistry.opencmis.commons.spi.Holder;
40  import org.apache.chemistry.opencmis.inmemory.FilterParser;
41  import org.apache.chemistry.opencmis.inmemory.storedobj.api.Document;
42  import org.apache.chemistry.opencmis.inmemory.storedobj.api.DocumentVersion;
43  import org.apache.chemistry.opencmis.inmemory.storedobj.api.StoreManager;
44  import org.apache.chemistry.opencmis.inmemory.storedobj.api.StoredObject;
45  import org.apache.chemistry.opencmis.inmemory.storedobj.api.VersionedDocument;
46  import org.apache.chemistry.opencmis.inmemory.types.PropertyCreationHelper;
47  import org.apache.commons.logging.Log;
48  import org.apache.commons.logging.LogFactory;
49  
50  public class InMemoryVersioningServiceImpl extends InMemoryAbstractServiceImpl {
51  
52      private static final Log LOG = LogFactory.getLog(InMemoryVersioningServiceImpl.class.getName());
53  
54      final InMemoryObjectServiceImpl fObjectService; // real implementation of the
55      // service
56      final AtomLinkInfoProvider fAtomLinkProvider;
57  
58      public InMemoryVersioningServiceImpl(StoreManager storeManager, InMemoryObjectServiceImpl objectService) {
59          super(storeManager);
60          fObjectService = objectService;
61          fAtomLinkProvider = new AtomLinkInfoProvider(fStoreManager);
62      }
63  
64      public void cancelCheckOut(CallContext context, String repositoryId, String objectId, ExtensionsData extension) {
65  
66          StoredObject so = validator.cancelCheckOut(context, repositoryId, objectId, extension);
67  
68          String user = context.getUsername();
69          VersionedDocument verDoc = testHasProperCheckedOutStatus(so, user);
70  
71          verDoc.cancelCheckOut(user);
72          
73          // if this is the last version delete the document itself
74          if (verDoc.getAllVersions().size() == 0)
75              fStoreManager.getObjectStore(repositoryId).deleteObject(verDoc.getId(), true, user);
76      }
77  
78      public void checkIn(CallContext context, String repositoryId, Holder<String> objectId, Boolean major,
79              Properties properties, ContentStream contentStream, String checkinComment, List<String> policies,
80              Acl addAces, Acl removeAces, ExtensionsData extension, ObjectInfoHandler objectInfos) {
81  
82          StoredObject so = validator.checkIn(context, repositoryId, objectId, addAces, removeAces, extension);
83  
84          String user = context.getUsername();
85          VersionedDocument verDoc = testHasProperCheckedOutStatus(so, user);
86  
87          // check if the contentStream is a usable object or ignore it otherwise
88          // Note Bworser binding sets an empty object
89          if (contentStream != null && contentStream.getStream() == null)
90              contentStream = null;
91          
92          verDoc.checkIn(major, properties, contentStream, checkinComment, user);
93  
94          // To be able to provide all Atom links in the response we need
95          // additional information:
96          if (context.isObjectInfoRequired()) {
97              ObjectInfoImpl objectInfo = new ObjectInfoImpl();
98              fAtomLinkProvider.fillInformationForAtomLinks(repositoryId, so, objectInfo);
99              objectInfos.addObjectInfo(objectInfo);
100         }
101     }
102 
103     public void checkOut(CallContext context, String repositoryId, Holder<String> objectId,
104             ExtensionsData extension, Holder<Boolean> contentCopied, ObjectInfoHandler objectInfos) {
105 
106         StoredObject so = validator.checkOut(context, repositoryId, objectId, extension, contentCopied);
107 
108         TypeDefinition typeDef = getTypeDefinition(repositoryId, so);
109         if (!typeDef.getBaseTypeId().equals(BaseTypeId.CMIS_DOCUMENT)) {
110             throw new CmisNotSupportedException("Only documents can be checked-out.");
111         } else if (!((DocumentTypeDefinition) typeDef).isVersionable()) {
112             throw new CmisNotSupportedException("Object can't be checked-out, type is not versionable.");
113         }
114 
115         checkIsVersionableObject(so);
116 
117         VersionedDocument verDoc = getVersionedDocumentOfObjectId(so);
118 
119         ContentStream content = null;
120 
121         if (so instanceof DocumentVersion) {
122             // get document the version is contained in to c
123             content = ((DocumentVersion) so).getContent(0, -1);
124         } else {
125             content = ((VersionedDocument) so).getLatestVersion(false).getContent(0, -1);
126         }
127 
128         if (verDoc.isCheckedOut()) {
129             throw new CmisUpdateConflictException("Document " + objectId.getValue() + " is already checked out.");
130         }
131 
132         String user = context.getUsername();
133         checkHasUser(user);
134 
135         DocumentVersion pwc = verDoc.checkOut(content, user);
136         objectId.setValue(pwc.getId()); // return the id of the created pwc
137         if (null != contentCopied) // Note: always null in AtomPub binding
138             contentCopied.setValue(true);
139         
140         // To be able to provide all Atom links in the response we need
141         // additional information:
142         if (context.isObjectInfoRequired()) {
143             ObjectInfoImpl objectInfo = new ObjectInfoImpl();
144             fAtomLinkProvider.fillInformationForAtomLinks(repositoryId, pwc, objectInfo);
145             objectInfos.addObjectInfo(objectInfo);
146         }
147     }
148 
149     public List<ObjectData> getAllVersions(CallContext context, String repositoryId, String objectId, String versionSeriesId,
150             String filter, Boolean includeAllowableActions, ExtensionsData extension, ObjectInfoHandler objectInfos) {
151         
152         // Note that in AtomPub object id is null and versionSeriesId is set and in SOAP bindinf versionSeriesId is set
153         // and objectId is null
154         StoredObject so;
155         List<ObjectData> res = new ArrayList<ObjectData>();
156         if (null == versionSeriesId)
157             versionSeriesId = objectId;
158         if (null == versionSeriesId)
159             throw new CmisInvalidArgumentException("getAllVersions requires a version series id, but it was null.");
160         so = validator.getAllVersions(context, repositoryId, objectId, versionSeriesId, extension);
161 
162         if (null == objectId)
163             objectId = versionSeriesId;
164 
165         if (!(so instanceof VersionedDocument)) {
166             if (!(so instanceof DocumentVersion))
167                 throw new CmisInvalidArgumentException("getAllVersions requires an id of a versioned document.");
168             so = ((DocumentVersion)so).getParentDocument();
169         }
170 //        ObjectData objData = getObject(context, repositoryId, so.getId(), filter, includeAllowableActions,
171 //                IncludeRelationships.NONE,extension, objectInfos);
172 //        res.add(objData);
173 
174         VersionedDocument verDoc = (VersionedDocument) so;
175         res = new ArrayList<ObjectData>();
176         List<DocumentVersion> versions = verDoc.getAllVersions();
177         for (DocumentVersion version : versions) {
178             ObjectData objData = getObject(context, repositoryId, version.getId(), filter, includeAllowableActions,
179                     IncludeRelationships.NONE,extension, objectInfos);
180             res.add(objData);
181         }
182 
183         // reverse list of versions because spec expects latest version first
184         List<ObjectData> temp = new ArrayList<ObjectData>(res.size());
185         for (ObjectData ver : res)
186             temp.add(0, ver);
187         res = temp;
188 
189         // provide information for Atom links for version series:
190         if (context.isObjectInfoRequired()) {
191             ObjectInfoImpl objectInfo = new ObjectInfoImpl();
192             fAtomLinkProvider.fillInformationForAtomLinks(repositoryId, so, objectInfo);
193             objectInfos.addObjectInfo(objectInfo);
194         }
195 
196         return res;
197     }
198 
199     public ObjectData getObjectOfLatestVersion(CallContext context, String repositoryId, String objectId, String versionSeriesId,
200             Boolean major, String filter, Boolean includeAllowableActions, IncludeRelationships includeRelationships,
201             String renditionFilter, Boolean includePolicyIds, Boolean includeAcl, ExtensionsData extension,
202             ObjectInfoHandler objectInfos) {
203 
204         StoredObject so = validator.getObjectOfLatestVersion(context, repositoryId, objectId, versionSeriesId, extension);
205 
206         ObjectData objData = null;
207 
208         // In AtomPu8b you do not get the version series id, only the object id
209         if (so instanceof DocumentVersion) {
210             so = ((DocumentVersion)so).getParentDocument();
211         }
212         
213         if (so instanceof VersionedDocument) {
214             VersionedDocument verDoc = (VersionedDocument) so;
215             DocumentVersion latestVersion = verDoc.getLatestVersion(major);
216             objData = getObject(context, repositoryId, latestVersion.getId(), filter, includeAllowableActions,
217                     includeRelationships, extension, objectInfos);
218         } else if (so instanceof Document) {
219             objData = getObject(context, repositoryId, so.getId(), filter, includeAllowableActions,
220                     includeRelationships, extension, objectInfos);
221         } else {
222             throw new CmisInvalidArgumentException("Object is not instance of a document (version series)");
223         }
224 
225         // provide information for Atom links for version series:
226         if (context.isObjectInfoRequired()) {
227             ObjectInfoImpl objectInfo = new ObjectInfoImpl();
228             fAtomLinkProvider.fillInformationForAtomLinks(repositoryId, so, objectInfo);
229             objectInfos.addObjectInfo(objectInfo);
230         }
231 
232         return objData;
233     }
234 
235     public Properties getPropertiesOfLatestVersion(CallContext context, String repositoryId, String objectId, String versionSeriesId,
236             Boolean major, String filter, ExtensionsData extension) {
237 
238         StoredObject so = validator.getPropertiesOfLatestVersion(context, repositoryId, objectId, versionSeriesId, extension);
239 
240         StoredObject latestVersionObject = null;
241 
242         // In AtomPu8b you do not get the version series id, only the object id
243         if (so instanceof DocumentVersion) {
244             so = ((DocumentVersion)so).getParentDocument();
245         }
246 
247         if (so instanceof VersionedDocument) {
248             VersionedDocument verDoc = (VersionedDocument) so;
249             latestVersionObject = verDoc.getLatestVersion(major);
250         } else if (so instanceof Document) {
251             latestVersionObject = so;
252         } else {
253             throw new CmisInvalidArgumentException("Object is not instance of a document (version series)");
254         }
255 
256         List<String> requestedIds = FilterParser.getRequestedIdsFromFilter(filter);
257 
258         TypeDefinition td = fStoreManager.getTypeById(repositoryId, latestVersionObject.getTypeId()).getTypeDefinition();
259         Properties props = PropertyCreationHelper.getPropertiesFromObject(latestVersionObject, td,
260                 requestedIds, true);
261 
262         return props;
263     }
264 
265     private ObjectData getObject(CallContext context, String repositoryId, String objectId, String filter,
266             Boolean includeAllowableActions, IncludeRelationships includeRelationships, ExtensionsData extension,
267             ObjectInfoHandler objectInfos) {
268 
269         return fObjectService.getObject(context, repositoryId, objectId, filter, includeAllowableActions,
270                 includeRelationships, null, false, includeAllowableActions, extension, objectInfos);
271     }
272 }