~ubuntu-branches/ubuntu/wily/picolisp/wily-proposed

« back to all changes in this revision

Viewing changes to java/Reflector.java

  • Committer: Package Import Robot
  • Author(s): Kan-Ru Chen (陳侃如)
  • Date: 2015-02-06 00:19:20 UTC
  • mfrom: (1.2.2)
  • Revision ID: package-import@ubuntu.com-20150206001920-ug3fakmqpq9apw5o
Tags: 3.1.9.7-1
* New upstream release
* Build *.jar from source
* Do not install doc/{db,utf8} as requested by upstream

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// 02feb15abu
 
2
// (c) Software Lab. Alexander Burger
 
3
 
 
4
import java.io.*;
 
5
import java.util.*;
 
6
import java.math.*;
 
7
import java.lang.reflect.*;
 
8
 
 
9
// java Reflector fifo/java fifo/rqst fifo/rply
 
10
public class Reflector {
 
11
   public static void main(String[] args) throws Exception {
 
12
      final InOut io = new InOut(System.in, System.out);
 
13
      final InOut rpc = new InOut(new FileInputStream(args[1]), new FileOutputStream(args[0]));
 
14
 
 
15
      for (;;) {
 
16
         try {
 
17
            int i;
 
18
            Object x, y, z, lst[];
 
19
 
 
20
            while ((lst = (Object[])io.read()) != null) {
 
21
               y = lst[1];
 
22
               switch((Integer)lst[0]) {
 
23
               // (java 'cls 'T ['any ..]) -> obj
 
24
               // (java 'cls 'msg ['any ..]) -> obj
 
25
               // (java 'obj 'msg ['any ..]) -> obj
 
26
               case 0:
 
27
                  z = lst[2];
 
28
                  i = lst.length-3;
 
29
                  Object[] arg = new Object[i];
 
30
                  Class[] par = new Class[i];
 
31
                  while (--i >= 0) {
 
32
                     Object v = lst[i+3];
 
33
                     if (v == InOut.T || v == InOut.Nil) {
 
34
                        arg[i] = v == InOut.T;
 
35
                        par[i] = Boolean.TYPE;
 
36
                     }
 
37
                     else {
 
38
                        arg[i] = v;
 
39
                        if (v instanceof Byte)
 
40
                           par[i] = Byte.TYPE;
 
41
                        else if (v instanceof Character)
 
42
                           par[i] = Character.TYPE;
 
43
                        else if (v instanceof Short)
 
44
                           par[i] = Short.TYPE;
 
45
                        else if (v instanceof Integer)
 
46
                           par[i] = Integer.TYPE;
 
47
                        else if (v instanceof Long)
 
48
                           par[i] = Long.TYPE;
 
49
                        else if (v instanceof Double)
 
50
                           par[i] = Double.TYPE;
 
51
                        else
 
52
                           par[i] = v.getClass();
 
53
                     }
 
54
                  }
 
55
                  if (z == InOut.T)
 
56
                     x = javaConstructor(Class.forName(y.toString()), par).newInstance(arg);
 
57
                  else {
 
58
                     Method m;
 
59
                     if (y instanceof String) {
 
60
                        m = javaMethod(Class.forName((String)y), z.toString(), par);
 
61
                        x = m.invoke(null, arg);
 
62
                     }
 
63
                     else {
 
64
                        m = javaMethod(y.getClass(), z.toString(), par);
 
65
                        x = m.invoke(y, arg);
 
66
                     }
 
67
                     if (m.getReturnType() == Void.TYPE)
 
68
                        x = null;
 
69
                  }
 
70
                  io.print(x);
 
71
                  break;
 
72
               // (public 'obj 'any ['any ..]) -> obj
 
73
               // (public 'cls 'any ['any ..]) -> obj
 
74
               case 1:
 
75
                  z = lst[2];
 
76
                  if (y instanceof String) {
 
77
                     Class cls = Class.forName((String)y);
 
78
                     x = cls.getField(z.toString()).get(cls);
 
79
                  }
 
80
                  else
 
81
                     x = y.getClass().getField(z.toString()).get(y);
 
82
                  for (i = 3; i < lst.length; ++i)
 
83
                     x = x.getClass().getField(lst[i].toString()).get(x);
 
84
                  io.print(x);
 
85
                  break;
 
86
               // (interface 'obj 'cls|lst 'sym 'fun ..) -> obj
 
87
               case 2:
 
88
                  final Object obj = y;
 
89
                  y = lst[2];
 
90
                  Class[] c = new Class[y instanceof Object[]? ((Object[])y).length : 1];
 
91
                  if (y instanceof Object[])
 
92
                     for (i = 0; i < c.length; ++i)
 
93
                        c[i] = Class.forName((((Object[])y)[i]).toString());
 
94
                  else
 
95
                     c[0] = Class.forName(y.toString());
 
96
                  InvocationHandler h = new InvocationHandler() {
 
97
                     public Object invoke(Object o, Method m, Object[] lst) {
 
98
                        String nm = m.getName();
 
99
                        if (nm.equals("hashCode"))
 
100
                           return System.identityHashCode(o);
 
101
                        try {
 
102
                           rpc.print(obj);
 
103
                           rpc.prSym(nm);
 
104
                           rpc.print(lst);
 
105
                           rpc.flush();
 
106
                           return rpc.read();
 
107
                        }
 
108
                        catch (Exception e) {}
 
109
                        return null;
 
110
                     }
 
111
                  };
 
112
                  io.print(Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), c, h));
 
113
                  break;
 
114
               // (reflect 'obj) -> [lst lst]
 
115
               case 3:
 
116
                  Class cls = y instanceof Class? ((Class)y).getSuperclass() : y.getClass();
 
117
                  Field[] fld = cls.getDeclaredFields();
 
118
                  io.Out.write(InOut.BEG);
 
119
                  io.Out.write(InOut.BEG);
 
120
                  io.print(cls);
 
121
                  io.Out.write(InOut.DOT);
 
122
                  io.print(cls.getName());
 
123
                  for (i = 0; i < fld.length; ++i) {
 
124
                     if (!(y instanceof Class)) {
 
125
                        io.Out.write(InOut.BEG);
 
126
                        if (fld[i].isAccessible())
 
127
                           io.print(fld[i].get(y));
 
128
                        else {
 
129
                           fld[i].setAccessible(true);
 
130
                           io.print(fld[i].get(y));
 
131
                           fld[i].setAccessible(false);
 
132
                        }
 
133
                        io.Out.write(InOut.DOT);
 
134
                     }
 
135
                     io.prSym(fld[i].getName());
 
136
                  }
 
137
                  io.Out.write(InOut.END);
 
138
                  break;
 
139
               default:
 
140
                  System.err.println("## " + lst[0] + ": Undefined");
 
141
               }
 
142
               io.flush();
 
143
            }
 
144
         }
 
145
         catch (EOFException e) {
 
146
            io.close();
 
147
            rpc.close();
 
148
            System.exit(0);
 
149
         }
 
150
         catch (Exception e) {
 
151
            System.err.println("## " + e);
 
152
            io.Out.write(InOut.NIX);
 
153
            io.flush();
 
154
            while (io.In.available() > 0)
 
155
               io.In.read();
 
156
            rpc.Out.write(InOut.NIX);
 
157
            rpc.flush();
 
158
            while (rpc.In.available() > 0)
 
159
               rpc.In.read();
 
160
         }
 
161
      }
 
162
   }
 
163
 
 
164
   final static Constructor javaConstructor(Class cls, Class[] par) throws NoSuchMethodException {
 
165
   looking:
 
166
      for (Constructor m : cls.getConstructors()) {
 
167
         Class<?>[] types = m.getParameterTypes();
 
168
         if (types.length == par.length) {
 
169
            for (int i = 0; i < types.length; ++i)
 
170
               if (!(types[i].isAssignableFrom(par[i])))
 
171
                  continue looking;
 
172
            return m;
 
173
         }
 
174
      }
 
175
      throw new NoSuchMethodException();
 
176
   }
 
177
 
 
178
   final static Method javaMethod(Class cls, String nm, Class[] par)  throws NoSuchMethodException {
 
179
   looking:
 
180
      for (Method m : cls.getMethods()) {
 
181
         if (m.getName().equals(nm)) {
 
182
            Class<?>[] types = m.getParameterTypes();
 
183
            if (types.length == par.length) {
 
184
               for (int i = 0; i < types.length; ++i)
 
185
                  if (!(types[i].isAssignableFrom(par[i])))
 
186
                     continue looking;
 
187
               return m;
 
188
            }
 
189
         }
 
190
      }
 
191
      throw new NoSuchMethodException(nm + "(" + par + ")");
 
192
   }
 
193
}