This project has retired. For details please refer to its Attic page.
RepositoryService 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.server.impl.atompub;
20  
21  import static org.apache.chemistry.opencmis.server.impl.atompub.AtomPubUtils.PAGE_SIZE;
22  import static org.apache.chemistry.opencmis.server.impl.atompub.AtomPubUtils.RESOURCE_CHANGES;
23  import static org.apache.chemistry.opencmis.server.impl.atompub.AtomPubUtils.RESOURCE_CHECKEDOUT;
24  import static org.apache.chemistry.opencmis.server.impl.atompub.AtomPubUtils.RESOURCE_CHILDREN;
25  import static org.apache.chemistry.opencmis.server.impl.atompub.AtomPubUtils.RESOURCE_DESCENDANTS;
26  import static org.apache.chemistry.opencmis.server.impl.atompub.AtomPubUtils.RESOURCE_FOLDERTREE;
27  import static org.apache.chemistry.opencmis.server.impl.atompub.AtomPubUtils.RESOURCE_OBJECTBYID;
28  import static org.apache.chemistry.opencmis.server.impl.atompub.AtomPubUtils.RESOURCE_OBJECTBYPATH;
29  import static org.apache.chemistry.opencmis.server.impl.atompub.AtomPubUtils.RESOURCE_QUERY;
30  import static org.apache.chemistry.opencmis.server.impl.atompub.AtomPubUtils.RESOURCE_TYPE;
31  import static org.apache.chemistry.opencmis.server.impl.atompub.AtomPubUtils.RESOURCE_TYPES;
32  import static org.apache.chemistry.opencmis.server.impl.atompub.AtomPubUtils.RESOURCE_TYPESDESC;
33  import static org.apache.chemistry.opencmis.server.impl.atompub.AtomPubUtils.RESOURCE_UNFILED;
34  import static org.apache.chemistry.opencmis.server.impl.atompub.AtomPubUtils.TYPE_AUTHOR;
35  import static org.apache.chemistry.opencmis.server.impl.atompub.AtomPubUtils.compileBaseUrl;
36  import static org.apache.chemistry.opencmis.server.impl.atompub.AtomPubUtils.compileUrl;
37  import static org.apache.chemistry.opencmis.server.impl.atompub.AtomPubUtils.compileUrlBuilder;
38  import static org.apache.chemistry.opencmis.server.impl.atompub.AtomPubUtils.writeTypeEntry;
39  import static org.apache.chemistry.opencmis.server.shared.HttpUtils.getBigIntegerParameter;
40  import static org.apache.chemistry.opencmis.server.shared.HttpUtils.getBooleanParameter;
41  import static org.apache.chemistry.opencmis.server.shared.HttpUtils.getStringParameter;
42  
43  import java.math.BigInteger;
44  import java.util.Collections;
45  import java.util.GregorianCalendar;
46  import java.util.List;
47  
48  import javax.servlet.http.HttpServletRequest;
49  import javax.servlet.http.HttpServletResponse;
50  
51  import org.apache.chemistry.opencmis.commons.data.RepositoryCapabilities;
52  import org.apache.chemistry.opencmis.commons.data.RepositoryInfo;
53  import org.apache.chemistry.opencmis.commons.definitions.TypeDefinition;
54  import org.apache.chemistry.opencmis.commons.definitions.TypeDefinitionContainer;
55  import org.apache.chemistry.opencmis.commons.definitions.TypeDefinitionList;
56  import org.apache.chemistry.opencmis.commons.enums.CapabilityChanges;
57  import org.apache.chemistry.opencmis.commons.enums.CapabilityQuery;
58  import org.apache.chemistry.opencmis.commons.impl.Constants;
59  import org.apache.chemistry.opencmis.commons.impl.UrlBuilder;
60  import org.apache.chemistry.opencmis.commons.server.CallContext;
61  import org.apache.chemistry.opencmis.commons.server.CmisService;
62  import org.apache.chemistry.opencmis.server.impl.CallContextImpl;
63  
64  /**
65   * Repository Service operations.
66   */
67  public final class RepositoryService {
68  
69      /**
70       * Private constructor.
71       */
72      private RepositoryService() {
73      }
74  
75      /**
76       * Renders the service document.
77       */
78      public static void getRepositories(CallContext context, CmisService service, HttpServletRequest request,
79              HttpServletResponse response) throws Exception {
80          // get parameters
81          String repositoryId = getStringParameter(request, Constants.PARAM_REPOSITORY_ID);
82  
83          // execute
84          List<RepositoryInfo> infoDataList = null;
85  
86          if (repositoryId == null) {
87              infoDataList = service.getRepositoryInfos(null);
88          } else {
89              infoDataList = Collections.singletonList(service.getRepositoryInfo(repositoryId, null));
90              if (context instanceof CallContextImpl) {
91                  ((CallContextImpl) context).put(CallContext.REPOSITORY_ID, repositoryId);
92              }
93          }
94  
95          // set headers
96          response.setStatus(HttpServletResponse.SC_OK);
97          response.setContentType(Constants.MEDIATYPE_SERVICE);
98  
99          // write XML
100         ServiceDocument serviceDoc = new ServiceDocument();
101 
102         serviceDoc.startDocument(response.getOutputStream());
103         serviceDoc.startServiceDocument();
104 
105         if (infoDataList != null) {
106             for (RepositoryInfo infoData : infoDataList) {
107                 if (infoData == null) {
108                     continue;
109                 }
110 
111                 String repId = infoData.getId();
112                 UrlBuilder baseUrl = compileBaseUrl(request, repId);
113 
114                 boolean supportsQuery = false;
115                 boolean supportsUnFiling = false;
116                 boolean supportsMultifiling = false;
117                 boolean supportsFolderTree = false;
118                 boolean supportsRootDescendants = false;
119                 boolean supportsChanges = false;
120 
121                 if (infoData.getCapabilities() != null) {
122                     RepositoryCapabilities cap = infoData.getCapabilities();
123 
124                     if (cap.getQueryCapability() != null) {
125                         supportsQuery = (cap.getQueryCapability() != CapabilityQuery.NONE);
126                     }
127 
128                     if (cap.isUnfilingSupported() != null) {
129                         supportsUnFiling = cap.isUnfilingSupported();
130                     }
131 
132                     if (cap.isMultifilingSupported() != null) {
133                         supportsMultifiling = cap.isMultifilingSupported();
134                     }
135 
136                     if (cap.isGetFolderTreeSupported() != null) {
137                         supportsFolderTree = cap.isGetFolderTreeSupported();
138                     }
139 
140                     if (cap.isGetDescendantsSupported() != null) {
141                         supportsRootDescendants = cap.isGetDescendantsSupported();
142                     }
143 
144                     if (cap.getChangesCapability() != null) {
145                         supportsChanges = (cap.getChangesCapability() != CapabilityChanges.NONE);
146                     }
147                 }
148 
149                 serviceDoc.startWorkspace(infoData.getId());
150 
151                 // add collections
152 
153                 // - root collection
154                 serviceDoc.writeCollection(compileUrl(baseUrl, RESOURCE_CHILDREN, infoData.getRootFolderId()),
155                         Constants.COLLECTION_ROOT, "Root Collection", Constants.MEDIATYPE_ENTRY,
156                         Constants.MEDIATYPE_CMISATOM);
157 
158                 // - types collection
159                 serviceDoc.writeCollection(compileUrl(baseUrl, RESOURCE_TYPES, null), Constants.COLLECTION_TYPES,
160                         "Types Collection", "");
161 
162                 // - query collection
163                 if (supportsQuery) {
164                     serviceDoc.writeCollection(compileUrl(baseUrl, RESOURCE_QUERY, null), Constants.COLLECTION_QUERY,
165                             "Query Collection", Constants.MEDIATYPE_QUERY);
166                 }
167 
168                 // - checked out collection collection
169                 serviceDoc.writeCollection(compileUrl(baseUrl, RESOURCE_CHECKEDOUT, null),
170                         Constants.COLLECTION_CHECKEDOUT, "Checked Out Collection", Constants.MEDIATYPE_CMISATOM);
171 
172                 // - unfiled collection collection
173                 if (supportsUnFiling || supportsMultifiling) {
174                     serviceDoc.writeCollection(compileUrl(baseUrl, RESOURCE_UNFILED, null),
175                             Constants.COLLECTION_UNFILED, "Unfiled Collection", Constants.MEDIATYPE_CMISATOM);
176 
177                 }
178 
179                 // add repository info
180                 serviceDoc.writeRepositoryInfo(infoData);
181 
182                 // add links
183 
184                 // - types descendants
185                 serviceDoc.writeLink(Constants.REP_REL_TYPEDESC, compileUrl(baseUrl, RESOURCE_TYPESDESC, null),
186                         Constants.MEDIATYPE_FEED, null);
187 
188                 // - folder tree
189                 if (supportsFolderTree) {
190                     serviceDoc.writeLink(Constants.REP_REL_FOLDERTREE,
191                             compileUrl(baseUrl, RESOURCE_FOLDERTREE, infoData.getRootFolderId()),
192                             Constants.MEDIATYPE_DESCENDANTS, null);
193                 }
194 
195                 // - root descendants
196                 if (supportsRootDescendants) {
197                     serviceDoc.writeLink(Constants.REP_REL_ROOTDESC,
198                             compileUrl(baseUrl, RESOURCE_DESCENDANTS, infoData.getRootFolderId()),
199                             Constants.MEDIATYPE_DESCENDANTS, infoData.getRootFolderId());
200                 }
201 
202                 // - changes
203                 if (supportsChanges) {
204                     serviceDoc.writeLink(Constants.REP_REL_CHANGES, compileUrl(baseUrl, RESOURCE_CHANGES, null),
205                             Constants.MEDIATYPE_FEED, null);
206                 }
207 
208                 // add URI templates
209 
210                 // - object by id
211                 String url = compileUrl(baseUrl, RESOURCE_OBJECTBYID, null)
212                         + "?id={id}&filter={filter}&includeAllowableActions={includeAllowableActions}&includeACL={includeACL}&includePolicyIds={includePolicyIds}&includeRelationships={includeRelationships}&renditionFilter={renditionFilter}";
213                 serviceDoc.writeUriTemplate(url, Constants.TEMPLATE_OBJECT_BY_ID, Constants.MEDIATYPE_ENTRY);
214 
215                 // - object by path
216                 url = compileUrl(baseUrl, RESOURCE_OBJECTBYPATH, null)
217                         + "?path={path}&filter={filter}&includeAllowableActions={includeAllowableActions}&includeACL={includeACL}&includePolicyIds={includePolicyIds}&includeRelationships={includeRelationships}&renditionFilter={renditionFilter}";
218                 serviceDoc.writeUriTemplate(url, Constants.TEMPLATE_OBJECT_BY_PATH, Constants.MEDIATYPE_ENTRY);
219 
220                 // - type by id
221                 url = compileUrl(baseUrl, RESOURCE_TYPE, null) + "?id={id}";
222                 serviceDoc.writeUriTemplate(url, Constants.TEMPLATE_TYPE_BY_ID, Constants.MEDIATYPE_ENTRY);
223 
224                 // - query
225                 if (supportsQuery) {
226                     url = compileUrl(baseUrl, RESOURCE_QUERY, null)
227                             + "?q={q}&searchAllVersions={searchAllVersions}&includeAllowableActions={includeAllowableActions}&includeRelationships={includeRelationships}&maxItems={maxItems}&skipCount={skipCount}";
228                     serviceDoc.writeUriTemplate(url, Constants.TEMPLATE_QUERY, Constants.MEDIATYPE_FEED);
229                 }
230 
231                 serviceDoc.endWorkspace();
232             }
233         }
234 
235         serviceDoc.endServiceDocument();
236         serviceDoc.endDocument();
237     }
238 
239     /**
240      * Renders a type children collection.
241      */
242     public static void getTypeChildren(CallContext context, CmisService service, String repositoryId,
243             HttpServletRequest request, HttpServletResponse response) throws Exception {
244         // get parameters
245         String typeId = getStringParameter(request, Constants.PARAM_TYPE_ID);
246         boolean includePropertyDefinitions = getBooleanParameter(request, Constants.PARAM_PROPERTY_DEFINITIONS, false);
247         BigInteger maxItems = getBigIntegerParameter(request, Constants.PARAM_MAX_ITEMS);
248         BigInteger skipCount = getBigIntegerParameter(request, Constants.PARAM_SKIP_COUNT);
249 
250         // execute
251         TypeDefinitionList typeList = service.getTypeChildren(repositoryId, typeId, includePropertyDefinitions,
252                 maxItems, skipCount, null);
253 
254         BigInteger numItems = (typeList == null ? null : typeList.getNumItems());
255         Boolean hasMoreItems = (typeList == null ? null : typeList.hasMoreItems());
256 
257         String parentTypeId = null;
258         String typeName = "Type Children";
259 
260         // in order to get the parent type, we need the type definition of this
261         // type as well
262         if (typeId != null) {
263             TypeDefinition typeDefinition = service.getTypeDefinition(repositoryId, typeId, null);
264 
265             parentTypeId = (typeDefinition == null ? null : typeDefinition.getParentTypeId());
266             typeName = (typeDefinition == null ? typeId : typeDefinition.getDisplayName());
267         }
268 
269         // write XML
270         response.setStatus(HttpServletResponse.SC_OK);
271         response.setContentType(Constants.MEDIATYPE_FEED);
272 
273         AtomFeed feed = new AtomFeed();
274         feed.startDocument(response.getOutputStream());
275         feed.startFeed(true);
276 
277         // write basic Atom feed elements
278         feed.writeFeedElements(typeId, TYPE_AUTHOR, typeName, new GregorianCalendar(), null, numItems);
279 
280         // write links
281         UrlBuilder baseUrl = compileBaseUrl(request, repositoryId);
282 
283         feed.writeServiceLink(baseUrl.toString(), repositoryId);
284 
285         UrlBuilder selfLink = compileUrlBuilder(baseUrl, RESOURCE_TYPES, null);
286         selfLink.addParameter(Constants.PARAM_TYPE_ID, typeId);
287         selfLink.addParameter(Constants.PARAM_PROPERTY_DEFINITIONS, includePropertyDefinitions);
288         feed.writeSelfLink(selfLink.toString(), typeId);
289 
290         feed.writeViaLink(compileUrl(baseUrl, RESOURCE_TYPE, typeId));
291 
292         UrlBuilder downLink = compileUrlBuilder(baseUrl, RESOURCE_TYPESDESC, null);
293         downLink.addParameter(Constants.PARAM_TYPE_ID, typeId);
294         feed.writeDownLink(downLink.toString(), Constants.MEDIATYPE_DESCENDANTS);
295 
296         if (parentTypeId != null) {
297             feed.writeUpLink(compileUrl(baseUrl, RESOURCE_TYPE, parentTypeId), Constants.MEDIATYPE_ENTRY);
298         }
299 
300         // write paging links
301         UrlBuilder pagingUrl = compileUrlBuilder(baseUrl, RESOURCE_TYPES, null);
302         pagingUrl.addParameter(Constants.PARAM_TYPE_ID, typeId);
303         pagingUrl.addParameter(Constants.PARAM_PROPERTY_DEFINITIONS, includePropertyDefinitions);
304         feed.writePagingLinks(pagingUrl, maxItems, skipCount, numItems, hasMoreItems, PAGE_SIZE);
305 
306         // write collection
307         UrlBuilder collectionUrl = compileUrlBuilder(baseUrl, RESOURCE_TYPES, null);
308         collectionUrl.addParameter(Constants.PARAM_TYPE_ID, typeId);
309         feed.writeCollection(collectionUrl.toString(), null, "Types Collection", "");
310 
311         // write type entries
312         if ((typeList != null) && (typeList.getList() != null)) {
313             AtomEntry entry = new AtomEntry(feed.getWriter());
314             for (TypeDefinition type : typeList.getList()) {
315                 writeTypeEntry(entry, type, null, repositoryId, baseUrl, false);
316             }
317         }
318 
319         // we are done
320         feed.endFeed();
321         feed.endDocument();
322     }
323 
324     /**
325      * Renders a type descendants feed.
326      */
327     public static void getTypeDescendants(CallContext context, CmisService service, String repositoryId,
328             HttpServletRequest request, HttpServletResponse response) throws Exception {
329         // get parameters
330         String typeId = getStringParameter(request, Constants.PARAM_TYPE_ID);
331         BigInteger depth = getBigIntegerParameter(request, Constants.PARAM_DEPTH);
332         boolean includePropertyDefinitions = getBooleanParameter(request, Constants.PARAM_PROPERTY_DEFINITIONS, false);
333 
334         // execute
335         List<TypeDefinitionContainer> typeTree = service.getTypeDescendants(repositoryId, typeId, depth,
336                 includePropertyDefinitions, null);
337 
338         String parentTypeId = null;
339         String typeName = "Type Children";
340 
341         // in order to get the parent type, we need the type definition of this
342         // type as well
343         if (typeId != null) {
344             TypeDefinition typeDefinition = service.getTypeDefinition(repositoryId, typeId, null);
345 
346             parentTypeId = (typeDefinition == null ? null : typeDefinition.getParentTypeId());
347             typeName = (typeDefinition == null ? typeId : typeDefinition.getDisplayName());
348         }
349 
350         // write XML
351         response.setStatus(HttpServletResponse.SC_OK);
352         response.setContentType(Constants.MEDIATYPE_FEED);
353 
354         AtomFeed feed = new AtomFeed();
355         feed.startDocument(response.getOutputStream());
356         feed.startFeed(true);
357 
358         // write basic Atom feed elements
359         feed.writeFeedElements(typeId, TYPE_AUTHOR, typeName, new GregorianCalendar(), null, null);
360 
361         // write links
362         UrlBuilder baseUrl = compileBaseUrl(request, repositoryId);
363 
364         feed.writeServiceLink(baseUrl.toString(), repositoryId);
365 
366         UrlBuilder selfLink = compileUrlBuilder(baseUrl, RESOURCE_TYPESDESC, null);
367         selfLink.addParameter(Constants.PARAM_TYPE_ID, typeId);
368         selfLink.addParameter(Constants.PARAM_DEPTH, depth);
369         selfLink.addParameter(Constants.PARAM_PROPERTY_DEFINITIONS, includePropertyDefinitions);
370         feed.writeSelfLink(selfLink.toString(), typeId);
371 
372         feed.writeViaLink(compileUrl(baseUrl, RESOURCE_TYPE, typeId));
373 
374         UrlBuilder downLink = compileUrlBuilder(baseUrl, RESOURCE_TYPES, null);
375         downLink.addParameter(Constants.PARAM_TYPE_ID, typeId);
376         feed.writeDownLink(downLink.toString(), Constants.MEDIATYPE_FEED);
377 
378         if (parentTypeId != null) {
379             feed.writeUpLink(compileUrl(baseUrl, RESOURCE_TYPE, parentTypeId), Constants.MEDIATYPE_ENTRY);
380         }
381 
382         // write tree
383         if (typeTree != null) {
384             AtomEntry entry = new AtomEntry(feed.getWriter());
385 
386             for (TypeDefinitionContainer container : typeTree) {
387                 if ((container != null) && (container.getTypeDefinition() != null)) {
388                     writeTypeEntry(entry, container.getTypeDefinition(), container.getChildren(), repositoryId,
389                             baseUrl, false);
390                 }
391             }
392         }
393 
394         // we are done
395         feed.endFeed();
396         feed.endDocument();
397     }
398 
399     /**
400      * Renders a type definition.
401      */
402     public static void getTypeDefinition(CallContext context, CmisService service, String repositoryId,
403             HttpServletRequest request, HttpServletResponse response) throws Exception {
404         // get parameters
405         String typeId = getStringParameter(request, Constants.PARAM_ID);
406 
407         // execute
408         TypeDefinition type = service.getTypeDefinition(repositoryId, typeId, null);
409 
410         // write XML
411         response.setStatus(HttpServletResponse.SC_OK);
412         response.setContentType(Constants.MEDIATYPE_ENTRY);
413 
414         AtomEntry entry = new AtomEntry();
415         entry.startDocument(response.getOutputStream());
416         writeTypeEntry(entry, type, null, repositoryId, compileBaseUrl(request, repositoryId), true);
417         entry.endDocument();
418     }
419 }