This project has retired. For details please refer to its Attic page.
ObjectServiceTest 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.inmemory;
20  
21  import static org.junit.Assert.assertEquals;
22  import static org.junit.Assert.assertFalse;
23  import static org.junit.Assert.assertNotNull;
24  import static org.junit.Assert.assertNull;
25  import static org.junit.Assert.assertTrue;
26  import static org.junit.Assert.fail;
27  
28  import java.math.BigInteger;
29  import java.util.ArrayList;
30  import java.util.HashMap;
31  import java.util.LinkedList;
32  import java.util.List;
33  import java.util.Map;
34  import java.util.Set;
35  
36  import org.apache.chemistry.opencmis.commons.PropertyIds;
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.ObjectInFolderList;
43  import org.apache.chemistry.opencmis.commons.data.ObjectParentData;
44  import org.apache.chemistry.opencmis.commons.data.Properties;
45  import org.apache.chemistry.opencmis.commons.data.PropertyData;
46  import org.apache.chemistry.opencmis.commons.definitions.PropertyDefinition;
47  import org.apache.chemistry.opencmis.commons.definitions.TypeDefinition;
48  import org.apache.chemistry.opencmis.commons.enums.Action;
49  import org.apache.chemistry.opencmis.commons.enums.IncludeRelationships;
50  import org.apache.chemistry.opencmis.commons.enums.UnfileObject;
51  import org.apache.chemistry.opencmis.commons.enums.Updatability;
52  import org.apache.chemistry.opencmis.commons.enums.VersioningState;
53  import org.apache.chemistry.opencmis.commons.exceptions.CmisConstraintException;
54  import org.apache.chemistry.opencmis.commons.exceptions.CmisContentAlreadyExistsException;
55  import org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentException;
56  import org.apache.chemistry.opencmis.commons.exceptions.CmisNameConstraintViolationException;
57  import org.apache.chemistry.opencmis.commons.exceptions.CmisNotSupportedException;
58  import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
59  import org.apache.chemistry.opencmis.commons.exceptions.CmisUpdateConflictException;
60  import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyIntegerDefinitionImpl;
61  import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyStringDefinitionImpl;
62  import org.apache.chemistry.opencmis.commons.spi.Holder;
63  import org.apache.chemistry.opencmis.inmemory.storedobj.impl.ContentStreamDataImpl;
64  import org.apache.chemistry.opencmis.inmemory.types.InMemoryDocumentTypeDefinition;
65  import org.apache.chemistry.opencmis.inmemory.types.InMemoryFolderTypeDefinition;
66  import org.apache.chemistry.opencmis.inmemory.types.PropertyCreationHelper;
67  import org.apache.chemistry.opencmis.util.repository.ObjectGenerator;
68  import org.apache.commons.logging.Log;
69  import org.apache.commons.logging.LogFactory;
70  import org.junit.After;
71  import org.junit.Before;
72  import org.junit.Test;
73  
74  /**
75   * @author Jens
76   */
77  
78  public class ObjectServiceTest extends AbstractServiceTest {
79  
80      private static final Log log = LogFactory.getLog(ObjectServiceTest.class);
81      public static final String TEST_FOLDER_TYPE_ID = "MyFolderType";
82      public static final String TEST_DOCUMENT_TYPE_ID = "MyDocumentType";
83      public static final String TEST_DOC_TYPE_WITH_DEFAULTS_ID = "DocumentTypeWithDefault";
84      public static final String TEST_FOLDER_TYPE_WITH_DEFAULTS_ID = "FolderTypeWithDefault";
85      public static final String TEST_FOLDER_STRING_PROP_ID = "MyFolderStringProp";
86      public static final String TEST_DOCUMENT_STRING_PROP_ID = "MyDocumentStringProp";
87      private static final String TEST_CUSTOM_DOCUMENT_TYPE_ID = "MyCustomDocumentType";
88      private static final String TEST_INHERITED_CUSTOM_DOCUMENT_TYPE_ID = "MyCustomInheritedDocType";
89      private static final String TEST_DOCUMENT_MY_STRING_PROP_ID = "MyCustomDocumentStringProp";
90      private static final String TEST_DOCUMENT_MY_MULTI_STRING_PROP_ID = "MyCustomDocumentMultiStringProp";
91      private static final String TEST_DOCUMENT_MY_INT_PROP_ID = "MyCustomDocumentIntProp";
92      private static final String TEST_DOCUMENT_MY_INT_PROP_ID_MANDATORY_DEFAULT = "MyCustomDocumentIntPropMandatoryDefault";
93      private static final String TEST_FOLDER_MY_MULTI_STRING_PROP_ID = "MyCustomDocumentMultiStringProp";
94      private static final String TEST_FOLDER_MY_INT_PROP_ID = "MyCustomDocumentIntProp";
95      private static final String TEST_FOLDER_MY_INT_PROP_ID_MANDATORY_DEFAULT = "MyCustomDocumentIntPropMandatoryDefault";
96      private static final String TEST_DOCUMENT_MY_SUB_STRING_PROP_ID = "MyInheritedStringProp";
97      private static final String TEST_DOCUMENT_MY_SUB_INT_PROP_ID = "MyInheritedIntProp";
98  
99      private static final String DOCUMENT_TYPE_ID = InMemoryDocumentTypeDefinition.getRootDocumentType().getId();
100     private static final String DOCUMENT_ID = "Document_1";
101     private static final String FOLDER_TYPE_ID = InMemoryFolderTypeDefinition.getRootFolderType().getId();
102     private static final String FOLDER_ID = "Folder_1";
103     private static final String MY_CUSTOM_NAME = "My Custom Document";
104     private static final int MAX_SIZE = 100;
105 
106     ObjectCreator fCreator;
107 
108     @Override
109     @Before
110     public void setUp() {
111         super.setTypeCreatorClass(ObjectTestTypeSystemCreator.class.getName());
112         super.setUp();
113         fCreator = new ObjectCreator(fFactory, fObjSvc, fRepositoryId);
114     }
115 
116     @Override
117     @After
118     public void tearDown() {
119         super.tearDown();
120     }
121 
122     @Override
123     protected void addParameters(Map<String, String> parameters) {
124         parameters.put(ConfigConstants.MAX_CONTENT_SIZE_KB, Integer.valueOf(MAX_SIZE).toString());
125     }
126 
127     @Test
128     public void testCreateDocument() {
129         log.info("starting testCreateObject() ...");
130         String id = createDocument(fRootFolderId, false);
131         if (id != null) {
132             log.info("createDocument succeeded with created id: " + id);
133         }
134         log.info("... testCreateObject() finished.");
135 
136         // test create a document with a folder type, should fail:
137         try {
138             Properties props = createDocumentProperties("DocumentWithAFolderType", FOLDER_TYPE_ID);
139             id = fObjSvc.createDocument(fRepositoryId, props, fRootFolderId, null, VersioningState.NONE, null, null,
140                     null, null);
141             assertNotNull(id);
142             fail("Creating  document with a folder type should fail.");
143         } catch (Exception e) {
144             log.info("Creating  document with a folder type failed as expected.");
145         }
146         // test create a document with an illegal name, should fail:
147         try {
148             Properties props = createDocumentProperties("abc ()", DOCUMENT_TYPE_ID);
149             fObjSvc.createDocument(fRepositoryId, props, fRootFolderId, null, VersioningState.NONE, null, null,
150                     null, null);
151             fail("Creating  document with an illegal name should fail.");
152         } catch (Exception e) {
153             assertTrue(e instanceof CmisInvalidArgumentException);
154             log.info("Creating  document with an illegal name failed as expected.");
155         }
156     }
157 
158     @Test
159     public void testCreateDocumentInvalidNames() {
160         try {
161             createDocumentNoCatch(null, fRootFolderId, DOCUMENT_TYPE_ID, VersioningState.NONE, false);
162             fail("Document creation with null name should fail.");
163         } catch (Exception e) {
164             assertTrue(e instanceof CmisInvalidArgumentException);
165         }
166 
167         try {
168             createDocumentNoCatch("", fRootFolderId, DOCUMENT_TYPE_ID, VersioningState.NONE, false);
169             fail("Document creation with empty name should fail.");
170         } catch (Exception e) {
171             assertTrue(e instanceof CmisInvalidArgumentException);
172         }
173 
174         try {
175             createDocumentNoCatch("/(%#$�", fRootFolderId, DOCUMENT_TYPE_ID, VersioningState.NONE, false);
176             fail("Document creation with ilegal name should fail.");
177         } catch (Exception e) {
178             assertTrue(e instanceof CmisInvalidArgumentException);
179         }
180 
181         try {
182             createDocumentNoCatch("DuplicatedName", fRootFolderId, DOCUMENT_TYPE_ID, VersioningState.NONE, false);
183             createDocumentNoCatch("DuplicatedName", fRootFolderId, DOCUMENT_TYPE_ID, VersioningState.NONE, false);
184             fail("Document creation with existing name should fail.");
185         } catch (Exception e) {
186             assertTrue(e instanceof CmisNameConstraintViolationException);
187         }
188     }
189 
190     @Test
191     public void testCreateFolderInvalidNames() {
192         try {
193             createFolderNoCatch(null, fRootFolderId, FOLDER_TYPE_ID);
194             fail("Folder creation with null name should fail.");
195         } catch (Exception e) {
196             assertTrue(e instanceof CmisInvalidArgumentException);
197         }
198 
199         try {
200             createFolderNoCatch("", fRootFolderId, FOLDER_TYPE_ID);
201             fail("Folder creation with empty name should fail.");
202         } catch (Exception e) {
203             assertTrue(e instanceof CmisInvalidArgumentException);
204         }
205 
206         try {
207             createFolderNoCatch("/(%#$�", fRootFolderId, FOLDER_TYPE_ID);
208             fail("Folder creation with ilegal name should fail.");
209         } catch (Exception e) {
210             assertTrue(e instanceof CmisInvalidArgumentException);
211         }
212 
213         try {
214             createFolderNoCatch("DuplicatedName", fRootFolderId, FOLDER_TYPE_ID);
215             createFolderNoCatch("DuplicatedName", fRootFolderId, FOLDER_TYPE_ID);
216             fail("Folder creation with existing name should fail.");
217         } catch (Exception e) {
218             assertTrue(e instanceof CmisNameConstraintViolationException || e instanceof IllegalArgumentException);
219         }
220     }
221 
222     @Test
223     public void testGetObject() {
224         log.info("starting testGetObject() ...");
225         log.info("  creating object");
226         String id = createDocument(fRootFolderId, false);
227         if (id != null) {
228             log.info("  createDocument succeeded with created id: " + id);
229         }
230 
231         log.info("  getting object");
232         retrieveDocument(id);
233         log.info("... testGetObject() finished.");
234     }
235 
236     @Test
237     public void testGetObjectByPath() {
238         log.info("starting testGetObjectByPath() ...");
239         log.info("  creating object");
240 
241         // create a tree for testing paths
242         String f1 = createFolder("folder1", fRootFolderId, FOLDER_TYPE_ID);
243         String f2 = createFolder("folder2", fRootFolderId, FOLDER_TYPE_ID);
244         String f3 = createFolder("folder3", fRootFolderId, FOLDER_TYPE_ID);
245         String f11 = createFolder("folder1.1", f1, FOLDER_TYPE_ID);
246         String f12 = createFolder("folder1.2", f1, FOLDER_TYPE_ID);
247         String f13 = createFolder("folder1.3", f1, FOLDER_TYPE_ID);
248         String f31 = createFolder("folder3.1", f3, FOLDER_TYPE_ID);
249         String f32 = createFolder("folder3.2", f3, FOLDER_TYPE_ID);
250         String f33 = createFolder("folder3.3", f3, FOLDER_TYPE_ID);
251         String f121 = createFolder("folder1.2.1", f12, FOLDER_TYPE_ID);
252         String f122 = createFolder("folder1.2.2", f12, FOLDER_TYPE_ID);
253         String f123 = createFolder("folder1.2.3", f12, FOLDER_TYPE_ID);
254         String f331 = createFolder("folder3.3.1", f33, FOLDER_TYPE_ID);
255         String f332 = createFolder("folder3.3.2", f33, FOLDER_TYPE_ID);
256         String f333 = createFolder("folder3.3.3", f33, FOLDER_TYPE_ID);
257         String doc12 = createDocument("Document1.2.Doc", f12, false);
258         String doc33 = createDocument("Document3.3.Doc", f33, false);
259         String doc331 = createDocument("Document3.3.1.Doc", f331, false);
260         String doc333 = createDocument("Document3.3.3.Doc", f333, false);
261 
262         log.info("  getting object by path");
263         getByPath(f1, "/folder1");
264         getByPath(f2, "/folder2");
265         getByPath(f3, "/folder3");
266         getByPath(f11, "/folder1/folder1.1");
267         getByPath(f12, "/folder1/folder1.2");
268         getByPath(f13, "/folder1/folder1.3");
269         getByPath(f31, "/folder3/folder3.1");
270         getByPath(f32, "/folder3/folder3.2");
271         getByPath(f33, "/folder3/folder3.3");
272         getByPath(f121, "/folder1/folder1.2/folder1.2.1");
273         getByPath(f122, "/folder1/folder1.2/folder1.2.2");
274         getByPath(f123, "/folder1/folder1.2/folder1.2.3");
275         getByPath(f331, "/folder3/folder3.3/folder3.3.1");
276         getByPath(f332, "/folder3/folder3.3/folder3.3.2");
277         getByPath(f333, "/folder3/folder3.3/folder3.3.3");
278         getByPath(doc12, "/folder1/folder1.2/Document1.2.Doc");
279         getByPath(doc33, "/folder3/folder3.3/Document3.3.Doc");
280         getByPath(doc331, "/folder3/folder3.3/folder3.3.1/Document3.3.1.Doc");
281         getByPath(doc333, "/folder3/folder3.3/folder3.3.3/Document3.3.3.Doc");
282 
283         log.info("... testGetObjectByPath() finished.");
284     }
285 
286     @Test
287     public void testCreateDocumentWithContent() {
288         log.info("starting testCreateDocumentWithContent() ...");
289         String id = createDocument(fRootFolderId, true);
290         if (id != null) {
291             log.info("createDocument succeeded with created id: " + id);
292         }
293 
294         ContentStream sd = fObjSvc.getContentStream(fRepositoryId, id, null, BigInteger.valueOf(-1) /* offset */,
295                 BigInteger.valueOf(-1) /* length */, null);
296         verifyContentResult(sd);
297 
298         // delete content again
299         Holder<String> idHolder = new Holder<String>(id);
300         Properties props = fObjSvc.getProperties(fRepositoryId, id, PropertyIds.CHANGE_TOKEN, null);
301         String changeToken = (String) props.getProperties().get(PropertyIds.CHANGE_TOKEN).getFirstValue();
302         Holder<String> tokenHolder = new Holder<String>(changeToken);
303         fObjSvc.deleteContentStream(fRepositoryId, idHolder, tokenHolder, null);
304         
305         try {
306             props = fObjSvc.getProperties(fRepositoryId, id, PropertyIds.CHANGE_TOKEN, null);
307             changeToken = (String) props.getProperties().get(PropertyIds.CHANGE_TOKEN).getFirstValue();
308             tokenHolder = new Holder<String>(changeToken);
309             sd = fObjSvc.getContentStream(fRepositoryId, id, null, BigInteger.valueOf(-1) /* offset */, BigInteger
310                     .valueOf(-1) /* length */, null);
311             fail("getContentStream with non existing content should raise a CmisConstraintException");
312         } catch (Exception e) {
313             assertTrue(e instanceof CmisConstraintException);
314         }
315         
316         // create content again in a second call
317         ContentStream contentStream = createContent();
318         fObjSvc.setContentStream(fRepositoryId, idHolder, true, tokenHolder, contentStream, null);
319         sd = fObjSvc.getContentStream(fRepositoryId, id, null, BigInteger.valueOf(-1) /* offset */, BigInteger
320                 .valueOf(-1) /* length */, null);
321         verifyContentResult(sd);
322 
323         // update content and do not set overwrite flag, expect failure
324         try {
325             props = fObjSvc.getProperties(fRepositoryId, id, PropertyIds.CHANGE_TOKEN, null);
326             changeToken = (String) props.getProperties().get(PropertyIds.CHANGE_TOKEN).getFirstValue();
327             tokenHolder = new Holder<String>(changeToken);
328             fObjSvc.setContentStream(fRepositoryId, idHolder, false, tokenHolder, contentStream, null);
329             fail("setContentStream with existing content and no overWriteFlag should fail");
330         } catch (Exception e) {
331             assertTrue(e instanceof CmisContentAlreadyExistsException);
332         }
333 
334         // cleanup
335         fObjSvc.deleteObject(fRepositoryId, id, true, null);
336 
337         log.info("... testCreateDocumentWithContent() finished.");
338     }
339 
340     @Test
341     public void testCreateDocumentWithContentNoFileNameNoMimeType() {
342         log.info("starting testCreateDocumentWithContent() ...");
343         ContentStreamDataImpl contentStream = null;
344         List<String> policies = null;
345         Acl addACEs = null;
346         Acl removeACEs = null;
347         ExtensionsData extension = null;
348 
349         Properties props = createDocumentProperties(DOCUMENT_ID, DOCUMENT_TYPE_ID);
350 
351         contentStream = (ContentStreamDataImpl) createContent();
352         contentStream.setFileName(null);
353         contentStream.setMimeType(null);
354 
355         String id = null;
356         try {
357             id = fObjSvc.createDocument(fRepositoryId, props, fRootFolderId, contentStream, VersioningState.NONE, policies,
358                     addACEs, removeACEs, extension);
359             if (null == id) {
360                 fail("createDocument failed.");
361             }
362 
363             ContentStream sd = fObjSvc.getContentStream(fRepositoryId, id, null, BigInteger.valueOf(-1) /* offset */,
364                     BigInteger.valueOf(-1) /* length */, null);
365             assertNotNull(sd.getMimeType());
366             assertNotNull(sd.getFileName());
367         } catch (Exception e) {
368             fail("createDocument() failed with exception: " + e);
369         }
370     }
371 
372     @Test
373     public void testCreateDocumentFromSource() {
374         log.info("starting testCreateDocumentFromSource() ...");
375         // create a 1st document
376         String id1 = createDocument(fRootFolderId, true);
377         // create a second document with first as source
378         String id2 = null;
379         try {
380             VersioningState versioningState = VersioningState.NONE;
381             Properties props = createDocumentPropertiesForDocumentFromSource("Document From Source");
382             id2 = fObjSvc.createDocumentFromSource(fRepositoryId, id1, props, fRootFolderId, versioningState, null,
383                     null, null, null);
384             if (null == id2) {
385                 fail("createDocumentFromSource failed.");
386             }
387         } catch (Exception e) {
388             fail("createDocumentFromSource() failed with exception: " + e);
389         }
390 
391         // get content from second document and compare it with original one
392         ContentStream sd = fObjSvc.getContentStream(fRepositoryId, id2, null, BigInteger.valueOf(-1) /* offset */,
393                 BigInteger.valueOf(-1) /* length */, null);
394         verifyContentResult(sd);
395 
396         // cleanup
397         fObjSvc.deleteObject(fRepositoryId, id1, true, null);
398         fObjSvc.deleteObject(fRepositoryId, id2, true, null);
399 
400         log.info("... testCreateDocumentFromSource() finished.");
401     }
402 
403     @Test
404     public void testCreatedDocumentInherited() {
405         log.info("starting testCreatedDocumentInherited() ...");
406         log.info("  creating object");
407 
408         String id = createDocumentInheritedProperties(fRootFolderId, false);
409         if (id != null) {
410             log.info("  createDocument succeeded with created id: " + id);
411         }
412 
413         log.info("  getting object");
414         try {
415             ObjectData res = fObjSvc.getObject(fRepositoryId, id, "*", false, IncludeRelationships.NONE, null, false,
416                     false, null);
417             assertNotNull(res);
418 
419             String returnedId = res.getId();
420             assertEquals(id, returnedId);
421             Map<String, PropertyData<?>> props = res.getProperties().getProperties();
422             for (PropertyData<?> pd : props.values()) {
423                 log.info("return property id: " + pd.getId() + ", value: " + pd.getValues());
424             }
425 
426             PropertyData<?> pd = props.get(PropertyIds.NAME);
427             assertNotNull(pd);
428             assertEquals(MY_CUSTOM_NAME, pd.getFirstValue());
429 
430             pd = props.get(PropertyIds.OBJECT_TYPE_ID);
431             assertEquals(TEST_INHERITED_CUSTOM_DOCUMENT_TYPE_ID, pd.getFirstValue());
432 
433             pd = props.get(TEST_DOCUMENT_MY_STRING_PROP_ID);
434             assertEquals("My pretty string", pd.getFirstValue());
435 
436             pd = props.get(TEST_DOCUMENT_MY_INT_PROP_ID);
437             assertEquals(BigInteger.valueOf(4711), pd.getFirstValue());
438 
439             pd = props.get(TEST_DOCUMENT_MY_SUB_STRING_PROP_ID);
440             assertEquals("another cool string", pd.getFirstValue());
441 
442             pd = props.get(TEST_DOCUMENT_MY_SUB_INT_PROP_ID);
443             assertEquals(BigInteger.valueOf(4712), pd.getFirstValue());
444         } catch (Exception e) {
445             fail("getObject() failed with exception: " + e);
446         }
447         log.info("... testCreatedDocumentInherited() finished.");
448     }
449 
450     @Test
451     public void testBuildFolderAndDocuments() {
452         // Create a hierarchy of folders and fill it with some documents
453 
454         ObjectGenerator gen = new ObjectGenerator(fFactory, fNavSvc, fObjSvc, fRepSvc, fRepositoryId,
455                 ObjectGenerator.CONTENT_KIND.LoremIpsumText);
456         int levels = 2; // create a hierarchy with two levels
457         int childrenPerLevel = 2; // create two folders on each level
458 
459         gen.setNumberOfDocumentsToCreatePerFolder(1); // create one document in
460         // each folder
461 
462         // Set the type id for all created documents:
463         gen.setDocumentTypeId(TEST_DOCUMENT_TYPE_ID);
464 
465         // Set the type id for all created folders:
466         gen.setFolderTypeId(TEST_FOLDER_TYPE_ID);
467 
468         // set the properties the generator should fill with values for
469         // documents:
470         // Note: must be valid properties in type TEST_DOCUMENT_TYPE_ID
471         List<String> propsToSet = new ArrayList<String>();
472         propsToSet.add(TEST_DOCUMENT_STRING_PROP_ID);
473         gen.setDocumentPropertiesToGenerate(propsToSet);
474 
475         // set the properties the generator should fill with values for folders:
476         // Note: must be valid properties in type TEST_FOLDER_TYPE_ID
477         propsToSet = new ArrayList<String>();
478         propsToSet.add(TEST_FOLDER_STRING_PROP_ID);
479         gen.setFolderPropertiesToGenerate(propsToSet);
480 
481         // Build the tree
482         try {
483             gen.createFolderHierachy(levels, childrenPerLevel, fRootFolderId);
484             // Dump the tree
485             gen.dumpFolder(fRootFolderId, "*");
486         } catch (Exception e) {
487             fail("Could not create folder hierarchy with documents. " + e);
488         }
489     }
490 
491     @Test
492     public void testDeleteObject() {
493         log.info("starting testDeleteObject() ...");
494         log.info("Testing to delete a document");
495         log.info("  creating object");
496         String id = createDocument(fRootFolderId, false);
497         if (id != null) {
498             log.info("  createDocument succeeded with created id: " + id);
499         }
500 
501         log.info("  getting object");
502         retrieveDocument(id);
503         log.info("  deleting object");
504         try {
505             fObjSvc.deleteObject(fRepositoryId, id, true, null);
506         } catch (Exception e) {
507             fail("deleteObject() for document failed with exception: " + e);
508         }
509 
510         // check that it does not exist anymore
511         try {
512             fObjSvc.getObject(fRepositoryId, id, "*", false, IncludeRelationships.NONE, null, false, false, null);
513             fail("object should not longer exist after it was deleted.");
514         } catch (CmisObjectNotFoundException e) {
515             assertTrue(e instanceof CmisObjectNotFoundException);
516         } catch (Exception e) {
517             fail("getting deleted object should raise CMISObjectNotFoundException, but got " + e);
518         }
519 
520         log.info("Testing to delete an empty folder");
521         // create and delete an empty folder
522         id = createFolder();
523         try {
524             fObjSvc.deleteObject(fRepositoryId, id, true, null);
525         } catch (Exception e) {
526             fail("deleteObject() for folder failed with exception: " + e);
527         }
528         // check that it does not exist anymore
529         try {
530             fObjSvc.getObject(fRepositoryId, id, "*", false, IncludeRelationships.NONE, null, false, false, null);
531             fail("object should not longer exist after it was deleted.");
532         } catch (CmisObjectNotFoundException e) {
533             assertTrue(e instanceof CmisObjectNotFoundException);
534         } catch (Exception e) {
535             fail("getting deleted object should raise CMISObjectNotFoundException, but got " + e);
536         }
537 
538         // create a folder with a document and delete should fail
539         // create and delete an empty folder
540         log.info("Testing to delete a folder with a contained document");
541         String folderId;
542         folderId = createFolder();
543         id = createDocument(folderId, false);
544 
545         try {
546             fObjSvc.deleteObject(fRepositoryId, folderId, true, null);
547             fail("deleteObject() for folder with a document should fail.");
548         } catch (Exception e) {
549             assertTrue(e instanceof CmisConstraintException);
550         }
551         // should succeed if we first delete document then folder
552         try {
553             fObjSvc.deleteObject(fRepositoryId, id, true, null);
554             fObjSvc.deleteObject(fRepositoryId, folderId, true, null);
555         } catch (Exception e) {
556             fail("deleteObject() for document and folder failed with exception: " + e);
557         }
558         // check that it does not exist anymore
559         try {
560             fObjSvc.getObject(fRepositoryId, id, "*", false, IncludeRelationships.NONE, null, false, false, null);
561             fail("object should not longer exist after it was deleted.");
562         } catch (CmisObjectNotFoundException e) {
563             assertTrue(e instanceof CmisObjectNotFoundException);
564         } catch (Exception e) {
565             fail("getting deleted object should raise CMISObjectNotFoundException, but got " + e);
566         }
567         try {
568             fObjSvc.getObject(fRepositoryId, folderId, "*", false, IncludeRelationships.NONE, null, false, false, null);
569             fail("object should not longer exist after it was deleted.");
570         } catch (CmisObjectNotFoundException e) {
571             assertTrue(e instanceof CmisObjectNotFoundException);
572         } catch (Exception e) {
573             fail("getting deleted object should raise CMISObjectNotFoundException, but got " + e);
574         }
575         log.info("... testDeleteObject() finished.");
576     }
577 
578     @Test
579     public void testDeleteTree() {
580         log.info("starting testDeleteTree() ...");
581         ObjectGenerator gen = new ObjectGenerator(fFactory, fNavSvc, fObjSvc, fRepSvc, fRepositoryId,
582                 ObjectGenerator.CONTENT_KIND.LoremIpsumText);
583         String rootFolderId = createFolder();
584         // Set the type id for all created documents:
585         gen.setDocumentTypeId(InMemoryDocumentTypeDefinition.getRootDocumentType().getId());
586         // Set the type id for all created folders:
587         gen.setFolderTypeId(InMemoryFolderTypeDefinition.getRootFolderType().getId());
588         gen.setNumberOfDocumentsToCreatePerFolder(2); // create two documents in
589         // each folder
590         gen.createFolderHierachy(1, 1, rootFolderId);
591         try {
592             fObjSvc.deleteTree(fRepositoryId, rootFolderId, null /* true */, UnfileObject.DELETE, true, null);
593         } catch (Exception e) {
594             fail("deleteTree failed unexpected. " + e);
595         }
596         log.info("Dumping folder, should only contain one empty folder under root");
597         gen.dumpFolder(fRootFolderId, "*");
598 
599         // After that we should be not be able to get the root folder, because
600         // it should be deleted
601         try {
602             fObjSvc.getObject(fRepositoryId, rootFolderId, "*", false, IncludeRelationships.NONE, null, false, false,
603                     null);
604             fail("object should not longer exist after it was deleted.");
605         } catch (CmisObjectNotFoundException e) {
606             assertTrue(e instanceof CmisObjectNotFoundException);
607         } catch (Exception e) {
608             fail("getting deleted object should raise CMISObjectNotFoundException, but got " + e);
609         }
610         log.info("... testDeleteTree() finished.");
611     }
612 
613     @Test
614     public void testMoveFolder() {
615         log.info("starting testMoveFolder() ...");
616         moveObjectTest(true);
617         log.info("... testMoveFolder() finished.");
618     }
619 
620     @Test
621     public void testMoveDocument() {
622         log.info("starting testMoveDocument() ...");
623         moveObjectTest(false);
624         log.info("... testMoveDocument() finished.");
625     }
626 
627     @Test
628     public void testUpdateProperties() {
629         log.info("starting testUpdateProperties() ...");
630         String oldChangeToken, newChangeToken;
631         String id = createDocumentWithCustomType(fRootFolderId, false);
632         if (id != null) {
633             log.info("createDocument succeeded with created id: " + id);
634         }
635 
636         log.info("  getting object");
637         try {
638             ObjectData res = fObjSvc.getObject(fRepositoryId, id, "*", false, IncludeRelationships.NONE, null, false,
639                     false, null);
640             assertNotNull(res);
641             Map<String, PropertyData<?>> props = res.getProperties().getProperties();
642 
643             // check returned properties
644             for (PropertyData<?> pd : props.values()) {
645                 log.info("  return property id: " + pd.getId() + ", value: " + pd.getValues());
646             }
647 
648             String returnedId = res.getId();
649             assertEquals(id, returnedId);
650             PropertyData<?> pd = props.get(PropertyIds.NAME);
651             assertNotNull(pd);
652             assertEquals(MY_CUSTOM_NAME, pd.getFirstValue());
653             pd = props.get(PropertyIds.OBJECT_TYPE_ID);
654             assertEquals(TEST_CUSTOM_DOCUMENT_TYPE_ID, pd.getFirstValue());
655             pd = props.get(TEST_DOCUMENT_MY_STRING_PROP_ID);
656             assertEquals("My pretty string", pd.getFirstValue());
657             pd = props.get(TEST_DOCUMENT_MY_INT_PROP_ID);
658             assertEquals(BigInteger.valueOf(4711), pd.getFirstValue());
659 
660             // update properties:
661             log.info("updating property");
662             final String newStringPropVal = "My ugly string";
663             final BigInteger newIntPropVal = BigInteger.valueOf(815);
664             List<PropertyData<?>> properties = new ArrayList<PropertyData<?>>();
665             // properties.add(fFactory.createPropertyIdData(PropertyIds.CMIS_NAME
666             // , MY_CUSTOM_NAME));
667             // properties.add(fFactory.createPropertyIdData(PropertyIds.
668             // CMIS_OBJECT_TYPE_ID, TEST_CUSTOM_DOCUMENT_TYPE_ID));
669             // Generate some property values for custom attributes
670             properties.add(fFactory.createPropertyStringData(TEST_DOCUMENT_MY_STRING_PROP_ID, newStringPropVal));
671             properties.add(fFactory.createPropertyIntegerData(TEST_DOCUMENT_MY_INT_PROP_ID, newIntPropVal));
672             Properties newProps = fFactory.createPropertiesData(properties);
673 
674             Holder<String> idHolder = new Holder<String>(id);
675             Holder<String> changeTokenHolder = new Holder<String>();
676             fObjSvc.updateProperties(fRepositoryId, idHolder, changeTokenHolder, newProps, null);
677             oldChangeToken = changeTokenHolder.getValue(); // store for later
678             // use
679             // check if we now retrieve new values
680             res = fObjSvc.getObject(fRepositoryId, id, "*", false, IncludeRelationships.NONE, null, false, false, null);
681             assertNotNull(res);
682             props = res.getProperties().getProperties();
683             for (PropertyData<?> pd2 : props.values()) {
684                 log.info("  return property id: " + pd2.getId() + ", value: " + pd2.getValues());
685             }
686             returnedId = res.getId();
687             assertEquals(id, returnedId);
688             pd = props.get(PropertyIds.NAME);
689             assertNotNull(pd);
690             assertEquals(MY_CUSTOM_NAME, pd.getFirstValue());
691             pd = props.get(PropertyIds.OBJECT_TYPE_ID);
692             assertEquals(TEST_CUSTOM_DOCUMENT_TYPE_ID, pd.getFirstValue());
693             pd = props.get(TEST_DOCUMENT_MY_STRING_PROP_ID);
694             assertEquals(newStringPropVal, pd.getFirstValue());
695             pd = props.get(TEST_DOCUMENT_MY_INT_PROP_ID);
696             assertEquals(newIntPropVal, pd.getFirstValue());
697 
698             // Test delete properties
699             log.info("deleting property");
700             properties = new ArrayList<PropertyData<?>>();
701             properties.add(fFactory.createPropertyStringData(TEST_DOCUMENT_MY_STRING_PROP_ID, (String) null));
702             newProps = fFactory.createPropertiesData(properties);
703             Thread.sleep(100); // ensure new change token, timer resolution is
704             // not good enough
705             fObjSvc.updateProperties(fRepositoryId, idHolder, changeTokenHolder, newProps, null);
706             res = fObjSvc.getObject(fRepositoryId, id, "*", false, IncludeRelationships.NONE, null, false, false, null);
707             assertNotNull(res);
708             props = res.getProperties().getProperties();
709             for (PropertyData<?> pd2 : props.values()) {
710                 log.info("  return property id: " + pd2.getId() + ", value: " + pd2.getValues());
711             }
712             pd = props.get(TEST_DOCUMENT_MY_STRING_PROP_ID);
713             assertNull(pd.getFirstValue());
714             // delete a required property and expect exception:
715             properties = new ArrayList<PropertyData<?>>();
716             properties.add(fFactory.createPropertyIntegerData(TEST_DOCUMENT_MY_INT_PROP_ID, (BigInteger) null));
717             newProps = fFactory.createPropertiesData(properties);
718             idHolder = new Holder<String>(id);
719             try {
720                 fObjSvc.updateProperties(fRepositoryId, idHolder, changeTokenHolder, newProps, null);
721                 fail("Deleteing a required property should fail.");
722             } catch (Exception e) {
723                 assertTrue(e instanceof CmisConstraintException);
724             }
725 
726             // Test violation of property definition constraints
727             log.info("Test violation of property definition constraints");
728             properties = new ArrayList<PropertyData<?>>();
729             properties.add(fFactory.createPropertyStringData(TEST_DOCUMENT_MY_STRING_PROP_ID,
730                     "A very long String ABCDEFHIJKLMNOPQRSTUVWXYZ"));
731             newProps = fFactory.createPropertiesData(properties);
732             idHolder = new Holder<String>(id);
733             try {
734                 fObjSvc.updateProperties(fRepositoryId, idHolder, changeTokenHolder, newProps, null);
735                 fail("Exceeding max String lengt h should fail.");
736             } catch (Exception e) {
737                 assertTrue(e instanceof CmisConstraintException);
738             }
739             // Test stale token
740             log.info("Test stale token");
741             properties = new ArrayList<PropertyData<?>>();
742             properties.add(fFactory.createPropertyStringData(TEST_DOCUMENT_MY_STRING_PROP_ID, "ABC"));
743             newProps = fFactory.createPropertiesData(properties);
744             // set outdated token
745             newChangeToken = changeTokenHolder.getValue();
746             changeTokenHolder.setValue(oldChangeToken);
747             assertFalse(oldChangeToken.equals(newChangeToken));
748             try {
749                 fObjSvc.updateProperties(fRepositoryId, idHolder, changeTokenHolder, newProps, null);
750                 fail("Update with an outdated changeToken should fail.");
751             } catch (Exception e) {
752                 assertTrue(e instanceof CmisUpdateConflictException);
753             }
754 
755             // test a rename
756             log.info("Test renaming");
757             final String newName = "My Renamed Document"; // MY_CUSTOM_NAME
758             properties = new ArrayList<PropertyData<?>>();
759             properties.add(fFactory.createPropertyIdData(PropertyIds.NAME, newName));
760             newProps = fFactory.createPropertiesData(properties);
761             changeTokenHolder.setValue(newChangeToken);
762             fObjSvc.updateProperties(fRepositoryId, idHolder, changeTokenHolder, newProps, null);
763             id = idHolder.getValue(); // note that id is path and has changed!
764             res = fObjSvc.getObject(fRepositoryId, id, "*", false, IncludeRelationships.NONE, null, false, false, null);
765             assertNotNull(res);
766             props = res.getProperties().getProperties();
767             pd = props.get(PropertyIds.NAME);
768             assertNotNull(pd);
769             assertEquals(newName, pd.getFirstValue());
770 
771             // test rename with a conflicting name
772             createDocumentWithCustomType(fRootFolderId, false);
773             properties = new ArrayList<PropertyData<?>>();
774             properties.add(fFactory.createPropertyIdData(PropertyIds.NAME, MY_CUSTOM_NAME));
775             newProps = fFactory.createPropertiesData(properties);
776             // now rename to old name
777             try {
778                 fObjSvc.updateProperties(fRepositoryId, idHolder, changeTokenHolder, newProps, null);
779                 fail("Update with a conflicting name should fail.");
780             } catch (Exception e) {
781                 assertTrue(e instanceof CmisNameConstraintViolationException);
782             }
783 
784         } catch (Exception e) {
785             fail("getObject() failed with exception: " + e);
786         }
787         log.info("... testUpdateProperties() finished.");
788     }
789 
790     @Test
791     public void testAllowableActions() {
792         log.info("starting testAllowableActions() ...");
793         final boolean withContent = false;
794         String id = createDocument(fRootFolderId, withContent);
795 
796         // get allowable actions via getObject
797         ObjectData res = fObjSvc.getObject(fRepositoryId, id, "*", true, IncludeRelationships.NONE, null, false, false,
798                 null);
799         assertNotNull(res.getAllowableActions());
800         Set<Action> actions = res.getAllowableActions().getAllowableActions();
801         assertNotNull(actions);
802         verifyAllowableActionsDocument(actions, false, withContent);
803 
804         // get allowable actions via getAllowableActions
805         AllowableActions allowableActions = fObjSvc.getAllowableActions(fRepositoryId, id, null);
806         assertNotNull(allowableActions);
807         actions = allowableActions.getAllowableActions();
808         assertNotNull(actions);
809         verifyAllowableActionsDocument(actions, false, withContent);
810 
811         // cleanup
812         fObjSvc.deleteObject(fRepositoryId, id, true, null);
813         log.info("... testAllowableActions() finished.");
814     }
815 
816     @Test
817     public void testDefaultPropertiesDocument() {
818         log.info("starting testDefaultPropertiesDocument() ...");
819         String id = createDocument("DefPropDoc", fRootFolderId, TEST_DOC_TYPE_WITH_DEFAULTS_ID, false);
820         if (id != null) {
821             log.info("createDocument succeeded with created id: " + id);
822         }
823         ObjectData res = getDocumentObjectData(id);
824         Map<String, PropertyData<?>> props = res.getProperties().getProperties();
825         PropertyData<?> pd =  props.get(TEST_DOCUMENT_MY_INT_PROP_ID);
826         assertNotNull(pd);
827         Object bi = pd.getFirstValue();
828         assertNotNull(bi);
829         assertEquals(BigInteger.valueOf(100), bi);
830 
831         pd =  props.get(TEST_DOCUMENT_MY_MULTI_STRING_PROP_ID);
832         assertNotNull(pd);
833         List<String> valueList = (List<String>) pd.getValues();
834         assertNotNull(valueList);
835         assertTrue(valueList.contains("Apache"));
836         assertTrue(valueList.contains("CMIS"));
837 
838         pd =  props.get(TEST_DOCUMENT_MY_INT_PROP_ID_MANDATORY_DEFAULT);
839         assertNotNull(pd);
840         bi = pd.getFirstValue();
841         assertNotNull(bi);
842         assertEquals(BigInteger.valueOf(100), bi);
843 
844         log.info("... testDefaultPropertiesDocument() finished.");
845     }
846 
847     @Test
848     public void testDefaultPropertiesFolder() {
849         log.info("starting testDefaultPropertiesFolder() ...");
850         String id = createFolder("DefPropFolder", fRootFolderId, TEST_FOLDER_TYPE_WITH_DEFAULTS_ID);
851         if (id != null) {
852             log.info("createDocument succeeded with created id: " + id);
853         }
854         ObjectData res = getDocumentObjectData(id);
855         Map<String, PropertyData<?>> props = res.getProperties().getProperties();
856         PropertyData<?> pd =  props.get(TEST_FOLDER_MY_INT_PROP_ID);
857         assertNotNull(pd);
858         Object bi = pd.getFirstValue();
859         assertNotNull(bi);
860         assertEquals(BigInteger.valueOf(100), bi);
861 
862         pd =  props.get(TEST_FOLDER_MY_MULTI_STRING_PROP_ID);
863         assertNotNull(pd);
864         List<String> valueList = (List<String>) pd.getValues();
865         assertNotNull(valueList);
866         assertTrue(valueList.contains("Apache"));
867         assertTrue(valueList.contains("CMIS"));
868 
869         pd =  props.get(TEST_FOLDER_MY_INT_PROP_ID_MANDATORY_DEFAULT);
870         assertNotNull(pd);
871         bi = pd.getFirstValue();
872         assertNotNull(bi);
873         assertEquals(BigInteger.valueOf(100), bi);
874 
875         log.info("... testDefaultPropertiesFolder() finished.");
876     }
877 
878     @Test
879     public void testGetObjectNoObjectIdInFilter() {
880         log.info("starting testGetObjectNoObjectIdInFilter() ...");
881         log.info("  creating object");
882         String id = createDocument(fRootFolderId, false);
883         if (id != null) {
884             log.info("  createDocument succeeded with created id: " + id);
885         }
886 
887         log.info("  getting object");
888         String filter = PropertyIds.NAME + "," + PropertyIds.CREATION_DATE + "," + PropertyIds.LAST_MODIFICATION_DATE;
889         ObjectData res = fObjSvc.getObject(fRepositoryId, id, filter, false, IncludeRelationships.NONE, null, false, false, null);
890 
891         String returnedId = res.getId();
892         assertEquals(id, returnedId);
893         log.info("... testGetObjectNoObjectIdInFilter() finished.");
894     }
895 
896     private static void verifyAllowableActionsDocument(Set<Action> actions, boolean isVersioned, boolean hasContent) {
897         assertTrue(actions.contains(Action.CAN_DELETE_OBJECT));
898         assertTrue(actions.contains(Action.CAN_UPDATE_PROPERTIES));
899         assertTrue(actions.contains(Action.CAN_GET_PROPERTIES));
900         assertFalse(actions.contains(Action.CAN_GET_OBJECT_RELATIONSHIPS));
901         assertTrue(actions.contains(Action.CAN_GET_OBJECT_PARENTS));
902 
903         assertFalse(actions.contains(Action.CAN_GET_FOLDER_PARENT));
904         assertFalse(actions.contains(Action.CAN_GET_FOLDER_TREE));
905         assertFalse(actions.contains(Action.CAN_GET_DESCENDANTS));
906         assertTrue(actions.contains(Action.CAN_MOVE_OBJECT));
907         if (hasContent) {
908             assertTrue(actions.contains(Action.CAN_DELETE_CONTENT_STREAM));
909             assertTrue(actions.contains(Action.CAN_GET_CONTENT_STREAM));
910             assertTrue(actions.contains(Action.CAN_GET_RENDITIONS));
911         } else {
912             assertFalse(actions.contains(Action.CAN_DELETE_CONTENT_STREAM));
913             assertFalse(actions.contains(Action.CAN_GET_CONTENT_STREAM));
914             assertFalse(actions.contains(Action.CAN_GET_RENDITIONS));
915         }
916         assertTrue(actions.contains(Action.CAN_ADD_OBJECT_TO_FOLDER));
917         assertTrue(actions.contains(Action.CAN_REMOVE_OBJECT_FROM_FOLDER));
918 
919         if (isVersioned) {
920             assertTrue(actions.contains(Action.CAN_CANCEL_CHECK_OUT));
921             assertTrue(actions.contains(Action.CAN_CHECK_IN));
922             assertTrue(actions.contains(Action.CAN_CHECK_OUT));
923             assertTrue(actions.contains(Action.CAN_GET_ALL_VERSIONS));
924 
925         } else {
926             assertFalse(actions.contains(Action.CAN_CANCEL_CHECK_OUT));
927             assertFalse(actions.contains(Action.CAN_CHECK_IN));
928             assertFalse(actions.contains(Action.CAN_CHECK_OUT));
929             assertFalse(actions.contains(Action.CAN_GET_ALL_VERSIONS));
930         }
931         assertTrue(actions.contains(Action.CAN_SET_CONTENT_STREAM));
932 //        assertFalse(actions.contains(Action.CAN_ADD_POLICY));
933         assertFalse(actions.contains(Action.CAN_GET_APPLIED_POLICIES));
934         assertFalse(actions.contains(Action.CAN_REMOVE_POLICY));
935         assertFalse(actions.contains(Action.CAN_GET_CHILDREN));
936         assertFalse(actions.contains(Action.CAN_CREATE_DOCUMENT));
937         assertFalse(actions.contains(Action.CAN_CREATE_FOLDER));
938         assertFalse(actions.contains(Action.CAN_CREATE_RELATIONSHIP));
939         assertFalse(actions.contains(Action.CAN_DELETE_TREE));
940         assertFalse(actions.contains(Action.CAN_GET_ACL));
941         assertFalse(actions.contains(Action.CAN_APPLY_ACL));
942     }
943 
944     private String retrieveDocument(String id) {
945         ObjectData res = getDocumentObjectData(id);
946         String returnedId = res.getId();
947         testReturnedProperties(returnedId, DOCUMENT_ID, DOCUMENT_TYPE_ID, res.getProperties().getProperties());
948         return returnedId;
949     }
950 
951     private void moveObjectTest(boolean isFolder) {
952         final String propertyFilter = PropertyIds.OBJECT_ID + "," + PropertyIds.NAME; // +
953         // ","
954         // +
955         // PropertyIds
956         // .
957         // CMIS_OBJECT_TYPE_ID
958         // +
959         // ","
960         // +
961         // PropertyIds
962         // .
963         // CMIS_BASE_TYPE_ID
964         // ;
965         String rootFolderId = createFolder();
966         ObjectGenerator gen = new ObjectGenerator(fFactory, fNavSvc, fObjSvc, fRepSvc, fRepositoryId,
967                 ObjectGenerator.CONTENT_KIND.LoremIpsumText);
968         // Set the type id for all created documents:
969         gen.setDocumentTypeId(InMemoryDocumentTypeDefinition.getRootDocumentType().getId());
970         // Set the type id for all created folders:
971         gen.setNumberOfDocumentsToCreatePerFolder(1); // create one document in
972         // each folder
973         gen.createFolderHierachy(3, 2, rootFolderId);
974         gen.setFolderTypeId(InMemoryFolderTypeDefinition.getRootFolderType().getId());
975         gen.dumpFolder(fRootFolderId, propertyFilter);
976         Holder<String> holder = new Holder<String>();
977         String sourceIdToMove = gen.getFolderId(rootFolderId, 2, 1);
978         if (!isFolder) {
979             sourceIdToMove = gen.getDocumentId(sourceIdToMove, 0);
980         }
981         holder.setValue(sourceIdToMove); // "/Folder_1/My Folder 0/My Folder 1");
982         String sourceFolderId = getSourceFolder(sourceIdToMove);
983         log.info("Id before moveObject: " + holder.getValue());
984         fObjSvc.moveObject(fRepositoryId, holder, rootFolderId, sourceFolderId, null);
985         log.info("Id after moveObject: " + holder.getValue());
986         gen.dumpFolder(fRootFolderId, propertyFilter);
987 
988         List<ObjectParentData> result = fNavSvc.getObjectParents(fRepositoryId, holder.getValue(), null, Boolean.FALSE,
989                 IncludeRelationships.NONE, null, Boolean.FALSE, null);
990         // check that new parent is set correctly
991         String newParentId = result.get(0).getObject().getId();
992         assertEquals(rootFolderId, newParentId);
993 
994         if (isFolder) {
995             log.info("testing moveFolder to a subfolder");
996             ObjectInFolderList ch = fNavSvc.getChildren(fRepositoryId, holder.getValue(), propertyFilter, null, false,
997                     IncludeRelationships.NONE, null, false, null, null, null);
998             String subFolderId = ch.getObjects().get(0).getObject().getId();
999 
1000             try {
1001                 fObjSvc.moveObject(fRepositoryId, holder, subFolderId, sourceFolderId, null);
1002                 fail("moveObject to a folder that is a descendant of the source must fail.");
1003             } catch (Exception e) {
1004                 assertTrue(e instanceof CmisNotSupportedException);
1005             }
1006         }
1007     }
1008 
1009     private String createFolder() {
1010         return createFolder(FOLDER_ID, fRootFolderId, FOLDER_TYPE_ID);
1011     }
1012 
1013     private String createDocument(String folderId, boolean withContent) {
1014         return createDocument(DOCUMENT_ID, folderId, withContent);
1015     }
1016 
1017     private String createDocument(String name, String folderId, boolean withContent) {
1018         return createDocument(name, folderId, DOCUMENT_TYPE_ID, withContent);
1019     }
1020 
1021     private Properties createDocumentPropertiesForDocumentFromSource(String name) {
1022         // We only provide a name but not a type id, as spec says to copy
1023         // missing attributes
1024         // from the existing one
1025         List<PropertyData<?>> properties = new ArrayList<PropertyData<?>>();
1026         properties.add(fFactory.createPropertyIdData(PropertyIds.NAME, name));
1027         Properties props = fFactory.createPropertiesData(properties);
1028         return props;
1029     }
1030 
1031     private void testReturnedProperties(String objectId, String objectName, String typeId,
1032             Map<String, PropertyData<?>> props) {
1033         super.testReturnedProperties(objectId, props);
1034 
1035         if (null != objectName) {
1036             PropertyData<?> pd = props.get(PropertyIds.NAME);
1037             assertNotNull(pd);
1038             assertEquals(objectName, pd.getFirstValue());
1039         }
1040         if (null != typeId) {
1041             PropertyData<?> pd = props.get(PropertyIds.OBJECT_TYPE_ID);
1042             assertEquals(typeId, pd.getFirstValue());
1043         }
1044     }
1045 
1046     private String createDocumentWithCustomType(String folderId, boolean withContent) {
1047         ContentStream contentStream = null;
1048         VersioningState versioningState = VersioningState.NONE;
1049         List<String> policies = null;
1050         Acl addACEs = null;
1051         Acl removeACEs = null;
1052         ExtensionsData extension = null;
1053 
1054         // create the properties:
1055         List<PropertyData<?>> properties = new ArrayList<PropertyData<?>>();
1056         properties.add(fFactory.createPropertyIdData(PropertyIds.NAME, MY_CUSTOM_NAME));
1057         properties.add(fFactory.createPropertyIdData(PropertyIds.OBJECT_TYPE_ID, TEST_CUSTOM_DOCUMENT_TYPE_ID));
1058         // Generate some property values for custom attributes
1059         properties.add(fFactory.createPropertyStringData(TEST_DOCUMENT_MY_STRING_PROP_ID, "My pretty string"));
1060         properties.add(fFactory.createPropertyIntegerData(TEST_DOCUMENT_MY_INT_PROP_ID, BigInteger.valueOf(4711)));
1061 
1062         Properties props = fFactory.createPropertiesData(properties);
1063 
1064         if (withContent) {
1065             contentStream = createContent();
1066         }
1067 
1068         // create the document
1069         String id = null;
1070         id = fObjSvc.createDocument(fRepositoryId, props, folderId, contentStream, versioningState, policies, addACEs,
1071                 removeACEs, extension);
1072         if (null == id) {
1073             throw new RuntimeException("createDocument failed.");
1074         }
1075         return id;
1076     }
1077 
1078     private String createDocumentInheritedProperties(String folderId, boolean withContent) {
1079         ContentStream contentStream = null;
1080         VersioningState versioningState = VersioningState.NONE;
1081         List<String> policies = null;
1082         Acl addACEs = null;
1083         Acl removeACEs = null;
1084         ExtensionsData extension = null;
1085 
1086         // create the properties:
1087         List<PropertyData<?>> properties = new ArrayList<PropertyData<?>>();
1088         properties.add(fFactory.createPropertyIdData(PropertyIds.NAME, MY_CUSTOM_NAME));
1089         properties.add(fFactory
1090                 .createPropertyIdData(PropertyIds.OBJECT_TYPE_ID, TEST_INHERITED_CUSTOM_DOCUMENT_TYPE_ID));
1091         // Generate some property values for custom attributes
1092         properties.add(fFactory.createPropertyStringData(TEST_DOCUMENT_MY_STRING_PROP_ID, "My pretty string"));
1093         properties.add(fFactory.createPropertyIntegerData(TEST_DOCUMENT_MY_INT_PROP_ID, BigInteger.valueOf(4711)));
1094         properties.add(fFactory.createPropertyStringData(TEST_DOCUMENT_MY_SUB_STRING_PROP_ID, "another cool string"));
1095         properties.add(fFactory.createPropertyIntegerData(TEST_DOCUMENT_MY_SUB_INT_PROP_ID, BigInteger.valueOf(4712)));
1096 
1097         Properties props = fFactory.createPropertiesData(properties);
1098 
1099         if (withContent) {
1100             contentStream = createContent();
1101         }
1102 
1103         // create the document
1104         String id = null;
1105         id = fObjSvc.createDocument(fRepositoryId, props, folderId, contentStream, versioningState, policies, addACEs,
1106                 removeACEs, extension);
1107         if (null == id) {
1108             throw new RuntimeException("createDocument failed.");
1109         }
1110         return id;
1111     }
1112 
1113     private String getSourceFolder(String objectId) {
1114         // return the first parent found in the result list of all parents
1115         List<ObjectParentData> parents = fNavSvc.getObjectParents(fRepositoryId, objectId, "*", false,
1116                 IncludeRelationships.NONE, null, true, null);
1117         return parents.get(0).getObject().getId();
1118     }
1119 
1120     // Helper class to create some type for testing the ObjectService
1121 
1122     public static class ObjectTestTypeSystemCreator implements TypeCreator {
1123 
1124         /**
1125          * create root types and a sample type for folder and document
1126          *
1127          * @return typesMap map filled with created types
1128          */
1129         public List<TypeDefinition> createTypesList() {
1130             List<TypeDefinition> typesList = new LinkedList<TypeDefinition>();
1131             InMemoryDocumentTypeDefinition cmisDocumentType = new InMemoryDocumentTypeDefinition(TEST_DOCUMENT_TYPE_ID,
1132                     "My Document Type", InMemoryDocumentTypeDefinition.getRootDocumentType());
1133 
1134             InMemoryFolderTypeDefinition cmisFolderType = new InMemoryFolderTypeDefinition(TEST_FOLDER_TYPE_ID,
1135                     "My Folder Type", InMemoryFolderTypeDefinition.getRootFolderType());
1136             // create a simple string property type and
1137             // attach the property definition to the type definition for
1138             // document and folder type
1139             Map<String, PropertyDefinition<?>> propertyDefinitions = new HashMap<String, PropertyDefinition<?>>();
1140             PropertyStringDefinitionImpl prop = PropertyCreationHelper.createStringDefinition(
1141                     TEST_DOCUMENT_STRING_PROP_ID, "Sample Doc String Property", Updatability.READWRITE);
1142             propertyDefinitions.put(prop.getId(), prop);
1143             cmisDocumentType.addCustomPropertyDefinitions(propertyDefinitions);
1144 
1145             propertyDefinitions = new HashMap<String, PropertyDefinition<?>>();
1146             prop = PropertyCreationHelper.createStringDefinition(TEST_FOLDER_STRING_PROP_ID,
1147                     "Sample Folder String Property", Updatability.READWRITE);
1148             propertyDefinitions.put(prop.getId(), prop);
1149             cmisFolderType.addCustomPropertyDefinitions(propertyDefinitions);
1150 
1151             InMemoryDocumentTypeDefinition customDocType = createCustomTypeWithStringIntProperty();
1152             // add type to types collection
1153             typesList.add(cmisDocumentType);
1154             typesList.add(cmisFolderType);
1155             typesList.add(customDocType);
1156             typesList.add(createCustomInheritedType(customDocType));
1157             typesList.add(createDocumentTypeWithDefault());
1158             typesList.add(createFolderTypeWithDefault());
1159             return typesList;
1160         }
1161 
1162         private static InMemoryDocumentTypeDefinition createCustomTypeWithStringIntProperty() {
1163             InMemoryDocumentTypeDefinition cmisDocumentType = new InMemoryDocumentTypeDefinition(
1164                     TEST_CUSTOM_DOCUMENT_TYPE_ID, "My Custom Document Type", InMemoryDocumentTypeDefinition
1165                             .getRootDocumentType());
1166             Map<String, PropertyDefinition<?>> propertyDefinitions = new HashMap<String, PropertyDefinition<?>>();
1167             PropertyStringDefinitionImpl prop = PropertyCreationHelper.createStringDefinition(
1168                     TEST_DOCUMENT_MY_STRING_PROP_ID, "My String Property", Updatability.READWRITE);
1169             prop.setIsRequired(false);
1170             prop.setMaxLength(BigInteger.valueOf(20)); // max len to 20
1171             propertyDefinitions.put(prop.getId(), prop);
1172 
1173             PropertyIntegerDefinitionImpl prop2 = PropertyCreationHelper.createIntegerDefinition(
1174                     TEST_DOCUMENT_MY_INT_PROP_ID, "My Integer Property", Updatability.READWRITE);
1175             prop2.setIsRequired(true);
1176             prop2.setMinValue(BigInteger.valueOf(-10000));
1177             prop2.setMaxValue(BigInteger.valueOf(10000));
1178             propertyDefinitions.put(prop2.getId(), prop2);
1179             cmisDocumentType.addCustomPropertyDefinitions(propertyDefinitions);
1180             return cmisDocumentType;
1181         }
1182 
1183         private static InMemoryDocumentTypeDefinition createCustomInheritedType(InMemoryDocumentTypeDefinition baseType) {
1184             InMemoryDocumentTypeDefinition cmisDocumentType = new InMemoryDocumentTypeDefinition(
1185                     TEST_INHERITED_CUSTOM_DOCUMENT_TYPE_ID, "My Custom Document Type", baseType);
1186             Map<String, PropertyDefinition<?>> propertyDefinitions = new HashMap<String, PropertyDefinition<?>>();
1187             PropertyStringDefinitionImpl prop = PropertyCreationHelper.createStringDefinition(
1188                     TEST_DOCUMENT_MY_SUB_STRING_PROP_ID, "Subtype String Property", Updatability.READWRITE);
1189             prop.setIsRequired(false);
1190             propertyDefinitions.put(prop.getId(), prop);
1191 
1192             PropertyIntegerDefinitionImpl prop2 = PropertyCreationHelper.createIntegerDefinition(
1193                     TEST_DOCUMENT_MY_SUB_INT_PROP_ID, "Subtype", Updatability.READWRITE);
1194             prop2.setIsRequired(true);
1195             propertyDefinitions.put(prop2.getId(), prop2);
1196             cmisDocumentType.addCustomPropertyDefinitions(propertyDefinitions);
1197             return cmisDocumentType;
1198         }
1199 
1200         private static InMemoryDocumentTypeDefinition createDocumentTypeWithDefault() {
1201             InMemoryDocumentTypeDefinition cmisDocumentType = new InMemoryDocumentTypeDefinition(
1202                     TEST_DOC_TYPE_WITH_DEFAULTS_ID, "Document Type With default values", InMemoryDocumentTypeDefinition
1203                     .getRootDocumentType());
1204             Map<String, PropertyDefinition<?>> propertyDefinitions = new HashMap<String, PropertyDefinition<?>>();
1205             PropertyStringDefinitionImpl prop = PropertyCreationHelper.createStringMultiDefinition(
1206                     TEST_DOCUMENT_MY_MULTI_STRING_PROP_ID, "Test Multi String Property", Updatability.READWRITE);
1207             prop.setIsRequired(false);
1208             List<String> defValS = new ArrayList<String>() {{ add("Apache"); add("CMIS"); }};
1209             prop.setDefaultValue(defValS);
1210             propertyDefinitions.put(prop.getId(), prop);
1211 
1212             PropertyIntegerDefinitionImpl prop2 = PropertyCreationHelper.createIntegerDefinition(
1213                     TEST_DOCUMENT_MY_INT_PROP_ID, "Test Integer Property", Updatability.READWRITE);
1214             prop2.setIsRequired(false);
1215             List<BigInteger> defVal = new ArrayList<BigInteger>() {{ add(BigInteger.valueOf(100)); }};
1216             prop2.setDefaultValue(defVal);
1217             propertyDefinitions.put(prop2.getId(), prop2);
1218 
1219             PropertyIntegerDefinitionImpl prop3 = PropertyCreationHelper.createIntegerDefinition(
1220                     TEST_DOCUMENT_MY_INT_PROP_ID_MANDATORY_DEFAULT, "Test Integer Property Mandatory default", Updatability.READWRITE);
1221             prop3.setIsRequired(true);
1222             List<BigInteger> defVal2 = new ArrayList<BigInteger>() {{ add(BigInteger.valueOf(100)); }};
1223             prop3.setDefaultValue(defVal2);
1224             propertyDefinitions.put(prop3.getId(), prop3);
1225 
1226             cmisDocumentType.addCustomPropertyDefinitions(propertyDefinitions);
1227 
1228             return cmisDocumentType;
1229         }
1230 
1231         private static InMemoryFolderTypeDefinition createFolderTypeWithDefault() {
1232             InMemoryFolderTypeDefinition cmisFolderType = new InMemoryFolderTypeDefinition(
1233                     TEST_FOLDER_TYPE_WITH_DEFAULTS_ID, "Folder Type With default values", InMemoryFolderTypeDefinition.
1234                     getRootFolderType());
1235             Map<String, PropertyDefinition<?>> propertyDefinitions = new HashMap<String, PropertyDefinition<?>>();
1236             PropertyStringDefinitionImpl prop = PropertyCreationHelper.createStringMultiDefinition(
1237                     TEST_FOLDER_MY_MULTI_STRING_PROP_ID, "Test Multi String Property", Updatability.READWRITE);
1238             prop.setIsRequired(false);
1239             List<String> defValS = new ArrayList<String>() {{ add("Apache"); add("CMIS"); }};
1240             prop.setDefaultValue(defValS);
1241             propertyDefinitions.put(prop.getId(), prop);
1242 
1243             PropertyIntegerDefinitionImpl prop2 = PropertyCreationHelper.createIntegerDefinition(
1244                     TEST_FOLDER_MY_INT_PROP_ID, "Test Integer Property", Updatability.READWRITE);
1245             prop2.setIsRequired(false);
1246             List<BigInteger> defVal = new ArrayList<BigInteger>() {{ add(BigInteger.valueOf(100)); }};
1247             prop2.setDefaultValue(defVal);
1248             propertyDefinitions.put(prop2.getId(), prop2);
1249 
1250             PropertyIntegerDefinitionImpl prop3 = PropertyCreationHelper.createIntegerDefinition(
1251                     TEST_FOLDER_MY_INT_PROP_ID_MANDATORY_DEFAULT, "Test Integer Property Mandatory default", Updatability.READWRITE);
1252             prop3.setIsRequired(true);
1253             List<BigInteger> defVal2 = new ArrayList<BigInteger>() {{ add(BigInteger.valueOf(100)); }};
1254             prop3.setDefaultValue(defVal2);
1255             propertyDefinitions.put(prop3.getId(), prop3);
1256 
1257             cmisFolderType.addCustomPropertyDefinitions(propertyDefinitions);
1258 
1259             return cmisFolderType;
1260         }
1261     }
1262 
1263     @Test
1264     public void testMaxContentSize() {
1265         log.info("starting testMaxContentSize() ...");
1266         try {
1267             createContent(MAX_SIZE + 1, MAX_SIZE);
1268             fail("createContent with exceeded content size should fail.");
1269         } catch (CmisInvalidArgumentException e) {
1270             log.debug("createDocument with exceeded failed as excpected.");
1271         } catch (Exception e1) {
1272             log.debug("createDocument with exceeded failed with wrong exception (expected CmisInvalidArgumentException, got "
1273                     + e1.getClass().getName() + ").");
1274         }
1275 
1276         try {
1277             ContentStream contentStream = createContent(MAX_SIZE + 1);
1278             Properties props = createDocumentProperties("TestMaxContentSize", DOCUMENT_TYPE_ID);
1279             fObjSvc.createDocument(fRepositoryId, props, fRootFolderId, contentStream, VersioningState.NONE, null,
1280                     null, null, null);
1281             fail("createDocument with exceeded content size should fail.");
1282         } catch (CmisInvalidArgumentException e) {
1283             log.debug("createDocument with exceeded failed as excpected.");
1284         } catch (Exception e1) {
1285             log.debug("createDocument with exceeded failed with wrong exception (expected CmisInvalidArgumentException, got "
1286                     + e1.getClass().getName() + ").");
1287         }
1288     }
1289 
1290 }