package org.cloudgraph.web.etl.loader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import javax.xml.datatype.XMLGregorianCalendar;
import org.apache.log4j.Logger;
import commonj.sdo.DataObject;
import commonj.sdo.Property;
/**
* This utility is temporary (throw away) code used to merge XML/JAXB staging data
* into SDO objects. It leverages the SDO metadata API on the SDO side and Java
* reflection on the XML side. It makes unfortunate assumptions about the naming of
* methods in the XML being the same as SDO property names. SDO has the notion of a local-name,
* which is a name used for XML marshaling which may differ from its metadata or logical name.
* To leverage the SDO local-name facilities, both source and target objects would need
* to be SDO's.
*
* @author scinnamond
*/
public class LoaderUtils {
private static Logger log = Logger.getLogger(LoaderUtils.class);
public static void merge(DataObject target, Object source) {
for (Property property : target.getType().getDeclaredProperties()) {
if (property.isMany())
continue;
if (!property.getType().isDataType())
continue;
if (property.isReadOnly())
continue;
String getterName = "get"
+ property.getName().substring(0, 1).toUpperCase()
+ property.getName().substring(1);
log.debug("method: " + source.getClass().getSimpleName() + "." + getterName);
Method getter = findMethod(source, getterName);
if (getter != null) {
Object value = null;
try {
value = getter.invoke(source, new Object[] {});
} catch (IllegalArgumentException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
Object oldValue = target.get(property);
if (value != null) {
if (value.getClass().isEnum())
value = value.toString();
if (value instanceof XMLGregorianCalendar) {
value = ((XMLGregorianCalendar)value).toGregorianCalendar().getTime();
}
if (value instanceof String)
value = ((String)value).trim();
if (oldValue == null) {
log.info("merging "+target.getType().getName() + "." + property.getName()+" value: " + value);
target.set(property, value);
} else {
if (oldValue instanceof String)
oldValue = ((String)oldValue).trim();
if (value instanceof Number) {
if (((Number)value).doubleValue() != ((Number)oldValue).doubleValue()) {
log.info("merging "+target.getType().getName() + "." + property.getName()+" old value " + oldValue + " with value: " + value);
target.set(property, value);
}
}
else {
if (!value.equals(oldValue)) {
log.info("merging "+target.getType().getName() + "." + property.getName()+" old value " + oldValue + " with value: " + value);
target.set(property, value);
}
}
}
} else {
if (oldValue != null)
target.unset(property); // user nulled it out
}
}
else
log.debug("not found method: " + source.getClass().getSimpleName() + "." + getterName);
}
}
public static void copy(DataObject target, Object source) {
for (Property property : target.getType().getDeclaredProperties()) {
if (property.isMany())
continue;
if (!property.getType().isDataType())
continue;
if (property.isReadOnly())
continue;
String getterName = "get"
+ property.getName().substring(0, 1).toUpperCase()
+ property.getName().substring(1);
log.debug("method: " + source.getClass().getSimpleName() + "." + getterName);
Method getter = findMethod(source, getterName);
if (getter != null) {
Object value = null;
try {
value = getter.invoke(source, new Object[] {});
} catch (IllegalArgumentException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
if (value != null) {
if (value.getClass().isEnum())
value = value.toString();
if (value instanceof XMLGregorianCalendar) {
value = ((XMLGregorianCalendar)value).toGregorianCalendar().getTime();
}
if (value instanceof String)
value = ((String)value).trim();
log.debug("copy "+target.getType().getName() + "." + property.getName()+" value: " + value);
target.set(property, value);
}
}
else
log.debug("not found method: " + source.getClass().getSimpleName() + "." + getterName);
}
}
public static Method findMethod(Object source, String name) {
for (Method method : source.getClass().getMethods()) {
if (method.getName().equals(name))
return method;
}
return null;
}
public static String formatName(String literal) {
String result = literal.trim();
result = literal.replace("&", "*");
result = result.replace('&', '*');
result = result.replace('\t', '*');
result = normalizeSpace(result);
return result;
}
/**
* Strips leading and trailing white space and replacing sequences of
* white space characters with a single space
* @param literal
* @return the normalized literal
*/
public static String normalizeSpace(String literal) {
String result = literal.trim();
StringBuilder builder = new StringBuilder(result.length());
char[] chars = result.toCharArray();
for (int i = 0; i < chars.length; i++) {
if (Character.isWhitespace(chars[i])) {
if (i > 0 && Character.isWhitespace(chars[i-1]))
continue;
else
builder.append(' ');
}
else
builder.append(chars[i]);
}
return builder.toString();
}
}