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/06 16:13:16 UTC

svn commit: r772271 - in /incubator/pivot/trunk: tutorials/src/pivot/tutorials/ tutorials/src/pivot/tutorials/drawing/ wtk/src/pivot/wtkx/

Author: tvolkert
Date: Wed May  6 14:13:15 2009
New Revision: 772271

URL: http://svn.apache.org/viewvc?rev=772271&view=rev
Log:
Created Bindable class, and moved the bind annotations to be nested classes within Bindable; changed users of the bind annotations to extend Bindable and call bind()

Added:
    incubator/pivot/trunk/wtk/src/pivot/wtkx/Bindable.java
Removed:
    incubator/pivot/trunk/wtk/src/pivot/wtkx/Bind.java
    incubator/pivot/trunk/wtk/src/pivot/wtkx/Load.java
Modified:
    incubator/pivot/trunk/tutorials/src/pivot/tutorials/Demo.java
    incubator/pivot/trunk/tutorials/src/pivot/tutorials/drawing/RotateLine.java
    incubator/pivot/trunk/wtk/src/pivot/wtkx/BindProcessor.java

Modified: incubator/pivot/trunk/tutorials/src/pivot/tutorials/Demo.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/tutorials/src/pivot/tutorials/Demo.java?rev=772271&r1=772270&r2=772271&view=diff
==============================================================================
--- incubator/pivot/trunk/tutorials/src/pivot/tutorials/Demo.java (original)
+++ incubator/pivot/trunk/tutorials/src/pivot/tutorials/Demo.java Wed May  6 14:13:15 2009
@@ -81,11 +81,10 @@
 import pivot.wtk.media.Image;
 import pivot.wtk.text.Document;
 import pivot.wtk.text.PlainTextSerializer;
-import pivot.wtkx.Bind;
-import pivot.wtkx.Load;
+import pivot.wtkx.Bindable;
 import pivot.wtkx.WTKXSerializer;
 
-public class Demo implements Application {
+public class Demo extends Bindable implements Application {
     private abstract class RollupStateHandler implements RollupStateListener {
         private String resourceName;
         private Component component = null;
@@ -170,6 +169,8 @@
         terraTheme.loadScheme(schemeLocation);
         */
 
+        bind();
+
         buttonsRollup.getRollupStateListeners().add(new RollupStateHandler("buttons.wtkx") {
             @Override
             protected void initialize(WTKXSerializer wtkxSerializer) {

Modified: incubator/pivot/trunk/tutorials/src/pivot/tutorials/drawing/RotateLine.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/tutorials/src/pivot/tutorials/drawing/RotateLine.java?rev=772271&r1=772270&r2=772271&view=diff
==============================================================================
--- incubator/pivot/trunk/tutorials/src/pivot/tutorials/drawing/RotateLine.java (original)
+++ incubator/pivot/trunk/tutorials/src/pivot/tutorials/drawing/RotateLine.java Wed May  6 14:13:15 2009
@@ -25,10 +25,9 @@
 import pivot.wtk.Window;
 import pivot.wtk.media.Drawing;
 import pivot.wtk.media.drawing.Shape;
-import pivot.wtkx.Bind;
-import pivot.wtkx.Load;
+import pivot.wtkx.Bindable;
 
-public class RotateLine implements Application {
+public class RotateLine extends Bindable implements Application {
     @Load("rotate_line.wtkd") private Drawing drawing;
     @Bind(resource="drawing") private Shape.Rotate rotation;
 
@@ -36,6 +35,8 @@
 
     public void startup(Display display, Dictionary<String, String> properties)
         throws Exception{
+        bind();
+
         ApplicationContext.scheduleRecurringCallback(new Runnable() {
             public void run() {
                 int angle = (int)rotation.getAngle();

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=772271&r1=772270&r2=772271&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/pivot/wtkx/BindProcessor.java (original)
+++ incubator/pivot/trunk/wtk/src/pivot/wtkx/BindProcessor.java Wed May  6 14:13:15 2009
@@ -97,7 +97,7 @@
                     BindScope.LoadGroup loadGroup = bindScope.loadGroups.get(loadFieldName);
                     JCTree.JCVariableDecl loadField = loadGroup.loadField;
                     Element loadElement = loadField.sym;
-                    Load loadAnnotation = loadElement.getAnnotation(Load.class);
+                    Bindable.Load loadAnnotation = loadElement.getAnnotation(Bindable.Load.class);
 
                     if (DEBUG) {
                         processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE,
@@ -122,7 +122,7 @@
                         for (JCTree.JCVariableDecl bindField : loadGroup.bindFields) {
                             String bindFieldName = bindField.name.toString();
                             Element bindElement = bindField.sym;
-                            Bind bindAnnotation = bindElement.getAnnotation(Bind.class);
+                            Bindable.Bind bindAnnotation = bindElement.getAnnotation(Bindable.Bind.class);
 
                             String bindID = bindAnnotation.id();
                             if ("\0".equals(bindID)) {
@@ -164,13 +164,13 @@
         public void visitVarDef(JCTree.JCVariableDecl tree) {
             super.visitVarDef(tree);
 
-            Load loadAnnotation = null;
-            Bind bindAnnotation = null;
+            Bindable.Load loadAnnotation = null;
+            Bindable.Bind bindAnnotation = null;
 
             Element element = tree.sym;
             if (element != null) {
-                loadAnnotation = element.getAnnotation(Load.class);
-                bindAnnotation = element.getAnnotation(Bind.class);
+                loadAnnotation = element.getAnnotation(Bindable.Load.class);
+                bindAnnotation = element.getAnnotation(Bindable.Bind.class);
             } else if (tree.mods != null
                 && tree.mods.annotations != null) {
                 List<JCTree.JCAnnotation> annotations = tree.mods.annotations;
@@ -180,8 +180,8 @@
             if (loadAnnotation != null
                 && bindAnnotation != null) {
                 processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR,
-                    "Cannot combine " + Load.class.getName()
-                    + " and " + Bind.class.getName() + " annotations.", element);
+                    "Cannot combine " + Bindable.Load.class.getName()
+                    + " and " + Bindable.Bind.class.getName() + " annotations.", element);
             } else if (loadAnnotation != null) {
                 BindScope bindScope = bindScopeStack.peek();
                 String fieldName = tree.name.toString();

Added: 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=772271&view=auto
==============================================================================
--- incubator/pivot/trunk/wtk/src/pivot/wtkx/Bindable.java (added)
+++ incubator/pivot/trunk/wtk/src/pivot/wtkx/Bindable.java Wed May  6 14:13:15 2009
@@ -0,0 +1,145 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package pivot.wtkx;
+
+import java.io.IOException;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.reflect.Field;
+import java.net.URL;
+
+import pivot.collections.HashMap;
+import pivot.serialization.SerializationException;
+
+/**
+ * Base class for objects that wish to leverage WTKX binding annotations.
+ *
+ * @author tvolkert
+ */
+public abstract class Bindable {
+    /**
+     * WTKX binding annotation.
+     *
+     * @author gbrown
+     */
+    @Retention(RetentionPolicy.RUNTIME)
+    @Target(ElementType.FIELD)
+    protected static @interface Load {
+        public String value();
+    }
+
+    /**
+     * WTKX binding annotation.
+     *
+     * @author gbrown
+     */
+    @Retention(RetentionPolicy.RUNTIME)
+    @Target(ElementType.FIELD)
+    protected static @interface Bind {
+        public String resource();
+        public String id() default "\0";
+    }
+
+    /**
+     * Applies WTKX binding annotations to this bindable object.
+     */
+    protected void bind() throws IOException, BindException {
+        // Maps resource field name to the serializer that loaded the resource
+        HashMap<String, WTKXSerializer> wtkxSerializers = new HashMap<String, WTKXSerializer>();
+
+        // Walk field lists and resolve WTKX annotations
+        Class<?> type = getClass();
+        Field[] fields = type.getDeclaredFields();
+        for (int i = 0; i < fields.length; i++) {
+            Field field = fields[i];
+            Load loadAnnotation = field.getAnnotation(Load.class);
+
+            if (loadAnnotation != null) {
+                // Create a serializer for the resource
+                String fieldName = field.getName();
+                assert(!wtkxSerializers.containsKey(fieldName));
+
+                WTKXSerializer wtkxSerializer = new WTKXSerializer();
+                wtkxSerializers.put(fieldName, wtkxSerializer);
+
+                // Load the resource
+                URL location = type.getResource(loadAnnotation.value());
+                Object resource;
+                try {
+                    resource = wtkxSerializer.readObject(location);
+                } catch (SerializationException exception) {
+                    throw new BindException(exception);
+                }
+
+                // Set the resource into the field
+                if (!field.isAccessible()) {
+                    try {
+                        field.setAccessible(true);
+                    } catch (Exception ex) {
+                        // No-op; the callers might have used public fields, in
+                        // which case we don't need to make them accessible
+                    }
+                }
+
+                try {
+                    field.set(this, resource);
+                } catch (IllegalAccessException exception) {
+                    throw new BindException(exception);
+                }
+            }
+
+            Bind bindAnnotation = field.getAnnotation(Bind.class);
+            if (bindAnnotation != null) {
+                if (loadAnnotation != null) {
+                    throw new BindException("Cannot combine " + Load.class.getName()
+                        + " and " + Bind.class.getName() + " annotations.");
+                }
+
+                // Bind to the value loaded by the field's serializer
+                String fieldName = bindAnnotation.resource();
+                WTKXSerializer wtkxSerializer = wtkxSerializers.get(fieldName);
+                if (wtkxSerializer == null) {
+                    throw new BindException("\"" + fieldName + "\" is not a valid resource name.");
+                }
+
+                String id = bindAnnotation.id();
+                Object value = wtkxSerializer.getObjectByName(id);
+                if (value == null) {
+                    throw new BindException("\"" + id + "\" does not exist.");
+                }
+
+                // Set the value into the field
+                if (!field.isAccessible()) {
+                    try {
+                        field.setAccessible(true);
+                    } catch (Exception ex) {
+                        // No-op; the callers might have used public fields, in
+                        // which case we don't need to make them accessible
+                    }
+                }
+
+                try {
+                    field.set(this, value);
+                } catch (IllegalAccessException exception) {
+                    throw new BindException(exception);
+                }
+            }
+        }
+    }
+}