/***************************************************************************** * 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.List; import java.util.Random; import org.apache.xmpbox.XMPMetadata; import org.apache.xmpbox.type.AbstractSimpleProperty; import org.apache.xmpbox.type.ArrayProperty; import org.apache.xmpbox.type.Cardinality; import org.apache.xmpbox.type.TypeMapping; import org.apache.xmpbox.type.AbstractTypeTester; import org.apache.xmpbox.type.Types; import org.apache.xmpbox.xml.DomXmpParser; import org.junit.Assert; import org.junit.Test; public abstract class AbstractSchemaTester extends AbstractTypeTester { protected XMPMetadata xmp; protected String fieldName; protected Types type; protected Cardinality cardinality; protected TypeMapping typeMapping = null; protected DomXmpParser builder; public void before() throws Exception { builder = new DomXmpParser(); xmp = XMPMetadata.createXMPMetadata(); typeMapping = xmp.getTypeMapping(); } protected abstract XMPSchema getSchema(); protected Class<? extends XMPSchema> getSchemaClass() { return getSchema().getClass(); } public AbstractSchemaTester(String fieldName, Types type, Cardinality card) { this.fieldName = fieldName; this.type = type; this.cardinality = card; } @Test public void testInitializedToNull() throws Exception { XMPSchema schema = getSchema(); // default method Assert.assertNull(schema.getProperty(fieldName)); // accessor if (cardinality == Cardinality.Simple) { String getter = calculateSimpleGetter(fieldName); Method get = getSchemaClass().getMethod(getter); Object result = get.invoke(schema); Assert.assertNull(result); } else { // arrays String getter = calculateArrayGetter(fieldName); Method get = getSchemaClass().getMethod(getter); Object result = get.invoke(schema); Assert.assertNull(result); } } @Test public void testSettingValue() throws Exception { internalTestSettingValue(); } @Test public void testRandomSettingValue() throws Exception { initializeSeed(new Random()); for (int i=0; i < RAND_LOOP_COUNT;i++) { internalTestSettingValue(); } } private void internalTestSettingValue() throws Exception { if (cardinality != Cardinality.Simple) { return; } XMPSchema schema = getSchema(); // only test simple properties Object value = getJavaValue(type); AbstractSimpleProperty property = schema.instanciateSimple(fieldName, value); schema.addProperty(property); String qn = getPropertyQualifiedName(fieldName); Assert.assertNotNull(schema.getProperty(fieldName)); // check other properties not modified List<Field> fields = getXmpFields(getSchemaClass()); for (Field field : fields) { // do not check the current name String fqn = getPropertyQualifiedName(field.get(null).toString()); if (!fqn.equals(qn)) { Assert.assertNull(schema.getProperty(fqn)); } } } @Test public void testSettingValueInArray() throws Exception { internalTestSettingValueInArray(); } @Test public void testRandomSettingValueInArray() throws Exception { initializeSeed(new Random()); for (int i=0; i < RAND_LOOP_COUNT;i++) { internalTestSettingValueInArray(); } } private void internalTestSettingValueInArray() throws Exception { if (cardinality == Cardinality.Simple) { return; } XMPSchema schema = getSchema(); // only test array properties Object value = getJavaValue(type); AbstractSimpleProperty property = schema.instanciateSimple(fieldName, value); switch (cardinality) { case Seq: schema.addUnqualifiedSequenceValue(property.getPropertyName(), property); break; case Bag: schema.addBagValue(property.getPropertyName(), property); break; default: throw new Exception("Unexpected case in test : " + cardinality.name()); } String qn = getPropertyQualifiedName(fieldName); Assert.assertNotNull(schema.getProperty(fieldName)); // check other properties not modified List<Field> fields = getXmpFields(getSchemaClass()); for (Field field : fields) { // do not check the current name String fqn = getPropertyQualifiedName(field.get(null).toString()); if (!fqn.equals(qn)) { Assert.assertNull(schema.getProperty(fqn)); } } } @Test public void testPropertySetterSimple() throws Exception { internalTestPropertySetterSimple(); } @Test public void testRandomPropertySetterSimple() throws Exception { initializeSeed(new Random()); for (int i=0; i < RAND_LOOP_COUNT;i++) { internalTestPropertySetterSimple(); } } private void internalTestPropertySetterSimple() throws Exception { if (cardinality != Cardinality.Simple) { return; } XMPSchema schema = getSchema(); String setter = calculateSimpleSetter(fieldName) + "Property"; Object value = getJavaValue(type); AbstractSimpleProperty asp = typeMapping.instanciateSimpleProperty(schema.getNamespace(), schema .getPrefix(), fieldName, value, type); Method set = getSchemaClass().getMethod(setter, type.getImplementingClass()); set.invoke(schema, asp); // check property set AbstractSimpleProperty stored = (AbstractSimpleProperty) schema.getProperty(fieldName); Assert.assertEquals(value, stored.getValue()); // check getter String getter = calculateSimpleGetter(fieldName) + "Property"; Method get = getSchemaClass().getMethod(getter); Object result = get.invoke(schema); Assert.assertTrue(type.getImplementingClass().isAssignableFrom(result.getClass())); Assert.assertEquals(asp, result); } @Test public void testPropertySetterInArray() throws Exception { internalTestPropertySetterInArray(); } @Test public void testRandomPropertySetterInArray() throws Exception { initializeSeed(new Random()); for (int i=0; i < RAND_LOOP_COUNT;i++) { internalTestPropertySetterInArray(); } } private void internalTestPropertySetterInArray() throws Exception { if (cardinality == Cardinality.Simple) { return; } XMPSchema schema = getSchema(); // add value String setter = "add" + calculateFieldNameForMethod(fieldName); // TypeDescription<AbstractSimpleProperty> td = // typeMapping.getSimpleDescription(type); Object value1 = getJavaValue(type); Method set = getSchemaClass().getMethod(setter, getJavaType(type)); set.invoke(schema, value1); // retrieve complex property String getter = calculateArrayGetter(fieldName) + "Property"; Method getcp = getSchemaClass().getMethod(getter); Object ocp = getcp.invoke(schema); Assert.assertTrue(ocp instanceof ArrayProperty); ArrayProperty cp = (ArrayProperty) ocp; // check size is ok (1) Assert.assertEquals(1, cp.getContainer().getAllProperties().size()); // add a new one Object value2 = getJavaValue(type); set.invoke(schema, value2); Assert.assertEquals(2, cp.getContainer().getAllProperties().size()); // remove the first String remover = "remove" + calculateFieldNameForMethod(fieldName); Method remove = getSchemaClass().getMethod(remover, getJavaType(type)); remove.invoke(schema, value1); Assert.assertEquals(1, cp.getContainer().getAllProperties().size()); } protected String getPropertyQualifiedName(String name) { StringBuilder sb = new StringBuilder(); sb.append(getSchema().getPrefix()).append(":").append(name); return sb.toString(); } }