Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/prolifics/jni/UCIHelper.java


1   /* @(#)UCIHelper.java  77.20 00/07/18 17:48:38" */
2   
3   /*************************************************/
4   /*  Copyright (c) 2000         */
5   /*      by         */
6   /*  JYACC, Inc., New York NY USA     */
7   /*  and contributors.         */
8   /*  Use of this program is governed by the   */
9   /*  JYACC Public License Version 1.0, a copy of   */
10  /*  which can be obtained at       */
11  /*  http://www.possl.org/jyacc-license.html   */
12  /*************************************************/
13  
14  package com.prolifics.jni;
15  
16  import com.prolifics.ejb.*;
17  import java.lang.reflect.*;
18  import java.util.*;
19  
20  class InOutParameter
21  {
22    boolean isInOut;
23    boolean isArray;
24    Class wrapper;
25    Class valueType;
26  
27    static Hashtable d = new Hashtable();
28  
29    private InOutParameter() { }
30    private InOutParameter(Class wrapper)
31    {
32      try {
33        valueType = wrapper.getDeclaredField("value").getType();
34        this.wrapper = wrapper;
35        isArray = valueType.isArray();
36        isInOut = true;
37        d.put(wrapper, this);
38      } catch (NoSuchFieldException e) {
39      }
40    }
41  
42    static InOutParameter notInOut = new InOutParameter();
43  
44    static {
45      new InOutParameter(SmWSIntHolder.class);
46      new InOutParameter(SmWSBooleanHolder.class);
47      new InOutParameter(SmWSDoubleHolder.class);
48      new InOutParameter(SmWSStringHolder.class);
49      new InOutParameter(SmWSObjectHolder.class);
50      new InOutParameter(SmWSIntArrayHolder.class);
51      new InOutParameter(SmWSBooleanArrayHolder.class);
52      new InOutParameter(SmWSDoubleArrayHolder.class);
53      new InOutParameter(SmWSStringArrayHolder.class);
54      new InOutParameter(SmWSObjectArrayHolder.class);
55    }
56  
57    public static InOutParameter forType(Class type)
58    {
59      InOutParameter iop = (InOutParameter)d.get(type);
60      return iop == null ? notInOut : iop;
61    }
62  }
63  
64  public class UCIHelper implements Constants
65  {
66    private final boolean enableDebug = false;
67  
68    public Object returnValue = null;
69  
70    public int lastError = 0;
71    public int lastObjError = 0;
72    public String lastMessage = null;
73  
74    private Method resolvedMethod = null;
75    private Constructor resolvedConstructor = null;
76    private String argumentTypes = null;
77    private Class sig[];
78  
79    private final Class oneString[] = { String.class };
80  
81    private static final Hashtable stringToClass = new Hashtable();
82    static {
83      stringToClass.put("boolean",    Boolean.TYPE);
84      stringToClass.put("byte",    Byte.TYPE);
85      stringToClass.put("char",    Character.TYPE);
86      stringToClass.put("double",    Double.TYPE);
87      stringToClass.put("float",    Float.TYPE);
88      stringToClass.put("int",    Integer.TYPE);
89      stringToClass.put("long",    Long.TYPE);
90      stringToClass.put("short",    Short.TYPE);
91    }
92  
93    private static final Hashtable classToWrapper = new Hashtable();
94    static {
95      classToWrapper.put(Boolean.TYPE,  Boolean.class);
96      classToWrapper.put(Byte.TYPE,    Byte.class);
97      classToWrapper.put(Character.TYPE,  Character.class);
98      classToWrapper.put(Double.TYPE,    Double.class);
99      classToWrapper.put(Float.TYPE,    Float.class);
100     classToWrapper.put(Integer.TYPE,  Integer.class);
101     classToWrapper.put(Long.TYPE,    Long.class);
102     classToWrapper.put(Short.TYPE,    Short.class);
103   }
104 
105   private void
106   setArgumentTypes(Class types[])
107   {
108     StringBuffer s = new StringBuffer(3 * types.length);
109     debug(types);
110     for (int i = types.length - 1; i >= 0; --i)
111     {
112       Class t = types[i];
113       InOutParameter iop = InOutParameter.forType(t);
114       debug(t);
115 
116       if (iop.isInOut)
117       {
118         t = iop.valueType;
119         s.append('I');  // InOut scalar
120       }
121       else
122         s.append('-');
123 
124       if (t.isArray())
125       {
126         t = t.getComponentType();
127         s.append('A');  // array
128       }
129       else
130         s.append('-');
131 
132       if (t.isPrimitive() || t == String.class)
133         s.append('-'); // primitive (or string)
134       else
135         s.append('O');  // object
136     }
137     argumentTypes = s.toString();
138     debug(argumentTypes);
139   }
140 
141   public UCIHelper()
142   {
143     debug("UCIHelper constructor called");
144   }
145 
146   protected void
147   debug(Object s)
148   {
149     if (enableDebug)
150       System.out.println(s);
151   }
152 
153   protected void
154   debug(int s)
155   {
156     if (enableDebug)
157       System.out.println(s);
158   }
159 
160   private void
161   marshalArguments(Object cargs,
162        String args[], Object argtype) throws Error, Throwable
163   {
164     debug("marshalArguments(args, argtype)");
165     debug(args);
166     debug(args.length);
167     debug(argtype);
168 
169     for (int i = 0; i < args.length; ++i)
170     {
171       Object arg = args[i];
172       Object nobj;
173       Class type;
174       if (argtype.getClass().isArray())
175         type = ((Class [])argtype)[i];
176       else
177         type = (Class)argtype;
178 
179       debug(arg);
180       debug(type);
181 
182       InOutParameter iop = InOutParameter.forType(type);
183       if (iop.isInOut)
184         type = iop.valueType;
185 
186       if (iop.isArray ||
187           arg != null && arg.getClass().isArray())
188       {
189         nobj = null;
190         if (Array.getLength(arg) != 0)
191         {
192           nobj = Array.newInstance(
193             type.getComponentType(),
194             Array.getLength(arg));
195           marshalArguments(
196             nobj,
197             (String [])arg,
198             type.getComponentType());
199         }
200       }
201       else
202       {
203         if (arg != null &&
204             arg.getClass() == String.class)
205           nobj = makeObject(type, (String)arg);
206         else
207           nobj = arg;
208       }
209       if (iop.isInOut)
210       {
211         Object wrapper = iop.wrapper.newInstance();
212         iop.wrapper.getField("value").
213           set(wrapper, nobj);
214         nobj = wrapper;
215       }
216       Array.set(cargs, i, nobj);
217     }
218   }
219 
220   private Object
221   resizeArray(Object obj, Object ref)
222   {
223     int nsize = 0;
224     if (ref != null)
225       nsize = Array.getLength(ref);
226     debug("resizing array to " + nsize);
227     return Array.newInstance(obj.getClass().
228            getComponentType(), nsize);
229   }
230 
231   private void
232   unmarshalArguments(Object args[], Object cargs,
233          boolean all, boolean isObject) throws Exception
234   {
235     debug("unmarshalling: args.length = " + args.length);
236 
237     int atidx = argumentTypes.length();
238     debug ("atidx = " + atidx);
239 
240     for (int i = 0; i < args.length; ++i)
241     {
242       Object obj = Array.get(cargs, i);
243       debug ("obj = " + obj);
244 
245       atidx -= 3;
246       boolean isInOut  = false;
247       boolean isArray  = false;
248 
249       if (!all)
250       {
251         isInOut  = argumentTypes.
252           charAt(atidx)     == 'I';
253         isArray  = argumentTypes.
254           charAt(atidx + 1) == 'A';
255         isObject = argumentTypes.
256           charAt(atidx + 2) == 'O';
257       }
258 
259       if (all || isInOut || isArray)
260       {
261         if (isInOut)
262         {
263           debug ("i = " + i + 
264             ", obj = " + obj);
265           obj = obj.getClass().
266             getField("value").get(obj);
267           debug ("i = " + i + 
268             ", obj = " + obj);
269         }
270         if (isArray)
271         {
272           debug("recurse");
273           if (isInOut)
274           {
275             args[i] =
276               resizeArray(args[i],
277                     obj);
278           }
279           unmarshalArguments((Object[])args[i],
280                  obj,
281                  true,
282                  isObject);
283           debug("back");
284         }
285         else if (isObject)
286         {
287           args[i] = obj;
288           debug("copy out as object args[" +
289               i + "] = " + args[i]);
290         }
291         else
292         {
293           if (obj == null)
294             args[i] = null;
295           else
296             args[i] = obj.toString();
297 
298           debug("copy out args[" +
299               i + "] = " + args[i]);
300         }
301       }
302     }
303   }
304 
305   private Method
306   getMethod(Class clazz, String name, int count) throws Error
307   {
308     debug("in getMethod");
309     if (sig != null)
310     {
311       try
312       {
313         return clazz.getMethod(name, sig);
314       }
315       catch (NoSuchMethodException e)
316       {
317         throw new Error(PR_E_ERROR, SM_NOFUNC, name);
318       }
319     }
320 
321     Method match = null;
322     Method methods[] = clazz.getMethods();
323 
324     for (int i = 0; i < methods.length; ++i)
325     {
326       Method m = methods[i];
327       if (m.getName().equals(name) &&
328           m.getParameterTypes().length == count)
329       {
330         debug("found " + m.getName());
331         if (match != null)
332         {
333           throw new Error(PR_E_ERROR,
334               SM_MULTFUNC, name);
335         }
336         match = m;
337       }
338     }
339 
340     if (match == null)
341       throw new Error(PR_E_ERROR, SM_NOFUNC, name);
342 
343     return match;
344   }
345 
346   private Constructor
347   getConstructor(Class clazz, int count) throws Error
348   {
349     debug("getConstructor(" + clazz + ", " + count + ")");
350     if (sig != null)
351     {
352       try
353       {
354         debug(sig);
355         debug(sig.length);
356         return clazz.getConstructor(sig);
357       }
358       catch (NoSuchMethodException e)
359       {
360         throw new Error(PR_E_ERROR,
361             SM_NOFUNC, clazz.getName());
362       }
363     }
364 
365     debug(clazz);
366 
367     Constructor match = null;
368     Constructor methods[] = clazz.getConstructors();
369 
370     for (int i = 0; i < methods.length; ++i)
371     {
372       Constructor m = methods[i];
373       if (m.getParameterTypes().length == count)
374       {
375         if (match != null)
376         {
377           throw new Error(PR_E_ERROR,
378             SM_MULTFUNC, clazz.getName());
379         }
380         match = m;
381       }
382     }
383 
384     if (match == null)
385       throw new Error(PR_E_ERROR,
386           SM_NOFUNC, clazz.getName());
387 
388     return match;
389   }
390 
391   public String
392   resolveMethod(Class clazz, Object object, String name, int count)
393               throws Exception
394   {
395     debug("resolveMethod called (class, object, name, count)");
396     debug(clazz);
397     debug(object);
398     debug(name);
399     debug(count);
400 
401     if (name == null)
402       return resolveConstructor(clazz, count);
403 
404     try {
405       resolvedMethod = getMethod(clazz, name, count);
406     } catch (Error e) {
407       return null;
408     }
409 
410     debug(resolvedMethod);
411 
412     if (resolvedMethod == null)
413       return null;
414 
415     setArgumentTypes(resolvedMethod.getParameterTypes());
416     debug("returning, loa = " + argumentTypes);
417     return argumentTypes;
418   }
419 
420   public int
421   callMethod(Class clazz, Object object, String args[]) throws Throwable
422   {
423     debug("callMethod called (class, object, args)");
424     debug(clazz);
425     debug(object);
426     debug(args);
427 
428     if (resolvedConstructor != null)
429       return callConstructor(clazz, args);
430 
431     Object oargs[] = null;
432     if (args != null)
433     {
434       oargs = new Object[args.length];
435       try {
436         marshalArguments(oargs, args,
437            resolvedMethod.getParameterTypes());
438       } catch (Error e) {
439         return -1;
440       }
441       debug("before invoke");
442       debug(oargs.getClass());
443       debug(oargs.length);
444       for (int i = 0; i < oargs.length; ++i)
445         debug(oargs[i]);
446     }
447 
448     Class t = resolvedMethod.getReturnType();
449     debug("return type is " + t.toString());
450 
451     try {
452       returnValue = resolvedMethod.invoke(object, oargs);
453     } catch (InvocationTargetException e1) {
454       throw e1.getTargetException();
455     }
456 
457     debug("returnValue is " + returnValue);
458     if (t.isPrimitive() || t == String.class)
459       if (returnValue != null)
460         returnValue = returnValue.toString();
461 
462     debug("after invoke");
463     if (args != null)
464       unmarshalArguments(args, oargs, false, false);
465 
466     return 0;
467   }
468 
469   public String
470   resolveConstructor(Class clazz, int count) throws Exception
471   {
472     debug("resolveConstructor called");
473     debug(clazz);
474     debug(count);
475 
476     try {
477       resolvedConstructor = getConstructor(clazz, count);
478     } catch (Error e) {
479         return null;
480     }
481 
482     debug(resolvedConstructor);
483     if (resolvedConstructor == null)
484       return null;
485 
486     setArgumentTypes(resolvedConstructor.getParameterTypes());
487     return argumentTypes;
488   }
489 
490   public int
491   callConstructor(Class clazz, String args[]) throws Throwable
492   {
493     debug("callConstructor called");
494     debug(clazz);
495     debug(args);
496 
497     Object oargs[] = new Object[args.length];
498     try {
499       marshalArguments(oargs,
500         args, resolvedConstructor.getParameterTypes());
501     } catch (Error e) {
502       return -1;
503     }
504     returnValue = resolvedConstructor.newInstance(oargs);
505     unmarshalArguments(args, oargs, false, false);
506 
507     return 0;
508   }
509 
510   private Class
511   wrap(Class dst)
512   {
513     if (!dst.isPrimitive())
514       return dst;
515 
516     return (Class)classToWrapper.get(dst);
517   }
518 
519   private Object
520   makeObject(Class dst, String s) throws Error, Throwable
521   {
522     try {
523       try {
524         debug(dst);
525         if (dst == s.getClass())
526           return s;
527         dst = wrap(dst);
528         debug(s);
529         return dst.getConstructor(oneString).
530           newInstance(new Object[] { s });
531       } catch (InvocationTargetException e) {
532         throw e.getTargetException();
533       }
534     } catch (NumberFormatException e) {
535       if (dst == Integer.class)
536       {
537         try {
538           return new Integer(Double.valueOf(s).
539                  intValue());
540         } catch (NumberFormatException e1) {
541         }
542       }
543       return dst.getConstructor(oneString).
544         newInstance(new Object[] { "0" });
545     } catch (IllegalArgumentException e) {
546       throw new Error(PR_E_ARGS, SM_MISMATCH, dst.getName());
547     } catch (Throwable e) {
548       new Error(PR_E_ARGS, SM_MISMATCH, dst.getName());
549       throw e;
550     }
551   }
552 
553   public String
554   getProperty(Object obj, String prop)
555   {
556     debug("getProperty " + obj.getClass() + "->" + prop);
557     Class c;
558     try {
559       c = obj.getClass();
560     } catch (Throwable e) {
561       new Error(PR_E_OBJID, SM_PR_OBJID, null);
562       return null;
563     }
564     try {
565       return c.getField(prop).get(obj).toString();
566     } catch (Throwable e) {
567       new Error(PR_E_PROP, SM_PR_PROP, prop);
568       return null;
569     }
570   }
571 
572   public int
573   setProperty(Object obj, String prop, String val)
574   {
575     debug("setProperty " + obj.getClass() + "->" + prop);
576     Class c;
577     try {
578       c = obj.getClass();
579     } catch (Throwable e) {
580       new Error(PR_E_OBJID, SM_PR_OBJID, null);
581       return -1;
582     }
583     java.lang.reflect.Field f;
584     try {
585        f = c.getField(prop);
586     } catch (Throwable e) {
587       new Error(PR_E_PROP, SM_PR_PROP, prop);
588       return -1;
589     }
590     try {
591       Object v = makeObject(f.getType(), val);
592       f.set(obj, v);
593       return 0;
594     } catch (Error e) {
595       return -1;
596     }
597     catch (Throwable e) {
598       new Error(PR_E_PROP_VAL, SM_PR_PROP_VAL, val);
599       return -1;
600     }
601   }
602 
603   protected class Error extends Exception
604   {
605     public Error(int objerror, int msgnum, String s)
606     {
607       lastObjError = objerror;
608       lastError = msgnum;
609       lastMessage = s;
610     }
611   };
612 
613   public int
614   xlateDescriptor(String prodesc)
615   {
616     Vector vsig = new Vector();
617 
618     prodesc = prodesc.trim();
619 
620     if (!prodesc.startsWith("("))
621     {
622       new Error(PR_E_ERROR, SM_MISSLEFTPAREN, prodesc);
623       return -1;
624     }
625 
626     String buf = "";
627 
628     prodesc = prodesc.substring(1).trim();
629     if (!prodesc.startsWith(")"))
630     for (;;)
631     {
632       Class clazz;
633 
634       debug("rest of prodesc is '" + prodesc + "'");
635 
636       if (!Character.
637           isJavaIdentifierStart(prodesc.charAt(0)))
638       {
639         new Error(PR_E_ERROR, SM_NONAME, prodesc);
640         return -1;
641       }
642 
643       while (Character.
644              isJavaIdentifierPart(prodesc.
645                charAt(0)) ||
646              prodesc.startsWith(".") ||
647              prodesc.startsWith("/"))
648       {
649         String h = prodesc.substring(0, 1);
650         if (h.equals("/"))
651           h = ".";
652         buf += h;
653         prodesc = prodesc.substring(1);
654       }
655 
656       prodesc = prodesc.trim();
657 
658       if (buf == "")
659         break;
660 
661       debug("need class " + buf);
662       if ((clazz = (Class)stringToClass.get(buf)) == null)
663       {
664         debug("not primitive");
665         try
666         {
667           clazz = Class.forName(buf);
668         }
669         catch (ClassNotFoundException e)
670         {
671           debug("not qualified");
672           clazz = null;
673         }
674         if (clazz == null) try
675         {
676           debug("qualified?");
677           clazz = Class.forName("java.lang.".
678                     concat(buf));
679         }
680         catch (ClassNotFoundException e)
681         {
682           debug("not found!");
683           new Error(PR_E_OBJ_TYPE,
684               JV_NOCLASS, buf);
685           return -1;
686         }
687       }
688 
689       if (prodesc.startsWith("["))
690       {
691         // we only support a one-
692         // dimensional arrays
693         prodesc = prodesc.substring(1).trim();
694         if (!prodesc.startsWith("]"))
695         {
696           new Error(PR_E_ARGS,
697               SM_MISKET, prodesc);
698           return -1;
699         }
700         prodesc = prodesc.substring(1);
701         clazz = Array.newInstance(clazz, 0).
702           getClass();
703       }
704 
705       debug("got class " + clazz.toString());
706       vsig.addElement(clazz);
707 
708       prodesc = prodesc.trim();
709 
710       if (!prodesc.startsWith(","))
711         break;
712     }
713 
714     if (!prodesc.trim().equals(")"))
715     {
716       if (!prodesc.startsWith(")"))
717       {
718         new Error(PR_E_ARGS, SM_MISSPARENS, prodesc);
719         return -1;
720       }
721       new Error(PR_E_ARGS, SM_EXCESS, prodesc);
722       return -1;
723     }
724 
725     sig = new Class[vsig.size()];
726     vsig.copyInto(sig);
727 
728     return 0;
729   }
730 };