home *** CD-ROM | disk | FTP | other *** search
/ Chip 1998 July / Chip_1998-07_cd.bin / zkuste / JBuilder / BDK / Win / bdk_sep97.exe / _SETUP.1 / HookupManager.java < prev    next >
Encoding:
Java Source  |  1997-09-10  |  7.7 KB  |  267 lines

  1.  
  2. /**
  3.  * This class manages events hookups between event source beans and 
  4.  * target methods on target beans.
  5.  * It does this for each hookup by generating a .java file for an adaptor
  6.  * class and then compiling and loading the adaptor.
  7.  */
  8.  
  9. package sun.beanbox;
  10.  
  11. import java.util.*;
  12. import java.beans.*;
  13. import java.lang.reflect.*;
  14.  
  15. public class HookupManager {
  16.  
  17.     static void hookup(EventSetDescriptor esd,
  18.         Method listenerMethod,
  19.         Wrapper sourceWrapper,
  20.         Wrapper targetWrapper,
  21.         Method targetMethod) {
  22.  
  23.     try {
  24.         // If we were smarter we might cache and reuse hookups.
  25.  
  26.         Object source = sourceWrapper.getBean();
  27.         Object target = targetWrapper.getBean();
  28.         String hookupName = generateHookup(esd, listenerMethod, source, target, targetMethod);
  29.  
  30.         if (hookupName == null) {
  31.         // The compile failed.
  32.             System.err.println("Could not create event adaptor.");
  33.         return;
  34.         }
  35.  
  36.         SimpleClassLoader loader = SimpleClassLoader.ourLoader;
  37.  
  38.         javaFiles.addElement(hookupName);
  39.          Class hookupClass = loader.loadClassFromFile(hookupName);
  40.         Object hookup = hookupClass.newInstance();
  41.  
  42.         Method setTargetMethod = findMethod(hookupClass, "setTarget");   
  43.         Object args[] = new Object[1];
  44.         args[0] = target;
  45.         setTargetMethod.invoke(hookup, args);
  46.  
  47.         sourceWrapper.addEventTarget(esd.getName(), targetWrapper, hookup);
  48.  
  49.     } catch (InvocationTargetException ex) {
  50.         System.err.println("Hookup caught exception on target: " + ex.getTargetException());
  51.         ex.getTargetException().printStackTrace();
  52.     } catch (Exception ex) {
  53.         System.err.println("Hookup caught: " + ex);
  54.         ex.printStackTrace();
  55.     }
  56.  
  57.     }
  58.  
  59.     static String[] getHookupFiles() {
  60.     String back[] = new String[javaFiles.size()];
  61.     Enumeration e = javaFiles.elements();
  62.     for (int i=0; e.hasMoreElements(); i++) {
  63.         back[i] = (String) e.nextElement();
  64.     }
  65.     return back;
  66.     }
  67.  
  68.     static String generateHookup(EventSetDescriptor esd, Method listenerMethod, Object source,
  69.         Object target, Method targetMethod) {
  70.  
  71.     String id = getId();
  72.     String className = "___Hookup_" + id;
  73.     String fileName = tmpDir + java.io.File.separator + className + ".java";
  74.     String targetType = target.getClass().getName();
  75.     Method methods[] = esd.getListenerMethods();
  76.  
  77.     // Create an appropriate subdirectory.
  78.     java.io.File tmp = new java.io.File(tmpDir);
  79.     tmp.mkdirs();
  80.  
  81.     // Open the new java source file,
  82.     java.io.PrintWriter out = null;
  83.     try {
  84.         java.io.FileWriter fout = new java.io.FileWriter(fileName);
  85.         out = new java.io.PrintWriter(fout);
  86.     } catch (Exception ex) {
  87.         System.err.println("Couldn't open hookup file " + fileName);
  88.         System.err.println("   " + ex);
  89.         return null;
  90.     }
  91.  
  92.     out.println("// Automatically generated event hookup file.");
  93.     out.println("");
  94.     out.println("package " + packageName + ";");
  95.  
  96.     // These imports are in case the target or listener types are
  97.     // in the default package.
  98.     out.println("import " + targetType + ";");
  99.     out.println("import " + esd.getListenerType().getName() + ";");
  100.  
  101.     // Now do any imports on argument types.
  102.     Hashtable argt = new Hashtable();
  103.     argt.put(targetType, argt);
  104.     argt.put(esd.getListenerType().getName(), argt);
  105.     for (int k = 0; k < methods.length; k++) {
  106.         Class argTypes[] = methods[k].getParameterTypes();
  107.         for (int i = 0; i < argTypes.length; i++) {
  108.         Class type = argTypes[i];
  109.         while (type.isArray()) {
  110.             type = type.getComponentType();
  111.         }
  112.         if (type.isPrimitive()) {
  113.             continue;
  114.         }
  115.         String typeName = type.getName();
  116.         if (argt.get(typeName) == null) {    
  117.             out.println("import " + typeName + ";");
  118.             argt.put(typeName, argt);
  119.         }
  120.         }
  121.     }
  122.     
  123.     
  124.     out.println("");
  125.     out.println("public class " + className + " implements " + 
  126.             esd.getListenerType().getName() + ", java.io.Serializable {");
  127.     out.println("");
  128.     out.println("    public void setTarget(" + targetType + " t) {");
  129.     out.println("        target = t;");
  130.     out.println("    }");
  131.  
  132.     for (int k = 0; k < methods.length; k++) {
  133.         out.println("");
  134.         out.print("    public void " + methods[k].getName() + "(");
  135.         Class argTypes[] = methods[k].getParameterTypes();
  136.         for (int i = 0; i < argTypes.length; i++) {
  137.             if (i > 0) {
  138.             out.print(", ");
  139.             }
  140.         // Figure out the string for the argument type.  We have
  141.         // have to treat array types specially.
  142.         Class type = argTypes[i];
  143.         String typeName = "";
  144.         while (type.isArray()) {
  145.             typeName = "[]" + typeName;
  146.             type = type.getComponentType();
  147.         }
  148.         typeName = type.getName() + typeName;
  149.  
  150.             out.print(typeName + " arg" + i);
  151.         }
  152.         out.print(")");
  153.         
  154.         /**
  155.              * At the moment getExceptionTypes fails to return the
  156.          * PropertyVetoException.  I've hacked around the problem.
  157.          */
  158.         /*
  159.          * Class[] exceptionTypes = methods[k].getExceptionTypes();
  160.          * if (exceptionTypes.length > 0) {
  161.          * out.print("\n         throws");
  162.          * for (int i = 0; i < exceptionTypes.length; i++)
  163.          *     out.print(((i != 0) ? ", " : " ") + exceptionTypes[i].getName());
  164.          * out.print(" ");
  165.          * }
  166.         */
  167.         if ("vetoableChange".equals(methods[k].getName())) {
  168.             out.print("     throws java.beans.PropertyVetoException");
  169.         }
  170.  
  171.         out.println(" {");
  172.         if (listenerMethod.getName() == methods[k].getName()) {
  173.             out.print("        target." + targetMethod.getName() + "(");
  174.         // Either the targetMethod must take zero args, or the
  175.         // same args as the listenerMethod.
  176.         if (targetMethod.getParameterTypes().length != 0) {
  177.                 for (int i = 0; i < argTypes.length; i++) {
  178.                     if (i > 0) {
  179.                     out.print(", ");
  180.                     }
  181.                     out.print("arg" + i);
  182.             }
  183.             }
  184.             out.println(");");
  185.             }
  186.         out.println("    }");
  187.     }
  188.     out.println("");
  189.     out.println("    private " + targetType + " target;");
  190.     out.println("}");
  191.     out.close();
  192.  
  193.     boolean ok = ClassCompiler.compile(fileName, pathFromLoadedJarFiles());    
  194.     if (!ok) {
  195.         return null;
  196.     }
  197.  
  198.     String fullClassName = packageName+"."+className;
  199.     String pathToFile = tmpDir+java.io.File.separatorChar+className+".class";
  200.     return pathToFile;
  201.     }
  202.  
  203.     /**
  204.      * A classpath corresponding to all the JAR files that have been
  205.      * loaded so far.
  206.      */
  207.  
  208.     static String pathFromLoadedJarFiles() {
  209.     String path = System.getProperty("java.class.path");
  210.     String sep = java.io.File.pathSeparator;
  211.     Vector allJI = BeanBoxFrame.getToolBox().getLoadedJarInfo();
  212.  
  213.     StringBuffer allJars = new StringBuffer(path);
  214.     Enumeration e = allJI.elements();
  215.     JarInfo prev = null;    // REMIND!! clean this up
  216.     while (e.hasMoreElements()) {
  217.         JarInfo ji = (JarInfo) e.nextElement();
  218.         if (ji == null) {
  219.         // the built-in BeanBox container
  220.         continue;
  221.         }
  222.         if (ji == prev) {
  223.         // we already dealt with this one
  224.         continue;
  225.         }
  226.         prev = ji;
  227.         allJars.append(sep);
  228.         allJars.append(ji.getJarName());
  229.     }
  230.     return allJars.toString();
  231.     }
  232.  
  233.     static String getId() {
  234.     java.util.Date now = new java.util.Date();
  235.     long id = now.getTime()/10;
  236.     return Long.toHexString(id);
  237.     }
  238.  
  239.     private static Method findMethod(Class cls, String methodName) {
  240.     try {
  241.             Method methods[] = cls.getMethods();
  242.         for (int i = 0; i < methods.length; i++) {
  243.             Method method = methods[i];
  244.             if (method.getName().equals(methodName)) {
  245.             return method;
  246.         }
  247.         }
  248.         throw new Error("method " + methodName + " not found");
  249.         } catch (Exception ex) {
  250.         throw new Error("findMethod caught : " + ex);
  251.         }
  252.     }
  253.  
  254.     static String shortPackageName = "sunw.beanbox";
  255.     static String shortTmpDir = BeanBoxFrame.getTmpDir();
  256.     static String packageName;
  257.     static String tmpDir;
  258.     static Vector javaFiles = new Vector();
  259.  
  260.     static {
  261.     packageName =
  262.         shortTmpDir.replace(java.io.File.separatorChar, '.')+"."+shortPackageName;
  263.     tmpDir = packageName.replace('.', java.io.File.separatorChar);
  264.     }
  265. }
  266.  
  267.