blob: 442c6e47b5897cbf794f1e089cfde282c9ba51ba [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.commons.impl.xml;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.TimeZone;
import org.apache.chemistry.opencmis.commons.data.CmisExtensionElement;
import org.apache.chemistry.opencmis.commons.data.PropertyData;
import org.apache.chemistry.opencmis.commons.data.PropertyId;
import org.apache.chemistry.opencmis.commons.enums.PropertyType;
import org.apache.chemistry.opencmis.commons.impl.dataobjects.AbstractPropertyData;
import org.apache.chemistry.opencmis.commons.impl.dataobjects.CmisExtensionElementImpl;
import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyBooleanImpl;
import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyDateTimeImpl;
import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyDecimalImpl;
import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyHtmlImpl;
import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyIdImpl;
import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyIntegerImpl;
import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyStringImpl;
import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyUriImpl;
import org.junit.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Base test class for converter tests.
*/
public abstract class AbstractConverterTest {
private final static Logger LOG = LoggerFactory.getLogger(AbstractConverterTest.class);
private final static long SEED = 1234567890;
protected Random rnd;
@Before
public void init() throws Exception {
rnd = new Random(SEED);
}
protected PropertyData<?> createPropertyData(PropertyType propertyType, int numValues) {
AbstractPropertyData<?> result = null;
switch (propertyType) {
case BOOLEAN:
result = new PropertyBooleanImpl();
if (numValues > 0) {
List<Boolean> values = new ArrayList<Boolean>();
for (int i = 0; i < numValues; i++) {
values.add(randomBoolean());
}
((PropertyBooleanImpl) result).setValues(values);
}
break;
case DATETIME:
result = new PropertyDateTimeImpl();
if (numValues > 0) {
List<GregorianCalendar> values = new ArrayList<GregorianCalendar>();
for (int i = 0; i < numValues; i++) {
values.add(randomDateTime());
}
((PropertyDateTimeImpl) result).setValues(values);
}
break;
case DECIMAL:
result = new PropertyDecimalImpl();
if (numValues > 0) {
List<BigDecimal> values = new ArrayList<BigDecimal>();
for (int i = 0; i < numValues; i++) {
values.add(randomDecimal());
}
((PropertyDecimalImpl) result).setValues(values);
}
break;
case HTML:
result = new PropertyHtmlImpl();
if (numValues > 0) {
List<String> values = new ArrayList<String>();
for (int i = 0; i < numValues; i++) {
values.add(randomString());
}
((PropertyHtmlImpl) result).setValues(values);
}
break;
case ID:
result = new PropertyIdImpl();
if (numValues > 0) {
List<String> values = new ArrayList<String>();
for (int i = 0; i < numValues; i++) {
values.add(randomString());
}
((PropertyIdImpl) result).setValues(values);
}
break;
case INTEGER:
result = new PropertyIntegerImpl();
if (numValues > 0) {
List<BigInteger> values = new ArrayList<BigInteger>();
for (int i = 0; i < numValues; i++) {
values.add(randomInteger());
}
((PropertyIntegerImpl) result).setValues(values);
}
break;
case STRING:
result = new PropertyStringImpl();
if (numValues > 0) {
List<String> values = new ArrayList<String>();
for (int i = 0; i < numValues; i++) {
values.add(randomString());
}
((PropertyStringImpl) result).setValues(values);
}
break;
case URI:
result = new PropertyUriImpl();
if (numValues > 0) {
List<String> values = new ArrayList<String>();
for (int i = 0; i < numValues; i++) {
values.add(randomUri());
}
((PropertyUriImpl) result).setValues(values);
}
break;
default:
assert false;
}
result.setId(randomString());
result.setDisplayName(randomString());
result.setLocalName(randomString());
result.setQueryName(randomString());
return result;
}
protected PropertyId createIdPropertyData(String id, String value) {
PropertyIdImpl result = new PropertyIdImpl();
result.setId(id);
result.setDisplayName(id);
result.setLocalName(id);
result.setQueryName(id);
result.setValue(value);
return result;
}
protected List<CmisExtensionElement> createExtensions(int depth) {
List<CmisExtensionElement> result = new ArrayList<CmisExtensionElement>();
String[] namespaces = new String[] { "http://ext1.com", "http://ext2.org", "http://ext3.net" };
for (int i = 0; i < randomInt(4) + 1; i++) {
String ns = namespaces[randomInt(namespaces.length)];
Map<String, String> attr = new HashMap<String, String>();
for (int j = 0; j < randomInt(3); j++) {
attr.put(randomTag(), randomString());
}
CmisExtensionElementImpl element;
if (randomBoolean() || depth < 1) {
element = new CmisExtensionElementImpl(ns, randomTag(), attr, randomString());
} else {
element = new CmisExtensionElementImpl(ns, randomTag(), attr, createExtensions(depth - 1));
}
result.add(element);
}
return result;
}
protected String randomString() {
StringBuilder sb = new StringBuilder();
int length = rnd.nextInt(21) + 3;
for (int i = 0; i < length; i++) {
sb.append((char) (rnd.nextInt(94) + 32));
}
return sb.toString();
}
protected String randomUri() {
StringBuilder sb = new StringBuilder("urn:test:");
int length = rnd.nextInt(21) + 3;
for (int i = 0; i < length; i++) {
sb.append((char) (rnd.nextInt(26) + 97));
}
return sb.toString();
}
protected Boolean randomBoolean() {
return Boolean.valueOf(rnd.nextBoolean());
}
protected BigInteger randomInteger() {
return BigInteger.valueOf(rnd.nextInt());
}
protected BigDecimal randomDecimal() {
return BigDecimal.valueOf(rnd.nextDouble() * rnd.nextInt());
}
protected GregorianCalendar randomDateTime() {
GregorianCalendar cal = new GregorianCalendar();
cal.setTimeZone(TimeZone.getTimeZone("GMT" + (rnd.nextBoolean() ? "+" : "-") + (rnd.nextInt(23) - 12) + ":00"));
cal.set(1583 + rnd.nextInt(8416), rnd.nextInt(12), rnd.nextInt(31) + 1, rnd.nextInt(23), rnd.nextInt(60),
rnd.nextInt(60));
cal.set(Calendar.MILLISECOND, 0);
return cal;
}
protected int randomInt(int n) {
return rnd.nextInt(n);
}
@SuppressWarnings("unchecked")
protected <T extends Enum<?>> T randomEnum(Class<T> enumClass) {
T[] values = null;
try {
values = (T[]) enumClass.getMethod("values", new Class<?>[0]).invoke(null, new Object[0]);
} catch (Exception e) {
throw new RuntimeException(e);
}
return values[rnd.nextInt(values.length)];
}
protected String randomTag() {
StringBuilder sb = new StringBuilder();
int length = rnd.nextInt(7) + 3;
for (int i = 0; i < length; i++) {
sb.append((char) (rnd.nextInt(26) + 'a'));
}
return sb.toString();
}
/**
* Compares two data objects.
*/
protected void assertDataObjectsEquals(String name, Object expected, Object actual, Set<String> ignoreMethods) {
LOG.debug(name + ": " + expected + " / " + actual);
if ((expected == null) && (actual == null)) {
return;
}
if ((expected == null) || (actual == null)) {
fail("Data object is null! name: " + name + " / expected: " + expected + " / actual: " + actual);
}
// handle simple types
if ((expected instanceof String) || (expected instanceof Boolean) || (expected instanceof BigInteger)
|| (expected instanceof BigDecimal) || (expected instanceof Enum<?>)) {
assertEquals(name, expected, actual);
return;
} else if (expected instanceof GregorianCalendar) {
long expectedMillis = ((GregorianCalendar) expected).getTimeInMillis();
long actualMillis = ((GregorianCalendar) actual).getTimeInMillis();
assertEquals(name, expectedMillis, actualMillis);
return;
} else if (expected instanceof List<?>) {
List<?> expectedList = (List<?>) expected;
List<?> actualList = (List<?>) actual;
assertEquals(name + ".length", expectedList.size(), actualList.size());
for (int i = 0; i < expectedList.size(); i++) {
assertDataObjectsEquals(name + "[" + i + "]", expectedList.get(i), actualList.get(i), ignoreMethods);
}
return;
} else if (expected instanceof Map<?, ?>) {
Map<?, ?> expectedMap = (Map<?, ?>) expected;
Map<?, ?> actualMap = (Map<?, ?>) actual;
assertEquals(name + ".length", expectedMap.size(), actualMap.size());
for (Map.Entry<?, ?> entry : expectedMap.entrySet()) {
assertTrue(name + ".contains[" + entry.getKey() + "]", actualMap.containsKey(entry.getKey()));
assertDataObjectsEquals(name + "[" + entry.getKey() + "]", entry.getValue(),
actualMap.get(entry.getKey()), ignoreMethods);
}
return;
} else if (expected instanceof Set<?>) {
Set<?> expectedSet = (Set<?>) expected;
Set<?> actualSet = (Set<?>) actual;
assertEquals(name + ".length", expectedSet.size(), actualSet.size());
for (Object item : expectedSet) {
assertTrue(name + ".contains[" + item + "]", actualSet.contains(item));
}
return;
}
for (Method m : expected.getClass().getMethods()) {
if (!m.getName().startsWith("get") && !m.getName().startsWith("is") && !m.getName().startsWith("supports")) {
continue;
}
if (ignoreMethods != null && ignoreMethods.contains(m.getName())) {
continue;
}
if (m.getName().equals("getClass")) {
continue;
}
if (m.getParameterTypes().length != 0) {
continue;
}
try {
Object expectedValue = m.invoke(expected, new Object[0]);
Object actualValue = m.invoke(actual, new Object[0]);
assertDataObjectsEquals(name + "." + m.getName(), expectedValue, actualValue, ignoreMethods);
} catch (Exception e) {
fail(e.toString());
}
}
}
}