// Apply instance attributes
Dictionary<String, Object> dictionary;
if (element.value instanceof Dictionary<?, ?>) {
dictionary = (Dictionary<String, Object>)element.value;
} else {
dictionary = new BeanAdapter(element.value);
}
for (Attribute attribute : instancePropertyAttributes) {
dictionary.put(attribute.localName, resolve(attribute.value));
}
// If the element's parent is a sequence or a listener list, add
// the element value to it
if (element.parent != null) {
if (element.parent.value instanceof Sequence<?>) {
Sequence<Object> sequence = (Sequence<Object>)element.parent.value;
sequence.add(element.value);
} else {
if (element.parent.value instanceof ListenerList<?>) {
ListenerList<Object> listenerList = (ListenerList<Object>)element.parent.value;
listenerList.add(element.value);
}
}
}
// Apply static attributes
if (element.value instanceof Dictionary<?, ?>) {
if (staticPropertyAttributes.getLength() > 0) {
throw new SerializationException("Static setters are only supported"
+ " for typed objects.");
}
} else {
for (Attribute attribute : staticPropertyAttributes) {
// Split the local name
String[] localNameComponents = attribute.localName.split("\\.");
if (localNameComponents.length != 2) {
throw new SerializationException("\"" + attribute.localName
+ "\" is not a valid attribute name.");
}
// Determine the type of the attribute
String propertyClassName = attribute.namespaceURI + "." + localNameComponents[0];
Class<?> propertyClass = null;
try {
propertyClass = Class.forName(propertyClassName);
} catch (ClassNotFoundException exception) {
throw new SerializationException(exception);
}
if (propertyClass.isInterface()) {
// The attribute represents an event listener
String listenerClassName = localNameComponents[0];
String getListenerListMethodName = "get" + Character.toUpperCase(listenerClassName.charAt(0))
+ listenerClassName.substring(1) + "s";
// Get the listener list
Method getListenerListMethod;
try {
Class<?> type = element.value.getClass();
getListenerListMethod = type.getMethod(getListenerListMethodName);
} catch (NoSuchMethodException exception) {
throw new SerializationException(exception);
}
Object listenerList;
try {
listenerList = getListenerListMethod.invoke(element.value);
} catch (InvocationTargetException exception) {
throw new SerializationException(exception);
} catch (IllegalAccessException exception) {
throw new SerializationException(exception);
}
// Create an invocation handler for this listener
ScriptEngine scriptEngine = scriptEngineManager.getEngineByName(language);
AttributeInvocationHandler handler =
new AttributeInvocationHandler(scriptEngine,
localNameComponents[1],
attribute.value);
Object listener = Proxy.newProxyInstance(ThreadUtilities.getClassLoader(),
new Class<?>[]{propertyClass}, handler);
// Add the listener
Class<?> listenerListClass = listenerList.getClass();
Method addMethod;
try {
addMethod = listenerListClass.getMethod("add", Object.class);
} catch (NoSuchMethodException exception) {
throw new RuntimeException(exception);
}
try {
addMethod.invoke(listenerList, listener);
} catch (IllegalAccessException exception) {
throw new SerializationException(exception);
} catch (InvocationTargetException exception) {
throw new SerializationException(exception);
}
} else {
// The attribute represents a static setter
setStaticProperty(element.value, propertyClass, localNameComponents[1],
resolve(attribute.value));
}
}
}
// If the parent element is a writable property, set this as its
// value; it will be applied later in the parent's closing tag
if (element.parent != null
&& element.parent.type == Element.Type.WRITABLE_PROPERTY) {
element.parent.value = element.value;
}
break;
}
case READ_ONLY_PROPERTY: {
if (element.value instanceof Dictionary<?, ?>) {
// Process attributes looking for instance property setters
for (Attribute attribute : element.attributes) {
if (Character.isUpperCase(attribute.localName.charAt(0))) {
throw new SerializationException("Static setters are not supported"
+ " for read-only properties.");
}
Dictionary<String, Object> dictionary =
(Dictionary<String, Object>)element.value;
dictionary.put(attribute.localName, resolve(attribute.value));
}
}
break;
}
case WRITABLE_PROPERTY: {
Dictionary<String, Object> dictionary;
if (element.parent.value instanceof Dictionary) {
dictionary = (Dictionary<String, Object>)element.parent.value;
} else {
dictionary = new BeanAdapter(element.parent.value);
}
if (Character.isUpperCase(element.localName.charAt(0))) {
if (element.parent == null
|| element.parent.value == null) {