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