/*****************************************************************************
*
* 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.xmpbox.schema;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;
import java.util.Map;
import org.apache.xmpbox.XMPMetadata;
import org.apache.xmpbox.type.AgentNameType;
import org.apache.xmpbox.type.BooleanType;
import org.apache.xmpbox.type.Cardinality;
import org.apache.xmpbox.type.DateType;
import org.apache.xmpbox.type.IntegerType;
import org.apache.xmpbox.type.PropertyType;
import org.apache.xmpbox.type.TextType;
import org.apache.xmpbox.type.ThumbnailType;
import org.apache.xmpbox.type.TypeMapping;
import org.apache.xmpbox.type.Types;
import org.apache.xmpbox.type.URIType;
import org.apache.xmpbox.type.URLType;
import org.junit.Assert;
import org.junit.Test;
public abstract class AbstractXMPSchemaTest
{
protected XMPMetadata metadata;
protected String property;
protected PropertyType type;
protected XMPSchema schema;
protected Class<?> schemaClass;
protected Object value;
public AbstractXMPSchemaTest(String property, PropertyType type, Object value)
{
this.property = property;
this.value = value;
this.type = type;
}
public static Object[] wrapProperty(String name, Types type, Object value)
{
return wrapProperty(name, type, Cardinality.Simple, value);
}
public static Object[] wrapProperty(String name, Types type, Cardinality card, Object value)
{
// if (type==Types.Boolean) {
// Assert.assertTrue(value instanceof Boolean);
// } else if (type==Types.Text) {
// Assert.assertTrue(value instanceof String);
// } else if (type==Types.Integer) {
// Assert.assertTrue(value instanceof Integer);
// } else if (type==Types.Date) {
// Assert.assertTrue(value instanceof Calendar);
// } else if (type==Types.URL) {
// Assert.assertTrue(value instanceof String);
// }
return new Object[] { name, TypeMapping.createPropertyType(type, card), value };
}
@Test
public void testGetSetValue() throws Exception
{
if (type.type() == Types.Text && type.card() == Cardinality.Simple)
{
testGetSetTextValue();
}
else if (type.type() == Types.Boolean && type.card() == Cardinality.Simple)
{
testGetSetBooleanValue();
}
else if (type.type() == Types.Integer && type.card() == Cardinality.Simple)
{
testGetSetIntegerValue();
}
else if (type.type() == Types.Date && type.card() == Cardinality.Simple)
{
testGetSetDateValue();
}
else if (type.type() == Types.URI && type.card() == Cardinality.Simple)
{
testGetSetTextValue();
}
else if (type.type() == Types.URL && type.card() == Cardinality.Simple)
{
testGetSetTextValue();
}
else if (type.type() == Types.AgentName && type.card() == Cardinality.Simple)
{
testGetSetTextValue();
}
else if (type.type() == Types.LangAlt && type.card() == Cardinality.Simple)
{
// do nothing
}
else if (type.type() == Types.ResourceRef && type.card() == Cardinality.Simple)
{
// do nothing
}
else if (type.card() != Cardinality.Simple)
{
// do nothing
}
else
{
throw new Exception("Unknown type : " + type);
}
}
@Test
public void testGetSetProperty() throws Exception
{
if (type.type() == Types.Text && type.card() == Cardinality.Simple)
{
testGetSetTextProperty();
}
else if (type.type() == Types.URI && type.card() == Cardinality.Simple)
{
testGetSetURIProperty();
}
else if (type.type() == Types.URL && type.card() == Cardinality.Simple)
{
testGetSetURLProperty();
}
else if (type.type() == Types.AgentName && type.card() == Cardinality.Simple)
{
testGetSetAgentNameProperty();
}
else if (type.type() == Types.Boolean && type.card() == Cardinality.Simple)
{
testGetSetBooleanProperty();
}
else if (type.type() == Types.Integer && type.card() == Cardinality.Simple)
{
testGetSetIntegerProperty();
}
else if (type.type() == Types.Date && type.card() == Cardinality.Simple)
{
testGetSetDateProperty();
}
else if (type.type() == Types.Text && type.card() == Cardinality.Seq)
{
testGetSetTextListValue("seq");
}
else if (type.type() == Types.Version && type.card() == Cardinality.Seq)
{
testGetSetTextListValue("seq");
}
else if (type.type() == Types.Text && type.card() == Cardinality.Bag)
{
testGetSetTextListValue("bag");
}
else if (type.type() == Types.ProperName && type.card() == Cardinality.Bag)
{
testGetSetTextListValue("bag");
}
else if (type.type() == Types.XPath && type.card() == Cardinality.Bag)
{
testGetSetTextListValue("bag");
}
else if (type.type() == Types.Date && type.card() == Cardinality.Seq)
{
testGetSetDateListValue("seq");
}
else if (type.type() == Types.LangAlt && type.card() == Cardinality.Simple)
{
testGetSetLangAltValue();
}
else if (type.type() == Types.Thumbnail && type.card() == Cardinality.Alt)
{
testGetSetThumbnail();
}
else
{
throw new Exception("Unknown type : " + type);
}
Field[] fields = schemaClass.getFields();
for (Field field : fields)
{
if (field.isAnnotationPresent(PropertyType.class))
{
if (!field.get(schema).equals(property))
{
PropertyType pt = field.getAnnotation(PropertyType.class);
if (pt.type() == Types.LangAlt)
{
// do not check method existence
}
else if (pt.type() == Types.Thumbnail && pt.card() == Cardinality.Alt)
{
// do not check method existence
}
else if (pt.type() == Types.ResourceRef)
{
// do not check method existence
}
else if (pt.type() == Types.Version && pt.card() == Cardinality.Seq)
{
// do not check method existence
}
else
{
// type test
PropertyType spt = retrievePropertyType(field.get(schema).toString());
String getNameProperty = "get" + prepareName(field.get(schema).toString(), spt) + "Property";
Method getMethod = schemaClass.getMethod(getNameProperty);
Assert.assertNull(getNameProperty + " should return null when testing " + property,
getMethod.invoke(schema));
// value test
String getNameValue = "get" + prepareName(field.get(schema).toString(), spt);
getMethod = schemaClass.getMethod(getNameValue);
Assert.assertNotNull(getNameValue + " method should exist", getMethod);
Assert.assertNull(getNameValue + " should return null when testing " + property,
getMethod.invoke(schema));
}
}
}
}
}
protected PropertyType retrievePropertyType(String prop) throws IllegalArgumentException, IllegalAccessException
{
Field[] fields = schemaClass.getFields();
for (Field field : fields)
{
if (field.isAnnotationPresent(PropertyType.class))
{
PropertyType pt = field.getAnnotation(PropertyType.class);
if (field.get(schema).equals(prop))
{
return pt;
}
}
}
return type;
}
protected String firstUpper(String name)
{
StringBuilder sb = new StringBuilder(name.length());
sb.append(name.substring(0, 1).toUpperCase());
sb.append(name.substring(1));
return sb.toString();
}
protected String prepareName(String prop, PropertyType type)
{
String fu = firstUpper(prop);
StringBuilder sb = new StringBuilder(fu.length() + 1);
sb.append(fu);
if (fu.endsWith("s"))
{
// do nothing
}
else if (fu.endsWith("y"))
{
// do nothing
}
else if (type.card() != Cardinality.Simple)
{
sb.append("s");
}
return sb.toString();
}
protected String setMethod(String prop)
{
StringBuilder sb = new StringBuilder(3 + prop.length());
sb.append("set").append(prepareName(prop, type)).append("Property");
return sb.toString();
}
protected String addMethod(String prop)
{
String fu = firstUpper(prop);
StringBuilder sb = new StringBuilder(3 + prop.length());
sb.append("add").append(fu);
return sb.toString();
}
protected String getMethod(String prop)
{
String fu = firstUpper(prop);
StringBuilder sb = new StringBuilder(3 + prop.length());
sb.append("get").append(fu).append("Property");
return sb.toString();
}
protected String setValueMethod(String prop)
{
String fu = firstUpper(prop);
StringBuilder sb = new StringBuilder(8 + prop.length());
sb.append("set").append(fu);
return sb.toString();
}
protected String getValueMethod(String prop)
{
StringBuilder sb = new StringBuilder(8 + prop.length());
sb.append("get").append(prepareName(prop, type));
return sb.toString();
}
protected String addToValueMethod(String prop)
{
String fu = firstUpper(prop);
StringBuilder sb = new StringBuilder(10 + prop.length());
sb.append("add").append(fu);
return sb.toString();
}
protected void testGetSetBooleanProperty() throws Exception
{
String setName = setMethod(property);
String getName = getMethod(property);
BooleanType bt = new BooleanType(metadata, null, schema.getPrefix(), property, value);
Method setMethod = schemaClass.getMethod(setName, BooleanType.class);
Method getMethod = schemaClass.getMethod(getName);
setMethod.invoke(schema, bt);
Boolean found = ((BooleanType) getMethod.invoke(schema)).getValue();
Assert.assertEquals(value, found);
}
protected void testGetSetDateProperty() throws Exception
{
String setName = setMethod(property);
String getName = getMethod(property);
DateType dt = new DateType(metadata, null, schema.getPrefix(), property, value);
Method setMethod = schemaClass.getMethod(setName, DateType.class);
Method getMethod = schemaClass.getMethod(getName);
setMethod.invoke(schema, dt);
Calendar found = ((DateType) getMethod.invoke(schema)).getValue();
Assert.assertEquals(value, found);
}
protected void testGetSetIntegerProperty() throws Exception
{
String setName = setMethod(property);
String getName = getMethod(property);
IntegerType it = new IntegerType(metadata, null, schema.getPrefix(), property, value);
Method setMethod = schemaClass.getMethod(setName, IntegerType.class);
Method getMethod = schemaClass.getMethod(getName);
setMethod.invoke(schema, it);
Integer found = ((IntegerType) getMethod.invoke(schema)).getValue();
Assert.assertEquals(value, found);
}
protected void testGetSetTextProperty() throws Exception
{
String setName = setMethod(property);
String getName = getMethod(property);
TextType tt = metadata.getTypeMapping().createText(null, schema.getPrefix(), property, (String) value);
Method setMethod = schemaClass.getMethod(setName, TextType.class);
Method getMethod = schemaClass.getMethod(getName);
setMethod.invoke(schema, tt);
String found = ((TextType) getMethod.invoke(schema)).getStringValue();
Assert.assertEquals(value, found);
}
protected void testGetSetURIProperty() throws Exception
{
String setName = setMethod(property);
String getName = getMethod(property);
URIType tt = metadata.getTypeMapping().createURI(null, schema.getPrefix(), property, (String) value);
Method setMethod = schemaClass.getMethod(setName, URIType.class);
Method getMethod = schemaClass.getMethod(getName);
setMethod.invoke(schema, tt);
String found = ((TextType) getMethod.invoke(schema)).getStringValue();
Assert.assertEquals(value, found);
}
protected void testGetSetURLProperty() throws Exception
{
String setName = setMethod(property);
String getName = getMethod(property);
URLType tt = metadata.getTypeMapping().createURL(null, schema.getPrefix(), property, (String) value);
Method setMethod = schemaClass.getMethod(setName, URLType.class);
Method getMethod = schemaClass.getMethod(getName);
setMethod.invoke(schema, tt);
String found = ((TextType) getMethod.invoke(schema)).getStringValue();
Assert.assertEquals(value, found);
}
protected void testGetSetAgentNameProperty() throws Exception
{
String setName = setMethod(property);
String getName = getMethod(property);
AgentNameType tt = metadata.getTypeMapping()
.createAgentName(null, schema.getPrefix(), property, (String) value);
Method setMethod = schemaClass.getMethod(setName, AgentNameType.class);
Method getMethod = schemaClass.getMethod(getName);
setMethod.invoke(schema, tt);
String found = ((AgentNameType) getMethod.invoke(schema)).getStringValue();
Assert.assertEquals(value, found);
}
protected void testGetSetTextListValue(String tp) throws Exception
{
String setName = addToValueMethod(property);
String getName = getValueMethod(property);
String[] svalue = (String[]) value;
Arrays.sort(svalue);
// push all
Method setMethod = schemaClass.getMethod(setName, String.class);
for (String string : svalue)
{
setMethod.invoke(schema, string);
}
// retrieve
Method getMethod = schemaClass.getMethod(getName);
List<String> fields = (List<String>) getMethod.invoke(schema);
for (String field : fields)
{
Assert.assertTrue(field + " should be found in list", Arrays.binarySearch(svalue, field) >= 0);
}
}
protected void testGetSetDateListValue(String tp) throws Exception
{
String setName = addToValueMethod(property);
String getName = getValueMethod(property);
Calendar[] svalue = (Calendar[]) value;
Arrays.sort(svalue);
// push all
Method setMethod = schemaClass.getMethod(setName, Calendar.class);
for (Calendar inst : svalue)
{
setMethod.invoke(schema, inst);
}
// retrieve
Method getMethod = schemaClass.getMethod(getName);
List<Calendar> fields = (List<Calendar>) getMethod.invoke(schema);
for (Calendar field : fields)
{
Assert.assertTrue(field + " should be found in list", Arrays.binarySearch(svalue, field) >= 0);
}
}
protected void testGetSetThumbnail() throws Exception
{
String addName = addMethod(property);
String getName = getMethod(property);
Method setMethod = schemaClass.getMethod(addName, Integer.class, Integer.class, String.class, String.class);
Method getMethod = schemaClass.getMethod(getName);
Integer height = 162;
Integer width = 400;
String format = "JPEG";
String img = "/9j/4AAQSkZJRgABAgEASABIAAD";
setMethod.invoke(schema, height, width, format, img);
List<ThumbnailType> found = ((List<ThumbnailType>) getMethod.invoke(schema));
Assert.assertTrue(found.size() == 1);
ThumbnailType t1 = found.get(0);
Assert.assertEquals(height, t1.getHeight());
Assert.assertEquals(width, t1.getWidth());
Assert.assertEquals(format, t1.getFormat());
Assert.assertEquals(img, t1.getImage());
}
protected void testGetSetLangAltValue() throws Exception
{
String setName = addToValueMethod(property);
String getName = getValueMethod(property);
Map<String, String> svalue = (Map<String, String>) value;
// push all
Method setMethod = schemaClass.getMethod(setName, String.class, String.class);
for (Map.Entry<String, String> inst : svalue.entrySet())
{
setMethod.invoke(schema, inst.getKey(), inst.getValue());
}
// retrieve
String getLanguagesName = "get" + firstUpper(property) + "Languages";
Method getLanguages = schemaClass.getMethod(getLanguagesName);
List<String> lgs = (List<String>) getLanguages.invoke(schema);
for (String string : lgs)
{
Method getMethod = schemaClass.getMethod(getName, String.class);
String res = (String) getMethod.invoke(schema, string);
Assert.assertEquals(res, svalue.get(string));
}
}
protected void testGetSetURLValue() throws Exception
{
String setName = addToValueMethod(property);
String getName = getValueMethod(property);
String svalue = (String) value;
// push all
Method setMethod = schemaClass.getMethod(setName, String.class, String.class);
setMethod.invoke(schema, property, svalue);
// retrieve
String getLanguagesName = "get" + firstUpper(property) + "Languages";
Method getLanguages = schemaClass.getMethod(getLanguagesName);
List<String> lgs = (List<String>) getLanguages.invoke(schema);
for (String string : lgs)
{
Method getMethod = schemaClass.getMethod(getName, String.class);
String res = (String) getMethod.invoke(schema, string);
Assert.assertEquals(res, svalue);
}
}
protected void testGetSetTextValue() throws Exception
{
String setName = setValueMethod(property);
String getName = getValueMethod(property);
Method setMethod = schemaClass.getMethod(setName, String.class);
Method getMethod = schemaClass.getMethod(getName);
setMethod.invoke(schema, value);
String found = (String) getMethod.invoke(schema);
Assert.assertEquals(value, found);
}
protected void testGetSetBooleanValue() throws Exception
{
String setName = setValueMethod(property);
String getName = getValueMethod(property);
Method setMethod = schemaClass.getMethod(setName, Boolean.class);
Method getMethod = schemaClass.getMethod(getName);
setMethod.invoke(schema, value);
Boolean found = (Boolean) getMethod.invoke(schema);
Assert.assertEquals(value, found);
}
protected void testGetSetDateValue() throws Exception
{
String setName = setValueMethod(property);
String getName = getValueMethod(property);
Method setMethod = schemaClass.getMethod(setName, Calendar.class);
Method getMethod = schemaClass.getMethod(getName);
setMethod.invoke(schema, value);
Calendar found = (Calendar) getMethod.invoke(schema);
Assert.assertEquals(value, found);
}
protected void testGetSetIntegerValue() throws Exception
{
String setName = setValueMethod(property);
String getName = getValueMethod(property);
Method setMethod = schemaClass.getMethod(setName, Integer.class);
Method getMethod = schemaClass.getMethod(getName);
setMethod.invoke(schema, value);
Integer found = (Integer) getMethod.invoke(schema);
Assert.assertEquals(value, found);
}
}