View Javadoc

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.server.impl.atompub;
20  
21  import static org.apache.chemistry.opencmis.commons.impl.CollectionsHelper.isNullOrEmpty;
22  
23  import java.util.List;
24  
25  import javax.servlet.http.HttpServletRequest;
26  import javax.servlet.http.HttpServletResponse;
27  
28  import org.apache.chemistry.opencmis.commons.data.ObjectData;
29  import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;
30  import org.apache.chemistry.opencmis.commons.impl.Constants;
31  import org.apache.chemistry.opencmis.commons.impl.UrlBuilder;
32  import org.apache.chemistry.opencmis.commons.server.CallContext;
33  import org.apache.chemistry.opencmis.commons.server.CmisService;
34  import org.apache.chemistry.opencmis.commons.server.ObjectInfo;
35  import org.apache.chemistry.opencmis.commons.spi.Holder;
36  import org.apache.chemistry.opencmis.server.shared.TempStoreOutputStreamFactory;
37  
38  /**
39   * Versioning Service operations.
40   */
41  public class VersioningService {
42  
43      /**
44       * Check Out.
45       */
46      public static class CheckOut extends AbstractAtomPubServiceCall {
47          @Override
48          public void serve(CallContext context, CmisService service, String repositoryId, HttpServletRequest request,
49                  HttpServletResponse response) throws Exception {
50              assert context != null;
51              assert service != null;
52              assert repositoryId != null;
53              assert request != null;
54              assert response != null;
55  
56              // get parameters
57              TempStoreOutputStreamFactory streamFactory = (TempStoreOutputStreamFactory) context
58                      .get(CallContext.STREAM_FACTORY);
59              AtomEntryParser parser = new AtomEntryParser(streamFactory);
60              parser.setIgnoreAtomContentSrc(true); // needed for some clients
61              parser.parse(request.getInputStream());
62  
63              // execute
64              Holder<String> checkOutId = new Holder<String>(parser.getId());
65              try {
66                  if (stopBeforeService(service)) {
67                      return;
68                  }
69  
70                  service.checkOut(repositoryId, checkOutId, null, null);
71  
72                  if (stopAfterService(service)) {
73                      return;
74                  }
75              } finally {
76                  parser.release();
77              }
78  
79              ObjectInfo objectInfo = service.getObjectInfo(repositoryId, checkOutId.getValue());
80              if (objectInfo == null) {
81                  throw new CmisRuntimeException("Object Info is missing!");
82              }
83  
84              ObjectData object = objectInfo.getObject();
85              if (object == null) {
86                  throw new CmisRuntimeException("Object is null!");
87              }
88  
89              if (object.getId() == null) {
90                  throw new CmisRuntimeException("Object Id is null!");
91              }
92  
93              // set headers
94              UrlBuilder baseUrl = compileBaseUrl(request, repositoryId);
95              String location = compileUrl(baseUrl, RESOURCE_ENTRY, object.getId());
96  
97              response.setStatus(HttpServletResponse.SC_CREATED);
98              response.setContentType(Constants.MEDIATYPE_ENTRY);
99              response.setHeader("Content-Location", location);
100             response.setHeader("Location", location);
101 
102             // write XML
103             AtomEntry entry = new AtomEntry();
104             entry.startDocument(response.getOutputStream(), getNamespaces(service));
105             writeObjectEntry(service, entry, object, null, repositoryId, null, null, baseUrl, true,
106                     context.getCmisVersion());
107             entry.endDocument();
108         }
109     }
110 
111     /**
112      * Get all versions.
113      */
114     public static class GetAllVersions extends AbstractAtomPubServiceCall {
115         @Override
116         public void serve(CallContext context, CmisService service, String repositoryId, HttpServletRequest request,
117                 HttpServletResponse response) throws Exception {
118             assert context != null;
119             assert service != null;
120             assert repositoryId != null;
121             assert request != null;
122             assert response != null;
123 
124             // get parameters
125             String objectId = getStringParameter(request, Constants.PARAM_ID);
126             String versionSeriesId = getStringParameter(request, Constants.PARAM_VERSION_SERIES_ID);
127             String filter = getStringParameter(request, Constants.PARAM_FILTER);
128             Boolean includeAllowableActions = getBooleanParameter(request, Constants.PARAM_ALLOWABLE_ACTIONS);
129 
130             // execute
131             if (stopBeforeService(service)) {
132                 return;
133             }
134 
135             List<ObjectData> versions = service.getAllVersions(repositoryId, objectId, versionSeriesId, filter,
136                     includeAllowableActions, null);
137 
138             if (stopAfterService(service)) {
139                 return;
140             }
141 
142             if (isNullOrEmpty(versions)) {
143                 throw new CmisRuntimeException("Version list is null or empty!");
144             }
145 
146             // set headers
147             response.setStatus(HttpServletResponse.SC_OK);
148             response.setContentType(Constants.MEDIATYPE_FEED);
149 
150             // write XML
151             AtomFeed feed = new AtomFeed();
152             feed.startDocument(response.getOutputStream(), getNamespaces(service));
153             feed.startFeed(true);
154 
155             // write basic Atom feed elements
156             ObjectInfo latestObjectInfo = service.getObjectInfo(repositoryId, versions.get(0).getId());
157             ObjectInfo firstObjectInfo = service.getObjectInfo(repositoryId, versions.get(versions.size() - 1).getId());
158 
159             feed.writeFeedElements(versionSeriesId, null, firstObjectInfo.getCreatedBy(), latestObjectInfo.getName(),
160                     latestObjectInfo.getLastModificationDate(), null, null);
161 
162             // write links
163             UrlBuilder baseUrl = compileBaseUrl(request, repositoryId);
164 
165             feed.writeServiceLink(baseUrl.toString(), repositoryId);
166 
167             if (objectId != null) {
168                 feed.writeViaLink(compileUrl(baseUrl, RESOURCE_ENTRY, objectId));
169             }
170 
171             // write entries
172             AtomEntry entry = new AtomEntry(feed.getWriter());
173             for (ObjectData object : versions) {
174                 if (object == null) {
175                     continue;
176                 }
177                 writeObjectEntry(service, entry, object, null, repositoryId, null, null, baseUrl, false,
178                         context.getCmisVersion());
179             }
180 
181             // we are done
182             feed.endFeed();
183             feed.endDocument();
184         }
185     }
186 
187     /**
188      * Delete object.
189      */
190     public static class DeleteAllVersions extends AbstractAtomPubServiceCall {
191         @Override
192         public void serve(CallContext context, CmisService service, String repositoryId, HttpServletRequest request,
193                 HttpServletResponse response) throws Exception {
194             assert context != null;
195             assert service != null;
196             assert repositoryId != null;
197             assert request != null;
198             assert response != null;
199 
200             // get parameters
201             String objectId = getStringParameter(request, Constants.PARAM_ID);
202 
203             // execute
204             if (stopBeforeService(service)) {
205                 return;
206             }
207 
208             service.deleteObjectOrCancelCheckOut(repositoryId, objectId, Boolean.TRUE, null);
209 
210             if (stopAfterService(service)) {
211                 return;
212             }
213 
214             // set headers
215             response.setStatus(HttpServletResponse.SC_NO_CONTENT);
216         }
217     }
218 }