/*
* (c) Copyright 2010-2011 AgileBirds
*
* This file is part of OpenFlexo.
*
* OpenFlexo is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenFlexo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenFlexo. If not, see <http://www.gnu.org/licenses/>.
*
*/
package org.openflexo.xmlcode;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
/**
* <p>
* <code>KeyValueCoder</code> is an utility class that allow to manipulate (set methods) properties of object (field or get/set methods
* pair) from values represented as String (very usefull for xml coding/decoding)
* </p>
* Those operations are done using the {@link java.lang.reflect} package and all developments done in {@link KeyValueProperty} class.<br>
* This class is used in the context of XML decoding using a mapping model allowing to instanciate directly object from XML strings or
* streams (and reverse operation).<br>
* Manipulated types are all the java primitives (<code>int</code>, <code>long</code>, <code>short</code>, <code>double</code>,
* <code>float</code>, <code>boolean</code>, <code>byte</code>, <code>char</code>) or a {@link java.util.Date}, a {@link java.lang.String} a
* {@link java.io.File} or a {@link java.net.URL})<br>
*
* @author <a href="mailto:Sylvain.Guerin@enst-bretagne.fr">Sylvain Guerin</a>
* @see KeyValueProperty
* @see XMLCoder
* @see XMLDecoder
* @see XMLMapping
* @see KeyValueDecoder
*
*/
public class KeyValueCoder {
/**
* Returns <code>KeyValueProperty</code> object matching <code>propertyName</code> value
*
* @param object
* an <code>Object</code> value
* @param propertyName
* a <code>String</code> value
* @return a <code>KeyValueProperty</code> value
* @exception InvalidObjectSpecificationException
* if an error occurs
*/
protected static KeyValueProperty getKeyValuePropertyFromName(Class<?> clazz, String propertyName, boolean setMethodIsMandatory)
throws InvalidObjectSpecificationException {
int modifiers = clazz.getModifiers();
// System.out.println("Class "+clazz.getName()+" public="+Modifier.isPublic(modifiers));
while (!(Modifier.isPublic(modifiers) || Modifier.isProtected(modifiers)) && clazz != null) {
clazz = clazz.getSuperclass();
modifiers = clazz.getModifiers();
}
Map<String, KeyValueProperty> kvpHash = classCache.get(clazz);
if (kvpHash == null) {
classCache.put(clazz, kvpHash = new Hashtable<String, KeyValueProperty>());
}
KeyValueProperty resp = kvpHash.get(propertyName);
if (resp != null) {
return resp;
}
try {
resp = new HashtableKeyValueProperty(clazz, propertyName, setMethodIsMandatory);
} catch (InvalidKeyValuePropertyException e) {
}
if (resp == null) {
try {
resp = new VectorKeyValueProperty(clazz, propertyName, setMethodIsMandatory);
} catch (InvalidKeyValuePropertyException e) {
}
}
if (resp == null) {
try {
if (ParameteredKeyValueProperty.isParameteredKeyValuePropertyPattern(propertyName)) {
resp = new ParameteredKeyValueProperty(clazz, propertyName, setMethodIsMandatory);
} else {
resp = new SingleKeyValueProperty(clazz, propertyName, setMethodIsMandatory);
}
} catch (InvalidKeyValuePropertyException e) {
throw new InvalidObjectSpecificationException("Can't handle property " + propertyName + " for object " + clazz.getName()
+ ". See following for details: " + e);
}
}
kvpHash.put(propertyName, resp);
return resp;
}
private static final Map<Class<?>, Map<String, KeyValueProperty>> classCache = new Hashtable<Class<?>, Map<String, KeyValueProperty>>();
public static void clearClassCache() {
classCache.clear();
}
/**
* <p>
* Sets value <code>textValue</code> for keyValueProperty <code>keyValueProperty </code> for object <code>object</code> asserting that
* corresponding keyValueProperty type is a java primitive (<code>int</code>, <code>long</code>, <code>short</code>, <code>double</code>, <code>float</code>, <code>boolean</code>, <code>byte</code>, <code>char</code>) or a {@link java.util.Date}, a
* {@link java.lang.String} a {@link java.io.File} or a {@link java.net.URL})
* </p>
* . No assertion is done on specific type and value is parsed from <code>textValue</code> according to corresponding type.
*
* @param object
* an <code>Object</code> value
* @param textValue
* a <code>String</code> value
* @param keyValueProperty
* a <code>KeyValueProperty</code> value
* @exception InvalidXMLDataException
* if an error occurs
* @exception InvalidObjectSpecificationException
* if keyValueProperty type is not a java primitive nor a <code>Date</code> nor a <code>String</code>
* @exception AccessorInvocationException
* if an error occurs during accessor invocation
*/
public static void setValueForKey(Object object, String textValue, SingleKeyValueProperty keyValueProperty)
throws InvalidXMLDataException, InvalidObjectSpecificationException, AccessorInvocationException {
setValueForKey(object, textValue, keyValueProperty, StringEncoder.getDefaultInstance());
}
/**
* <p>
* Sets value <code>textValue</code> for keyValueProperty <code>keyValueProperty </code> for object <code>object</code> asserting that
* corresponding keyValueProperty type is a java primitive (<code>int</code>, <code>long</code>, <code>short</code>, <code>double</code>, <code>float</code>, <code>boolean</code>, <code>byte</code>, <code>char</code>) or a {@link java.util.Date}, a
* {@link java.lang.String} a {@link java.io.File} or a {@link java.net.URL} of an object that can be encoded by
* <code>stringEncoder</code>.
* </p>
* No assertion is done on specific type and value is parsed from <code>textValue</code> according to corresponding type.
*
* @param object
* an <code>Object</code> value
* @param textValue
* a <code>String</code> value
* @param keyValueProperty
* a <code>KeyValueProperty</code> value
* @param stringEncoder
* a <code>StringEncoder</code> value
* @exception InvalidXMLDataException
* if an error occurs
* @exception InvalidObjectSpecificationException
* if keyValueProperty type is not a java primitive nor a <code>Date</code> nor a <code>String</code>
* @exception AccessorInvocationException
* if an error occurs during accessor invocation
*/
public static void setValueForKey(Object object, String textValue, SingleKeyValueProperty keyValueProperty, StringEncoder stringEncoder)
throws InvalidXMLDataException, InvalidObjectSpecificationException, AccessorInvocationException {
// Debugging.debug ("setValueForKey() called with '"+textValue+"' for
// keyValueProperty '"+keyValueProperty.getName()+"' for object of class
// "+object.getClass().getName());
if (keyValueProperty.getType().isPrimitive()) {
// Class of keyValueProperty is a primitive such as int, long,
// short, double, float, boolean, byte, char
if (keyValueProperty.getType() == Boolean.TYPE) {
setBooleanAsStringForKey(object, textValue, keyValueProperty);
} else if (keyValueProperty.getType() == Character.TYPE) {
setCharacterAsStringForKey(object, textValue, keyValueProperty);
} else if (keyValueProperty.getType() == Byte.TYPE) {
setByteAsStringForKey(object, textValue, keyValueProperty);
} else if (keyValueProperty.getType() == Short.TYPE) {
setShortAsStringForKey(object, textValue, keyValueProperty);
} else if (keyValueProperty.getType() == Integer.TYPE) {
setIntegerAsStringForKey(object, textValue, keyValueProperty);
} else if (keyValueProperty.getType() == Long.TYPE) {
setLongAsStringForKey(object, textValue, keyValueProperty);
} else if (keyValueProperty.getType() == Float.TYPE) {
setFloatAsStringForKey(object, textValue, keyValueProperty);
} else if (keyValueProperty.getType() == Double.TYPE) {
setDoubleAsStringForKey(object, textValue, keyValueProperty);
}
} else {
if (textValue == null) {
throw new InvalidXMLDataException("Class " + keyValueProperty.getObjectClass().getName() + ": keyValueProperty "
+ keyValueProperty.getName() + " supplied value is null");
} else {
Object objectValue = null;
try {
objectValue = stringEncoder._decodeObject(textValue, keyValueProperty.getType());
} catch (InvalidDataException e) {
// System.out.println("InvalidDataException raised while evaluating "+keyValueProperty.getName()+" with value="+textValue+" for object "+object);
e.printStackTrace();
}
if (objectValue != null) {
setObjectForKey(object, objectValue, keyValueProperty);
}
}
}
}
/**
* Sets value <code>textValue</code> for keyValueProperty <code>propertyName</code> for object <code>object</code> asserting that
* corresponding keyValueProperty type is a java primitive (<code>int</code>, <code>long</code>, <code>short</code>, <code>double</code>
* , <code>float</code>, <code>boolean</code>, <code>byte</code>, <code>char</code>) or a <code>Date</code> or a <code>String</code>
* object. No assertion is done on specific type and value is parsed from <code>textValue</code> according to corresponding type.
*
* @param object
* an <code>Object</code> value
* @param textValue
* a <code>String</code> value
* @param propertyName
* a <code>String</code> value
* @exception InvalidXMLDataException
* if an error occurs
* @exception InvalidObjectSpecificationException
* if an error occurs
* @exception AccessorInvocationException
* if an error occurs during accessor invocation
*/
public static void setValueForKey(Object object, String textValue, String propertyName) throws InvalidXMLDataException,
InvalidObjectSpecificationException, AccessorInvocationException {
setValueForKey(object, textValue, (SingleKeyValueProperty) getKeyValuePropertyFromName(object.getClass(), propertyName, true),
StringEncoder.getDefaultInstance());
}
/**
* Sets value <code>textValue</code> for keyValueProperty <code>propertyName</code> for object <code>object</code> asserting that
* corresponding keyValueProperty type is a java primitive (<code>int</code>, <code>long</code>, <code>short</code>, <code>double</code>
* , <code>float</code>, <code>boolean</code>, <code>byte</code>, <code>char</code>) or a <code>Date</code> or a <code>String</code>
* object. No assertion is done on specific type and value is parsed from <code>textValue</code> according to corresponding type.
*
* @param object
* an <code>Object</code> value
* @param textValue
* a <code>String</code> value
* @param propertyName
* a <code>String</code> value
* @exception InvalidXMLDataException
* if an error occurs
* @exception InvalidObjectSpecificationException
* if an error occurs
* @exception AccessorInvocationException
* if an error occurs during accessor invocation
*/
public static void setValueForKey(Object object, String textValue, String propertyName, StringEncoder stringEncoder)
throws InvalidXMLDataException, InvalidObjectSpecificationException, AccessorInvocationException {
setValueForKey(object, textValue, (SingleKeyValueProperty) getKeyValuePropertyFromName(object.getClass(), propertyName, true),
stringEncoder);
}
/**
* Sets value <code>textValue</code> for keyValueProperty <code>keyValueProperty</code> for object <code>object</code> asserting that
* corresponding keyValueProperty type is a <code>boolean</code>. Value is parsed from string <code>textValue</code>.
*
* @param object
* an <code>Object</code> value
* @param value
* a <code>boolean</code> value
* @param keyValueProperty
* a <code>KeyValueProperty</code> value
* @exception InvalidXMLDataException
* if an error occurs
* @exception InvalidObjectSpecificationException
* if an error occurs
* @exception AccessorInvocationException
* if an error occurs during accessor invocation
*/
public static void setBooleanValueForKey(Object object, boolean value, SingleKeyValueProperty keyValueProperty)
throws InvalidXMLDataException, InvalidObjectSpecificationException, AccessorInvocationException {
try {
keyValueProperty.setBooleanValue(value, object);
} catch (AccessorInvocationException e) {
throw e;
} catch (Exception e) {
throw new InvalidObjectSpecificationException("Class " + keyValueProperty.getObjectClass().getName() + ": keyValueProperty "
+ keyValueProperty.getName() + " Exception raised: " + e.toString());
}
}
/**
* Sets value <code>textValue</code> for keyValueProperty <code>keyValueProperty</code> for object <code>object</code> asserting that
* corresponding keyValueProperty type is a <code>boolean</code>. Value is parsed from string <code>textValue</code>.
*
* @param object
* an <code>Object</code> value
* @param textValue
* a <code>String</code> value
* @param keyValueProperty
* a <code>KeyValueProperty</code> value
* @exception InvalidXMLDataException
* if an error occurs
* @exception InvalidObjectSpecificationException
* if an error occurs
* @exception AccessorInvocationException
* if an error occurs during accessor invocation
*/
public static void setBooleanAsStringForKey(Object object, String textValue, SingleKeyValueProperty keyValueProperty)
throws InvalidXMLDataException, InvalidObjectSpecificationException, AccessorInvocationException {
if (textValue == null) {
throw new InvalidXMLDataException("Class " + keyValueProperty.getObjectClass().getName() + ": keyValueProperty "
+ keyValueProperty.getName() + " supplied value is null");
} else {
setBooleanValueForKey(object, StringEncoder.decodeAsBoolean(textValue), keyValueProperty);
}
}
/**
* Sets value <code>textValue</code> for keyValueProperty <code>propertyName</code> for object <code>object</code> asserting that
* corresponding keyValueProperty type is a <code>boolean</code>. Value is parsed from string <code>textValue</code>.
*
* @param object
* an <code>Object</code> value
* @param value
* a <code>char</code> value
* @param propertyName
* a <code>String</code> value
* @exception InvalidXMLDataException
* if an error occurs
* @exception InvalidObjectSpecificationException
* if an error occurs
* @exception AccessorInvocationException
* if an error occurs during accessor invocation
*/
public static void setBooleanValueForKey(Object object, boolean value, String propertyName) throws InvalidXMLDataException,
InvalidObjectSpecificationException, AccessorInvocationException {
setBooleanValueForKey(object, value, (SingleKeyValueProperty) getKeyValuePropertyFromName(object.getClass(), propertyName, true));
}
/**
* Sets value <code>textValue</code> for keyValueProperty <code>keyValueProperty</code> for object <code>object</code> asserting that
* corresponding keyValueProperty type is a <code>char</code>. Value is parsed from string <code>textValue</code>.
*
* @param object
* an <code>Object</code> value
* @param value
* a <code>char</code> value
* @param keyValueProperty
* a <code>KeyValueProperty</code> value
* @exception InvalidXMLDataException
* if an error occurs
* @exception InvalidObjectSpecificationException
* if an error occurs
*/
public static void setCharacterValueForKey(Object object, char value, SingleKeyValueProperty keyValueProperty)
throws InvalidXMLDataException, InvalidObjectSpecificationException, AccessorInvocationException {
try {
keyValueProperty.setCharValue(value, object);
} catch (AccessorInvocationException e) {
throw e;
} catch (Exception e) {
throw new InvalidObjectSpecificationException("Class " + keyValueProperty.getObjectClass().getName() + ": keyValueProperty "
+ keyValueProperty.getName() + " Exception raised: " + e.toString());
}
}
/**
* Sets value <code>textValue</code> for keyValueProperty <code>keyValueProperty</code> for object <code>object</code> asserting that
* corresponding keyValueProperty type is a <code>char</code>. Value is parsed from string <code>textValue</code>.
*
* @param object
* an <code>Object</code> value
* @param textValue
* a <code>String</code> value
* @param keyValueProperty
* a <code>KeyValueProperty</code> value
* @exception InvalidXMLDataException
* if an error occurs
* @exception InvalidObjectSpecificationException
* if an error occurs
*/
public static void setCharacterAsStringForKey(Object object, String textValue, SingleKeyValueProperty keyValueProperty)
throws InvalidXMLDataException, InvalidObjectSpecificationException, AccessorInvocationException {
if (textValue == null) {
throw new InvalidXMLDataException("Class " + keyValueProperty.getObjectClass().getName() + ": keyValueProperty "
+ keyValueProperty.getName() + " supplied value is null");
} else {
setCharacterValueForKey(object, StringEncoder.decodeAsCharacter(textValue), keyValueProperty);
}
}
/**
* Sets value <code>textValue</code> for keyValueProperty <code>propertyName</code> for object <code>object</code> asserting that
* corresponding keyValueProperty type is a <code>char</code>. Value is parsed from string <code>textValue</code>.
*
* @param object
* an <code>Object</code> value
* @param value
* a <code>char</code> value
* @param propertyName
* a <code>String</code> value
* @exception InvalidXMLDataException
* if an error occurs
* @exception InvalidObjectSpecificationException
* if an error occurs
* @exception AccessorInvocationException
* if an error occurs during accessor invocation
*/
public static void setCharacterValueForKey(Object object, char value, String propertyName) throws InvalidXMLDataException,
InvalidObjectSpecificationException, AccessorInvocationException {
setCharacterValueForKey(object, value, (SingleKeyValueProperty) getKeyValuePropertyFromName(object.getClass(), propertyName, true));
}
/**
* Sets value <code>textValue</code> for keyValueProperty <code>keyValueProperty</code> for object <code>object</code> asserting that
* corresponding keyValueProperty type is a <code>byte</code>. Value is parsed from string <code>textValue</code>.
*
* @param object
* an <code>Object</code> value
* @param value
* a <code>byte</code> value
* @param keyValueProperty
* a <code>KeyValueProperty</code> value
* @exception InvalidXMLDataException
* if an error occurs
* @exception InvalidObjectSpecificationException
* if an error occurs
*/
public static void setByteValueForKey(Object object, byte value, SingleKeyValueProperty keyValueProperty)
throws InvalidXMLDataException, InvalidObjectSpecificationException, AccessorInvocationException {
try {
keyValueProperty.setByteValue(value, object);
} catch (NumberFormatException e) {
throw new InvalidXMLDataException("Class " + keyValueProperty.getObjectClass().getName() + ": keyValueProperty "
+ keyValueProperty.getName() + " supplied value is not parsable as a byte.");
} catch (AccessorInvocationException e) {
throw e;
} catch (Exception e) {
throw new InvalidObjectSpecificationException("Class " + keyValueProperty.getObjectClass().getName() + ": keyValueProperty "
+ keyValueProperty.getName() + " Exception raised: " + e.toString());
}
}
/**
* Sets value <code>textValue</code> for keyValueProperty <code>keyValueProperty</code> for object <code>object</code> asserting that
* corresponding keyValueProperty type is a <code>byte</code>. Value is parsed from string <code>textValue</code>.
*
* @param object
* an <code>Object</code> value
* @param textValue
* a <code>String</code> value
* @param keyValueProperty
* a <code>KeyValueProperty</code> value
* @exception InvalidXMLDataException
* if an error occurs
* @exception InvalidObjectSpecificationException
* if an error occurs
*/
public static void setByteAsStringForKey(Object object, String textValue, SingleKeyValueProperty keyValueProperty)
throws InvalidXMLDataException, InvalidObjectSpecificationException, AccessorInvocationException {
if (textValue == null) {
throw new InvalidXMLDataException("Class " + keyValueProperty.getObjectClass().getName() + ": keyValueProperty "
+ keyValueProperty.getName() + " supplied value is null");
} else {
setByteValueForKey(object, StringEncoder.decodeAsByte(textValue), keyValueProperty);
}
}
/**
* Sets value <code>textValue</code> for keyValueProperty <code>propertyName</code> for object <code>object</code> asserting that
* corresponding keyValueProperty type is a <code>byte</code>. Value is parsed from string <code>textValue</code>.
*
* @param object
* an <code>Object</code> value
* @param value
* a <code>byte</code> value
* @param propertyName
* a <code>String</code> value
* @exception InvalidXMLDataException
* if an error occurs
* @exception InvalidObjectSpecificationException
* if an error occurs
* @exception AccessorInvocationException
* if an error occurs during accessor invocation
*/
public static void setByteValueForKey(Object object, byte value, String propertyName) throws InvalidXMLDataException,
InvalidObjectSpecificationException, AccessorInvocationException {
setByteValueForKey(object, value, (SingleKeyValueProperty) getKeyValuePropertyFromName(object.getClass(), propertyName, true));
}
/**
* Sets value <code>textValue</code> for keyValueProperty <code>keyValueProperty</code> for object <code>object</code> asserting that
* corresponding keyValueProperty type is a <code>short</code>. Value is parsed from string <code>textValue</code>.
*
* @param object
* an <code>Object</code> value
* @param value
* a <code>short</code> value
* @param keyValueProperty
* a <code>KeyValueProperty</code> value
* @exception InvalidXMLDataException
* if an error occurs
* @exception InvalidObjectSpecificationException
* if an error occurs
*/
public static void setShortValueForKey(Object object, short value, SingleKeyValueProperty keyValueProperty)
throws InvalidXMLDataException, InvalidObjectSpecificationException, AccessorInvocationException {
try {
keyValueProperty.setShortValue(value, object);
} catch (NumberFormatException e) {
throw new InvalidXMLDataException("Class " + keyValueProperty.getObjectClass().getName() + ": keyValueProperty "
+ keyValueProperty.getName() + " supplied value is not parsable as a short.");
} catch (AccessorInvocationException e) {
throw e;
} catch (Exception e) {
throw new InvalidObjectSpecificationException("Class " + keyValueProperty.getObjectClass().getName() + ": keyValueProperty "
+ keyValueProperty.getName() + " Exception raised: " + e.toString());
}
}
/**
* Sets value <code>textValue</code> for keyValueProperty <code>keyValueProperty</code> for object <code>object</code> asserting that
* corresponding keyValueProperty type is a <code>short</code>. Value is parsed from string <code>textValue</code>.
*
* @param object
* an <code>Object</code> value
* @param textValue
* a <code>String</code> value
* @param keyValueProperty
* a <code>KeyValueProperty</code> value
* @exception InvalidXMLDataException
* if an error occurs
* @exception InvalidObjectSpecificationException
* if an error occurs
*/
public static void setShortAsStringForKey(Object object, String textValue, SingleKeyValueProperty keyValueProperty)
throws InvalidXMLDataException, InvalidObjectSpecificationException, AccessorInvocationException {
if (textValue == null) {
throw new InvalidXMLDataException("Class " + keyValueProperty.getObjectClass().getName() + ": keyValueProperty "
+ keyValueProperty.getName() + " supplied value is null");
} else {
setShortValueForKey(object, StringEncoder.decodeAsShort(textValue), keyValueProperty);
}
}
/**
* Sets value <code>textValue</code> for keyValueProperty <code>propertyName</code> for object <code>object</code> asserting that
* corresponding keyValueProperty type is a <code>short</code>. Value is parsed from string <code>textValue</code>.
*
* @param object
* an <code>Object</code> value
* @param short a <code>short</code> value
* @param propertyName
* a <code>String</code> value
* @exception InvalidXMLDataException
* if an error occurs
* @exception InvalidObjectSpecificationException
* if an error occurs
* @exception AccessorInvocationException
* if an error occurs during accessor invocation
*/
public static void setShortValueForKey(Object object, short value, String propertyName) throws InvalidXMLDataException,
InvalidObjectSpecificationException, AccessorInvocationException {
setShortValueForKey(object, value, (SingleKeyValueProperty) getKeyValuePropertyFromName(object.getClass(), propertyName, true));
}
/**
* Sets value <code>textValue</code> for keyValueProperty <code>keyValueProperty</code> for object <code>object</code> asserting that
* corresponding keyValueProperty type is a <code>int</code>. Value is parsed from string <code>textValue</code>.
*
* @param object
* an <code>Object</code> value
* @param value
* a <code>int</code> value
* @param keyValueProperty
* a <code>KeyValueProperty</code> value
* @exception InvalidXMLDataException
* if an error occurs
* @exception InvalidObjectSpecificationException
* if an error occurs
*/
public static void setIntegerValueForKey(Object object, int value, SingleKeyValueProperty keyValueProperty)
throws InvalidXMLDataException, InvalidObjectSpecificationException, AccessorInvocationException {
try {
keyValueProperty.setIntValue(value, object);
} catch (NumberFormatException e) {
throw new InvalidXMLDataException("Class " + keyValueProperty.getObjectClass().getName() + ": keyValueProperty "
+ keyValueProperty.getName() + " supplied value is not parsable as an int.");
} catch (AccessorInvocationException e) {
throw e;
} catch (Exception e) {
throw new InvalidObjectSpecificationException("Class " + keyValueProperty.getObjectClass().getName() + ": keyValueProperty "
+ keyValueProperty.getName() + " Exception raised: " + e.toString());
}
}
/**
* Sets value <code>textValue</code> for keyValueProperty <code>keyValueProperty</code> for object <code>object</code> asserting that
* corresponding keyValueProperty type is a <code>int</code>. Value is parsed from string <code>textValue</code>.
*
* @param object
* an <code>Object</code> value
* @param textValue
* a <code>String</code> value
* @param keyValueProperty
* a <code>KeyValueProperty</code> value
* @exception InvalidXMLDataException
* if an error occurs
* @exception InvalidObjectSpecificationException
* if an error occurs
*/
public static void setIntegerAsStringForKey(Object object, String textValue, SingleKeyValueProperty keyValueProperty)
throws InvalidXMLDataException, InvalidObjectSpecificationException, AccessorInvocationException {
if (textValue == null) {
throw new InvalidXMLDataException("Class " + keyValueProperty.getObjectClass().getName() + ": keyValueProperty "
+ keyValueProperty.getName() + " supplied value is null");
} else {
setIntegerValueForKey(object, StringEncoder.decodeAsInteger(textValue), keyValueProperty);
}
}
/**
* Sets value <code>textValue</code> for keyValueProperty <code>propertyName</code> for object <code>object</code> asserting that
* corresponding keyValueProperty type is a <code>int</code>. Value is parsed from string <code>textValue</code>.
*
* @param object
* an <code>Object</code> value
* @param value
* a <code>int</code> value
* @param propertyName
* a <code>String</code> value
* @exception InvalidXMLDataException
* if an error occurs
* @exception InvalidObjectSpecificationException
* if an error occurs
* @exception AccessorInvocationException
* if an error occurs during accessor invocation
*/
public static void setIntegerValueForKey(Object object, int value, String propertyName) throws InvalidXMLDataException,
InvalidObjectSpecificationException, AccessorInvocationException {
setIntegerValueForKey(object, value, (SingleKeyValueProperty) getKeyValuePropertyFromName(object.getClass(), propertyName, true));
}
/**
* Sets value <code>textValue</code> for keyValueProperty <code>keyValueProperty</code> for object <code>object</code> asserting that
* corresponding keyValueProperty type is a <code>long</code>. Value is parsed from string <code>textValue</code>.
*
* @param object
* an <code>Object</code> value
* @param value
* a <code>long</code> value
* @param keyValueProperty
* a <code>KeyValueProperty</code> value
* @exception InvalidXMLDataException
* if an error occurs
* @exception InvalidObjectSpecificationException
* if an error occurs
*/
public static void setLongValueForKey(Object object, long value, SingleKeyValueProperty keyValueProperty)
throws InvalidXMLDataException, InvalidObjectSpecificationException, AccessorInvocationException {
try {
keyValueProperty.setLongValue(value, object);
} catch (NumberFormatException e) {
throw new InvalidXMLDataException("Class " + keyValueProperty.getObjectClass().getName() + ": keyValueProperty "
+ keyValueProperty.getName() + " supplied value is not parsable as a long.");
} catch (AccessorInvocationException e) {
throw e;
} catch (Exception e) {
throw new InvalidObjectSpecificationException("Class " + keyValueProperty.getObjectClass().getName() + ": keyValueProperty "
+ keyValueProperty.getName() + " Exception raised: " + e.toString());
}
}
/**
* Sets value <code>textValue</code> for keyValueProperty <code>keyValueProperty</code> for object <code>object</code> asserting that
* corresponding keyValueProperty type is a <code>long</code>. Value is parsed from string <code>textValue</code>.
*
* @param object
* an <code>Object</code> value
* @param textValue
* a <code>String</code> value
* @param keyValueProperty
* a <code>KeyValueProperty</code> value
* @exception InvalidXMLDataException
* if an error occurs
* @exception InvalidObjectSpecificationException
* if an error occurs
*/
public static void setLongAsStringForKey(Object object, String textValue, SingleKeyValueProperty keyValueProperty)
throws InvalidXMLDataException, InvalidObjectSpecificationException, AccessorInvocationException {
if (textValue == null) {
throw new InvalidXMLDataException("Class " + keyValueProperty.getObjectClass().getName() + ": keyValueProperty "
+ keyValueProperty.getName() + " supplied value is null");
} else {
setLongValueForKey(object, StringEncoder.decodeAsLong(textValue), keyValueProperty);
}
}
/**
* Sets value <code>textValue</code> for keyValueProperty <code>propertyName</code> for object <code>object</code> asserting that
* corresponding keyValueProperty type is a <code>long</code>. Value is parsed from string <code>textValue</code>.
*
* @param object
* an <code>Object</code> value
* @param value
* a <code>long</code> value
* @param propertyName
* a <code>String</code> value
* @exception InvalidXMLDataException
* if an error occurs
* @exception InvalidObjectSpecificationException
* if an error occurs
* @exception AccessorInvocationException
* if an error occurs during accessor invocation
*/
public static void setLongValueForKey(Object object, long value, String propertyName) throws InvalidXMLDataException,
InvalidObjectSpecificationException, AccessorInvocationException {
setLongValueForKey(object, value, (SingleKeyValueProperty) getKeyValuePropertyFromName(object.getClass(), propertyName, true));
}
/**
* Sets value <code>textValue</code> for keyValueProperty <code>keyValueProperty</code> for object <code>object</code> asserting that
* corresponding keyValueProperty type is a <code>float</code>. Value is parsed from string <code>textValue</code>.
*
* @param object
* an <code>Object</code> value
* @param value
* a <code>float</code> value
* @param keyValueProperty
* a <code>KeyValueProperty</code> value
* @exception InvalidXMLDataException
* if an error occurs
* @exception InvalidObjectSpecificationException
* if an error occurs
*/
public static void setFloatValueForKey(Object object, float value, SingleKeyValueProperty keyValueProperty)
throws InvalidXMLDataException, InvalidObjectSpecificationException, AccessorInvocationException {
try {
keyValueProperty.setFloatValue(value, object);
} catch (NumberFormatException e) {
throw new InvalidXMLDataException("Class " + keyValueProperty.getObjectClass().getName() + ": keyValueProperty "
+ keyValueProperty.getName() + " supplied value is not parsable as a float.");
} catch (AccessorInvocationException e) {
throw e;
} catch (Exception e) {
throw new InvalidObjectSpecificationException("Class " + keyValueProperty.getObjectClass().getName() + ": keyValueProperty "
+ keyValueProperty.getName() + " Exception raised: " + e.toString());
}
}
/**
* Sets value <code>textValue</code> for keyValueProperty <code>keyValueProperty</code> for object <code>object</code> asserting that
* corresponding keyValueProperty type is a <code>float</code>. Value is parsed from string <code>textValue</code>.
*
* @param object
* an <code>Object</code> value
* @param textValue
* a <code>String</code> value
* @param keyValueProperty
* a <code>KeyValueProperty</code> value
* @exception InvalidXMLDataException
* if an error occurs
* @exception InvalidObjectSpecificationException
* if an error occurs
*/
public static void setFloatAsStringForKey(Object object, String textValue, SingleKeyValueProperty keyValueProperty)
throws InvalidXMLDataException, InvalidObjectSpecificationException, AccessorInvocationException {
if (textValue == null) {
throw new InvalidXMLDataException("Class " + keyValueProperty.getObjectClass().getName() + ": keyValueProperty "
+ keyValueProperty.getName() + " supplied value is null");
} else {
setFloatValueForKey(object, StringEncoder.decodeAsFloat(textValue), keyValueProperty);
}
}
/**
* Sets value <code>textValue</code> for keyValueProperty <code>propertyName</code> for object <code>object</code> asserting that
* corresponding keyValueProperty type is a <code>float</code>. Value is parsed from string <code>textValue</code>.
*
* @param object
* an <code>Object</code> value
* @param value
* a <code>float</code> value
* @param propertyName
* a <code>String</code> value
* @exception InvalidXMLDataException
* if an error occurs
* @exception InvalidObjectSpecificationException
* if an error occurs
* @exception AccessorInvocationException
* if an error occurs during accessor invocation
*/
public static void setFloatValueForKey(Object object, float value, String propertyName) throws InvalidXMLDataException,
InvalidObjectSpecificationException, AccessorInvocationException {
setFloatValueForKey(object, value, (SingleKeyValueProperty) getKeyValuePropertyFromName(object.getClass(), propertyName, true));
}
/**
* Sets value <code>textValue</code> for keyValueProperty <code>keyValueProperty</code> for object <code>object</code> asserting that
* corresponding keyValueProperty type is a <code>double</code>. Value is parsed from string <code>textValue</code>.
*
* @param object
* an <code>Object</code> value
* @param value
* a <code>double</code> value
* @param keyValueProperty
* a <code>KeyValueProperty</code> value
* @exception InvalidXMLDataException
* if an error occurs
* @exception InvalidObjectSpecificationException
* if an error occurs
*/
public static void setDoubleValueForKey(Object object, double value, SingleKeyValueProperty keyValueProperty)
throws InvalidXMLDataException, InvalidObjectSpecificationException, AccessorInvocationException {
try {
keyValueProperty.setDoubleValue(value, object);
} catch (NumberFormatException e) {
throw new InvalidXMLDataException("Class " + keyValueProperty.getObjectClass().getName() + ": keyValueProperty "
+ keyValueProperty.getName() + " supplied value is not parsable as a double.");
} catch (AccessorInvocationException e) {
throw e;
} catch (Exception e) {
throw new InvalidObjectSpecificationException("Class " + keyValueProperty.getObjectClass().getName() + ": keyValueProperty "
+ keyValueProperty.getName() + " Exception raised: " + e.toString());
}
}
/**
* Sets value <code>textValue</code> for keyValueProperty <code>keyValueProperty</code> for object <code>object</code> asserting that
* corresponding keyValueProperty type is a <code>double</code>. Value is parsed from string <code>textValue</code>.
*
* @param object
* an <code>Object</code> value
* @param textValue
* a <code>String</code> value
* @param keyValueProperty
* a <code>KeyValueProperty</code> value
* @exception InvalidXMLDataException
* if an error occurs
* @exception InvalidObjectSpecificationException
* if an error occurs
*/
public static void setDoubleAsStringForKey(Object object, String textValue, SingleKeyValueProperty keyValueProperty)
throws InvalidXMLDataException, InvalidObjectSpecificationException, AccessorInvocationException {
if (textValue == null) {
throw new InvalidXMLDataException("Class " + keyValueProperty.getObjectClass().getName() + ": keyValueProperty "
+ keyValueProperty.getName() + " supplied value is null");
} else {
setDoubleValueForKey(object, StringEncoder.decodeAsDouble(textValue), keyValueProperty);
}
}
/**
* Sets value <code>textValue</code> for keyValueProperty <code>propertyName</code> for object <code>object</code> asserting that
* corresponding keyValueProperty type is a <code>double</code>. Value is parsed from string <code>textValue</code>.
*
* @param object
* an <code>Object</code> value
* @param value
* a <code>double</code> value
* @param propertyName
* a <code>String</code> value
* @exception InvalidXMLDataException
* if an error occurs
* @exception InvalidObjectSpecificationException
* if an error occurs
* @exception AccessorInvocationException
* if an error occurs during accessor invocation
*/
public static void setDoubleValueForKey(Object object, double value, String propertyName) throws InvalidXMLDataException,
InvalidObjectSpecificationException, AccessorInvocationException {
setDoubleValueForKey(object, value, (SingleKeyValueProperty) getKeyValuePropertyFromName(object.getClass(), propertyName, true));
}
/**
* Sets value <code>objectValue</code> for keyValueProperty <code>keyValueProperty</code> for object <code>object</code> asserting that
* corresponding keyValueProperty type is compatible with <code>objectValue</code>.
*
* @param object
* an <code>Object</code> value
* @param objectValue
* an <code>Object</code> value
* @param keyValueProperty
* a <code>KeyValueProperty</code> value
* @exception InvalidXMLDataException
* if an error occurs
* @exception InvalidObjectSpecificationException
* if an error occurs
*/
public static void setObjectForKey(Object object, Object objectValue, KeyValueProperty keyValueProperty)
throws InvalidXMLDataException, InvalidObjectSpecificationException, AccessorInvocationException {
// Debugging.debug ("setObjectForKey() called with
// '"+objectValue.toString()
// +"' for keyValueProperty '"+keyValueProperty.getName()
// +"' for object of class "+object.getClass().getName());
/*
* if (objectValue == null) { throw new InvalidXMLDataException ("Class
* "+keyValueProperty.getObjectClass().getName() +": keyValueProperty
* "+keyValueProperty.getName()+" supplied object value is null"); }
*
* else {
*/
try {
if (objectValue != null) {
if (!objectValue.getClass().equals(keyValueProperty.getType())) {
objectValue = castTo(objectValue, keyValueProperty.getType());
}
}
keyValueProperty.setObjectValue(objectValue, object);
} catch (AccessorInvocationException e) {
throw e;
} catch (Exception e) {
// e.printStackTrace();
// System.out.println("objectValue="+objectValue);
throw new InvalidObjectSpecificationException("Class " + keyValueProperty.getObjectClass().getName() + ": keyValueProperty "
+ keyValueProperty.getName() + " Exception raised: " + e.toString());
}
// }
}
private static Object castTo(Object object, Type desiredType) {
if (object == null) {
return null;
}
// System.out.println("Object type: "+object.getClass());
// System.out.println("desiredType: "+desiredType);
if (object.getClass().equals(desiredType)) {
return object;
}
if (object instanceof Number) {
if (KeyValueProperty.isByte(desiredType)) {
return ((Number) object).byteValue();
}
if (KeyValueProperty.isShort(desiredType)) {
return ((Number) object).shortValue();
}
if (KeyValueProperty.isInteger(desiredType)) {
return ((Number) object).intValue();
}
if (KeyValueProperty.isLong(desiredType)) {
return ((Number) object).longValue();
}
if (KeyValueProperty.isDouble(desiredType)) {
return ((Number) object).doubleValue();
}
if (KeyValueProperty.isFloat(desiredType)) {
return ((Number) object).floatValue();
}
}
return object;
}
/**
* Sets value <code>objectValue</code> for keyValueProperty <code>propertyName</code> for object <code>object</code> asserting that
* corresponding keyValueProperty type is compatible with <code>objectValue</code>.
*
* @param object
* an <code>Object</code> value
* @param objectValue
* an <code>Object</code> value
* @param propertyName
* a <code>String</code> value
* @exception InvalidXMLDataException
* if an error occurs
* @exception InvalidObjectSpecificationException
* if an error occurs
* @exception AccessorInvocationException
* if an error occurs during accessor invocation
*/
public static void setObjectForKey(Object object, Object objectValue, String propertyName) throws InvalidXMLDataException,
InvalidObjectSpecificationException, AccessorInvocationException {
setObjectForKey(object, objectValue, getKeyValuePropertyFromName(object.getClass(), propertyName, true));
}
/**
* Sets values contained in <code>Vector</code> <code>values</code> for keyValueProperty <code>keyValueProperty</code> for object
* <code>object</code> asserting that corresponding keyValueProperty is a vector-like property.
*
* @param object
* an <code>Object</code> value
* @param values
* a <code>Vector</code> value
* @param keyValueProperty
* a <code>KeyValueProperty</code> value
* @exception InvalidXMLDataException
* if an error occurs
* @exception InvalidObjectSpecificationException
* if an error occurs
*/
public static void setVectorForKey(Object object, List values, VectorKeyValueProperty keyValueProperty) throws InvalidXMLDataException,
InvalidObjectSpecificationException, AccessorInvocationException {
// Debugging.debug ("setValuesListForKey() called with 'Vector'"
// +values.toString()+" for keyValueProperty '"
// +keyValueProperty.getName()+"' for object of class "
// +object.getClass().getName());
List<?> vectorObject;
vectorObject = keyValueProperty.newInstance();
setObjectForKey(object, vectorObject, keyValueProperty);
for (Object obj : values) {
// System.out.println ("Adding "+obj+obj.getClass().getName()+" for
// property "+keyValueProperty.getName());
keyValueProperty.addObjectValue(obj, object);
}
}
/**
* Sets values contained in <code>Vector</code> <code>values</code> for keyValueProperty <code>keyValueProperty</code> for object
* <code>object</code> asserting that corresponding keyValueProperty is an array property.
*
* @param object
* an <code>Object</code> value
* @param values
* a <code>Vector</code> value
* @param keyValueProperty
* a <code>KeyValueProperty</code> value
* @exception InvalidXMLDataException
* if an error occurs
* @exception InvalidObjectSpecificationException
* if an error occurs
* @exception AccessorInvocationException
* if an error occurs during accessor invocation
*/
public static void setArrayForKey(Object object, List values, ArrayKeyValueProperty keyValueProperty) throws InvalidXMLDataException,
InvalidObjectSpecificationException, AccessorInvocationException {
// Debugging.debug ("setValuesListForKey() called with 'Vector'"
// +values.toString()+" for keyValueProperty '"
// +keyValueProperty.getName()+"' for object of class "
// +object.getClass().getName());
Object arrayObject;
arrayObject = keyValueProperty.newInstance(values.size());
setObjectForKey(object, arrayObject, keyValueProperty);
int index = 0;
for (Object obj : values) {
keyValueProperty.setObjectValueAtIndex(obj, index, object);
index++;
}
}
/**
* Sets values contained in <code>Hashtable</code> <code>values</code> for keyValueProperty <code>keyValueProperty</code> for object
* <code>object</code> asserting that corresponding keyValueProperty is a hashtable-like property.
*
* @param object
* an <code>Object</code> value
* @param values
* a <code>Hashtable</code> value
* @param keyValueProperty
* a <code>KeyValueProperty</code> value
* @exception InvalidXMLDataException
* if an error occurs
* @exception InvalidObjectSpecificationException
* if an error occurs
*/
public static void setHashtableForKey(Object object, Map values, HashtableKeyValueProperty keyValueProperty)
throws InvalidXMLDataException, InvalidObjectSpecificationException, AccessorInvocationException {
// Debugging.debug ("setValuesListForKey() called with 'Hashtable'"
// +values.toString()+" for keyValueProperty '"
// +keyValueProperty.getName()+"' for object of class "
// +object.getClass().getName());
Map hashtableObject;
hashtableObject = keyValueProperty.newInstance();
setObjectForKey(object, hashtableObject, keyValueProperty);
for (Entry e : (Set<Entry>) values.entrySet()) {
keyValueProperty.setObjectValueForKey(e.getValue(), e.getKey(), object);
}
}
/**
* Sets values contained in <code>Vector</code> <code>values</code> for keyValueProperty <code>propertyName</code> for object
* <code>object</code> asserting that corresponding keyValueProperty'type is a <code>Vector</code> class (or inherits from).
*
* @param object
* an <code>Object</code> value
* @param values
* a <code>Vector</code> value
* @param propertyName
* a <code>String</code> value
* @exception InvalidXMLDataException
* if an error occurs
* @exception InvalidObjectSpecificationException
* if an error occurs
* @exception AccessorInvocationException
* if an error occurs during accessor invocation
*/
public static void setVectorForKey(Object object, List values, String propertyName) throws InvalidXMLDataException,
InvalidObjectSpecificationException, AccessorInvocationException {
setVectorForKey(object, values, (VectorKeyValueProperty) getKeyValuePropertyFromName(object.getClass(), propertyName, true));
}
/**
* Sets values contained in <code>Hashtable</code> <code>values</code> for keyValueProperty <code>propertyName</code> for object
* <code>object</code> asserting that corresponding keyValueProperty'type is a <code>Hashtable</code> class (or inherits from).
*
* @param object
* an <code>Object</code> value
* @param values
* a <code>Hashtable</code> value
* @param propertyName
* a <code>String</code> value
* @exception InvalidXMLDataException
* if an error occurs
* @exception InvalidObjectSpecificationException
* if an error occurs
* @exception AccessorInvocationException
* if an error occurs during accessor invocation
*/
public static void setHashtableForKey(Object object, Map values, String propertyName) throws InvalidXMLDataException,
InvalidObjectSpecificationException, AccessorInvocationException {
setHashtableForKey(object, values, (HashtableKeyValueProperty) getKeyValuePropertyFromName(object.getClass(), propertyName, true));
}
}