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.client.bindings.framework;
20  
21  import static org.apache.chemistry.opencmis.commons.impl.CollectionsHelper.isNotEmpty;
22  
23  import java.io.ByteArrayInputStream;
24  import java.io.ByteArrayOutputStream;
25  import java.io.FileInputStream;
26  import java.io.InputStream;
27  import java.math.BigInteger;
28  import java.util.ArrayList;
29  import java.util.Enumeration;
30  import java.util.List;
31  import java.util.Set;
32  
33  import junit.framework.TestCase;
34  
35  import org.apache.chemistry.opencmis.commons.PropertyIds;
36  import org.apache.chemistry.opencmis.commons.data.Ace;
37  import org.apache.chemistry.opencmis.commons.data.Acl;
38  import org.apache.chemistry.opencmis.commons.data.AllowableActions;
39  import org.apache.chemistry.opencmis.commons.data.ContentStream;
40  import org.apache.chemistry.opencmis.commons.data.ExtensionsData;
41  import org.apache.chemistry.opencmis.commons.data.ObjectData;
42  import org.apache.chemistry.opencmis.commons.data.ObjectInFolderData;
43  import org.apache.chemistry.opencmis.commons.data.ObjectInFolderList;
44  import org.apache.chemistry.opencmis.commons.data.ObjectParentData;
45  import org.apache.chemistry.opencmis.commons.data.Properties;
46  import org.apache.chemistry.opencmis.commons.data.PropertyData;
47  import org.apache.chemistry.opencmis.commons.data.PropertyDateTime;
48  import org.apache.chemistry.opencmis.commons.data.PropertyId;
49  import org.apache.chemistry.opencmis.commons.data.PropertyString;
50  import org.apache.chemistry.opencmis.commons.data.RenditionData;
51  import org.apache.chemistry.opencmis.commons.data.RepositoryInfo;
52  import org.apache.chemistry.opencmis.commons.definitions.DocumentTypeDefinition;
53  import org.apache.chemistry.opencmis.commons.definitions.PropertyDefinition;
54  import org.apache.chemistry.opencmis.commons.definitions.TypeDefinition;
55  import org.apache.chemistry.opencmis.commons.enums.AclPropagation;
56  import org.apache.chemistry.opencmis.commons.enums.Action;
57  import org.apache.chemistry.opencmis.commons.enums.CapabilityAcl;
58  import org.apache.chemistry.opencmis.commons.enums.CapabilityChanges;
59  import org.apache.chemistry.opencmis.commons.enums.CapabilityQuery;
60  import org.apache.chemistry.opencmis.commons.enums.CapabilityRenditions;
61  import org.apache.chemistry.opencmis.commons.enums.IncludeRelationships;
62  import org.apache.chemistry.opencmis.commons.enums.UnfileObject;
63  import org.apache.chemistry.opencmis.commons.enums.VersioningState;
64  import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
65  import org.apache.chemistry.opencmis.commons.impl.IOUtils;
66  import org.apache.chemistry.opencmis.commons.spi.BindingsObjectFactory;
67  import org.apache.chemistry.opencmis.commons.spi.CmisBinding;
68  import org.slf4j.Logger;
69  import org.slf4j.LoggerFactory;
70  
71  /**
72   * Base test case for CMIS tests.
73   */
74  public abstract class AbstractCmisTestCase extends TestCase {
75  
76      public static final String DEFAULT_TESTS_ENABLED = "true";
77      public static final String DEFAULT_USERNAME = "admin";
78      public static final String DEFAULT_PASSWORD = "admin";
79      public static final String DEFAULT_ATOMPUB_URL = "http://localhost:8080/opencmis/atom11";
80      public static final String DEFAULT_WEBSERVICES_URLPREFIX = "http://localhost:8080/opencmis/services/";
81      public static final String DEFAULT_DOCTYPE = "cmis:document";
82      public static final String DEFAULT_FOLDERTYPE = "cmis:folder";
83  
84      public static final String PROP_TESTS_ENABLED = "opencmis.test";
85      public static final String PROP_USERNAME = "opencmis.test.username";
86      public static final String PROP_PASSWORD = "opencmis.test.password";
87      public static final String PROP_REPOSITORY = "opencmis.test.repository";
88      public static final String PROP_TESTFOLDER = "opencmis.test.testfolder";
89      public static final String PROP_DOCTYPE = "opencmis.test.documenttype";
90      public static final String PROP_FOLDERTYPE = "opencmis.test.foldertype";
91      public static final String PROP_CONFIG_FILE = "opencmis.test.config";
92  
93      public static final String PROP_ATOMPUB_URL = "opencmis.test.atompub.url";
94      public static final String PROP_WEBSERVICES_URLPREFIX = "opencmis.test.webservices.url";
95  
96      private CmisBinding binding;
97      private String fTestRepositoryId;
98      private String fTestFolderId;
99  
100     private static final Logger log = LoggerFactory.getLogger(AbstractCmisTestCase.class);
101 
102     /**
103      * Read configuration file.
104      */
105     static {
106         String configFileName = System.getProperty(PROP_CONFIG_FILE);
107         if (configFileName != null) {
108 
109             try {
110                 java.util.Properties properties = new java.util.Properties();
111                 properties.load(new FileInputStream(configFileName));
112 
113                 for (Enumeration<?> e = properties.propertyNames(); e.hasMoreElements();) {
114                     String key = (String) e.nextElement();
115                     String value = properties.getProperty(key);
116                     System.setProperty(key, value);
117                 }
118             } catch (Exception e) {
119                 System.err.println("Could not load test properties: " + e.toString());
120             }
121         }
122     }
123 
124     /**
125      * Returns the binding object or creates one if does not exist.
126      */
127     protected CmisBinding getBinding() {
128         if (binding == null) {
129             log.info("Creating binding...");
130             binding = createBinding();
131         }
132 
133         return binding;
134     }
135 
136     /**
137      * Creates a binding object.
138      */
139     protected abstract CmisBinding createBinding();
140 
141     /**
142      * Returns a set of test names that enabled.
143      */
144     protected abstract Set<String> getEnabledTests();
145 
146     /**
147      * Returns the test repository id.
148      */
149     protected String getTestRepositoryId() {
150         if (fTestRepositoryId != null) {
151             return fTestRepositoryId;
152         }
153 
154         fTestRepositoryId = System.getProperty(PROP_REPOSITORY);
155         if (fTestRepositoryId != null) {
156             log.info("Test repository: " + fTestRepositoryId);
157             return fTestRepositoryId;
158         }
159 
160         fTestRepositoryId = getFirstRepositoryId();
161         log.info("Test repository: " + fTestRepositoryId);
162 
163         return fTestRepositoryId;
164     }
165 
166     /**
167      * Returns the test root folder id.
168      */
169     protected String getTestRootFolder() {
170         if (fTestFolderId != null) {
171             return fTestFolderId;
172         }
173 
174         fTestFolderId = System.getProperty(PROP_TESTFOLDER);
175         if (fTestFolderId != null) {
176             log.info("Test root folder: " + fTestFolderId);
177             return fTestFolderId;
178         }
179 
180         fTestFolderId = getRootFolderId();
181         log.info("Test root folder: " + fTestFolderId);
182 
183         return fTestFolderId;
184     }
185 
186     /**
187      * Returns if the test is enabled.
188      */
189     protected boolean isEnabled(String name) {
190         boolean testsEnabled = Boolean.parseBoolean(System.getProperty(PROP_TESTS_ENABLED, DEFAULT_TESTS_ENABLED));
191 
192         if (testsEnabled && getEnabledTests().contains(name)) {
193             return true;
194         }
195 
196         log.info("Skipping test '" + name + "'!");
197 
198         return false;
199     }
200 
201     /**
202      * Returns the test username.
203      */
204     protected String getUsername() {
205         return System.getProperty(PROP_USERNAME, DEFAULT_USERNAME);
206     }
207 
208     /**
209      * Returns the test password.
210      */
211     protected String getPassword() {
212         return System.getProperty(PROP_PASSWORD, DEFAULT_PASSWORD);
213     }
214 
215     /**
216      * Returns the default document type.
217      */
218     protected String getDefaultDocumentType() {
219         return System.getProperty(PROP_DOCTYPE, DEFAULT_DOCTYPE);
220     }
221 
222     /**
223      * Returns the default folder type.
224      */
225     protected String getDefaultFolderType() {
226         return System.getProperty(PROP_FOLDERTYPE, DEFAULT_FOLDERTYPE);
227     }
228 
229     /**
230      * Returns the AtomPub URL.
231      */
232     protected String getAtomPubURL() {
233         return System.getProperty(PROP_ATOMPUB_URL, DEFAULT_ATOMPUB_URL);
234     }
235 
236     /**
237      * Returns the Web Services URL prefix.
238      */
239     protected String getWebServicesURL() {
240         return System.getProperty(PROP_WEBSERVICES_URLPREFIX, DEFAULT_WEBSERVICES_URLPREFIX);
241     }
242 
243     /**
244      * Returns the object factory.
245      */
246     protected BindingsObjectFactory getObjectFactory() {
247         return getBinding().getObjectFactory();
248     }
249 
250     /**
251      * Returns the id of the first repository.
252      */
253     protected String getFirstRepositoryId() {
254         List<RepositoryInfo> repositories = getBinding().getRepositoryService().getRepositoryInfos(null);
255 
256         assertNotNull(repositories);
257         assertFalse(repositories.isEmpty());
258         assertNotNull(repositories.get(0).getId());
259 
260         return repositories.get(0).getId();
261     }
262 
263     /**
264      * Returns the info object of the test repository.
265      */
266     protected RepositoryInfo getRepositoryInfo() {
267         RepositoryInfo repositoryInfo = getBinding().getRepositoryService().getRepositoryInfo(getTestRepositoryId(),
268                 null);
269 
270         assertNotNull(repositoryInfo);
271         assertNotNull(repositoryInfo.getId());
272         assertEquals(getTestRepositoryId(), repositoryInfo.getId());
273 
274         return repositoryInfo;
275     }
276 
277     /**
278      * Returns the root folder of the test repository.
279      */
280     protected String getRootFolderId() {
281         RepositoryInfo repository = getRepositoryInfo();
282 
283         assertNotNull(repository.getRootFolderId());
284 
285         return repository.getRootFolderId();
286     }
287 
288     /**
289      * Returns if the test repository supports reading ACLs.
290      */
291     protected boolean supportsDiscoverACLs() {
292         RepositoryInfo repository = getRepositoryInfo();
293 
294         assertNotNull(repository.getCapabilities());
295 
296         return repository.getCapabilities().getAclCapability() != CapabilityAcl.NONE;
297     }
298 
299     /**
300      * Returns if the test repository supports setting ACLs.
301      */
302     protected boolean supportsManageACLs() {
303         RepositoryInfo repository = getRepositoryInfo();
304 
305         assertNotNull(repository.getCapabilities());
306 
307         return repository.getCapabilities().getAclCapability() == CapabilityAcl.MANAGE;
308     }
309 
310     /**
311      * Returns if the test repository supports renditions.
312      */
313     protected boolean supportsRenditions() {
314         RepositoryInfo repository = getRepositoryInfo();
315 
316         assertNotNull(repository.getCapabilities());
317 
318         if (repository.getCapabilities().getRenditionsCapability() == null) {
319             return false;
320         }
321 
322         return repository.getCapabilities().getRenditionsCapability() != CapabilityRenditions.NONE;
323     }
324 
325     /**
326      * Returns if the test repository supports descendants.
327      */
328     protected boolean supportsDescendants() {
329         RepositoryInfo repository = getRepositoryInfo();
330 
331         assertNotNull(repository.getCapabilities());
332 
333         if (repository.getCapabilities().isGetDescendantsSupported() == null) {
334             return false;
335         }
336 
337         return repository.getCapabilities().isGetDescendantsSupported();
338     }
339 
340     /**
341      * Returns if the test repository supports descendants.
342      */
343     protected boolean supportsFolderTree() {
344         RepositoryInfo repository = getRepositoryInfo();
345 
346         assertNotNull(repository.getCapabilities());
347 
348         if (repository.getCapabilities().isGetFolderTreeSupported() == null) {
349             return false;
350         }
351 
352         return repository.getCapabilities().isGetFolderTreeSupported();
353     }
354 
355     /**
356      * Returns if the test repository supports content changes.
357      */
358     protected boolean supportsContentChanges() {
359         RepositoryInfo repository = getRepositoryInfo();
360 
361         assertNotNull(repository.getCapabilities());
362 
363         if (repository.getCapabilities().getChangesCapability() == null) {
364             return false;
365         }
366 
367         return repository.getCapabilities().getChangesCapability() != CapabilityChanges.NONE;
368     }
369 
370     /**
371      * Returns if the test repository supports query.
372      */
373     protected boolean supportsQuery() {
374         RepositoryInfo repository = getRepositoryInfo();
375 
376         assertNotNull(repository.getCapabilities());
377 
378         if (repository.getCapabilities().getQueryCapability() == null) {
379             return false;
380         }
381 
382         return repository.getCapabilities().getQueryCapability() != CapabilityQuery.NONE;
383     }
384 
385     /**
386      * Returns if the test repository supports relationships.
387      */
388     protected boolean supportsRelationships() {
389         TypeDefinition relType = null;
390 
391         try {
392             relType = getBinding().getRepositoryService().getTypeDefinition(getTestRepositoryId(), "cmis:relationship",
393                     null);
394         } catch (CmisObjectNotFoundException e) {
395             return false;
396         }
397 
398         return relType != null;
399     }
400 
401     /**
402      * Returns if the test repository supports policies.
403      */
404     protected boolean supportsPolicies() {
405         TypeDefinition relType = null;
406 
407         try {
408             relType = getBinding().getRepositoryService().getTypeDefinition(getTestRepositoryId(), "cmis:policy", null);
409         } catch (CmisObjectNotFoundException e) {
410             return false;
411         }
412 
413         return relType != null;
414     }
415 
416     /**
417      * Returns the AclPropagation from the ACL capabilities.
418      */
419     protected AclPropagation getAclPropagation() {
420         RepositoryInfo repository = getRepositoryInfo();
421 
422         assertNotNull(repository.getCapabilities());
423 
424         if (repository.getAclCapabilities().getAclPropagation() == null) {
425             return AclPropagation.REPOSITORYDETERMINED;
426         }
427 
428         return repository.getAclCapabilities().getAclPropagation();
429     }
430 
431     // ---- helpers ----
432 
433     /**
434      * Prints a warning.
435      */
436     protected void warning(String message) {
437         System.out.println("**** " + message);
438     }
439 
440     /**
441      * Creates a ContentStreamData object from a byte array.
442      */
443     protected ContentStream createContentStreamData(String mimeType, byte[] content) {
444         assertNotNull(content);
445 
446         return getObjectFactory().createContentStream("test", BigInteger.valueOf(content.length), mimeType,
447                 new ByteArrayInputStream(content));
448     }
449 
450     /**
451      * Extracts the path from a folder object.
452      */
453     protected String getPath(ObjectData folderObject) {
454         assertNotNull(folderObject);
455         assertNotNull(folderObject.getProperties());
456         assertNotNull(folderObject.getProperties().getProperties());
457         assertTrue(folderObject.getProperties().getProperties().get(PropertyIds.PATH) instanceof PropertyString);
458 
459         PropertyString pathProperty = (PropertyString) folderObject.getProperties().getProperties()
460                 .get(PropertyIds.PATH);
461 
462         assertNotNull(pathProperty.getValues());
463         assertEquals(1, pathProperty.getValues().size());
464         assertNotNull(pathProperty.getValues().get(0));
465 
466         return pathProperty.getValues().get(0);
467     }
468 
469     // ---- short cuts ----
470 
471     /**
472      * Retrieves an object.
473      */
474     protected ObjectData getObject(String objectId, String filter, Boolean includeAllowableActions,
475             IncludeRelationships includeRelationships, String renditionFilter, Boolean includePolicyIds,
476             Boolean includeACL, ExtensionsData extension) {
477         ObjectData object = getBinding().getObjectService()
478                 .getObject(getTestRepositoryId(), objectId, filter, includeAllowableActions, includeRelationships,
479                         renditionFilter, includePolicyIds, includeACL, extension);
480 
481         assertNotNull(object);
482 
483         return object;
484     }
485 
486     /**
487      * Retrieves a full blown object.
488      */
489     protected ObjectData getObject(String objectId) {
490         ObjectData object = getObject(objectId, "*", Boolean.TRUE, IncludeRelationships.BOTH, null, Boolean.TRUE,
491                 Boolean.TRUE, null);
492 
493         assertBasicProperties(object.getProperties());
494 
495         return object;
496     }
497 
498     /**
499      * Retrieves an object by path.
500      */
501     protected ObjectData getObjectByPath(String path, String filter, Boolean includeAllowableActions,
502             IncludeRelationships includeRelationships, String renditionFilter, Boolean includePolicyIds,
503             Boolean includeACL, ExtensionsData extension) {
504         ObjectData object = getBinding().getObjectService()
505                 .getObjectByPath(getTestRepositoryId(), path, filter, includeAllowableActions, includeRelationships,
506                         renditionFilter, includePolicyIds, includeACL, extension);
507 
508         assertNotNull(object);
509 
510         return object;
511     }
512 
513     /**
514      * Retrieves a full blown object by path.
515      */
516     protected ObjectData getObjectByPath(String path) {
517         ObjectData object = getObjectByPath(path, "*", Boolean.TRUE, IncludeRelationships.BOTH, null, Boolean.TRUE,
518                 Boolean.TRUE, null);
519 
520         assertBasicProperties(object.getProperties());
521 
522         return object;
523     }
524 
525     /**
526      * Returns <code>true</code> if the object with the given id exists,
527      * <code>false</code> otherwise.
528      */
529     protected boolean existsObject(String objectId) {
530         try {
531             ObjectData object = getObject(objectId, PropertyIds.OBJECT_ID, Boolean.FALSE, IncludeRelationships.NONE,
532                     null, Boolean.FALSE, Boolean.FALSE, null);
533 
534             assertNotNull(object);
535             assertNotNull(object.getId());
536         } catch (CmisObjectNotFoundException e) {
537             return false;
538         }
539 
540         return true;
541     }
542 
543     /**
544      * Returns the child of a folder.
545      */
546     protected ObjectInFolderData getChild(String folderId, String objectId) {
547         boolean hasMore = true;
548 
549         while (hasMore) {
550             ObjectInFolderList children = getBinding().getNavigationService().getChildren(getTestRepositoryId(),
551                     folderId, "*", null, Boolean.TRUE, IncludeRelationships.BOTH, null, Boolean.TRUE, null, null, null);
552 
553             assertNotNull(children);
554             assertTrue(isNotEmpty(children.getObjects()));
555 
556             hasMore = children.hasMoreItems() == null ? false : children.hasMoreItems().booleanValue();
557 
558             for (ObjectInFolderData object : children.getObjects()) {
559                 assertNotNull(object);
560                 assertNotNull(object.getPathSegment());
561                 assertNotNull(object.getObject());
562                 assertNotNull(object.getObject().getId());
563 
564                 assertBasicProperties(object.getObject().getProperties());
565 
566                 if (object.getObject().getId().equals(objectId)) {
567                     return object;
568                 }
569             }
570         }
571 
572         fail("Child not found!");
573 
574         return null;
575     }
576 
577     /**
578      * Gets the version series id of an object.
579      */
580     protected String getVersionSeriesId(ObjectData object) {
581         PropertyData<?> versionSeriesId = object.getProperties().getProperties().get(PropertyIds.VERSION_SERIES_ID);
582         assertNotNull(versionSeriesId);
583         assertTrue(versionSeriesId instanceof PropertyId);
584 
585         return ((PropertyId) versionSeriesId).getFirstValue();
586     }
587 
588     /**
589      * Gets the version series id of an object.
590      */
591     protected String getVersionSeriesId(String docId) {
592         return getVersionSeriesId(getObject(docId));
593     }
594 
595     /**
596      * Creates a folder.
597      */
598     protected String createFolder(Properties properties, String folderId, List<String> policies, Acl addACEs,
599             Acl removeACEs) {
600         String objectId = getBinding().getObjectService().createFolder(getTestRepositoryId(), properties, folderId,
601                 policies, addACEs, removeACEs, null);
602         assertNotNull(objectId);
603         assertTrue(existsObject(objectId));
604 
605         ObjectInFolderData folderChild = getChild(folderId, objectId);
606 
607         // check canGetProperties
608         assertAllowableAction(folderChild.getObject().getAllowableActions(), Action.CAN_GET_PROPERTIES, true);
609 
610         // check name
611         PropertyData<?> nameProp = properties.getProperties().get(PropertyIds.NAME);
612         if (nameProp != null) {
613             assertPropertyValue(folderChild.getObject().getProperties(), PropertyIds.NAME, PropertyString.class,
614                     nameProp.getFirstValue());
615         }
616 
617         // check object type
618         PropertyData<?> typeProp = properties.getProperties().get(PropertyIds.OBJECT_TYPE_ID);
619         assertNotNull(typeProp);
620         assertPropertyValue(folderChild.getObject().getProperties(), PropertyIds.OBJECT_TYPE_ID, PropertyId.class,
621                 typeProp.getFirstValue());
622 
623         // check parent
624         ObjectData parent = getBinding().getNavigationService().getFolderParent(getTestRepositoryId(), objectId, null,
625                 null);
626         assertNotNull(parent);
627         assertNotNull(parent.getProperties());
628         assertNotNull(parent.getProperties().getProperties());
629         assertNotNull(parent.getProperties().getProperties().get(PropertyIds.OBJECT_ID));
630         assertEquals(folderId, parent.getProperties().getProperties().get(PropertyIds.OBJECT_ID).getFirstValue());
631 
632         return objectId;
633     }
634 
635     /**
636      * Creates a folder with the default type.
637      */
638     protected String createDefaultFolder(String folderId, String name) {
639         List<PropertyData<?>> propList = new ArrayList<PropertyData<?>>();
640         propList.add(getObjectFactory().createPropertyStringData(PropertyIds.NAME, name));
641         propList.add(getObjectFactory().createPropertyIdData(PropertyIds.OBJECT_TYPE_ID, getDefaultFolderType()));
642 
643         Properties properties = getObjectFactory().createPropertiesData(propList);
644 
645         return createFolder(properties, folderId, null, null, null);
646     }
647 
648     /**
649      * Creates a document.
650      */
651     protected String createDocument(Properties properties, String folderId, ContentStream contentStream,
652             VersioningState versioningState, List<String> policies, Acl addACEs, Acl removeACEs) {
653         String objectId = getBinding().getObjectService().createDocument(getTestRepositoryId(), properties, folderId,
654                 contentStream, versioningState, policies, addACEs, removeACEs, null);
655         assertNotNull(objectId);
656         assertTrue(existsObject(objectId));
657 
658         if (folderId != null) {
659             ObjectInFolderData folderChild = getChild(folderId, objectId);
660 
661             // check canGetProperties
662             assertAllowableAction(folderChild.getObject().getAllowableActions(), Action.CAN_GET_PROPERTIES, true);
663 
664             // check canGetContentStream
665             if (contentStream != null) {
666                 assertAllowableAction(folderChild.getObject().getAllowableActions(), Action.CAN_GET_CONTENT_STREAM,
667                         true);
668             }
669 
670             // check name
671             PropertyData<?> nameProp = properties.getProperties().get(PropertyIds.NAME);
672             if (nameProp != null) {
673                 assertPropertyValue(folderChild.getObject().getProperties(), PropertyIds.NAME, PropertyString.class,
674                         nameProp.getFirstValue());
675             }
676 
677             // check object type
678             PropertyData<?> typeProp = properties.getProperties().get(PropertyIds.OBJECT_TYPE_ID);
679             assertNotNull(typeProp);
680             assertPropertyValue(folderChild.getObject().getProperties(), PropertyIds.OBJECT_TYPE_ID, PropertyId.class,
681                     typeProp.getFirstValue());
682 
683             // check parent
684             List<ObjectParentData> parents = getBinding().getNavigationService().getObjectParents(
685                     getTestRepositoryId(), objectId, "*", Boolean.TRUE, IncludeRelationships.BOTH, null, Boolean.TRUE,
686                     null);
687             assertNotNull(parents);
688             assertEquals(1, parents.size());
689 
690             ObjectParentData parent = parents.get(0);
691             assertNotNull(parent);
692             assertNotNull(parent.getRelativePathSegment());
693             assertNotNull(parent.getObject());
694             assertNotNull(parent.getObject().getProperties().getProperties());
695             assertNotNull(parent.getObject().getProperties().getProperties().get(PropertyIds.OBJECT_ID));
696             assertEquals(folderId, parent.getObject().getProperties().getProperties().get(PropertyIds.OBJECT_ID)
697                     .getFirstValue());
698 
699             // get document by path (check relative path segment)
700             assertNotNull(parent.getObject().getProperties().getProperties().get(PropertyIds.PATH));
701             String parentPath = parent.getObject().getProperties().getProperties().get(PropertyIds.PATH)
702                     .getFirstValue().toString();
703 
704             ObjectData docByPath = getObjectByPath((parentPath.equals("/") ? "" : parentPath) + "/"
705                     + folderChild.getPathSegment());
706 
707             PropertyData<?> idProp = docByPath.getProperties().getProperties().get(PropertyIds.OBJECT_ID);
708             assertNotNull(idProp);
709             assertEquals(objectId, idProp.getFirstValue());
710         } else {
711             List<ObjectParentData> parents = getBinding().getNavigationService().getObjectParents(
712                     getTestRepositoryId(), objectId, null, Boolean.TRUE, IncludeRelationships.BOTH, null, Boolean.TRUE,
713                     null);
714             assertNotNull(parents);
715             assertEquals(0, parents.size());
716         }
717 
718         return objectId;
719     }
720 
721     /**
722      * Creates a document with the default type.
723      */
724     protected String createDefaultDocument(String folderId, String name, String contentType, byte[] content) {
725         VersioningState vs = (isVersionable(getDefaultDocumentType()) ? VersioningState.MAJOR : VersioningState.NONE);
726 
727         List<PropertyData<?>> propList = new ArrayList<PropertyData<?>>();
728         propList.add(getObjectFactory().createPropertyStringData(PropertyIds.NAME, name));
729         propList.add(getObjectFactory().createPropertyIdData(PropertyIds.OBJECT_TYPE_ID, getDefaultDocumentType()));
730 
731         Properties properties = getObjectFactory().createPropertiesData(propList);
732 
733         ContentStream contentStream = createContentStreamData(contentType, content);
734 
735         return createDocument(properties, folderId, contentStream, vs, null, null, null);
736     }
737 
738     /**
739      * Creates a document from source.
740      */
741     protected String createDocumentFromSource(String sourceId, Properties properties, String folderId,
742             VersioningState versioningState, List<String> policies, Acl addACEs, Acl removeACEs) {
743         String objectId = getBinding().getObjectService().createDocumentFromSource(getTestRepositoryId(), sourceId,
744                 properties, folderId, versioningState, policies, addACEs, removeACEs, null);
745         assertNotNull(objectId);
746         assertTrue(existsObject(objectId));
747 
748         if (folderId != null) {
749             ObjectInFolderData folderChild = getChild(folderId, objectId);
750 
751             // check name
752             PropertyData<?> nameProp = properties.getProperties().get(PropertyIds.NAME);
753             if (nameProp != null) {
754                 assertPropertyValue(folderChild.getObject().getProperties(), PropertyIds.NAME, PropertyString.class,
755                         nameProp.getValues().get(0));
756             }
757 
758             // check parent
759             List<ObjectParentData> parents = getBinding().getNavigationService().getObjectParents(
760                     getTestRepositoryId(), objectId, null, Boolean.TRUE, IncludeRelationships.BOTH, null, Boolean.TRUE,
761                     null);
762             assertNotNull(parents);
763             assertEquals(1, parents.size());
764 
765             ObjectParentData parent = parents.get(0);
766             assertNotNull(parent);
767             assertNotNull(parent.getRelativePathSegment());
768             assertNotNull(parent.getObject());
769             assertNotNull(parent.getObject().getProperties().getProperties());
770             assertNotNull(parent.getObject().getProperties().getProperties().get(PropertyIds.OBJECT_ID));
771             assertEquals(folderId, parent.getObject().getProperties().getProperties().get(PropertyIds.OBJECT_ID)
772                     .getFirstValue());
773         }
774 
775         return objectId;
776     }
777 
778     /**
779      * Deletes an object.
780      */
781     protected void delete(String objectId, boolean allVersions) {
782         getBinding().getObjectService().deleteObject(getTestRepositoryId(), objectId, allVersions, null);
783         assertFalse(existsObject(objectId));
784     }
785 
786     /**
787      * Deletes a tree.
788      */
789     protected void deleteTree(String folderId) {
790         getBinding().getObjectService().deleteTree(getTestRepositoryId(), folderId, Boolean.TRUE, UnfileObject.DELETE,
791                 Boolean.TRUE, null);
792         assertFalse(existsObject(folderId));
793     }
794 
795     /**
796      * Gets a content stream.
797      */
798     protected ContentStream getContent(String objectId, String streamId) {
799         ContentStream contentStream = getBinding().getObjectService().getContentStream(getTestRepositoryId(), objectId,
800                 streamId, null, null, null);
801         assertNotNull(contentStream);
802         assertNotNull(contentStream.getMimeType());
803         assertNotNull(contentStream.getStream());
804 
805         return contentStream;
806     }
807 
808     /**
809      * Reads the content from a content stream into a byte array.
810      */
811     protected byte[] readContent(ContentStream contentStream) throws Exception {
812         assertNotNull(contentStream);
813         assertNotNull(contentStream.getStream());
814 
815         InputStream stream = contentStream.getStream();
816         ByteArrayOutputStream baos = new ByteArrayOutputStream();
817 
818         IOUtils.copy(stream, baos);
819 
820         return baos.toByteArray();
821     }
822 
823     /**
824      * Returns a type definition.
825      */
826     protected TypeDefinition getTypeDefinition(String typeName) {
827         TypeDefinition typeDef = getBinding().getRepositoryService().getTypeDefinition(getTestRepositoryId(), typeName,
828                 null);
829 
830         assertNotNull(typeDef);
831         assertNotNull(typeDef.getId());
832 
833         return typeDef;
834     }
835 
836     /**
837      * Returns if the type is versionable.
838      */
839     protected boolean isVersionable(String typeName) {
840         TypeDefinition type = getTypeDefinition(typeName);
841 
842         assertTrue(type instanceof DocumentTypeDefinition);
843 
844         Boolean isVersionable = ((DocumentTypeDefinition) type).isVersionable();
845         assertNotNull(isVersionable);
846 
847         return isVersionable;
848     }
849 
850     // ---- asserts ----
851 
852     protected void assertEquals(TypeDefinition expected, TypeDefinition actual, boolean checkPropertyDefintions) {
853         if (expected == null && actual == null) {
854             return;
855         }
856 
857         if (expected == null) {
858             fail("Expected type definition is null!");
859         }
860 
861         if (actual == null) {
862             fail("Actual type definition is null!");
863         }
864 
865         assertEquals("TypeDefinition id:", expected.getId(), actual.getId());
866         assertEquals("TypeDefinition local name:", expected.getLocalName(), actual.getLocalName());
867         assertEquals("TypeDefinition local namespace:", expected.getLocalNamespace(), actual.getLocalNamespace());
868         assertEquals("TypeDefinition display name:", expected.getDisplayName(), actual.getDisplayName());
869         assertEquals("TypeDefinition description:", expected.getDescription(), actual.getDescription());
870         assertEquals("TypeDefinition query name:", expected.getQueryName(), actual.getQueryName());
871         assertEquals("TypeDefinition parent id:", expected.getParentTypeId(), actual.getParentTypeId());
872         assertEquals("TypeDefinition base id:", expected.getBaseTypeId(), actual.getBaseTypeId());
873 
874         if (!checkPropertyDefintions) {
875             return;
876         }
877 
878         if (expected.getPropertyDefinitions() == null && actual.getPropertyDefinitions() == null) {
879             return;
880         }
881 
882         if (expected.getPropertyDefinitions() == null) {
883             fail("Expected property definition list is null!");
884         }
885 
886         if (actual.getPropertyDefinitions() == null) {
887             fail("Actual property definition list is null!");
888         }
889 
890         assertEquals(expected.getPropertyDefinitions().size(), actual.getPropertyDefinitions().size());
891 
892         for (PropertyDefinition<?> expectedPropDef : expected.getPropertyDefinitions().values()) {
893             PropertyDefinition<?> actualPropDef = actual.getPropertyDefinitions().get(expectedPropDef.getId());
894 
895             assertEquals(expectedPropDef, actualPropDef);
896         }
897     }
898 
899     protected void assertEquals(PropertyDefinition<?> expected, PropertyDefinition<?> actual) {
900         if (expected == null && actual == null) {
901             return;
902         }
903 
904         if (expected == null) {
905             fail("Expected property definition is null!");
906         }
907 
908         if (actual == null) {
909             fail("Actual property definition is null!");
910         }
911 
912         assertNotNull(expected.getId());
913         assertNotNull(actual.getId());
914 
915         String id = expected.getId();
916 
917         assertEquals("PropertyDefinition " + id + " id:", expected.getId(), actual.getId());
918         assertEquals("PropertyDefinition " + id + " local name:", expected.getLocalName(), actual.getLocalName());
919         assertEquals("PropertyDefinition " + id + " local namespace:", expected.getLocalNamespace(),
920                 actual.getLocalNamespace());
921         assertEquals("PropertyDefinition " + id + " query name:", expected.getQueryName(), actual.getQueryName());
922         assertEquals("PropertyDefinition " + id + " display name:", expected.getDisplayName(), actual.getDisplayName());
923         assertEquals("PropertyDefinition " + id + " description:", expected.getDescription(), actual.getDescription());
924         assertEquals("PropertyDefinition " + id + " property type:", expected.getPropertyType(),
925                 actual.getPropertyType());
926         assertEquals("PropertyDefinition " + id + " cardinality:", expected.getCardinality(), actual.getCardinality());
927         assertEquals("PropertyDefinition " + id + " updatability:", expected.getUpdatability(),
928                 actual.getUpdatability());
929     }
930 
931     protected void assertEquals(Properties expected, Properties actual) {
932         if (expected == null && actual == null) {
933             return;
934         }
935 
936         if (expected == null) {
937             fail("Expected properties data is null!");
938         }
939 
940         if (actual == null) {
941             fail("Actual properties data is null!");
942         }
943 
944         if (expected.getProperties() == null && actual.getProperties() == null) {
945             return;
946         }
947 
948         if (expected.getProperties() == null || actual.getProperties() == null) {
949             fail("Properties are null!");
950         }
951 
952         if (expected.getProperties() == null) {
953             fail("Expected properties are null!");
954         }
955 
956         if (actual.getProperties() == null) {
957             fail("Actual properties are null!");
958         }
959 
960         assertEquals(expected.getProperties().size(), actual.getProperties().size());
961 
962         for (String id : expected.getProperties().keySet()) {
963             PropertyData<?> expectedProperty = expected.getProperties().get(id);
964             assertNotNull(expectedProperty);
965             assertEquals(id, expectedProperty.getId());
966 
967             PropertyData<?> actualProperty = actual.getProperties().get(id);
968             assertNotNull(actualProperty);
969             assertEquals(id, actualProperty.getId());
970 
971             assertEquals(expectedProperty, actualProperty);
972         }
973     }
974 
975     protected void assertEquals(PropertyData<?> expected, PropertyData<?> actual) {
976         if (expected == null && actual == null) {
977             return;
978         }
979 
980         if (expected == null || actual == null) {
981             fail("Properties data is null!");
982         }
983 
984         String id = expected.getId();
985 
986         assertEquals("PropertyData " + id + " id:", expected.getId(), actual.getId());
987         assertEquals("PropertyData " + id + " display name:", expected.getDisplayName(), actual.getDisplayName());
988         assertEquals("PropertyData " + id + " local name:", expected.getLocalName(), actual.getLocalName());
989         assertEquals("PropertyData " + id + " query name:", expected.getQueryName(), actual.getQueryName());
990 
991         assertEquals("PropertyData " + id + " values:", expected.getValues().size(), actual.getValues().size());
992 
993         for (int i = 0; i < expected.getValues().size(); i++) {
994             assertEquals("PropertyData " + id + " value[" + i + "]:", expected.getValues().get(i), actual.getValues()
995                     .get(i));
996         }
997     }
998 
999     protected void assertBasicProperties(Properties properties) {
1000         assertNotNull(properties);
1001         assertNotNull(properties.getProperties());
1002 
1003         assertProperty(properties.getProperties().get(PropertyIds.OBJECT_ID), PropertyIds.OBJECT_ID, PropertyId.class);
1004         assertProperty(properties.getProperties().get(PropertyIds.OBJECT_TYPE_ID), PropertyIds.OBJECT_TYPE_ID,
1005                 PropertyId.class);
1006         assertProperty(properties.getProperties().get(PropertyIds.BASE_TYPE_ID), PropertyIds.BASE_TYPE_ID,
1007                 PropertyId.class);
1008         assertProperty(properties.getProperties().get(PropertyIds.NAME), PropertyIds.NAME, PropertyString.class);
1009         assertProperty(properties.getProperties().get(PropertyIds.CREATED_BY), PropertyIds.CREATED_BY,
1010                 PropertyString.class);
1011         assertProperty(properties.getProperties().get(PropertyIds.CREATION_DATE), PropertyIds.CREATION_DATE,
1012                 PropertyDateTime.class);
1013         assertProperty(properties.getProperties().get(PropertyIds.LAST_MODIFIED_BY), PropertyIds.LAST_MODIFIED_BY,
1014                 PropertyString.class);
1015         assertProperty(properties.getProperties().get(PropertyIds.LAST_MODIFICATION_DATE),
1016                 PropertyIds.LAST_MODIFICATION_DATE, PropertyDateTime.class);
1017     }
1018 
1019     protected void assertProperty(PropertyData<?> property, String id, Class<?> clazz) {
1020         assertNotNull(property);
1021         assertNotNull(property.getId());
1022         assertEquals("PropertyData " + id + " id:", id, property.getId());
1023         assertTrue(clazz.isAssignableFrom(property.getClass()));
1024         assertNotNull(property.getValues());
1025         assertFalse(property.getValues().isEmpty());
1026     }
1027 
1028     protected void assertPropertyValue(PropertyData<?> property, String id, Class<?> clazz, Object... values) {
1029         assertProperty(property, id, clazz);
1030 
1031         assertEquals("Property " + id + " values:", values.length, property.getValues().size());
1032 
1033         int i = 0;
1034         for (Object value : property.getValues()) {
1035             assertEquals("Property " + id + " value[" + i + "]:", values[i], value);
1036             i++;
1037         }
1038     }
1039 
1040     protected void assertPropertyValue(Properties properties, String id, Class<?> clazz, Object... values) {
1041         assertNotNull(properties);
1042         assertNotNull(properties.getProperties());
1043 
1044         PropertyData<?> property = properties.getProperties().get(id);
1045         assertNotNull(property);
1046 
1047         assertPropertyValue(property, id, clazz, values);
1048     }
1049 
1050     protected void assertEquals(AllowableActions expected, AllowableActions actual) {
1051         if (expected == null && actual == null) {
1052             return;
1053         }
1054 
1055         if (expected == null) {
1056             fail("Expected allowable action data is null!");
1057         }
1058 
1059         if (actual == null) {
1060             fail("Actual allowable action data is null!");
1061         }
1062 
1063         assertNotNull(expected.getAllowableActions());
1064         assertNotNull(actual.getAllowableActions());
1065 
1066         assertEquals("Allowable action size:", expected.getAllowableActions().size(), actual.getAllowableActions()
1067                 .size());
1068 
1069         for (Action action : expected.getAllowableActions()) {
1070             boolean expectedBoolean = expected.getAllowableActions().contains(action);
1071             boolean actualBoolean = actual.getAllowableActions().contains(action);
1072 
1073             assertEquals("AllowableAction " + action + ":", expectedBoolean, actualBoolean);
1074         }
1075     }
1076 
1077     protected void assertAllowableAction(AllowableActions allowableActions, Action action, boolean expected) {
1078         assertNotNull(allowableActions);
1079         assertNotNull(allowableActions.getAllowableActions());
1080         assertNotNull(action);
1081 
1082         assertEquals("Allowable action \"" + action + "\":", expected,
1083                 allowableActions.getAllowableActions().contains(action));
1084     }
1085 
1086     protected void assertEquals(Acl expected, Acl actual) {
1087         if (expected == null && actual == null) {
1088             return;
1089         }
1090 
1091         if (expected == null) {
1092             fail("Expected ACL data is null!");
1093         }
1094 
1095         if (actual == null) {
1096             fail("Actual ACL data is null!");
1097         }
1098 
1099         if (expected.getAces() == null && actual.getAces() == null) {
1100             return;
1101         }
1102 
1103         if (expected.getAces() == null) {
1104             fail("Expected ACE data is null!");
1105         }
1106 
1107         if (actual.getAces() == null) {
1108             fail("Actual ACE data is null!");
1109         }
1110 
1111         // assertEquals(expected.isExact(), actual.isExact());
1112         assertEquals(expected.getAces().size(), actual.getAces().size());
1113 
1114         for (int i = 0; i < expected.getAces().size(); i++) {
1115             assertEquals(expected.getAces().get(i), actual.getAces().get(i));
1116         }
1117     }
1118 
1119     protected void assertEquals(Ace expected, Ace actual) {
1120         if (expected == null && actual == null) {
1121             return;
1122         }
1123 
1124         if (expected == null) {
1125             fail("Expected ACE data is null!");
1126         }
1127 
1128         if (actual == null) {
1129             fail("Actual ACE data is null!");
1130         }
1131 
1132         assertNotNull(expected.getPrincipal());
1133         assertNotNull(expected.getPrincipal().getId());
1134         assertNotNull(actual.getPrincipal());
1135         assertNotNull(actual.getPrincipal().getId());
1136         assertEquals("ACE Principal:", expected.getPrincipal().getId(), actual.getPrincipal().getId());
1137 
1138         assertEqualLists(expected.getPermissions(), actual.getPermissions());
1139     }
1140 
1141     protected void assertEquals(RenditionData expected, RenditionData actual) {
1142         if (expected == null && actual == null) {
1143             return;
1144         }
1145 
1146         if (expected == null) {
1147             fail("Expected rendition is null!");
1148         }
1149 
1150         if (actual == null) {
1151             fail("Actual rendition is null!");
1152         }
1153 
1154         assertEquals("Rendition kind:", expected.getKind(), actual.getKind());
1155         assertEquals("Rendition MIME type:", expected.getMimeType(), actual.getMimeType());
1156         assertEquals("Rendition length:", expected.getBigLength(), actual.getBigLength());
1157         assertEquals("Rendition stream id:", expected.getStreamId(), actual.getStreamId());
1158         assertEquals("Rendition title:", expected.getTitle(), actual.getTitle());
1159         assertEquals("Rendition height:", expected.getBigHeight(), actual.getBigHeight());
1160         assertEquals("Rendition width:", expected.getBigWidth(), actual.getBigWidth());
1161         assertEquals("Rendition document id:", expected.getRenditionDocumentId(), actual.getRenditionDocumentId());
1162     }
1163 
1164     protected void assertContent(byte[] expected, byte[] actual) {
1165         assertNotNull(expected);
1166         assertNotNull(actual);
1167 
1168         assertEquals("Content size:", expected.length, actual.length);
1169 
1170         for (int i = 0; i < expected.length; i++) {
1171             assertEquals("Content not equal.", expected[i], actual[i]);
1172         }
1173     }
1174 
1175     protected void assertMimeType(String expected, String actual) {
1176         assertNotNull(expected);
1177         assertNotNull(actual);
1178 
1179         int paramIdx = actual.indexOf(';');
1180         if (paramIdx != -1) {
1181             actual = actual.substring(0, paramIdx);
1182         }
1183 
1184         assertEquals(expected, actual);
1185     }
1186 
1187     protected void assertEqualLists(List<?> expected, List<?> actual) {
1188         if (expected == null && actual == null) {
1189             return;
1190         }
1191 
1192         if (expected == null) {
1193             fail("Expected list is null!");
1194         }
1195 
1196         if (actual == null) {
1197             fail("Actual list is null!");
1198         }
1199 
1200         assertEquals("List size:", expected.size(), actual.size());
1201 
1202         for (int i = 0; i < expected.size(); i++) {
1203             assertEquals("List element " + i + ":", expected.get(i), actual.get(i));
1204         }
1205     }
1206 }