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.tck.tests.types;
20  
21  import static org.apache.chemistry.opencmis.tck.CmisTestResultStatus.FAILURE;
22  import static org.apache.chemistry.opencmis.tck.CmisTestResultStatus.SKIPPED;
23  import static org.apache.chemistry.opencmis.tck.CmisTestResultStatus.WARNING;
24  
25  import java.util.ArrayList;
26  import java.util.List;
27  import java.util.Map;
28  
29  import org.apache.chemistry.opencmis.client.api.ObjectType;
30  import org.apache.chemistry.opencmis.client.api.Session;
31  import org.apache.chemistry.opencmis.commons.data.CreatablePropertyTypes;
32  import org.apache.chemistry.opencmis.commons.data.NewTypeSettableAttributes;
33  import org.apache.chemistry.opencmis.commons.definitions.PropertyDefinition;
34  import org.apache.chemistry.opencmis.commons.enums.Cardinality;
35  import org.apache.chemistry.opencmis.commons.enums.CmisVersion;
36  import org.apache.chemistry.opencmis.commons.enums.ContentStreamAllowed;
37  import org.apache.chemistry.opencmis.commons.enums.PropertyType;
38  import org.apache.chemistry.opencmis.commons.enums.Updatability;
39  import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
40  import org.apache.chemistry.opencmis.commons.impl.dataobjects.AbstractPropertyDefinition;
41  import org.apache.chemistry.opencmis.commons.impl.dataobjects.DocumentTypeDefinitionImpl;
42  import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyBooleanDefinitionImpl;
43  import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyDateTimeDefinitionImpl;
44  import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyDecimalDefinitionImpl;
45  import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyHtmlDefinitionImpl;
46  import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyIdDefinitionImpl;
47  import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyIntegerDefinitionImpl;
48  import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyStringDefinitionImpl;
49  import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyUriDefinitionImpl;
50  import org.apache.chemistry.opencmis.tck.CmisTestResult;
51  import org.apache.chemistry.opencmis.tck.impl.AbstractSessionTest;
52  
53  public class CreateAndDeleteTypeTest extends AbstractSessionTest {
54      @Override
55      public void init(Map<String, String> parameters) {
56          super.init(parameters);
57          setName("Create and Delete Type Test");
58          setDescription("Creates a document type and deletes it again.");
59      }
60  
61      @Override
62      public void run(Session session) {
63          if (session.getRepositoryInfo().getCmisVersion() == CmisVersion.CMIS_1_0) {
64              addResult(createResult(SKIPPED, "Type mutability is not supported by CMIS 1.0. Test skipped!"));
65              return;
66          }
67  
68          ObjectType parentType = session.getTypeDefinition(getDocumentTestTypeId());
69          if (parentType.getTypeMutability() == null || !Boolean.TRUE.equals(parentType.getTypeMutability().canCreate())) {
70              addResult(createResult(SKIPPED, "Test document type doesn't allow creating a sub-type. Test skipped!"));
71              return;
72          }
73  
74          createTypeWithoutProperties(session, parentType);
75          createTypeWithProperties(session, parentType);
76      }
77  
78      private void createTypeWithoutProperties(Session session, ObjectType parentType) {
79          CmisTestResult failure = null;
80  
81          // define the type
82          DocumentTypeDefinitionImpl newTypeDef = createDocumentTypeDefinition(session, "tck:testid_without_properties",
83                  parentType);
84  
85          // create the type
86          ObjectType newType = createType(session, newTypeDef);
87          if (newType == null) {
88              return;
89          }
90  
91          // get the type
92          ObjectType newType2 = null;
93          try {
94              newType2 = session.getTypeDefinition(newType.getId());
95  
96              // assert type definitions
97              failure = createResult(FAILURE,
98                      "The type definition returned by createType() doesn't match the type definition returned by getTypeDefinition()!");
99              addResult(assertEquals(newType, newType2, null, failure));
100         } catch (CmisObjectNotFoundException e) {
101             addResult(createResult(FAILURE, "Newly created type can not be fetched. Id: " + newType.getId(), e, false));
102         }
103 
104         // delete the type
105         deleteType(session, newType.getId());
106     }
107 
108     private void createTypeWithProperties(Session session, ObjectType parentType) {
109         CmisTestResult failure = null;
110 
111         CreatablePropertyTypes cpt = session.getRepositoryInfo().getCapabilities().getCreatablePropertyTypes();
112         if (cpt == null || cpt.canCreate() == null || cpt.canCreate().isEmpty()) {
113             addResult(createResult(FAILURE, "Repository Info does not indicate, which property types can be created!"));
114             return;
115         }
116 
117         // define the type
118         DocumentTypeDefinitionImpl newTypeDef = createDocumentTypeDefinition(session, "tck:testid_with_properties",
119                 parentType);
120 
121         // add a property for each creatable property type
122         for (PropertyType propType : PropertyType.values()) {
123             if (!cpt.canCreate().contains(propType)) {
124                 continue;
125             }
126 
127             newTypeDef.addPropertyDefinition(createPropertyDefinition(propType));
128         }
129 
130         // create the type
131         ObjectType newType = createType(session, newTypeDef);
132         if (newType == null) {
133             return;
134         }
135 
136         // get the type
137         ObjectType newType2 = null;
138         try {
139             newType2 = session.getTypeDefinition(newType.getId());
140 
141             // assert type definitions
142             failure = createResult(FAILURE,
143                     "The type definition returned by createType() doesn't match the type definition returned by getTypeDefinition()!");
144             addResult(assertEquals(newType, newType2, null, failure));
145         } catch (CmisObjectNotFoundException e) {
146             addResult(createResult(FAILURE, "Newly created type can not be fetched. Id: " + newType.getId(), e, false));
147         }
148 
149         // check properties
150         List<PropertyDefinition<?>> newPropDefs = new ArrayList<PropertyDefinition<?>>();
151         for (Map.Entry<String, PropertyDefinition<?>> propDef : newType.getPropertyDefinitions().entrySet()) {
152             if (Boolean.FALSE.equals(propDef.getValue().isInherited())) {
153                 newPropDefs.add(propDef.getValue());
154             }
155         }
156 
157         failure = createResult(FAILURE,
158                 "The number of defined properties and the number of non-inherited properties don't match!");
159         addResult(assertEquals(newTypeDef.getPropertyDefinitions().size(), newPropDefs.size(), null, failure));
160 
161         // check the order of the properties, which must match the order of the
162         // original type definition
163         // (OpenCMIS keeps the order of the property definitions.)
164         int i = 0;
165         for (Map.Entry<String, PropertyDefinition<?>> propDef : newTypeDef.getPropertyDefinitions().entrySet()) {
166             PropertyDefinition<?> newPropDef = newPropDefs.get(i);
167 
168             failure = createResult(FAILURE, "Property " + (i + 1) + " must be of type "
169                     + propDef.getValue().getPropertyType() + " but is of type " + newPropDef.getPropertyType() + "!");
170             addResult(assertEquals(propDef.getValue().getPropertyType(), newPropDef.getPropertyType(), null, failure));
171 
172             addResult(createInfoResult("Repository assigned the property '" + propDef.getValue().getId()
173                     + "' the following property id: " + newPropDef.getId()));
174 
175             i++;
176         }
177 
178         // delete the type
179         deleteType(session, newType.getId());
180     }
181 
182     private DocumentTypeDefinitionImpl createDocumentTypeDefinition(Session session, String typeId,
183             ObjectType parentType) {
184         CmisTestResult failure = null;
185 
186         NewTypeSettableAttributes settableAttributes = session.getRepositoryInfo().getCapabilities()
187                 .getNewTypeSettableAttributes();
188         if (settableAttributes == null) {
189             addResult(createResult(WARNING, "Capability NewTypeSettableAttributes is not set!"));
190         }
191 
192         DocumentTypeDefinitionImpl result = new DocumentTypeDefinitionImpl();
193 
194         result.setBaseTypeId(parentType.getBaseTypeId());
195         result.setParentTypeId(parentType.getId());
196 
197         if (settableAttributes == null || Boolean.TRUE.equals(settableAttributes.canSetId())) {
198             result.setId(typeId);
199         } else if (settableAttributes != null) {
200             failure = createResult(WARNING, "Flag 'id' in capability NewTypeSettableAttributes is not set!");
201             addResult(assertNotNull(settableAttributes.canSetId(), null, failure));
202         }
203 
204         if (settableAttributes == null || Boolean.TRUE.equals(settableAttributes.canSetLocalName())) {
205             result.setLocalName("tck:testlocal");
206         } else if (settableAttributes != null) {
207             failure = createResult(WARNING, "Flag 'localName' in capability NewTypeSettableAttributes is not set!");
208             addResult(assertNotNull(settableAttributes.canSetLocalName(), null, failure));
209         }
210 
211         if (settableAttributes == null || Boolean.TRUE.equals(settableAttributes.canSetLocalNamespace())) {
212             result.setLocalNamespace("http://tck/testlocalnamespace");
213         } else if (settableAttributes != null) {
214             failure = createResult(WARNING, "Flag 'localNamespace' in capability NewTypeSettableAttributes is not set!");
215             addResult(assertNotNull(settableAttributes.canSetLocalNamespace(), null, failure));
216         }
217 
218         if (settableAttributes == null || Boolean.TRUE.equals(settableAttributes.canSetDisplayName())) {
219             result.setDisplayName("TCK Document Type");
220         } else if (settableAttributes != null) {
221             failure = createResult(WARNING, "Flag 'displayName' in capability NewTypeSettableAttributes is not set!");
222             addResult(assertNotNull(settableAttributes.canSetDisplayName(), null, failure));
223         }
224 
225         if (settableAttributes == null || Boolean.TRUE.equals(settableAttributes.canSetDescription())) {
226             result.setDescription("This is the TCK document type");
227         } else if (settableAttributes != null) {
228             failure = createResult(WARNING, "Flag 'description' in capability NewTypeSettableAttributes is not set!");
229             addResult(assertNotNull(settableAttributes.canSetDescription(), null, failure));
230         }
231 
232         if (settableAttributes == null || Boolean.TRUE.equals(settableAttributes.canSetQueryName())) {
233             result.setQueryName("tck:testqueryname");
234         } else if (settableAttributes != null) {
235             failure = createResult(WARNING, "Flag 'queryName' in capability NewTypeSettableAttributes is not set!");
236             addResult(assertNotNull(settableAttributes.canSetQueryName(), null, failure));
237         }
238 
239         if (settableAttributes == null || Boolean.TRUE.equals(settableAttributes.canSetQueryable())) {
240             result.setIsQueryable(false);
241         } else if (settableAttributes != null) {
242             failure = createResult(WARNING, "Flag 'queryable' in capability NewTypeSettableAttributes is not set!");
243             addResult(assertNotNull(settableAttributes.canSetQueryable(), null, failure));
244         }
245 
246         if (settableAttributes == null || Boolean.TRUE.equals(settableAttributes.canSetFulltextIndexed())) {
247             result.setIsFulltextIndexed(false);
248         } else if (settableAttributes != null) {
249             failure = createResult(WARNING,
250                     "Flag 'fulltextIndexed' in capability NewTypeSettableAttributes is not set!");
251             addResult(assertNotNull(settableAttributes.canSetFulltextIndexed(), null, failure));
252         }
253 
254         if (settableAttributes == null || Boolean.TRUE.equals(settableAttributes.canSetIncludedInSupertypeQuery())) {
255             result.setIsIncludedInSupertypeQuery(false);
256         } else if (settableAttributes != null) {
257             failure = createResult(WARNING,
258                     "Flag 'includedInSupertypeQuery' in capability NewTypeSettableAttributes is not set!");
259             addResult(assertNotNull(settableAttributes.canSetIncludedInSupertypeQuery(), null, failure));
260         }
261 
262         if (settableAttributes == null || Boolean.TRUE.equals(settableAttributes.canSetControllableAcl())) {
263             result.setIsControllableAcl(false);
264         } else if (settableAttributes != null) {
265             failure = createResult(WARNING,
266                     "Flag 'controllableACL' in capability NewTypeSettableAttributes is not set!");
267             addResult(assertNotNull(settableAttributes.canSetControllableAcl(), null, failure));
268         }
269 
270         if (settableAttributes == null || Boolean.TRUE.equals(settableAttributes.canSetControllablePolicy())) {
271             result.setIsControllablePolicy(false);
272         } else if (settableAttributes != null) {
273             failure = createResult(WARNING,
274                     "Flag 'controllablePolicy' in capability NewTypeSettableAttributes is not set!");
275             addResult(assertNotNull(settableAttributes.canSetControllablePolicy(), null, failure));
276         }
277 
278         if (settableAttributes == null || Boolean.TRUE.equals(settableAttributes.canSetCreatable())) {
279             result.setIsCreatable(true);
280         } else if (settableAttributes != null) {
281             failure = createResult(WARNING, "Flag 'creatable' in capability NewTypeSettableAttributes is not set!");
282             addResult(assertNotNull(settableAttributes.canSetCreatable(), null, failure));
283         }
284 
285         if (settableAttributes == null || Boolean.TRUE.equals(settableAttributes.canSetFileable())) {
286             result.setIsFileable(true);
287         } else if (settableAttributes != null) {
288             failure = createResult(WARNING, "Flag 'fileable' in capability NewTypeSettableAttributes is not set!");
289             addResult(assertNotNull(settableAttributes.canSetFileable(), null, failure));
290         }
291 
292         result.setIsVersionable(false);
293         result.setContentStreamAllowed(ContentStreamAllowed.ALLOWED);
294 
295         return result;
296     }
297 
298     private AbstractPropertyDefinition<?> createPropertyDefinition(PropertyType propertyType) {
299         AbstractPropertyDefinition<?> result = null;
300 
301         switch (propertyType) {
302         case BOOLEAN:
303             result = new PropertyBooleanDefinitionImpl();
304             break;
305         case ID:
306             result = new PropertyIdDefinitionImpl();
307             break;
308         case INTEGER:
309             result = new PropertyIntegerDefinitionImpl();
310             break;
311         case DATETIME:
312             result = new PropertyDateTimeDefinitionImpl();
313             break;
314         case DECIMAL:
315             result = new PropertyDecimalDefinitionImpl();
316             break;
317         case HTML:
318             result = new PropertyHtmlDefinitionImpl();
319             break;
320         case URI:
321             result = new PropertyUriDefinitionImpl();
322             break;
323         default:
324             result = new PropertyStringDefinitionImpl();
325         }
326 
327         result.setPropertyType(propertyType);
328         result.setId("tck:" + propertyType.value());
329         result.setLocalName("tck:local_" + propertyType.value());
330         result.setLocalNamespace("tck:testlocalnamespace");
331         result.setDisplayName("TCK " + propertyType.value() + " propertry");
332         result.setQueryName("tck:" + propertyType.value());
333         result.setDescription("TCK " + propertyType.value() + " propertry");
334         result.setCardinality(Cardinality.SINGLE);
335         result.setUpdatability(Updatability.READWRITE);
336         result.setIsInherited(false);
337         result.setIsQueryable(false);
338         result.setIsOrderable(false);
339         result.setIsRequired(false);
340         result.setIsOpenChoice(true);
341 
342         return result;
343     }
344 }