You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pivot.apache.org by gb...@apache.org on 2009/09/24 22:59:01 UTC
svn commit: r818623 - in /incubator/pivot/trunk:
demos/src/org/apache/pivot/demos/scripting/scripting_demo.wtkx
wtk/src/org/apache/pivot/wtkx/WTKXSerializer.java
Author: gbrown
Date: Thu Sep 24 20:59:00 2009
New Revision: 818623
URL: http://svn.apache.org/viewvc?rev=818623&view=rev
Log:
Resolve issue PIVOT-274.
Modified:
incubator/pivot/trunk/demos/src/org/apache/pivot/demos/scripting/scripting_demo.wtkx
incubator/pivot/trunk/wtk/src/org/apache/pivot/wtkx/WTKXSerializer.java
Modified: incubator/pivot/trunk/demos/src/org/apache/pivot/demos/scripting/scripting_demo.wtkx
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/demos/src/org/apache/pivot/demos/scripting/scripting_demo.wtkx?rev=818623&r1=818622&r2=818623&view=diff
==============================================================================
Binary files - no diff available.
Modified: incubator/pivot/trunk/wtk/src/org/apache/pivot/wtkx/WTKXSerializer.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/org/apache/pivot/wtkx/WTKXSerializer.java?rev=818623&r1=818622&r2=818623&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/org/apache/pivot/wtkx/WTKXSerializer.java (original)
+++ incubator/pivot/trunk/wtk/src/org/apache/pivot/wtkx/WTKXSerializer.java Thu Sep 24 20:59:00 2009
@@ -252,6 +252,9 @@
xmlInputFactory = XMLInputFactory.newInstance();
xmlInputFactory.setProperty("javax.xml.stream.isCoalescing", true);
+
+ scriptEngineManager = new javax.script.ScriptEngineManager();
+ scriptEngineManager.setBindings(new NamedObjectBindings());
}
public Resources getResources() {
@@ -677,12 +680,6 @@
}
case SCRIPT: {
- // Load the script engine manager
- if (scriptEngineManager == null) {
- scriptEngineManager = new javax.script.ScriptEngineManager();
- scriptEngineManager.setBindings(new NamedObjectBindings());
- }
-
// Process attributes looking for src and language
String src = null;
for (Attribute attribute : element.attributes) {
@@ -758,14 +755,6 @@
// Create an invocation handler for this listener
Class<?> listenerListClass = element.parent.value.getClass();
- Method addMethod;
- try {
- addMethod = listenerListClass.getMethod("add",
- new Class<?>[] {Object.class});
- } catch (NoSuchMethodException exception) {
- throw new RuntimeException(exception);
- }
-
InvocationHandler handler = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args)
@@ -786,13 +775,13 @@
}
// If the function didn't return a value, return the default
- Class<?> returnType = method.getReturnType();
- if (returnType == Vote.class
- && result == null) {
- result = Vote.APPROVE;
- } else if (returnType == Boolean.TYPE
- && result == null) {
- result = false;
+ if (result == null) {
+ Class<?> returnType = method.getReturnType();
+ if (returnType == Vote.class) {
+ result = Vote.APPROVE;
+ } else if (returnType == Boolean.TYPE) {
+ result = false;
+ }
}
return result;
@@ -807,6 +796,14 @@
Proxy.newProxyInstance(ThreadUtilities.getClassLoader(),
new Class[]{listenerClass}, handler);
+ Method addMethod;
+ try {
+ addMethod = listenerListClass.getMethod("add",
+ new Class<?>[] {Object.class});
+ } catch (NoSuchMethodException exception) {
+ throw new RuntimeException(exception);
+ }
+
try {
addMethod.invoke(element.parent.value, new Object[] {listener});
} catch (IllegalAccessException exception) {
@@ -1208,7 +1205,7 @@
String propertyName =
attribute.localName.substring(attribute.localName.lastIndexOf(".") + 1);
propertyName = Character.toUpperCase(propertyName.charAt(0)) +
- propertyName.substring(1);
+ propertyName.substring(1);
String propertyClassName = attribute.namespaceURI + "."
+ attribute.localName.substring(0, attribute.localName.length()
@@ -1221,35 +1218,117 @@
throw new SerializationException(exception);
}
- Method setterMethod = null;
- if (value != null) {
- setterMethod = getStaticSetterMethod(propertyClass, propertyName,
- objectType, value.getClass());
- }
+ if (propertyClass.isInterface()) {
+ // The attribute represents an event listener
+ String listenerClassName = propertyClassName.substring(propertyClassName.lastIndexOf('.') + 1);
+ String getListenerListMethodName = "get" + Character.toUpperCase(listenerClassName.charAt(0))
+ + listenerClassName.substring(1) + "s";
- if (setterMethod == null) {
- Method getterMethod = getStaticGetterMethod(propertyClass, propertyName, objectType);
+ // Get the listener list
+ Method getListenerListMethod;
+ try {
+ getListenerListMethod = objectType.getMethod(getListenerListMethodName, new Class<?>[]{});
+ } catch (NoSuchMethodException exception) {
+ throw new SerializationException(exception);
+ }
+
+ Object listenerList;
+ try {
+ listenerList = getListenerListMethod.invoke(object, new Object[]{});
+ } catch (InvocationTargetException exception) {
+ throw new SerializationException(exception);
+ } catch (IllegalAccessException exception) {
+ throw new SerializationException(exception);
+ }
- if (getterMethod != null) {
- Class<?> propertyType = getterMethod.getReturnType();
+ // Don't pollute the engine namespace with the listener functions
+ final ScriptEngine scriptEngine = scriptEngineManager.getEngineByName(language);
+ scriptEngine.setBindings(new SimpleBindings(), ScriptContext.ENGINE_SCOPE);
+
+ // TODO It isn't very efficient to construct the event name this way; try to clean
+ // up this method a bit
+ final String eventName =
+ Character.toLowerCase(propertyName.charAt(0)) + propertyName.substring(1);
+ final String script = attribute.value;
+
+ // Create an invocation handler for this listener
+ InvocationHandler handler = new InvocationHandler() {
+ @Override
+ public Object invoke(Object proxy, Method method, Object[] args)
+ throws Throwable {
+ Object result = null;
+
+ String methodName = method.getName();
+ if (methodName.equals(eventName)) {
+ scriptEngine.eval(script);
+ }
+
+ // If the function didn't return a value, return the default
+ if (result == null) {
+ Class<?> returnType = method.getReturnType();
+ if (returnType == Vote.class) {
+ result = Vote.APPROVE;
+ } else if (returnType == Boolean.TYPE) {
+ result = false;
+ }
+ }
+
+ return result;
+ }
+ };
+
+ Object listener = Proxy.newProxyInstance(ThreadUtilities.getClassLoader(),
+ new Class[]{propertyClass}, handler);
+
+ // Add the listener
+ Class<?> listenerListClass = listenerList.getClass();
+ Method addMethod;
+ try {
+ addMethod = listenerListClass.getMethod("add",
+ new Class<?>[] {Object.class});
+ } catch (NoSuchMethodException exception) {
+ throw new RuntimeException(exception);
+ }
+
+ try {
+ addMethod.invoke(listenerList, new Object[] {listener});
+ } catch (IllegalAccessException exception) {
+ throw new SerializationException(exception);
+ } catch (InvocationTargetException exception) {
+ throw new SerializationException(exception);
+ }
+ } else {
+ // The attribute represents a static setter
+ Method setterMethod = null;
+ if (value != null) {
setterMethod = getStaticSetterMethod(propertyClass, propertyName,
- objectType, propertyType);
+ objectType, value.getClass());
+ }
+
+ if (setterMethod == null) {
+ Method getterMethod = getStaticGetterMethod(propertyClass, propertyName, objectType);
- if (value instanceof String) {
- value = BeanDictionary.coerce((String)value, propertyType);
+ if (getterMethod != null) {
+ Class<?> propertyType = getterMethod.getReturnType();
+ setterMethod = getStaticSetterMethod(propertyClass, propertyName,
+ objectType, propertyType);
+
+ if (value instanceof String) {
+ value = BeanDictionary.coerce((String)value, propertyType);
+ }
}
}
- }
- if (setterMethod == null) {
- throw new SerializationException(attribute.localName + " is not valid static property.");
- }
+ if (setterMethod == null) {
+ throw new SerializationException(attribute.localName + " is not valid static property.");
+ }
- // Invoke the setter
- try {
- setterMethod.invoke(null, new Object[] {object, value});
- } catch (Exception exception) {
- throw new SerializationException(exception);
+ // Invoke the setter
+ try {
+ setterMethod.invoke(null, new Object[] {object, value});
+ } catch (Exception exception) {
+ throw new SerializationException(exception);
+ }
}
}