checkpoint
[sbp.git] / src / edu / berkeley / sbp / bind / Bindable.java
index 7c620c9..a51996e 100644 (file)
@@ -1,3 +1,5 @@
+// Copyright 2006 all rights reserved; see LICENSE file for BSD-style license
+
 package edu.berkeley.sbp.bind;
 
 import edu.berkeley.sbp.util.*;
@@ -8,6 +10,7 @@ import java.util.*;
 import java.lang.annotation.*;
 import java.lang.reflect.*;
 import java.io.*;
+import java.security.*;
 import static edu.berkeley.sbp.util.Reflection.*;
 
 public abstract class Bindable implements ToJava {
@@ -22,6 +25,11 @@ public abstract class Bindable implements ToJava {
     public abstract String[]       getArgNames();
     public abstract Class[]        getArgTypes();
 
+    public Binding createBinding() { return new SimpleBinding(); }
+    public Binding createBinding(final int[] map) { return new SimpleBinding(map); }
+    public Binding createBinding(final int[] map, Object prepend) { return new SimpleBinding(map, prepend); }
+
+
     public static Bindable create(Object o) {
         if (o instanceof Class) return new BindableClass((Class)o);
         if (o instanceof Method) return new BindableMethod((Method)o);
@@ -29,31 +37,14 @@ public abstract class Bindable implements ToJava {
         return null;
     }
 
-    public Binding createBinding() {
-        return new Binding() {
-                public Object invoke(Object[] o) {
-                    return impose(o);
-                }
-            };
-    }
-    public Binding createBinding(final int[] map) {
-        return new Binding() {
-                public Object invoke(Object[] o) {
-                    int max = 0;
-                    for(int i=0; i<map.length; i++) max = Math.max(map[i], max);
-                    Object[] o2 = new Object[max+1];
-                    for(int i=0; i<o.length; i++) o2[map[i]] = o[i];
-                    return impose(o2);
-                }
-            };
-    }
+    // Subclasses //////////////////////////////////////////////////////////////////////////////
 
     private static class BindableMethod extends Bindable {
         private final Method _method;
         public String toString() { return "BindableMethod["+_method+"]"; }
         public BindableMethod(Method _method) { this._method = _method; }
         public String getSimpleName() { return _method.getName(); }
-        public <A extends Annotation> A getAnnotation(Class<A> c) { return _method.getAnnotation(c); }
+        public <A extends Annotation> A getAnnotation(final Class<A> c) { return _method.getAnnotation(c); }
         public Object impose(Object[] fields) { return Reflection.impose(_method, fields); }
         public Annotation[][] getArgAnnotations() { return _method.getParameterAnnotations(); }
         public String[]       getArgNames() { return new String[_method.getParameterTypes().length]; }
@@ -124,6 +115,8 @@ public abstract class Bindable implements ToJava {
     }
 
 
+    // Helpers //////////////////////////////////////////////////////////////////////////////
+
     private static void appendClassArray(StringBuffer sb, Class[] c) {
         sb.append("new Class[] {");
         for(int i=0; i<c.length; i++) {
@@ -139,4 +132,40 @@ public abstract class Bindable implements ToJava {
         if (!c.isArray()) return c.getName().replace('$','.');
         return makeClass(c.getComponentType())+"[]";
     }
+
+
+    // Creating Bindings //////////////////////////////////////////////////////////////////////////////
+
+    private class SimpleBinding implements Binding, ToJava {
+        private int[] map = null;
+        private Object prepend = null;
+        public SimpleBinding() { }
+        public SimpleBinding(int[] map) { this.map = map; }
+        public SimpleBinding(int[] map, Object prepend) { this.map = map; this.prepend = prepend; }
+
+        public Object invoke(Object[] o) {
+            if (map==null) return impose(o);
+            int max = 0;
+            for(int i=0; i<map.length; i++) max = Math.max(map[i], max);
+            Object[] o2 = new Object[max+1];
+            for(int i=0; i<o.length; i++) o2[map[i]+(prepend==null?0:1)] = o[i];
+            if (prepend != null) o2[0] = prepend;
+            return impose(o2);
+        }
+
+        public void toJava(StringBuffer sb) {
+            Bindable.this.toJava(sb);
+            sb.append(".createBinding(");
+            if (map != null) {
+                sb.append("new int[] {");
+                for(int i=0; i<map.length; i++) {
+                    sb.append(i);
+                    if (i<map.length-1) sb.append(",");
+                }
+                sb.append("}");
+            }
+            sb.append(")");
+        }
+    }
+
 }