1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package fr.paris.lutece.plugins.document.modules.cmis.service;
35
36 import org.apache.chemistry.opencmis.commons.PropertyIds;
37 import org.apache.chemistry.opencmis.commons.definitions.PropertyDefinition;
38 import org.apache.chemistry.opencmis.commons.definitions.TypeDefinition;
39 import org.apache.chemistry.opencmis.commons.definitions.TypeDefinitionContainer;
40 import org.apache.chemistry.opencmis.commons.definitions.TypeDefinitionList;
41 import org.apache.chemistry.opencmis.commons.enums.*;
42 import org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentException;
43 import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
44 import org.apache.chemistry.opencmis.commons.impl.dataobjects.*;
45 import org.apache.chemistry.opencmis.commons.server.CallContext;
46
47 import java.math.BigInteger;
48
49 import java.util.ArrayList;
50 import java.util.HashMap;
51 import java.util.List;
52 import java.util.Map;
53
54
55
56
57
58 public class TypeManager
59 {
60
61
62
63 public static final String DOCUMENT_TYPE_ID = BaseTypeId.CMIS_DOCUMENT.value( );
64
65
66
67
68 public static final String FOLDER_TYPE_ID = BaseTypeId.CMIS_FOLDER.value( );
69
70
71
72
73 public static final String RELATIONSHIP_TYPE_ID = BaseTypeId.CMIS_RELATIONSHIP.value( );
74
75
76
77
78 public static final String POLICY_TYPE_ID = BaseTypeId.CMIS_POLICY.value( );
79 private static final String NAMESPACE = "http://opencmis.org/fileshare";
80 private Map<String, TypeDefinitionContainerImpl> types;
81 private List<TypeDefinitionContainer> typesList;
82
83
84
85
86 public TypeManager( )
87 {
88 setup( );
89 }
90
91
92
93
94 private void setup( )
95 {
96 types = new HashMap<String, TypeDefinitionContainerImpl>( );
97 typesList = new ArrayList<TypeDefinitionContainer>( );
98
99
100 FolderTypeDefinitionImpl folderType = new FolderTypeDefinitionImpl( );
101 folderType.setBaseTypeId( BaseTypeId.CMIS_FOLDER );
102 folderType.setIsControllableAcl( false );
103 folderType.setIsControllablePolicy( false );
104 folderType.setIsCreatable( true );
105 folderType.setDescription( "Folder" );
106 folderType.setDisplayName( "Folder" );
107 folderType.setIsFileable( true );
108 folderType.setIsFulltextIndexed( false );
109 folderType.setIsIncludedInSupertypeQuery( true );
110 folderType.setLocalName( "Folder" );
111 folderType.setLocalNamespace( NAMESPACE );
112 folderType.setIsQueryable( false );
113 folderType.setQueryName( "cmis:folder" );
114 folderType.setId( FOLDER_TYPE_ID );
115
116 addBasePropertyDefinitions( folderType );
117 addFolderPropertyDefinitions( folderType );
118
119 addTypeInteral( folderType );
120
121
122 DocumentTypeDefinitionImpl documentType = new DocumentTypeDefinitionImpl( );
123 documentType.setBaseTypeId( BaseTypeId.CMIS_DOCUMENT );
124 documentType.setIsControllableAcl( false );
125 documentType.setIsControllablePolicy( false );
126 documentType.setIsCreatable( true );
127 documentType.setDescription( "Document" );
128 documentType.setDisplayName( "Document" );
129 documentType.setIsFileable( true );
130 documentType.setIsFulltextIndexed( false );
131 documentType.setIsIncludedInSupertypeQuery( true );
132 documentType.setLocalName( "Document" );
133 documentType.setLocalNamespace( NAMESPACE );
134 documentType.setIsQueryable( false );
135 documentType.setQueryName( "cmis:document" );
136 documentType.setId( DOCUMENT_TYPE_ID );
137
138 documentType.setIsVersionable( false );
139 documentType.setContentStreamAllowed( ContentStreamAllowed.ALLOWED );
140
141 addBasePropertyDefinitions( documentType );
142 addDocumentPropertyDefinitions( documentType );
143
144 addTypeInteral( documentType );
145
146
147 RelationshipTypeDefinitionImpl relationshipType = new RelationshipTypeDefinitionImpl( );
148 relationshipType.setBaseTypeId( BaseTypeId.CMIS_RELATIONSHIP );
149 relationshipType.setIsControllableAcl( false );
150 relationshipType.setIsControllablePolicy( false );
151 relationshipType.setIsCreatable( false );
152 relationshipType.setDescription( "Relationship" );
153 relationshipType.setDisplayName( "Relationship" );
154 relationshipType.setIsFileable( false );
155 relationshipType.setIsIncludedInSupertypeQuery( true );
156 relationshipType.setLocalName( "Relationship" );
157 relationshipType.setLocalNamespace( NAMESPACE );
158 relationshipType.setIsQueryable( false );
159 relationshipType.setQueryName( "cmis:relationship" );
160 relationshipType.setId( RELATIONSHIP_TYPE_ID );
161
162 addBasePropertyDefinitions( relationshipType );
163
164
165
166
167
168 PolicyTypeDefinitionImpl policyType = new PolicyTypeDefinitionImpl( );
169 policyType.setBaseTypeId( BaseTypeId.CMIS_POLICY );
170 policyType.setIsControllableAcl( false );
171 policyType.setIsControllablePolicy( false );
172 policyType.setIsCreatable( false );
173 policyType.setDescription( "Policy" );
174 policyType.setDisplayName( "Policy" );
175 policyType.setIsFileable( false );
176 policyType.setIsIncludedInSupertypeQuery( true );
177 policyType.setLocalName( "Policy" );
178 policyType.setLocalNamespace( NAMESPACE );
179 policyType.setIsQueryable( false );
180 policyType.setQueryName( "cmis:policy" );
181 policyType.setId( POLICY_TYPE_ID );
182
183 addBasePropertyDefinitions( policyType );
184
185
186
187 }
188
189 private static void addBasePropertyDefinitions( AbstractTypeDefinition type )
190 {
191 type.addPropertyDefinition( createPropDef( PropertyIds.BASE_TYPE_ID, "Base Type Id", "Base Type Id",
192 PropertyType.ID, Cardinality.SINGLE, Updatability.READONLY, false, false ) );
193
194 type.addPropertyDefinition( createPropDef( PropertyIds.OBJECT_ID, "Object Id", "Object Id", PropertyType.ID,
195 Cardinality.SINGLE, Updatability.READONLY, false, false ) );
196
197 type.addPropertyDefinition( createPropDef( PropertyIds.OBJECT_TYPE_ID, "Type Id", "Type Id", PropertyType.ID,
198 Cardinality.SINGLE, Updatability.ONCREATE, false, true ) );
199
200 type.addPropertyDefinition( createPropDef( PropertyIds.NAME, "Name", "Name", PropertyType.STRING,
201 Cardinality.SINGLE, Updatability.READWRITE, false, true ) );
202
203 type.addPropertyDefinition( createPropDef( PropertyIds.CREATED_BY, "Created By", "Created By",
204 PropertyType.STRING, Cardinality.SINGLE, Updatability.READONLY, false, false ) );
205
206 type.addPropertyDefinition( createPropDef( PropertyIds.CREATION_DATE, "Creation Date", "Creation Date",
207 PropertyType.DATETIME, Cardinality.SINGLE, Updatability.READONLY, false, false ) );
208
209 type.addPropertyDefinition( createPropDef( PropertyIds.LAST_MODIFIED_BY, "Last Modified By",
210 "Last Modified By", PropertyType.STRING, Cardinality.SINGLE, Updatability.READONLY, false, false ) );
211
212 type.addPropertyDefinition( createPropDef( PropertyIds.LAST_MODIFICATION_DATE, "Last Modification Date",
213 "Last Modification Date", PropertyType.DATETIME, Cardinality.SINGLE, Updatability.READONLY, false, false ) );
214
215 type.addPropertyDefinition( createPropDef( PropertyIds.CHANGE_TOKEN, "Change Token", "Change Token",
216 PropertyType.STRING, Cardinality.SINGLE, Updatability.READONLY, false, false ) );
217 }
218
219 private static void addFolderPropertyDefinitions( FolderTypeDefinitionImpl type )
220 {
221 type.addPropertyDefinition( createPropDef( PropertyIds.PARENT_ID, "Parent Id", "Parent Id", PropertyType.ID,
222 Cardinality.SINGLE, Updatability.READONLY, false, false ) );
223
224 type.addPropertyDefinition( createPropDef( PropertyIds.ALLOWED_CHILD_OBJECT_TYPE_IDS,
225 "Allowed Child Object Type Ids", "Allowed Child Object Type Ids", PropertyType.ID, Cardinality.MULTI,
226 Updatability.READONLY, false, false ) );
227
228 type.addPropertyDefinition( createPropDef( PropertyIds.PATH, "Path", "Path", PropertyType.STRING,
229 Cardinality.SINGLE, Updatability.READONLY, false, false ) );
230 }
231
232 private static void addDocumentPropertyDefinitions( DocumentTypeDefinitionImpl type )
233 {
234 type.addPropertyDefinition( createPropDef( PropertyIds.IS_IMMUTABLE, "Is Immutable", "Is Immutable",
235 PropertyType.BOOLEAN, Cardinality.SINGLE, Updatability.READONLY, false, false ) );
236
237 type.addPropertyDefinition( createPropDef( PropertyIds.IS_LATEST_VERSION, "Is Latest Version",
238 "Is Latest Version", PropertyType.BOOLEAN, Cardinality.SINGLE, Updatability.READONLY, false, false ) );
239
240 type.addPropertyDefinition( createPropDef( PropertyIds.IS_MAJOR_VERSION, "Is Major Version",
241 "Is Major Version", PropertyType.BOOLEAN, Cardinality.SINGLE, Updatability.READONLY, false, false ) );
242
243 type.addPropertyDefinition( createPropDef( PropertyIds.IS_LATEST_MAJOR_VERSION, "Is Latest Major Version",
244 "Is Latest Major Version", PropertyType.BOOLEAN, Cardinality.SINGLE, Updatability.READONLY, false, false ) );
245
246 type.addPropertyDefinition( createPropDef( PropertyIds.VERSION_LABEL, "Version Label", "Version Label",
247 PropertyType.STRING, Cardinality.SINGLE, Updatability.READONLY, false, true ) );
248
249 type.addPropertyDefinition( createPropDef( PropertyIds.VERSION_SERIES_ID, "Version Series Id",
250 "Version Series Id", PropertyType.ID, Cardinality.SINGLE, Updatability.READONLY, false, true ) );
251
252 type.addPropertyDefinition( createPropDef( PropertyIds.IS_VERSION_SERIES_CHECKED_OUT,
253 "Is Verison Series Checked Out", "Is Verison Series Checked Out", PropertyType.BOOLEAN,
254 Cardinality.SINGLE, Updatability.READONLY, false, false ) );
255
256 type.addPropertyDefinition( createPropDef( PropertyIds.VERSION_SERIES_CHECKED_OUT_ID,
257 "Version Series Checked Out Id", "Version Series Checked Out Id", PropertyType.ID, Cardinality.SINGLE,
258 Updatability.READONLY, false, false ) );
259
260 type.addPropertyDefinition( createPropDef( PropertyIds.VERSION_SERIES_CHECKED_OUT_BY,
261 "Version Series Checked Out By", "Version Series Checked Out By", PropertyType.STRING,
262 Cardinality.SINGLE, Updatability.READONLY, false, false ) );
263
264 type.addPropertyDefinition( createPropDef( PropertyIds.CHECKIN_COMMENT, "Checkin Comment", "Checkin Comment",
265 PropertyType.STRING, Cardinality.SINGLE, Updatability.READONLY, false, false ) );
266
267 type.addPropertyDefinition( createPropDef( PropertyIds.CONTENT_STREAM_LENGTH, "Content Stream Length",
268 "Content Stream Length", PropertyType.INTEGER, Cardinality.SINGLE, Updatability.READONLY, false, false ) );
269
270 type.addPropertyDefinition( createPropDef( PropertyIds.CONTENT_STREAM_MIME_TYPE, "MIME Type", "MIME Type",
271 PropertyType.STRING, Cardinality.SINGLE, Updatability.READONLY, false, false ) );
272
273 type.addPropertyDefinition( createPropDef( PropertyIds.CONTENT_STREAM_FILE_NAME, "Filename", "Filename",
274 PropertyType.STRING, Cardinality.SINGLE, Updatability.READONLY, false, false ) );
275
276 type.addPropertyDefinition( createPropDef( PropertyIds.CONTENT_STREAM_ID, "Content Stream Id",
277 "Content Stream Id", PropertyType.ID, Cardinality.SINGLE, Updatability.READONLY, false, false ) );
278 }
279
280
281
282
283 private static PropertyDefinition<?> createPropDef( String id, String displayName, String description,
284 PropertyType datatype, Cardinality cardinality, Updatability updateability, boolean inherited, boolean required )
285 {
286 AbstractPropertyDefinition<?> result = null;
287
288 switch ( datatype )
289 {
290 case BOOLEAN:
291 result = new PropertyBooleanDefinitionImpl( );
292
293 break;
294
295 case DATETIME:
296 result = new PropertyDateTimeDefinitionImpl( );
297
298 break;
299
300 case DECIMAL:
301 result = new PropertyDecimalDefinitionImpl( );
302
303 break;
304
305 case HTML:
306 result = new PropertyHtmlDefinitionImpl( );
307
308 break;
309
310 case ID:
311 result = new PropertyIdDefinitionImpl( );
312
313 break;
314
315 case INTEGER:
316 result = new PropertyIntegerDefinitionImpl( );
317
318 break;
319
320 case STRING:
321 result = new PropertyStringDefinitionImpl( );
322
323 break;
324
325 case URI:
326 result = new PropertyUriDefinitionImpl( );
327
328 break;
329
330 default:
331 throw new RuntimeException( "Unknown datatype! Spec change?" );
332 }
333
334 result.setId( id );
335 result.setLocalName( id );
336 result.setDisplayName( displayName );
337 result.setDescription( description );
338 result.setPropertyType( datatype );
339 result.setCardinality( cardinality );
340 result.setUpdatability( updateability );
341 result.setIsInherited( inherited );
342 result.setIsRequired( required );
343 result.setIsQueryable( false );
344 result.setIsOrderable( false );
345 result.setQueryName( id );
346
347 return result;
348 }
349
350
351
352
353
354
355 public boolean addType( TypeDefinition type )
356 {
357 if ( type == null )
358 {
359 return false;
360 }
361
362 if ( type.getBaseTypeId( ) == null )
363 {
364 return false;
365 }
366
367
368 TypeDefinition baseType;
369
370 if ( type.getBaseTypeId( ) == BaseTypeId.CMIS_DOCUMENT )
371 {
372 baseType = copyTypeDefintion( types.get( DOCUMENT_TYPE_ID ).getTypeDefinition( ) );
373 }
374 else if ( type.getBaseTypeId( ) == BaseTypeId.CMIS_FOLDER )
375 {
376 baseType = copyTypeDefintion( types.get( FOLDER_TYPE_ID ).getTypeDefinition( ) );
377 }
378 else if ( type.getBaseTypeId( ) == BaseTypeId.CMIS_RELATIONSHIP )
379 {
380 baseType = copyTypeDefintion( types.get( RELATIONSHIP_TYPE_ID ).getTypeDefinition( ) );
381 }
382 else if ( type.getBaseTypeId( ) == BaseTypeId.CMIS_POLICY )
383 {
384 baseType = copyTypeDefintion( types.get( POLICY_TYPE_ID ).getTypeDefinition( ) );
385 }
386 else
387 {
388 return false;
389 }
390
391 AbstractTypeDefinition newType = (AbstractTypeDefinition) copyTypeDefintion( type );
392
393
394 for ( PropertyDefinition<?> propDef : baseType.getPropertyDefinitions( ).values( ) )
395 {
396 ( (AbstractPropertyDefinition<?>) propDef ).setIsInherited( true );
397 newType.addPropertyDefinition( propDef );
398 }
399
400
401 addTypeInteral( newType );
402
403 return true;
404 }
405
406
407
408
409 private void addTypeInteral( AbstractTypeDefinition type )
410 {
411 if ( type == null )
412 {
413 return;
414 }
415
416 if ( types.containsKey( type.getId( ) ) )
417 {
418
419 return;
420 }
421
422 TypeDefinitionContainerImpl tc = new TypeDefinitionContainerImpl( );
423 tc.setTypeDefinition( type );
424
425
426 if ( type.getParentTypeId( ) != null )
427 {
428 TypeDefinitionContainerImpl tdc = types.get( type.getParentTypeId( ) );
429
430 if ( tdc != null )
431 {
432 if ( tdc.getChildren( ) == null )
433 {
434 tdc.setChildren( new ArrayList<TypeDefinitionContainer>( ) );
435 }
436
437 tdc.getChildren( ).add( tc );
438 }
439 }
440
441 types.put( type.getId( ), tc );
442 typesList.add( tc );
443 }
444
445
446
447
448
449
450
451
452
453
454 public TypeDefinitionList getTypesChildren( CallContext context, String typeId, boolean includePropertyDefinitions,
455 BigInteger maxItems, BigInteger skipCount )
456 {
457 TypeDefinitionListImpl result = new TypeDefinitionListImpl( new ArrayList<TypeDefinition>( ) );
458
459 int skip = ( ( skipCount == null ) ? 0 : skipCount.intValue( ) );
460
461 if ( skip < 0 )
462 {
463 skip = 0;
464 }
465
466 int max = ( ( maxItems == null ) ? Integer.MAX_VALUE : maxItems.intValue( ) );
467
468 if ( max < 1 )
469 {
470 return result;
471 }
472
473 if ( typeId == null )
474 {
475 if ( skip < 1 )
476 {
477 result.getList( ).add( copyTypeDefintion( types.get( FOLDER_TYPE_ID ).getTypeDefinition( ) ) );
478 max--;
479 }
480
481 if ( ( skip < 2 ) && ( max > 0 ) )
482 {
483 result.getList( ).add( copyTypeDefintion( types.get( DOCUMENT_TYPE_ID ).getTypeDefinition( ) ) );
484 max--;
485 }
486
487 result.setHasMoreItems( ( result.getList( ).size( ) + skip ) < 2 );
488 result.setNumItems( BigInteger.valueOf( 2 ) );
489 }
490 else
491 {
492 TypeDefinitionContainer tc = types.get( typeId );
493
494 if ( ( tc == null ) || ( tc.getChildren( ) == null ) )
495 {
496 return result;
497 }
498
499 for ( TypeDefinitionContainer child : tc.getChildren( ) )
500 {
501 if ( skip > 0 )
502 {
503 skip--;
504
505 continue;
506 }
507
508 result.getList( ).add( copyTypeDefintion( child.getTypeDefinition( ) ) );
509
510 max--;
511
512 if ( max == 0 )
513 {
514 break;
515 }
516 }
517
518 result.setHasMoreItems( ( result.getList( ).size( ) + skip ) < tc.getChildren( ).size( ) );
519 result.setNumItems( BigInteger.valueOf( tc.getChildren( ).size( ) ) );
520 }
521
522 if ( !includePropertyDefinitions )
523 {
524 for ( TypeDefinition type : result.getList( ) )
525 {
526 type.getPropertyDefinitions( ).clear( );
527 }
528 }
529
530 return result;
531 }
532
533
534
535
536
537
538
539
540
541 public List<TypeDefinitionContainer> getTypesDescendants( CallContext context, String typeId, BigInteger depth,
542 Boolean includePropertyDefinitions )
543 {
544 List<TypeDefinitionContainer> result = new ArrayList<TypeDefinitionContainer>( );
545
546
547 int d = ( ( depth == null ) ? ( -1 ) : depth.intValue( ) );
548
549 if ( d == 0 )
550 {
551 throw new CmisInvalidArgumentException( "Depth must not be 0!" );
552 }
553
554
555 boolean ipd = ( ( includePropertyDefinitions == null ) ? false : includePropertyDefinitions.booleanValue( ) );
556
557 if ( typeId == null )
558 {
559 result.add( getTypesDescendants( d, types.get( FOLDER_TYPE_ID ), ipd ) );
560 result.add( getTypesDescendants( d, types.get( DOCUMENT_TYPE_ID ), ipd ) );
561
562
563
564
565
566 }
567 else
568 {
569 TypeDefinitionContainer tc = types.get( typeId );
570
571 if ( tc != null )
572 {
573 result.add( getTypesDescendants( d, tc, ipd ) );
574 }
575 }
576
577 return result;
578 }
579
580
581
582
583 private TypeDefinitionContainer getTypesDescendants( int depth, TypeDefinitionContainer tc,
584 boolean includePropertyDefinitions )
585 {
586 TypeDefinitionContainerImpl result = new TypeDefinitionContainerImpl( );
587
588 TypeDefinition type = copyTypeDefintion( tc.getTypeDefinition( ) );
589
590 if ( !includePropertyDefinitions )
591 {
592 type.getPropertyDefinitions( ).clear( );
593 }
594
595 result.setTypeDefinition( type );
596
597 if ( depth != 0 )
598 {
599 if ( tc.getChildren( ) != null )
600 {
601 result.setChildren( new ArrayList<TypeDefinitionContainer>( ) );
602
603 for ( TypeDefinitionContainer tdc : tc.getChildren( ) )
604 {
605 result.getChildren( )
606 .add( getTypesDescendants( ( depth < 0 ) ? ( -1 ) : ( depth - 1 ), tdc,
607 includePropertyDefinitions ) );
608 }
609 }
610 }
611
612 return result;
613 }
614
615
616
617
618
619
620 public TypeDefinition getType( String typeId )
621 {
622 TypeDefinitionContainer tc = types.get( typeId );
623
624 if ( tc == null )
625 {
626 return null;
627 }
628
629 return tc.getTypeDefinition( );
630 }
631
632
633
634
635
636
637
638 public TypeDefinition getTypeDefinition( CallContext context, String typeId )
639 {
640 TypeDefinitionContainer tc = types.get( typeId );
641
642 if ( tc == null )
643 {
644 throw new CmisObjectNotFoundException( "Type '" + typeId + "' is unknown!" );
645 }
646
647 return copyTypeDefintion( tc.getTypeDefinition( ) );
648 }
649
650 private static TypeDefinition copyTypeDefintion( TypeDefinition type )
651 {
652 return type;
653
654
655 }
656 }