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