You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pivot.apache.org by tv...@apache.org on 2009/05/11 22:34:16 UTC
svn commit: r773679 - in /incubator/pivot/trunk/wtk/src/pivot/wtkx:
BindProcessor.java Bindable.java WTKXSerializer.java
Author: tvolkert
Date: Mon May 11 20:34:16 2009
New Revision: 773679
URL: http://svn.apache.org/viewvc?rev=773679&view=rev
Log:
Added getNamedObjects():Dictionary<String,Object> method to WTKXSerializer, and made getObjectByName() call into it. Changed Bindable#bind overload to use this new concept and take a namedObjectsDictionaries parameter instead of a wtkxSerializers parameter; added compile():boolean to @Load annotation. This is all in preparation for working compile-time WTKX loading
Modified:
incubator/pivot/trunk/wtk/src/pivot/wtkx/BindProcessor.java
incubator/pivot/trunk/wtk/src/pivot/wtkx/Bindable.java
incubator/pivot/trunk/wtk/src/pivot/wtkx/WTKXSerializer.java
Modified: incubator/pivot/trunk/wtk/src/pivot/wtkx/BindProcessor.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/pivot/wtkx/BindProcessor.java?rev=773679&r1=773678&r2=773679&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/pivot/wtkx/BindProcessor.java (original)
+++ incubator/pivot/trunk/wtk/src/pivot/wtkx/BindProcessor.java Mon May 11 20:34:16 2009
@@ -259,17 +259,19 @@
// creating the source code buffer
StringBuilder sourceCode = new StringBuilder("class _A {");
sourceCode.append("@Override ");
- sourceCode.append("protected void bind(pivot.collections.Map<String,pivot.wtkx.WTKXSerializer> namedSerializers) {");
- sourceCode.append("super.bind(namedSerializers);");
+ sourceCode.append("protected void bind(pivot.collections.Dictionary<String,");
+ sourceCode.append("pivot.collections.Dictionary<String, Object>> namedObjectsDictionaries) {");
+ sourceCode.append("super.bind(namedObjectsDictionaries);");
- // Local variable declarations
sourceCode.append("pivot.wtkx.WTKXSerializer wtkxSerializer;");
sourceCode.append("Object object;");
- sourceCode.append("java.net.URL location;");
- sourceCode.append("java.util.Locale locale;");
- sourceCode.append("pivot.util.Resources resources;");
if (loadGroups != null) {
+ // Process WTKX loads in this class
+ sourceCode.append("java.net.URL location;");
+ sourceCode.append("java.util.Locale locale;");
+ sourceCode.append("pivot.util.Resources resources;");
+
for (String loadFieldName : loadGroups) {
AnnotationDossier.LoadGroup loadGroup = loadGroups.get(loadFieldName);
JCVariableDecl loadField = loadGroup.loadField;
@@ -278,6 +280,7 @@
String resourceName = getAnnotationProperty(loadAnnotation, "name");
String baseName = getAnnotationProperty(loadAnnotation, "resources");
String language = getAnnotationProperty(loadAnnotation, "locale");
+ //Boolean compile = getAnnotationProperty(loadAnnotation, "compile");
boolean defaultResources = (baseName == null);
if (DEBUG) {
@@ -302,7 +305,8 @@
sourceCode.append(String.format("locale = new java.util.Locale(\"%s\");", language));
}
sourceCode.append("try {");
- sourceCode.append(String.format("resources = new pivot.util.Resources(%s, locale, \"UTF8\");",
+ sourceCode.append(String.format
+ ("resources = new pivot.util.Resources(%s, locale, \"UTF8\");",
defaultResources ? (baseName + ".class.getName()") : ("\"" + baseName + "\"")));
sourceCode.append("} catch(java.io.IOException ex) {");
sourceCode.append("throw new pivot.wtkx.BindException(ex);");
@@ -330,8 +334,8 @@
// Public and protected fields get kept for subclasses
if ((loadField.mods.flags & (Flags.PUBLIC | Flags.PROTECTED)) != 0) {
- sourceCode.append(String.format("namedSerializers.put(\"%s\", wtkxSerializer);",
- loadFieldName));
+ sourceCode.append(String.format
+ ("namedObjectsDictionaries.put(\"%s\", wtkxSerializer.getNamedObjects());", loadFieldName));
}
// Bind the resource lookups to their corresponding fields
@@ -353,19 +357,25 @@
bindName, classDeclaration.name.toString(), bindFieldName));
}
- sourceCode.append(String.format("object = wtkxSerializer.getObjectByName(\"%s\");",
- bindName));
- sourceCode.append("if (object == null) {");
- sourceCode.append(String.format("throw new pivot.wtkx.BindException(\"Element not found: %s.\");", bindName));
- sourceCode.append("}");
- sourceCode.append(String.format("%s = (%s)object;", bindFieldName,
- bindField.vartype.toString()));
+ sourceCode.append(String.format
+ ("object = wtkxSerializer.getObjectByName(\"%s\");", bindName));
+ sourceCode.append
+ ("if (object == null) {");
+ sourceCode.append(String.format
+ ("throw new pivot.wtkx.BindException(\"Element not found: %s.\");", bindName));
+ sourceCode.append
+ ("}");
+ sourceCode.append(String.format
+ ("%s = (%s)object;", bindFieldName, bindField.vartype.toString()));
}
}
}
}
if (strandedBindFields != null) {
+ // Process binds to superclass-loaded fields
+ sourceCode.append("pivot.collections.Dictionary<String, Object> namedObjects;");
+
for (JCVariableDecl bindField : strandedBindFields) {
String bindFieldName = bindField.name.toString();
JCAnnotation bindAnnotation = getBindAnnotation(bindField);
@@ -377,20 +387,26 @@
bindName = bindFieldName;
}
- sourceCode.append(String.format("wtkxSerializer = namedSerializers.get(\"%s\");",
- loadFieldName));
-
- sourceCode.append("if (wtkxSerializer == null) {");
- sourceCode.append(String.format("throw new pivot.wtkx.BindException(\"Property not found: %s.\");", loadFieldName));
- sourceCode.append("}");
+ sourceCode.append(String.format
+ ("namedObjects = namedObjectsDictionaries.get(\"%s\");", loadFieldName));
- sourceCode.append(String.format("object = wtkxSerializer.getObjectByName(\"%s\");",
- bindName));
- sourceCode.append("if (object == null) {");
- sourceCode.append(String.format("throw new pivot.wtkx.BindException(\"Element not found: %s.\");", bindName));
- sourceCode.append("}");
- sourceCode.append(String.format("%s = (%s)object;", bindFieldName,
- bindField.vartype.toString()));
+ sourceCode.append
+ ("if (namedObjects == null) {");
+ sourceCode.append(String.format
+ ("throw new pivot.wtkx.BindException(\"Property not found: %s.\");", loadFieldName));
+ sourceCode.append
+ ("}");
+
+ sourceCode.append(String.format
+ ("object = namedObjects.get(\"%s\");", bindName));
+ sourceCode.append
+ ("if (object == null) {");
+ sourceCode.append(String.format
+ ("throw new pivot.wtkx.BindException(\"Element not found: %s.\");", bindName));
+ sourceCode.append
+ ("}");
+ sourceCode.append(String.format
+ ("%s = (%s)object;", bindFieldName, bindField.vartype.toString()));
}
}
@@ -563,8 +579,9 @@
* The value of the property, or <tt>null</tt> if it is not explicitly
* set in the annotation
*/
- private static String getAnnotationProperty(JCAnnotation annotation, String propertyName) {
- String result = null;
+ @SuppressWarnings("unchecked")
+ private static <T> T getAnnotationProperty(JCAnnotation annotation, String propertyName) {
+ Object result = null;
for (JCExpression arg : annotation.args) {
JCAssign assign = (JCAssign)arg;
@@ -572,11 +589,11 @@
if (key.name.contentEquals(propertyName)) {
JCLiteral value = (JCLiteral)assign.rhs;
- result = (String)value.value;
+ result = value.getValue();
break;
}
}
- return result;
+ return (T)result;
}
}
Modified: incubator/pivot/trunk/wtk/src/pivot/wtkx/Bindable.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/pivot/wtkx/Bindable.java?rev=773679&r1=773678&r2=773679&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/pivot/wtkx/Bindable.java (original)
+++ incubator/pivot/trunk/wtk/src/pivot/wtkx/Bindable.java Mon May 11 20:34:16 2009
@@ -29,8 +29,8 @@
import java.util.MissingResourceException;
import pivot.collections.ArrayList;
+import pivot.collections.Dictionary;
import pivot.collections.HashMap;
-import pivot.collections.Map;
import pivot.serialization.SerializationException;
import pivot.util.Resources;
@@ -67,19 +67,36 @@
public String name();
/**
- * The base name of the resources to associate with the WTKX load
- * (optional). The base name should be of the form defined by the
- * {@link Resources} class. If unspecified, the WTKX load will be
- * assumed to not use resource strings.
+ * The base name of the resources to associate with the WTKX load.
+ * The base name should be of the form defined by the {@link Resources}
+ * class. If unspecified, the WTKX load will be assumed to not use
+ * resource strings.
*/
public String resources() default "\0";
/**
- * The locale with which to load the WTKX (optional). This should be a
- * lowercase two-letter ISO-639 code. If unspecified, the user's
- * default locale will be used.
+ * The locale with which to load the WTKX. This should be a lowercase
+ * two-letter ISO-639 code. If unspecified, the user's default locale
+ * will be used.
*/
public String locale() default "\0";
+
+ /**
+ * Indicates whether the loaded WTKX should be compiled into the class
+ * or if it should be loaded at runtime via the <tt>WTKXSerializer</tt>
+ * class. If unspecified, the WTKX loading will be done at runtime.
+ * <p>
+ * <b>Note</b>: This option only has meaning when the annotations are
+ * processed during compilation using {@link BindProcessor}. Callers
+ * who choose to skip the annotation processing will always be using a
+ * runtime implementation of WTKX loading, and in such cases, the
+ * <tt>compile</tt> flag will be ignored.
+ * <p>
+ * Also note that if the loaded WTKX is compiled into the class, the
+ * WTKX resource may not be needed at runtime; in such cases, the
+ * caller may wish to exclude it from their JAR file.
+ */
+ public boolean compile() default false;
}
/**
@@ -103,8 +120,8 @@
public String property();
/**
- * The name of the WTKX variable that references the element to bind
- * (optional). It should be a valid <tt>wtkx:id</tt> from the loaded
+ * The name of the WTKX variable that references the element to bind.
+ * It should be a valid <tt>wtkx:id</tt> from the loaded
* WTKX resource. If unspecified, the name of the annotated field will
* be used.
*
@@ -153,7 +170,7 @@
for (int i = 0, n = typeHierarchy.getLength(); i < n; i++) {
type = typeHierarchy.get(i);
try {
- bindOverload = type.getDeclaredMethod("bind", new Class<?>[] {Map.class});
+ bindOverload = type.getDeclaredMethod("bind", new Class<?>[] {Dictionary.class});
break;
} catch(NoSuchMethodException exception) {
// No-op
@@ -306,8 +323,9 @@
}
} else {
// Invoke the bind overload
- HashMap<String, WTKXSerializer> namedSerializers = new HashMap<String, WTKXSerializer>();
- bind(namedSerializers);
+ HashMap<String, Dictionary<String, Object>> namedObjectsDictionaries =
+ new HashMap<String, Dictionary<String, Object>>();
+ bind(namedObjectsDictionaries);
}
}
@@ -316,7 +334,7 @@
* override. It exists to support {@link BindProcessor}. Dealing directly
* with this method in any way may yield unpredictable behavior.
*/
- protected void bind(Map<String, WTKXSerializer> namedSerializers) {
+ protected void bind(Dictionary<String, Dictionary<String, Object>> namedObjectsDictionaries) {
// No-op
}
}
Modified: incubator/pivot/trunk/wtk/src/pivot/wtkx/WTKXSerializer.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/pivot/wtkx/WTKXSerializer.java?rev=773679&r1=773678&r2=773679&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/pivot/wtkx/WTKXSerializer.java (original)
+++ incubator/pivot/trunk/wtk/src/pivot/wtkx/WTKXSerializer.java Mon May 11 20:34:16 2009
@@ -92,15 +92,120 @@
}
}
+ /**
+ * Dictionary used for named object lookup.
+ *
+ * @author tvolkert
+ */
+ private class NamedObjectsDictionary implements Dictionary<String, Object> {
+ /**
+ * Retrieves a named object.
+ *
+ * @param name
+ * The name of the object, relative to this loader. The values's name
+ * is the concatentation of its parent namespaces and its ID, separated
+ * by periods (e.g. "foo.bar.baz").
+ *
+ * @return
+ * The named object, or <tt>null</tt> if an object with the given name
+ * does not exist.
+ *
+ * @author gbrown
+ */
+ public Object get(String key) {
+ if (key == null) {
+ throw new IllegalArgumentException("key is null.");
+ }
+
+ Object object = null;
+ WTKXSerializer serializer = WTKXSerializer.this;
+ String[] namespacePath = key.split("\\.");
+
+ int i = 0;
+ int n = namespacePath.length - 1;
+ while (i < n && serializer != null) {
+ String namespace = namespacePath[i++];
+ serializer = serializer.includeSerializers.get(namespace);
+ }
+
+ if (serializer != null) {
+ object = serializer.getObjectByID(namespacePath[i]);
+ }
+
+ return object;
+ }
+
+ public Object put(String key, Object value) {
+ throw new UnsupportedOperationException();
+ }
+
+ public Object remove(String key) {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean containsKey(String key) {
+ if (key == null) {
+ throw new IllegalArgumentException("key is null.");
+ }
+
+ boolean result = false;
+ WTKXSerializer serializer = WTKXSerializer.this;
+ String[] namespacePath = key.split("\\.");
+
+ int i = 0;
+ int n = namespacePath.length - 1;
+ while (i < n && serializer != null) {
+ String namespace = namespacePath[i++];
+ serializer = serializer.includeSerializers.get(namespace);
+ }
+
+ if (serializer != null) {
+ if (serializer.namedObjects.containsKey(key)) {
+ result = true;
+ } else if (serializer.scriptEngineBindings != null) {
+ result = serializer.scriptEngineBindings.containsKey(key);
+ }
+ }
+
+ return result;
+ }
+
+ @SuppressWarnings("unchecked")
+ public boolean isEmpty() {
+ boolean empty = namedObjects.isEmpty();
+
+ if (empty && scriptEngineBindings != null) {
+ // Check for script bindings
+ empty = scriptEngineBindings.isEmpty();
+ }
+
+ if (empty) {
+ // Check include serializers
+ for (String namespace : includeSerializers) {
+ WTKXSerializer includeSerializer = includeSerializers.get(namespace);
+ if (!includeSerializer.getNamedObjects().isEmpty()) {
+ empty = false;
+ break;
+ }
+ }
+ }
+
+ return empty;
+ }
+ }
+
private URL location = null;
private Resources resources = null;
private HashMap<String, Object> namedObjects = new HashMap<String, Object>();
private HashMap<String, WTKXSerializer> includeSerializers = new HashMap<String, WTKXSerializer>();
+ private NamedObjectsDictionary namedObjectsDictionary = new NamedObjectsDictionary();
+
private XMLInputFactory xmlInputFactory;
private Object scriptEngineManager;
private Class<?> scriptEngineManagerClass;
+ private java.util.Map<String, Object> scriptEngineBindings;
public static final char URL_PREFIX = '@';
public static final char RESOURCE_KEY_PREFIX = '%';
@@ -123,6 +228,7 @@
this(null);
}
+ @SuppressWarnings("unchecked")
public WTKXSerializer(Resources resources) {
this.resources = resources;
@@ -130,11 +236,16 @@
xmlInputFactory.setProperty("javax.xml.stream.isCoalescing", true);
try {
- scriptEngineManagerClass = Class.forName("javax.script.ScriptEngineManager");
- scriptEngineManager = scriptEngineManagerClass.newInstance();
+ scriptEngineManagerClass = Class.forName("javax.script.ScriptEngineManager");
+ scriptEngineManager = scriptEngineManagerClass.newInstance();
+ Method getBindingsMethod = scriptEngineManagerClass.getMethod
+ ("getBindings", new Class<?>[] {});
+ scriptEngineBindings = (java.util.Map<String, Object>)
+ getBindingsMethod.invoke(scriptEngineManager, new Object[] {});
} catch(Exception exception) {
- scriptEngineManagerClass = null;
- scriptEngineManager = null;
+ scriptEngineManagerClass = null;
+ scriptEngineManager = null;
+ scriptEngineBindings = null;
}
}
@@ -364,12 +475,8 @@
Method evalMethod = scriptEngine.getClass().getMethod("eval",
new Class<?>[] {Reader.class, bindingsClass});
- Method getBindingsMethod =
- scriptEngineManagerClass.getMethod("getBindings", new Class<?>[] {});
-
- Object bindings = getBindingsMethod.invoke(scriptEngineManager, new Object[] {});
Reader scriptReader = new BufferedReader(new InputStreamReader(scriptLocation.openStream()));
- evalMethod.invoke(scriptEngine, new Object[] {scriptReader, bindings});
+ evalMethod.invoke(scriptEngine, new Object[] {scriptReader, scriptEngineBindings});
} catch(Exception exception) {
throw new SerializationException(exception);
}
@@ -739,28 +846,22 @@
*/
@SuppressWarnings("unchecked")
public <T> T getObjectByName(String name) {
- if (name == null) {
- throw new IllegalArgumentException("name is null.");
- }
-
- Object object = null;
- WTKXSerializer serializer = this;
- String[] namespacePath = name.split("\\.");
-
- int i = 0;
- int n = namespacePath.length - 1;
- while (i < n && serializer != null) {
- String namespace = namespacePath[i++];
- serializer = serializer.includeSerializers.get(namespace);
- }
-
- if (serializer != null) {
- object = serializer.getObjectByID(namespacePath[i]);
- }
-
+ Object object = namedObjectsDictionary.get(name);
return (T)object;
}
+ /**
+ * Retrieves the named objects dictionary. The names are relative to this
+ * loader and can reference objects located in nested includes by using
+ * period-separated path strings (e.g. <tt>"foo.bar.baz"</tt>).
+ *
+ * @return
+ * The read-only named objects dictionary.
+ */
+ public Dictionary<String, Object> getNamedObjects() {
+ return namedObjectsDictionary;
+ }
+
private Object getObjectByID(String id) {
Object object = null;