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