This project has retired. For details please refer to its Attic page.
QueryTestDataCreator 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.query;
20  
21  import static org.junit.Assert.assertNotNull;
22  import static org.junit.Assert.fail;
23  
24  import java.io.ByteArrayInputStream;
25  import java.io.ByteArrayOutputStream;
26  import java.io.IOException;
27  import java.math.BigDecimal;
28  import java.math.BigInteger;
29  import java.util.ArrayList;
30  import java.util.GregorianCalendar;
31  import java.util.HashMap;
32  import java.util.List;
33  import java.util.Map;
34  import java.util.TimeZone;
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.ContentStream;
39  import org.apache.chemistry.opencmis.commons.data.ExtensionsData;
40  import org.apache.chemistry.opencmis.commons.data.ObjectData;
41  import org.apache.chemistry.opencmis.commons.data.Properties;
42  import org.apache.chemistry.opencmis.commons.data.PropertyData;
43  import org.apache.chemistry.opencmis.commons.enums.IncludeRelationships;
44  import org.apache.chemistry.opencmis.commons.enums.VersioningState;
45  import org.apache.chemistry.opencmis.commons.impl.dataobjects.BindingsObjectFactoryImpl;
46  import org.apache.chemistry.opencmis.commons.spi.BindingsObjectFactory;
47  import org.apache.chemistry.opencmis.commons.spi.Holder;
48  import org.apache.chemistry.opencmis.commons.spi.ObjectService;
49  import org.apache.chemistry.opencmis.commons.spi.VersioningService;
50  import org.apache.chemistry.opencmis.inmemory.UnitTestTypeSystemCreator;
51  import org.apache.chemistry.opencmis.inmemory.storedobj.impl.ContentStreamDataImpl;
52  
53  import static org.apache.chemistry.opencmis.inmemory.UnitTestTypeSystemCreator.*;
54  
55  /**
56   * Utility class that fills the in-memory repository with some test objects that
57   * can be used for query
58   *
59   * @author Jens
60   *
61   * This class uses the following data for query testing. We have one document type
62   * "ComplexType" and one folder type "FolderType" The document type has one property of
63   * each of the types boolean, integer, decimal, string and datetime. id, uri and html are
64   * treated like a string and do not make a difference.
65   *
66   * String   Int         Double      DateTime  Boolean
67   * ------------------------------------------------
68   * Alpha    -100        -1.6E-5     23.05.1618  true
69   * Beta     -50         -4.0E24     08.05.1945  false
70   * Gamma    0           3.141592    (now)       true
71   * Delta    50          1.23456E-6  20.01.2038  true
72   * Epsilon  100         1.2345E12   14.07.2345  false
73   *
74   * For folder and tree tests this series is put in each of the three test folders
75   */
76  public class QueryTestDataCreator {
77  
78      private final BindingsObjectFactory fFactory = new BindingsObjectFactoryImpl();
79      private final String rootFolderId;
80      private final String repositoryId;
81      private final ObjectService fObjSvc;
82      private final VersioningService fVerSvc;
83      private String doc1, doc2, doc3, doc4, doc5;
84      private String folder1;
85      private String folder2;
86      private String folder11;
87      private static final TimeZone TZ = TimeZone.getTimeZone("Zulu");
88  
89      public QueryTestDataCreator(String repositoryId, String rootFolderId, ObjectService objSvc, VersioningService verSvc) {
90          this.rootFolderId = rootFolderId;
91          this.repositoryId = repositoryId;
92          fObjSvc = objSvc;
93          fVerSvc = verSvc;
94      }
95  
96      public String getFolder1() {
97          return folder1;
98      }
99      public String getFolder2() {
100         return folder2;
101     }
102     public String getFolder11() {
103         return folder11;
104     }
105 
106     public void createBasicTestData() {
107         createTestFolders();
108         createBasicTestDocuments();
109     }
110 
111     @SuppressWarnings("serial")
112     public void createBasicTestDocuments() {
113 
114         final GregorianCalendar gc1 = new GregorianCalendar(TZ);
115         gc1.clear();
116         gc1.set(1945, 4, 8);
117 
118         final Map<String, Object> propertyMap1 =
119             new HashMap<String, Object>() {
120             {
121                 put(PROP_ID_STRING, "Alpha");
122                 put(PROP_ID_INT, Integer.valueOf(-100));
123                 put(PROP_ID_DECIMAL, Double.valueOf(-4.0E24d));
124                 put(PROP_ID_DATETIME, gc1);
125                 put(PROP_ID_BOOLEAN, true);
126             }};
127         ContentStream content1 = createContent("I have a cat.");
128         doc1 = createDocument("alpha", rootFolderId, COMPLEX_TYPE, propertyMap1, content1);
129         assertNotNull(doc1);
130 
131         final GregorianCalendar gc2 = new GregorianCalendar(TZ);
132         gc2.clear();
133         gc2.set(1618, 4, 23);
134 
135         final Map<String, Object> propertyMap2 =
136             new HashMap<String, Object>() {
137             {
138                 put(PROP_ID_STRING, "Beta");
139                 put(PROP_ID_INT, Integer.valueOf(-50));
140                 put(PROP_ID_DECIMAL, Double.valueOf(-1.6E-5d));
141                 put(PROP_ID_DATETIME, gc2);
142                 put(PROP_ID_BOOLEAN, false);
143             }};
144         ContentStream content2 = createContent("I have a cat named Kitty Katty.");
145         doc2 = createDocument("beta", rootFolderId, COMPLEX_TYPE, propertyMap2, content2);
146         assertNotNull(doc2);
147 
148         final Map<String, Object> propertyMap3 =
149             new HashMap<String, Object>() {
150             {
151                 put(PROP_ID_STRING, "Gamma");
152                 put(PROP_ID_INT, Integer.valueOf(0));
153                 put(PROP_ID_DECIMAL, Double.valueOf(Math.PI));
154                 put(PROP_ID_DATETIME, new GregorianCalendar(TZ));
155                 put(PROP_ID_BOOLEAN, true);
156             }};
157         
158         ContentStream content3 = createContent("I have a dog.");
159         doc3 = createDocument("gamma", rootFolderId, COMPLEX_TYPE, propertyMap3, content3);
160         assertNotNull(doc3);
161 
162         final GregorianCalendar gc4 = new GregorianCalendar(TZ);
163         gc4.clear();
164         gc4.set(2038, 0, 20);
165 
166         final Map<String, Object> propertyMap4 =
167             new HashMap<String, Object>() {
168             {
169                 put(PROP_ID_STRING, "Delta");
170                 put(PROP_ID_INT, Integer.valueOf(50));
171                 put(PROP_ID_DECIMAL, Double.valueOf(1.23456E-6));
172                 put(PROP_ID_DATETIME, gc4);
173                 put(PROP_ID_BOOLEAN, true);
174             }};
175         ContentStream content4 = createContent("I have a cat and a dog.");
176         doc4 = createDocument("delta", rootFolderId, COMPLEX_TYPE, propertyMap4, content4);
177         assertNotNull(doc4);
178 
179         final GregorianCalendar gc5 = new GregorianCalendar(TZ);
180         gc5.clear();
181         gc5.set(2345, 6, 14);
182 
183         final Map<String, Object> propertyMap5 =
184             new HashMap<String, Object>() {
185             {
186                 put(PROP_ID_STRING, "Epsilon");
187                 put(PROP_ID_INT, Integer.valueOf(100));
188                 put(PROP_ID_DECIMAL, Double.valueOf(1.2345E12));
189                 put(PROP_ID_DATETIME, gc5);
190                 put(PROP_ID_BOOLEAN, false);
191             }};
192         ContentStream content5 = createContent("I hate having pets.");
193         doc5 = createDocument("epsilon", rootFolderId, COMPLEX_TYPE, propertyMap5, content5);
194         assertNotNull(doc5);
195 
196     }
197 
198     @SuppressWarnings("serial")
199     public void createMultiValueDocuments() {
200         final List<String> mvProps1 =
201             new ArrayList<String>() {
202             {
203                 add("red");
204                 add("green");
205                 add("blue");
206             }};
207 
208         final Map<String, Object> propertyMap1 =
209             new HashMap<String, Object>() {
210             {
211                 put(PROP_ID_STRING_MULTI_VALUE, mvProps1);
212                 put(PROP_ID_INT, Integer.valueOf(100));
213             }};
214         createDocument("mv-alpha", rootFolderId, COMPLEX_TYPE, propertyMap1);
215 
216         final List<String> mvProps2 =
217             new ArrayList<String>() {
218             {
219                 add("red");
220                 add("pink");
221                 add("violet");
222             }};
223 
224         final Map<String, Object> propertyMap2 =
225             new HashMap<String, Object>() {
226             {
227                 put(PROP_ID_STRING_MULTI_VALUE, mvProps2);
228                 put(PROP_ID_INT, Integer.valueOf(200));
229             }};
230         createDocument("mv-beta", rootFolderId, COMPLEX_TYPE, propertyMap2);
231     }
232 
233     @SuppressWarnings("serial")
234     public void createTestFolders() {
235         final Map<String, Object> propertyMap1 =
236             new HashMap<String, Object>() {
237             {
238                 put(PROP_ID_INT, Integer.valueOf(1234));
239                 put(PROP_ID_STRING, "ABCD");
240             }};
241         folder1 = createFolder("Folder 1", rootFolderId, FOLDER_TYPE, propertyMap1);
242 
243         final Map<String, Object> propertyMap2 =
244             new HashMap<String, Object>() {
245             {
246                 put(PROP_ID_INT, Integer.valueOf(-2345));
247                 put(PROP_ID_STRING, "defg");
248             }};
249         folder2 = createFolder("Folder 2", rootFolderId, FOLDER_TYPE, propertyMap2);
250 
251         final Map<String, Object> propertyMap3 =
252             new HashMap<String, Object>() {
253             {
254                 put(PROP_ID_INT, Integer.valueOf(123));
255                 put(PROP_ID_STRING, "ZZZZ");
256             }};
257         folder11 = createFolder("Folder 11", folder1, FOLDER_TYPE, propertyMap3);
258     }
259 
260     @SuppressWarnings("serial")
261     public void createNullTestDocument() {
262 
263         final Map<String, Object> propertyMap1 =
264             new HashMap<String, Object>() {
265             {
266                 put(PROP_ID_STRING, "DocumentWithNulls");
267             }};
268         createDocument("nulldoc", rootFolderId, COMPLEX_TYPE, propertyMap1);
269     }
270 
271     @SuppressWarnings("serial")
272     public void createLikeTestDocuments(String folderId) {
273 
274         final Map<String, Object> propertyMap1 =
275             new HashMap<String, Object>() {
276             {
277                 put(PROP_ID_STRING, "ABCDEF");
278             }};
279         createDocument("likedoc1", folderId, COMPLEX_TYPE, propertyMap1);
280 
281         final Map<String, Object> propertyMap2 =
282             new HashMap<String, Object>() {
283             {
284                 put(PROP_ID_STRING, "ABC123");
285             }};
286         createDocument("likedoc2", folderId, COMPLEX_TYPE, propertyMap2);
287 
288         final Map<String, Object> propertyMap3 =
289             new HashMap<String, Object>() {
290             {
291                 put(PROP_ID_STRING, "123ABC");
292             }};
293         createDocument("likedoc3", folderId, COMPLEX_TYPE, propertyMap3);
294     }
295 
296     @SuppressWarnings("serial")
297     public String createVersionedDocument() {
298         final Map<String, Object> propertyMap1 =
299             new HashMap<String, Object>() {
300             {
301                 put(VERSION_PROPERTY_ID, "ver123");
302             }};
303 
304         String verIdV1 = createDocument("verdoc1", rootFolderId, UnitTestTypeSystemCreator.VERSIONED_TYPE,
305                 propertyMap1, VersioningState.MAJOR, null);
306         ObjectData version = fObjSvc.getObject(repositoryId, verIdV1, "*", false, IncludeRelationships.NONE, null,
307                 false, false, null);
308 
309         // get version series id
310         String verIdSer = (String) version.getProperties().getProperties().get(PropertyIds.VERSION_SERIES_ID).getFirstValue();
311 
312         // create second version
313         final Map<String, Object> propertyMap2 =
314             new HashMap<String, Object>() {
315             {
316                 put(VERSION_PROPERTY_ID, "ver456");
317             }};
318         Properties propsV2 = createDocumentProperties(null, null, propertyMap2);
319 
320         Holder<String> idHolder = new Holder<String>(verIdV1);
321         Holder<Boolean> contentCopied = new Holder<Boolean>(false);
322         fVerSvc.checkOut(repositoryId, idHolder, null, contentCopied);
323 
324         idHolder = new Holder<String>(verIdV1);
325         // Test check-in and pass content and properties
326         String checkinComment = "Here comes next version.";
327         fVerSvc.checkIn(repositoryId, idHolder, true, propsV2, null, checkinComment, null, null, null, null);
328         // String verIdV2 = idHolder.getValue();
329         return verIdSer;
330     }
331 
332     private String createFolder(String folderName, String parentFolderId, String typeId, Map<String, Object> properties) {
333         Properties props = createFolderProperties(folderName, typeId, properties);
334         String id = null;
335         try {
336             id = fObjSvc.createFolder(repositoryId, props, parentFolderId, null, null, null, null);
337             if (null == id) {
338                 fail("createFolder failed.");
339             }
340         } catch (Exception e) {
341             fail("createFolder() failed with exception: " + e);
342         }
343         return id;
344     }
345 
346     private String createDocument(String name, String folderId, String typeId, Map<String, Object> properties) {
347         return createDocument(name, folderId, typeId, properties, VersioningState.NONE, null);
348     }
349 
350     private String createDocument(String name, String folderId, String typeId, Map<String, Object> properties,
351             ContentStream contentStream) {
352         return createDocument(name, folderId, typeId, properties, VersioningState.NONE, contentStream);
353     }
354 
355     private String createDocument(String name, String folderId, String typeId, Map<String, Object> properties,
356             VersioningState verState, ContentStream contentStream) {
357         List<String> policies = null;
358         Acl addACEs = null;
359         Acl removeACEs = null;
360         ExtensionsData extension = null;
361 
362         Properties props = createDocumentProperties(name, typeId, properties);
363 
364         String id = null;
365         try {
366             id = fObjSvc.createDocument(repositoryId, props, folderId, contentStream, verState, policies, addACEs,
367                     removeACEs, extension);
368             if (null == id) {
369                 fail("createDocument failed.");
370             }
371         } catch (Exception e) {
372             fail("createDocument() failed with exception: " + e);
373         }
374         return id;
375 
376     }
377 
378     private Properties createDocumentProperties(String name, String typeId, Map<String, Object> propertyMap) {
379         List<PropertyData<?>> properties = new ArrayList<PropertyData<?>>();
380         if (name != null)
381             properties.add(fFactory.createPropertyIdData(PropertyIds.NAME, name));
382         if (typeId != null)
383             properties.add(fFactory.createPropertyIdData(PropertyIds.OBJECT_TYPE_ID, typeId));
384         for (Map.Entry<String,Object> propEntry :propertyMap.entrySet()) {
385             PropertyData<?> pd =
386             createPropertyData(propEntry.getKey(), propEntry.getValue());
387             properties.add(pd);
388         }
389         Properties props = fFactory.createPropertiesData(properties);
390         return props;
391     }
392 
393     private Properties createFolderProperties(String folderName, String typeId, Map<String, Object> propertyMap) {
394         List<PropertyData<?>> properties = new ArrayList<PropertyData<?>>();
395         properties.add(fFactory.createPropertyIdData(PropertyIds.NAME, folderName));
396         properties.add(fFactory.createPropertyIdData(PropertyIds.OBJECT_TYPE_ID, typeId));
397         for (Map.Entry<String,Object> propEntry :propertyMap.entrySet()) {
398             PropertyData<?> pd =
399             createPropertyData(propEntry.getKey(), propEntry.getValue());
400             properties.add(pd);
401         }
402         Properties props = fFactory.createPropertiesData(properties);
403         return props;
404     }
405 
406 
407     /**
408      * Simplified property creation method, create Property of Boolean, String, Integer,
409      * Decimal, or DataTime depending on class of value (Boolean, String, Integer, Double,
410      * or GregorianCalendar. Id, Html and URI are not supported
411      *
412      * @param propId
413      * @param value
414      * @return
415      */
416     @SuppressWarnings("unchecked")
417     private PropertyData<?> createPropertyData (String propId, Object value) {
418         Class<?> clazz = value.getClass();
419         if (clazz.equals(Boolean.class)) {
420             return fFactory.createPropertyBooleanData(propId, (Boolean)value);
421         } else if (clazz.equals(Double.class)) {
422             return fFactory.createPropertyDecimalData(propId, BigDecimal.valueOf((Double)value));
423         } else if (clazz.equals(Integer.class)) {
424             return fFactory.createPropertyIntegerData(propId, BigInteger.valueOf((Integer)value));
425         } else if (clazz.equals(String.class)) {
426             return fFactory.createPropertyStringData(propId, (String)value);
427         } else if (clazz.equals(GregorianCalendar.class)) {
428             return fFactory.createPropertyDateTimeData(propId, (GregorianCalendar)value);
429         } else if (value instanceof List) {
430             clazz = ((List<?>)value).get(0).getClass();
431             if (clazz.equals(Boolean.class)) {
432                 return fFactory.createPropertyBooleanData(propId, (List<Boolean>)value);
433             } else if (clazz.equals(Double.class)) {
434                 return fFactory.createPropertyDecimalData(propId, (List<BigDecimal>)value);
435             } else if (clazz.equals(Integer.class)) {
436                 return fFactory.createPropertyIntegerData(propId, (List<BigInteger>)value);
437             } else if (clazz.equals(String.class)) {
438                 return fFactory.createPropertyStringData(propId, (List<String>)value);
439             } else if (clazz.equals(GregorianCalendar.class)) {
440                 return fFactory.createPropertyDateTimeData(propId, (List<GregorianCalendar>)value);
441             } else {
442                 fail("unsupported type in propery value: " + clazz);
443             }
444         } else {
445             fail("unsupported type in propery value: " + clazz);
446         }
447         return null;
448     }
449     
450     private ContentStream createContent(String text) {
451         ContentStreamDataImpl content = new ContentStreamDataImpl(-1);
452         content.setFileName("data.txt");
453         content.setMimeType("text/plain");
454 
455         try {
456             content.setContent(new ByteArrayInputStream(text.getBytes()));
457         } catch (IOException e) {
458             throw new RuntimeException("Failed to fill content stream with data", e);
459         }
460         return content;
461     }
462     
463 }