blob: 9fec88a77b3e8f77250128ea7e68ea6e224b2ebf [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.chemistry.opencmis.inmemory.query;
import static org.apache.chemistry.opencmis.inmemory.UnitTestTypeSystemCreator.COMPLEX_TYPE;
import static org.apache.chemistry.opencmis.inmemory.UnitTestTypeSystemCreator.FOLDER_TYPE;
import static org.apache.chemistry.opencmis.inmemory.UnitTestTypeSystemCreator.PROP_ID_BOOLEAN;
import static org.apache.chemistry.opencmis.inmemory.UnitTestTypeSystemCreator.PROP_ID_DATETIME;
import static org.apache.chemistry.opencmis.inmemory.UnitTestTypeSystemCreator.PROP_ID_DECIMAL;
import static org.apache.chemistry.opencmis.inmemory.UnitTestTypeSystemCreator.PROP_ID_INT;
import static org.apache.chemistry.opencmis.inmemory.UnitTestTypeSystemCreator.PROP_ID_STRING;
import static org.apache.chemistry.opencmis.inmemory.UnitTestTypeSystemCreator.PROP_ID_STRING_MULTI_VALUE;
import static org.apache.chemistry.opencmis.inmemory.UnitTestTypeSystemCreator.SECONDARY_INTEGER_PROP;
import static org.apache.chemistry.opencmis.inmemory.UnitTestTypeSystemCreator.SECONDARY_STRING_PROP;
import static org.apache.chemistry.opencmis.inmemory.UnitTestTypeSystemCreator.SECONDARY_TYPE;
import static org.apache.chemistry.opencmis.inmemory.UnitTestTypeSystemCreator.VERSION_PROPERTY_ID;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
import org.apache.chemistry.opencmis.commons.PropertyIds;
import org.apache.chemistry.opencmis.commons.data.Acl;
import org.apache.chemistry.opencmis.commons.data.ContentStream;
import org.apache.chemistry.opencmis.commons.data.ExtensionsData;
import org.apache.chemistry.opencmis.commons.data.ObjectData;
import org.apache.chemistry.opencmis.commons.data.Properties;
import org.apache.chemistry.opencmis.commons.data.PropertyData;
import org.apache.chemistry.opencmis.commons.enums.BaseTypeId;
import org.apache.chemistry.opencmis.commons.enums.IncludeRelationships;
import org.apache.chemistry.opencmis.commons.enums.VersioningState;
import org.apache.chemistry.opencmis.commons.impl.dataobjects.BindingsObjectFactoryImpl;
import org.apache.chemistry.opencmis.commons.spi.BindingsObjectFactory;
import org.apache.chemistry.opencmis.commons.spi.Holder;
import org.apache.chemistry.opencmis.commons.spi.ObjectService;
import org.apache.chemistry.opencmis.commons.spi.VersioningService;
import org.apache.chemistry.opencmis.inmemory.UnitTestTypeSystemCreator;
import org.apache.chemistry.opencmis.inmemory.storedobj.impl.ContentStreamDataImpl;
/**
* Utility class that fills the in-memory repository with some test objects that
* can be used for query
*
* This class uses the following data for query testing. We have one
* document type "ComplexType" and one folder type "FolderType" The
* document type has one property of each of the types boolean, integer,
* decimal, string and datetime. id, uri and html are treated like a
* string and do not make a difference.
*
* String Int Double DateTime Boolean
* ------------------------------------------------ Alpha -100 -1.6E-5
* 23.05.1618 true Beta -50 -4.0E24 08.05.1945 false Gamma 0 3.141592
* (now) true Delta 50 1.23456E-6 20.01.2038 true Epsilon 100 1.2345E12
* 14.07.2345 false
*
* For folder and tree tests this series is put in each of the three
* test folders
*/
public class QueryTestDataCreator {
private final BindingsObjectFactory fFactory = new BindingsObjectFactoryImpl();
private final String rootFolderId;
private final String repositoryId;
private final ObjectService fObjSvc;
private final VersioningService fVerSvc;
private String doc1, doc2, doc3, doc4, doc5;
private String folder1;
private String folder2;
private String folder11;
private static final TimeZone TZ = TimeZone.getTimeZone("Zulu");
public QueryTestDataCreator(String repositoryId, String rootFolderId, ObjectService objSvc, VersioningService verSvc) {
this.rootFolderId = rootFolderId;
this.repositoryId = repositoryId;
fObjSvc = objSvc;
fVerSvc = verSvc;
}
public String getFolder1() {
return folder1;
}
public String getFolder2() {
return folder2;
}
public String getFolder11() {
return folder11;
}
public void createBasicTestData() {
createTestFolders();
createBasicTestDocuments();
}
@SuppressWarnings("serial")
public void createBasicTestDocuments() {
final GregorianCalendar gc1 = new GregorianCalendar(TZ);
gc1.clear();
gc1.set(1945, 4, 8);
final Map<String, Object> propertyMap1 = new HashMap<String, Object>() {
{
put(PROP_ID_STRING, "Alpha");
put(PROP_ID_INT, Integer.valueOf(-100));
put(PROP_ID_DECIMAL, Double.valueOf(-4.0E24d));
put(PROP_ID_DATETIME, gc1);
put(PROP_ID_BOOLEAN, true);
}
};
ContentStream content1 = createContent("I have a cat.");
doc1 = createDocument("alpha", rootFolderId, COMPLEX_TYPE, propertyMap1, content1);
assertNotNull(doc1);
final GregorianCalendar gc2 = new GregorianCalendar(TZ);
gc2.clear();
gc2.set(1618, 4, 23);
final Map<String, Object> propertyMap2 = new HashMap<String, Object>() {
{
put(PROP_ID_STRING, "Beta");
put(PROP_ID_INT, Integer.valueOf(-50));
put(PROP_ID_DECIMAL, Double.valueOf(-1.6E-5d));
put(PROP_ID_DATETIME, gc2);
put(PROP_ID_BOOLEAN, false);
}
};
ContentStream content2 = createContent("I have a cat named Kitty Katty.");
doc2 = createDocument("beta", rootFolderId, COMPLEX_TYPE, propertyMap2, content2);
assertNotNull(doc2);
final Map<String, Object> propertyMap3 = new HashMap<String, Object>() {
{
put(PROP_ID_STRING, "Gamma");
put(PROP_ID_INT, Integer.valueOf(0));
put(PROP_ID_DECIMAL, Double.valueOf(Math.PI));
put(PROP_ID_DATETIME, new GregorianCalendar(TZ));
put(PROP_ID_BOOLEAN, true);
}
};
ContentStream content3 = createContent("I have a dog.");
doc3 = createDocument("gamma", rootFolderId, COMPLEX_TYPE, propertyMap3, content3);
assertNotNull(doc3);
final GregorianCalendar gc4 = new GregorianCalendar(TZ);
gc4.clear();
gc4.set(2038, 0, 20);
final Map<String, Object> propertyMap4 = new HashMap<String, Object>() {
{
put(PROP_ID_STRING, "Delta");
put(PROP_ID_INT, Integer.valueOf(50));
put(PROP_ID_DECIMAL, Double.valueOf(1.23456E-6));
put(PROP_ID_DATETIME, gc4);
put(PROP_ID_BOOLEAN, true);
}
};
ContentStream content4 = createContent("I have a cat and a dog.");
doc4 = createDocument("delta", rootFolderId, COMPLEX_TYPE, propertyMap4, content4);
assertNotNull(doc4);
final GregorianCalendar gc5 = new GregorianCalendar(TZ);
gc5.clear();
gc5.set(2345, 6, 14);
final Map<String, Object> propertyMap5 = new HashMap<String, Object>() {
{
put(PROP_ID_STRING, "Epsilon");
put(PROP_ID_INT, Integer.valueOf(100));
put(PROP_ID_DECIMAL, Double.valueOf(1.2345E12));
put(PROP_ID_DATETIME, gc5);
put(PROP_ID_BOOLEAN, false);
}
};
ContentStream content5 = createContent("I hate having pets.");
doc5 = createDocument("epsilon", rootFolderId, COMPLEX_TYPE, propertyMap5, content5);
assertNotNull(doc5);
final Map<String, Object> propertyMap6 = new HashMap<String, Object>();
doc4 = createDocument("John's Document", rootFolderId, BaseTypeId.CMIS_DOCUMENT.value(), propertyMap6, null);
assertNotNull(doc4);
}
@SuppressWarnings("serial")
public void createMultiValueDocuments() {
final List<String> mvProps1 = new ArrayList<String>() {
{
add("red");
add("green");
add("blue");
}
};
final Map<String, Object> propertyMap1 = new HashMap<String, Object>() {
{
put(PROP_ID_STRING_MULTI_VALUE, mvProps1);
put(PROP_ID_INT, Integer.valueOf(100));
}
};
createDocument("mv-alpha", rootFolderId, COMPLEX_TYPE, propertyMap1);
final List<String> mvProps2 = new ArrayList<String>() {
{
add("red");
add("pink");
add("violet");
}
};
final Map<String, Object> propertyMap2 = new HashMap<String, Object>() {
{
put(PROP_ID_STRING_MULTI_VALUE, mvProps2);
put(PROP_ID_INT, Integer.valueOf(200));
}
};
createDocument("mv-beta", rootFolderId, COMPLEX_TYPE, propertyMap2);
}
@SuppressWarnings("serial")
public void createTestFolders() {
final Map<String, Object> propertyMap1 = new HashMap<String, Object>() {
{
put(PROP_ID_INT, Integer.valueOf(1234));
put(PROP_ID_STRING, "ABCD");
}
};
folder1 = createFolder("Folder 1", rootFolderId, FOLDER_TYPE, propertyMap1);
final Map<String, Object> propertyMap2 = new HashMap<String, Object>() {
{
put(PROP_ID_INT, Integer.valueOf(-2345));
put(PROP_ID_STRING, "defg");
}
};
folder2 = createFolder("Folder 2", rootFolderId, FOLDER_TYPE, propertyMap2);
final Map<String, Object> propertyMap3 = new HashMap<String, Object>() {
{
put(PROP_ID_INT, Integer.valueOf(123));
put(PROP_ID_STRING, "ZZZZ");
}
};
folder11 = createFolder("Folder 11", folder1, FOLDER_TYPE, propertyMap3);
}
@SuppressWarnings("serial")
public void createNullTestDocument() {
final Map<String, Object> propertyMap1 = new HashMap<String, Object>() {
{
put(PROP_ID_STRING, "DocumentWithNulls");
}
};
createDocument("nulldoc", rootFolderId, COMPLEX_TYPE, propertyMap1);
}
@SuppressWarnings("serial")
public void createLikeTestDocuments(String folderId) {
final Map<String, Object> propertyMap1 = new HashMap<String, Object>() {
{
put(PROP_ID_STRING, "ABCDEF");
}
};
createDocument("likedoc1", folderId, COMPLEX_TYPE, propertyMap1);
final Map<String, Object> propertyMap2 = new HashMap<String, Object>() {
{
put(PROP_ID_STRING, "ABC123");
}
};
createDocument("likedoc2", folderId, COMPLEX_TYPE, propertyMap2);
final Map<String, Object> propertyMap3 = new HashMap<String, Object>() {
{
put(PROP_ID_STRING, "123ABC");
}
};
createDocument("likedoc3", folderId, COMPLEX_TYPE, propertyMap3);
}
@SuppressWarnings("serial")
public String createVersionedDocument() {
final Map<String, Object> propertyMap1 = new HashMap<String, Object>() {
{
put(VERSION_PROPERTY_ID, "ver123");
}
};
String verIdV1 = createDocument("verdoc1", rootFolderId, UnitTestTypeSystemCreator.VERSIONED_TYPE,
propertyMap1, VersioningState.MAJOR, null);
ObjectData version = fObjSvc.getObject(repositoryId, verIdV1, "*", false, IncludeRelationships.NONE, null,
false, false, null);
// get version series id
String verIdSer = (String) version.getProperties().getProperties().get(PropertyIds.VERSION_SERIES_ID)
.getFirstValue();
// create second version
final Map<String, Object> propertyMap2 = new HashMap<String, Object>() {
{
put(VERSION_PROPERTY_ID, "ver456");
}
};
Properties propsV2 = createDocumentProperties(null, null, propertyMap2);
Holder<String> idHolder = new Holder<String>(verIdV1);
Holder<Boolean> contentCopied = new Holder<Boolean>(false);
fVerSvc.checkOut(repositoryId, idHolder, null, contentCopied);
idHolder = new Holder<String>(verIdV1);
// Test check-in and pass content and properties
String checkinComment = "Here comes next version.";
fVerSvc.checkIn(repositoryId, idHolder, true, propsV2, null, checkinComment, null, null, null, null);
// String verIdV2 = idHolder.getValue();
return verIdSer;
}
@SuppressWarnings("serial")
public void createSecondaryTestDocuments() {
final int intPropVal1 = 100;
final String stringPropVal1 = "Secondary Property Value";
final int intPropVal2 = 200;
final String stringPropVal2 = "Secondary String";
final GregorianCalendar gc1 = new GregorianCalendar(TZ);
gc1.clear();
gc1.set(1945, 4, 8);
final Map<String, Object> propertyMap1 = new HashMap<String, Object>() {
{
put(PROP_ID_STRING, "Secondary");
put(PROP_ID_INT, Integer.valueOf(-100));
put(PROP_ID_DECIMAL, Double.valueOf(-4.0E24d));
put(PROP_ID_DATETIME, gc1);
put(PROP_ID_BOOLEAN, true);
put(SECONDARY_STRING_PROP, stringPropVal1);
put(SECONDARY_INTEGER_PROP, intPropVal1);
put(PropertyIds.SECONDARY_OBJECT_TYPE_IDS, SECONDARY_TYPE);
}
};
ContentStream content1 = createContent("Some more content.");
doc1 = createDocument("docwithsecondary", rootFolderId, COMPLEX_TYPE, propertyMap1, content1);
assertNotNull(doc1);
final Map<String, Object> propertyMap2 = new HashMap<String, Object>() {
{
put(PROP_ID_STRING, "Secondary 2");
put(PROP_ID_INT, Integer.valueOf(123));
put(PROP_ID_DECIMAL, Double.valueOf(1.23E24d));
put(PROP_ID_BOOLEAN, false);
put(SECONDARY_STRING_PROP, stringPropVal2);
put(SECONDARY_INTEGER_PROP, intPropVal2);
put(PropertyIds.SECONDARY_OBJECT_TYPE_IDS, SECONDARY_TYPE);
}
};
ContentStream content2 = createContent("Even still some more content.");
doc1 = createDocument("docwithsecondary2", rootFolderId, COMPLEX_TYPE, propertyMap2, content2);
assertNotNull(doc1);
}
private String createFolder(String folderName, String parentFolderId, String typeId, Map<String, Object> properties) {
Properties props = createFolderProperties(folderName, typeId, properties);
String id = null;
try {
id = fObjSvc.createFolder(repositoryId, props, parentFolderId, null, null, null, null);
if (null == id) {
fail("createFolder failed.");
}
} catch (Exception e) {
fail("createFolder() failed with exception: " + e);
}
return id;
}
private String createDocument(String name, String folderId, String typeId, Map<String, Object> properties) {
return createDocument(name, folderId, typeId, properties, VersioningState.NONE, null);
}
private String createDocument(String name, String folderId, String typeId, Map<String, Object> properties,
ContentStream contentStream) {
return createDocument(name, folderId, typeId, properties, VersioningState.NONE, contentStream);
}
private String createDocument(String name, String folderId, String typeId, Map<String, Object> properties,
VersioningState verState, ContentStream contentStream) {
List<String> policies = null;
Acl addACEs = null;
Acl removeACEs = null;
ExtensionsData extension = null;
Properties props = createDocumentProperties(name, typeId, properties);
String id = null;
try {
id = fObjSvc.createDocument(repositoryId, props, folderId, contentStream, verState, policies, addACEs,
removeACEs, extension);
if (null == id) {
fail("createDocument failed.");
}
} catch (Exception e) {
fail("createDocument() failed with exception: " + e);
}
return id;
}
private Properties createDocumentProperties(String name, String typeId, Map<String, Object> propertyMap) {
List<PropertyData<?>> properties = new ArrayList<PropertyData<?>>();
if (name != null) {
properties.add(fFactory.createPropertyIdData(PropertyIds.NAME, name));
}
if (typeId != null) {
properties.add(fFactory.createPropertyIdData(PropertyIds.OBJECT_TYPE_ID, typeId));
}
for (Map.Entry<String, Object> propEntry : propertyMap.entrySet()) {
PropertyData<?> pd = createPropertyData(propEntry.getKey(), propEntry.getValue());
properties.add(pd);
}
Properties props = fFactory.createPropertiesData(properties);
return props;
}
private Properties createFolderProperties(String folderName, String typeId, Map<String, Object> propertyMap) {
List<PropertyData<?>> properties = new ArrayList<PropertyData<?>>();
properties.add(fFactory.createPropertyIdData(PropertyIds.NAME, folderName));
properties.add(fFactory.createPropertyIdData(PropertyIds.OBJECT_TYPE_ID, typeId));
for (Map.Entry<String, Object> propEntry : propertyMap.entrySet()) {
PropertyData<?> pd = createPropertyData(propEntry.getKey(), propEntry.getValue());
properties.add(pd);
}
Properties props = fFactory.createPropertiesData(properties);
return props;
}
/**
* Simplified property creation method, create Property of Boolean, String,
* Integer, Decimal, or DataTime depending on class of value (Boolean,
* String, Integer, Double, or GregorianCalendar. Id, Html and URI are not
* supported
*
* @param propId
* @param value
* @return
*/
@SuppressWarnings("unchecked")
private PropertyData<?> createPropertyData(String propId, Object value) {
Class<?> clazz = value.getClass();
if (clazz.equals(Boolean.class)) {
return fFactory.createPropertyBooleanData(propId, (Boolean) value);
} else if (clazz.equals(Double.class)) {
return fFactory.createPropertyDecimalData(propId, BigDecimal.valueOf((Double) value));
} else if (clazz.equals(Integer.class)) {
return fFactory.createPropertyIntegerData(propId, BigInteger.valueOf((Integer) value));
} else if (clazz.equals(String.class)) {
return fFactory.createPropertyStringData(propId, (String) value);
} else if (clazz.equals(GregorianCalendar.class)) {
return fFactory.createPropertyDateTimeData(propId, (GregorianCalendar) value);
} else if (value instanceof List) {
clazz = ((List<?>) value).get(0).getClass();
if (clazz.equals(Boolean.class)) {
return fFactory.createPropertyBooleanData(propId, (List<Boolean>) value);
} else if (clazz.equals(Double.class)) {
return fFactory.createPropertyDecimalData(propId, (List<BigDecimal>) value);
} else if (clazz.equals(Integer.class)) {
return fFactory.createPropertyIntegerData(propId, (List<BigInteger>) value);
} else if (clazz.equals(String.class)) {
return fFactory.createPropertyStringData(propId, (List<String>) value);
} else if (clazz.equals(GregorianCalendar.class)) {
return fFactory.createPropertyDateTimeData(propId, (List<GregorianCalendar>) value);
} else {
fail("unsupported type in propery value: " + clazz);
}
} else {
fail("unsupported type in propery value: " + clazz);
}
return null;
}
private ContentStream createContent(String text) {
ContentStreamDataImpl content = new ContentStreamDataImpl(-1);
content.setFileName("data.txt");
content.setMimeType("text/plain");
try {
content.setContent(new ByteArrayInputStream(text.getBytes()));
} catch (IOException e) {
throw new RuntimeException("Failed to fill content stream with data", e);
}
return content;
}
}