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.WARNING;
23  
24  import java.math.BigInteger;
25  import java.util.HashMap;
26  import java.util.HashSet;
27  import java.util.List;
28  import java.util.Map;
29  import java.util.Set;
30  
31  import org.apache.chemistry.opencmis.client.api.ItemIterable;
32  import org.apache.chemistry.opencmis.client.api.ObjectType;
33  import org.apache.chemistry.opencmis.client.api.Session;
34  import org.apache.chemistry.opencmis.client.api.Tree;
35  import org.apache.chemistry.opencmis.commons.definitions.TypeDefinition;
36  import org.apache.chemistry.opencmis.commons.definitions.TypeDefinitionList;
37  import org.apache.chemistry.opencmis.commons.enums.BaseTypeId;
38  import org.apache.chemistry.opencmis.commons.enums.CmisVersion;
39  import org.apache.chemistry.opencmis.commons.exceptions.CmisBaseException;
40  import org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentException;
41  import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
42  import org.apache.chemistry.opencmis.tck.CmisTestResult;
43  import org.apache.chemistry.opencmis.tck.impl.AbstractSessionTest;
44  
45  public class BaseTypesTest extends AbstractSessionTest {
46      @Override
47      public void init(Map<String, String> parameters) {
48          super.init(parameters);
49          setName("Types Test");
50          setDescription("Checks all types exposed by the repository for specification compliance.");
51      }
52  
53      @Override
54      public void run(Session session) {
55          CmisTestResult failure;
56  
57          // check base types
58          Set<String> cmisTypes = new HashSet<String>();
59          cmisTypes.add(BaseTypeId.CMIS_DOCUMENT.value());
60          cmisTypes.add(BaseTypeId.CMIS_FOLDER.value());
61          cmisTypes.add(BaseTypeId.CMIS_RELATIONSHIP.value());
62          cmisTypes.add(BaseTypeId.CMIS_POLICY.value());
63  
64          if (session.getRepositoryInfo().getCmisVersion() != CmisVersion.CMIS_1_0) {
65              cmisTypes.add(BaseTypeId.CMIS_ITEM.value());
66              cmisTypes.add(BaseTypeId.CMIS_SECONDARY.value());
67          }
68  
69          for (TypeDefinition typeDef : session.getTypeChildren(null, false)) {
70              String typeId = typeDef.getId();
71  
72              if (typeId == null || !cmisTypes.contains(typeId)) {
73                  addResult(createResult(FAILURE, "Base type has an invalid ID: " + typeId));
74              }
75  
76              if (typeDef.getPropertyDefinitions() != null && !typeDef.getPropertyDefinitions().isEmpty()) {
77                  addResult(createResult(WARNING, "Property type definitions were not requested but delivered. Type ID: "
78                          + typeId));
79              }
80          }
81  
82          // document
83          try {
84              TypeDefinition documentType = session.getTypeDefinition(BaseTypeId.CMIS_DOCUMENT.value());
85              addResult(checkTypeDefinition(session, documentType,
86                      "Document type spec compliance: " + documentType.getId()));
87  
88              failure = createResult(FAILURE, "Document type has the wrong base type: " + documentType.getBaseTypeId());
89              addResult(assertEquals(BaseTypeId.CMIS_DOCUMENT, documentType.getBaseTypeId(), null, failure));
90          } catch (CmisObjectNotFoundException e) {
91              addResult(createResult(FAILURE, "Document type not available!", e, false));
92          }
93  
94          // folder
95          try {
96              TypeDefinition folderType = session.getTypeDefinition(BaseTypeId.CMIS_FOLDER.value());
97  
98              addResult(checkTypeDefinition(session, folderType, "Folder type spec compliance: " + folderType.getId()));
99  
100             failure = createResult(FAILURE, "Folder type has the wrong base type: " + folderType.getBaseTypeId());
101             addResult(assertEquals(BaseTypeId.CMIS_FOLDER, folderType.getBaseTypeId(), null, failure));
102         } catch (CmisObjectNotFoundException e) {
103             addResult(createResult(FAILURE, "Folder type not available!", e, false));
104         }
105 
106         // relationship
107         try {
108             TypeDefinition relationshipType = session.getTypeDefinition(BaseTypeId.CMIS_RELATIONSHIP.value());
109             addResult(checkTypeDefinition(session, relationshipType, "Relationship type spec compliance: "
110                     + relationshipType.getId()));
111 
112             failure = createResult(FAILURE,
113                     "Relationship type has the wrong base type: " + relationshipType.getBaseTypeId());
114             addResult(assertEquals(BaseTypeId.CMIS_RELATIONSHIP, relationshipType.getBaseTypeId(), null, failure));
115         } catch (CmisObjectNotFoundException e) {
116             addResult(createResult(WARNING, "Relationship type not available!", e, false));
117         }
118 
119         // policy
120         try {
121             TypeDefinition policyType = session.getTypeDefinition(BaseTypeId.CMIS_POLICY.value());
122             addResult(checkTypeDefinition(session, policyType, "Policy type spec compliance: " + policyType.getId()));
123 
124             failure = createResult(FAILURE, "Policy type has the wrong base type: " + policyType.getBaseTypeId());
125             addResult(assertEquals(BaseTypeId.CMIS_POLICY, policyType.getBaseTypeId(), null, failure));
126         } catch (CmisInvalidArgumentException e) {
127             addResult(createResult(WARNING, "Policy type not available!", e, false));
128         } catch (CmisObjectNotFoundException e) {
129             addResult(createResult(WARNING, "Policy type not available!", e, false));
130         }
131 
132         // CMIS 1.1 types
133         if (session.getRepositoryInfo().getCmisVersion() == CmisVersion.CMIS_1_1) {
134             // item
135             try {
136                 TypeDefinition itemType = session.getTypeDefinition(BaseTypeId.CMIS_ITEM.value());
137                 addResult(checkTypeDefinition(session, itemType, "Item type spec compliance: " + itemType.getId()));
138 
139                 failure = createResult(FAILURE, "Item type has the wrong base type: " + itemType.getBaseTypeId());
140                 addResult(assertEquals(BaseTypeId.CMIS_ITEM, itemType.getBaseTypeId(), null, failure));
141             } catch (CmisInvalidArgumentException e) {
142                 addResult(createResult(WARNING, "Item type not available!", e, false));
143             } catch (CmisObjectNotFoundException e) {
144                 addResult(createResult(WARNING, "Item type not available!", e, false));
145             }
146 
147             // secondary type
148             try {
149                 TypeDefinition secondaryType = session.getTypeDefinition(BaseTypeId.CMIS_SECONDARY.value());
150                 addResult(checkTypeDefinition(session, secondaryType, "Secondary type spec compliance: "
151                         + secondaryType.getId()));
152 
153                 failure = createResult(FAILURE,
154                         "Secondary type has the wrong base type: " + secondaryType.getBaseTypeId());
155                 addResult(assertEquals(BaseTypeId.CMIS_SECONDARY, secondaryType.getBaseTypeId(), null, failure));
156             } catch (CmisInvalidArgumentException e) {
157                 addResult(createResult(WARNING, "Secondary type not available!", e, false));
158             } catch (CmisObjectNotFoundException e) {
159                 addResult(createResult(WARNING, "Secondary type not available!", e, false));
160             }
161         } else {
162             try {
163                 session.getTypeDefinition(BaseTypeId.CMIS_ITEM.value());
164                 addResult(createResult(FAILURE, "CMIS 1.0 repository returns cmis:item type definition!"));
165             } catch (CmisBaseException e) {
166                 // expected
167             }
168 
169             try {
170                 session.getTypeDefinition(BaseTypeId.CMIS_SECONDARY.value());
171                 addResult(createResult(FAILURE, "CMIS 1.0 repository returns cmis:secondary type definition!"));
172             } catch (CmisBaseException e) {
173                 // expected
174             }
175         }
176 
177         // simple getTypeChildren paging test - skipping over all base types mut
178         // return an empty list
179         TypeDefinitionList typeDefinitionList = session
180                 .getBinding()
181                 .getRepositoryService()
182                 .getTypeChildren(session.getRepositoryInfo().getId(), null, false, BigInteger.valueOf(100),
183                         BigInteger.valueOf(6), null);
184         if (typeDefinitionList == null) {
185             addResult(createResult(FAILURE, "getTypeChildren() returned nothing!"));
186         } else {
187             if (typeDefinitionList.getList() != null && !typeDefinitionList.getList().isEmpty()) {
188                 addResult(createResult(
189                         FAILURE,
190                         "A getTypeChildren() call on the base types must retrun an empty list if skipCount is >= 6! The repository returned a list of "
191                                 + typeDefinitionList.getList().size() + " elements."));
192             }
193 
194             if (Boolean.TRUE.equals(typeDefinitionList.hasMoreItems())) {
195                 addResult(createResult(
196                         FAILURE,
197                         "A getTypeChildren() call on the base types must retrun an empty list if skipCount is >= 6! The repository returned hasMoreItems == true."));
198             }
199         }
200 
201         // test getTypeDescendants()
202         int numOfTypes = runTypeChecks(session, session.getTypeDescendants(null, -1, true));
203 
204         addResult(createInfoResult("Checked " + numOfTypes + " type definitions."));
205     }
206 
207     private int runTypeChecks(Session session, List<Tree<ObjectType>> types) {
208         if (types == null) {
209             return 0;
210         }
211 
212         int numOfTypes = 0;
213         CmisTestResult failure;
214 
215         for (Tree<ObjectType> tree : types) {
216             failure = createResult(FAILURE, "Types tree contains null leaf!");
217             addResult(assertNotNull(tree, null, failure));
218 
219             if (tree != null) {
220                 numOfTypes++;
221 
222                 addResult(checkTypeDefinition(session, tree.getItem(), "Type spec compliance: "
223                         + tree.getItem().getId()));
224 
225                 // clear the cache to ensure that the type definition is
226                 // reloaded from the repository
227                 session.clear();
228 
229                 try {
230                     TypeDefinition reloadedType = session.getTypeDefinition(tree.getItem().getId());
231 
232                     addResult(checkTypeDefinition(session, reloadedType, "Type spec compliance: "
233                             + (reloadedType == null ? "?" : reloadedType.getId())));
234 
235                     failure = createResult(FAILURE,
236                             "Type fetched via getTypeDescendants() is does not macth type fetched via getTypeDefinition(): "
237                                     + tree.getItem().getId());
238                     addResult(assertEquals(tree.getItem(), reloadedType, null, failure));
239                 } catch (CmisObjectNotFoundException e) {
240                     addResult(createResult(FAILURE,
241                             "Type fetched via getTypeDescendants() is not available via getTypeDefinition(): "
242                                     + tree.getItem().getId(), e, false));
243                 }
244 
245                 // clear the cache again to ensure that the type definition
246                 // children are reloaded from the repository
247                 session.clear();
248 
249                 try {
250                     ItemIterable<ObjectType> reloadedTypeChildren = session.getTypeChildren(tree.getItem().getId(),
251                             true);
252 
253                     // check type children
254                     Map<String, ObjectType> typeChilden = new HashMap<String, ObjectType>();
255                     for (ObjectType childType : reloadedTypeChildren) {
256                         if (childType == null) {
257                             addResult(createResult(FAILURE, "The list of types contains a null entry!"));
258                             continue;
259                         }
260 
261                         addResult(checkTypeDefinition(session, childType, "Type spec compliance: " + childType.getId()));
262 
263                         typeChilden.put(childType.getId(), childType);
264                     }
265 
266                     // compare type children and type descendants
267                     if (tree.getChildren() == null) {
268                         failure = createResult(FAILURE,
269                                 "Type children fetched via getTypeDescendants() don't match type children fetched via getTypeChildren(): "
270                                         + tree.getItem().getId());
271                         addResult(assertEquals(0, typeChilden.size(), null, failure));
272                     } else {
273                         // collect the children
274                         Map<String, ObjectType> typeDescendants = new HashMap<String, ObjectType>();
275                         for (Tree<ObjectType> childType : tree.getChildren()) {
276                             if ((childType != null) && (childType.getItem() != null)) {
277                                 typeDescendants.put(childType.getItem().getId(), childType.getItem());
278                             }
279                         }
280 
281                         failure = createResult(FAILURE,
282                                 "Type children fetched via getTypeDescendants() don't match type children fetched via getTypeChildren(): "
283                                         + tree.getItem().getId());
284                         addResult(assertEquals(typeDescendants.size(), typeChilden.size(), null, failure));
285 
286                         for (ObjectType compareType : typeDescendants.values()) {
287                             failure = createResult(FAILURE,
288                                     "Type fetched via getTypeDescendants() doesn't match type fetched via getTypeChildren(): "
289                                             + tree.getItem().getId());
290                             addResult(assertEquals(compareType, typeChilden.get(compareType.getId()), null, failure));
291                         }
292                     }
293                 } catch (CmisObjectNotFoundException e) {
294                     addResult(createResult(FAILURE,
295                             "Type children fetched via getTypeDescendants() are not available via getTypeChildren(): "
296                                     + tree.getItem().getId(), e, false));
297                 }
298 
299                 numOfTypes += runTypeChecks(session, tree.getChildren());
300             }
301         }
302 
303         return numOfTypes;
304     }
305 
306 }