Author: sanka
Date: Sat Sep  2 11:13:30 2006
New Revision: 439627

URL: http://svn.apache.org/viewvc?rev=439627&view=rev
Log:
Applied the set of patches sent by Kev Jackson. Many thanks Kev ..

Modified:
    jakarta/bsf/trunk/build.xml
    jakarta/bsf/trunk/src/org/apache/bsf/BSFManager.java
    jakarta/bsf/trunk/src/org/apache/bsf/Main.java
    jakarta/bsf/trunk/src/org/apache/bsf/engines/java/JavaEngine.java

Modified: jakarta/bsf/trunk/build.xml
URL: 
http://svn.apache.org/viewvc/jakarta/bsf/trunk/build.xml?rev=439627&r1=439626&r2=439627&view=diff
==============================================================================
--- jakarta/bsf/trunk/build.xml (original)
+++ jakarta/bsf/trunk/build.xml Sat Sep  2 11:13:30 2006
@@ -62,7 +62,7 @@
        <!-- 
=================================================================== -->
        <patternset id="java.source.files">
                <!-- Optionally includes engines based on dependencies being 
present -->
-               <!-- FIXME: Exclude the first three, temporarily -->
+
 
                <include name="**/bsf/*.java" />
                <include name="**/util/**/*.java" />
@@ -179,7 +179,7 @@
                <antcall target="checkJython" />
                <antcall target="checkNetRexx" />
                <antcall target="checkRhino" />
-               <!--<echo message="Warning: Rhino dependencies were not 
resolved." unless="rhino.present"/>-->
+
                <antcall target="checkXalan" />
                <antcall target="checkJUnit" />
        </target>
@@ -196,9 +196,11 @@
                <mkdir dir="${build.dest}"/>
                <javac srcdir="${src.dir}" destdir="${build.dest}" 
debug="${project.debug}" deprecation="${project.deprecation}">
                        <classpath>
-                               <fileset dir="lib"><include 
name="*.jar"/></fileset>
+                               <fileset dir="lib">
+                                       <include name="*.jar"/>
+                               </fileset>
                        </classpath>
-                       <patternset refid="java.source.files"></patternset>     
                
+                       <patternset refid="java.source.files"/>
                </javac>
        </target>
 
@@ -252,11 +254,11 @@
                        <classpath refid="anakia.classpath" />
                </taskdef>
 
-               <anakia basedir="${site.src}" destdir="${site.dest}/" 
extension=".html" style="./site.vsl" projectFile="${site.projectFile}" 
excludes="**/stylesheets/** faq.xml" includes="**/*.xml" 
lastModifiedCheck="true" templatePath="${templ.path}" 
velocityPropertiesFile="${velocity.props}">
-               </anakia>
+               <anakia basedir="${site.src}" destdir="${site.dest}/" 
extension=".html" style="./site.vsl" projectFile="${site.projectFile}" 
excludes="**/stylesheets/** faq.xml" includes="**/*.xml" 
lastModifiedCheck="true" templatePath="${templ.path}" 
velocityPropertiesFile="${velocity.props}"/>
+
+
+               <anakia basedir="${site.src}" destdir="${site.dest}/" 
extension=".html" style="./faq.vsl" projectFile="${site.projectFile}" 
includes="faq.xml" lastModifiedCheck="true" templatePath="${templ.path}" 
velocityPropertiesFile="${velocity.props}"/>
 
-               <anakia basedir="${site.src}" destdir="${site.dest}/" 
extension=".html" style="./faq.vsl" projectFile="${site.projectFile}" 
includes="faq.xml" lastModifiedCheck="true" templatePath="${templ.path}" 
velocityPropertiesFile="${velocity.props}">
-               </anakia>
 
                <copy todir="${site.dest}/images" filtering="no">
                        <fileset dir="${site.src}/images">
@@ -370,4 +372,4 @@
        </target>
 
        <target name="all" depends="build-site, dist" />
-</project>
+</project>
\ No newline at end of file

Modified: jakarta/bsf/trunk/src/org/apache/bsf/BSFManager.java
URL: 
http://svn.apache.org/viewvc/jakarta/bsf/trunk/src/org/apache/bsf/BSFManager.java?rev=439627&r1=439626&r2=439627&view=diff
==============================================================================
--- jakarta/bsf/trunk/src/org/apache/bsf/BSFManager.java (original)
+++ jakarta/bsf/trunk/src/org/apache/bsf/BSFManager.java Sat Sep  2 11:13:30 
2006
@@ -25,6 +25,7 @@
 import java.security.PrivilegedExceptionAction;
 import java.util.Enumeration;
 import java.util.Hashtable;
+import java.util.Iterator;
 import java.util.MissingResourceException;
 import java.util.NoSuchElementException;
 import java.util.Properties;
@@ -114,16 +115,17 @@
                 Properties p = new Properties();
                 p.load(is);
 
-                Enumeration keys = p.propertyNames();
-                while (keys.hasMoreElements()) {
+                for (Enumeration keys = p.propertyNames(); 
keys.hasMoreElements();) {
+
                     String key = (String) keys.nextElement();
                     String value = p.getProperty(key);
+                    String className = value.substring(0, value.indexOf(","));
+
+
 
-                    StringTokenizer tokens = new StringTokenizer(value, ",");
-                    String className = (String) tokens.nextToken();
 
                     // get the extensions for this language
-                    String exts = (String) tokens.nextToken();
+                    String exts = value.substring(value.indexOf(",")+1, 
value.length());
                     StringTokenizer st = new StringTokenizer(exts, "|");
                     String[] extensions = new String[st.countTokens()];
                     for (int i = 0; st.hasMoreTokens(); i++) {
@@ -133,16 +135,16 @@
                     registerScriptingEngine(key, className, extensions);
                 }
             }
-        }
-        catch (IOException ex) {
+        } catch (IOException ex) {
+
             ex.printStackTrace();
             System.err.println("Error reading Languages file " + ex);
-        }
-        catch (NoSuchElementException nsee) {
+        } catch (NoSuchElementException nsee) {
+
             nsee.printStackTrace();
             System.err.println("Syntax error in Languages resource bundle");
-        }
-        catch (MissingResourceException mre) {
+        } catch (MissingResourceException mre) {
+
             mre.printStackTrace();
             System.err.println("Initialization error: " + mre.toString());
         }
@@ -163,8 +165,8 @@
          *      &quot;dd&quot; two digit day.
      * @since 2006-01-17
      */
-    public static String getVersion()
-    {
+    public static String getVersion() {
+
         return version;
     }
 
@@ -210,8 +212,8 @@
                         }
                     });
             result = resultf;
-        }
-        catch (PrivilegedActionException prive) {
+        } catch (PrivilegedActionException prive) {
+
                logger.error("Exception: ", prive);
             throw (BSFException) prive.getException();
         }
@@ -263,8 +265,8 @@
                         return null;
                     }
                 });
-        }
-        catch (PrivilegedActionException prive) {
+        } catch (PrivilegedActionException prive) {
+
                logger.error("Exception :", prive);
             throw (BSFException) prive.getException();
         }
@@ -306,8 +308,8 @@
                         return null;
                     }
                 });
-        }
-        catch (PrivilegedActionException prive) {
+        } catch (PrivilegedActionException prive) {
+
                logger.error("Exception :", prive);
             throw (BSFException) prive.getException();
         }
@@ -350,8 +352,8 @@
                         return null;
                     }
                 });
-        }
-        catch (PrivilegedActionException prive) {
+        } catch (PrivilegedActionException prive) {
+
                logger.error("Exception :", prive);
             throw (BSFException) prive.getException();
         }
@@ -439,8 +441,8 @@
                         }
                     });
             result = resultf;
-        }
-        catch (PrivilegedActionException prive) {
+        } catch (PrivilegedActionException prive) {
+
                logger.error("Exception: ", prive);
             throw (BSFException) prive.getException();
         }
@@ -487,8 +489,8 @@
                         return null;
                     }
                 });
-        }
-        catch (PrivilegedActionException prive) {
+        } catch (PrivilegedActionException prive) {
+
                logger.error("Exception :", prive);
             throw (BSFException) prive.getException();
         }
@@ -527,8 +529,8 @@
                         return null;
                     }
                 });
-        }
-        catch (PrivilegedActionException prive) {
+        } catch (PrivilegedActionException prive) {
+
                logger.error("Exception :", prive);
             throw (BSFException) prive.getException();
         }
@@ -550,8 +552,8 @@
         if (classPath == null) {
             try {
                 classPath = System.getProperty("java.class.path");
-            }
-            catch (Throwable t) {
+            } catch (Throwable t) {
+
                logger.debug("Exception :", t);
                 // prolly a security exception .. so no can do
             }
@@ -577,8 +579,9 @@
 
         if (dotIndex != -1) {
             String extn = fileName.substring(dotIndex + 1);
-            String langval = (String) extn2Lang.get(extn), lang = null;
-            int index = 0, loops = 0;
+            String langval = (String) extn2Lang.get(extn);
+            String lang = null;
+            int index, loops = 0;
 
             if (langval != null) {
                 while ((index = langval.indexOf(":", 0)) != -1) {
@@ -594,8 +597,8 @@
                         String engineName =
                             (String) registeredEngines.get(lang);
                         Class.forName(engineName);
-                    }
-                    catch (ClassNotFoundException cnfe) {
+                    } catch (ClassNotFoundException cnfe) {
+
                         // Bummer.
                         lang = langval;
                         continue;
@@ -604,7 +607,7 @@
                     // Got past that? Good.
                     break;
                 }
-                if (loops == 0) lang = langval;
+                if (loops == 0) { lang = langval; }
             }
 
             if (lang != null && lang != "") {
@@ -700,12 +703,12 @@
             loadedEngines.put(lang, eng);
             pcs.addPropertyChangeListener(eng);
             return eng;
-        }
-        catch (PrivilegedActionException prive) {
+        } catch (PrivilegedActionException prive) {
+
                    logger.error("Exception :", prive);
                 throw (BSFException) prive.getException();
-        }
-        catch (Throwable t) {
+        } catch (Throwable t) {
+
                logger.error("Exception :", t);
             throw new BSFException(BSFException.REASON_OTHER_ERROR,
                                    "unable to load language: " + lang,
@@ -726,8 +729,8 @@
 
         try {
             return ((BSFDeclaredBean)objectRegistry.lookup(beanName)).bean;
-        }
-        catch (IllegalArgumentException e) {
+        } catch (IllegalArgumentException e) {
+
                logger.debug("Exception :", e);
             return null;
         }
@@ -747,8 +750,8 @@
 
         if(bean == null) {
             tempBean = new BSFDeclaredBean(beanName, null, null);
-        }
-        else {
+        } else {
+
             tempBean = new BSFDeclaredBean(beanName, bean, bean.getClass());
         }
         objectRegistry.register(beanName, tempBean);
@@ -871,8 +874,8 @@
 
         BSFDeclaredBean tempBean = null;
         boolean found = false;
-        for (int i = 0; i < declaredBeans.size(); i++) {
-            tempBean = (BSFDeclaredBean) declaredBeans.elementAt(i);
+        for (Iterator i = declaredBeans.iterator(); i.hasNext();) {
+            tempBean = (BSFDeclaredBean) i.next();
             if (tempBean.name.equals(beanName)) {
                found = true;
                 break;
@@ -900,4 +903,4 @@
 
         objectRegistry.unregister(beanName);
     }
-}
+}
\ No newline at end of file

Modified: jakarta/bsf/trunk/src/org/apache/bsf/Main.java
URL: 
http://svn.apache.org/viewvc/jakarta/bsf/trunk/src/org/apache/bsf/Main.java?rev=439627&r1=439626&r2=439627&view=diff
==============================================================================
--- jakarta/bsf/trunk/src/org/apache/bsf/Main.java (original)
+++ jakarta/bsf/trunk/src/org/apache/bsf/Main.java Sat Sep  2 11:13:30 2006
@@ -92,7 +92,7 @@
                                in = new FileReader(inFileName);
                        } else {
                                in = new InputStreamReader(System.in);
-                               inFileName = "<STDIN>";
+                               inFileName = DEFAULT_IN_FILE_NAME;
                        }
 
                        BSFManager mgr = new BSFManager();
@@ -114,45 +114,47 @@
                                        cb);
                                cb.print(pw, true);
                                out.close();
-                       } else
+                       } else {
                                if (mode.equals(ARG_VAL_EXEC)) {
                                        mgr.exec(language, inFileName, 0, 0, 
IOUtils.getStringFromReader(in));
-                               } else /* eval */ {
-                                       Object obj =
-                                            mgr.eval(language, inFileName, 0, 
0, IOUtils.getStringFromReader(in));
-                                        
+                               } else { /* eval */
+                                       Object obj = mgr.eval(language, 
inFileName, 0, 0, IOUtils.getStringFromReader(in));
+
+
                                        // Try to display the result.
-                                        
+
                                        if (obj instanceof java.awt.Component) {
-                                            Frame f;
-                                            
-                                            if (obj instanceof Frame) {
-                                               f = (Frame) obj;
-                                            } else {
-                                               f = new Frame ("BSF Result: " + 
inFileName);
-                                               f.add ((java.awt.Component) 
obj);
-                                            }
-                                            
-                                            // Add a window listener to quit 
on closing.
-                                            f.addWindowListener(
-                                                                new 
WindowAdapter () {
-                                                                    public 
void windowClosing (WindowEvent e) {
-                                                                        
System.exit (0);
-                                                                    }
-                                                                });
-                                            f.pack ();
-                                            f.show ();
+                                           Frame f;
+                        if (obj instanceof Frame) {
+                            f = (Frame) obj;
+                        } else {
+                            f = new Frame ("BSF Result: " + inFileName);
+                            f.add ((java.awt.Component) obj);
+                        }
+                        // Add a window listener to quit on closing.
+                        f.addWindowListener(
+                                new WindowAdapter () {
+                                    public void windowClosing (WindowEvent e) {
+                                        System.exit (0);
+                                    }
+                                }
+                        );
+                        f.pack ();
+                        f.show ();
+
                                        } else {
-                                            System.err.println("Result: " + 
-                                                               obj);
+                        System.err.println("Result: " + obj);
+
                                        }
-                                        
+
                                        System.err.println("Result: " + obj);
                                }
+            }
                } catch (BSFException e) {
-                    e.printStackTrace();
+                   e.printStackTrace();
                }
        }
+    
        private static void printHelp() {
                System.err.println("Usage:");
                System.err.println();
@@ -183,4 +185,4 @@
                System.err.println(
                        "      [-out              className]   default: " + 
DEFAULT_CLASS_NAME);
        }
-}
+}
\ No newline at end of file

Modified: jakarta/bsf/trunk/src/org/apache/bsf/engines/java/JavaEngine.java
URL: 
http://svn.apache.org/viewvc/jakarta/bsf/trunk/src/org/apache/bsf/engines/java/JavaEngine.java?rev=439627&r1=439626&r2=439627&view=diff
==============================================================================
--- jakarta/bsf/trunk/src/org/apache/bsf/engines/java/JavaEngine.java (original)
+++ jakarta/bsf/trunk/src/org/apache/bsf/engines/java/JavaEngine.java Sat Sep  
2 11:13:30 2006
@@ -81,291 +81,271 @@
  * <p>
  * @author Joe Kesselman
  */
-public class JavaEngine extends BSFEngineImpl
-{
-  Class javaclass=null;
-  static Hashtable codeToClass=new Hashtable();
-  static String serializeCompilation="";
-  static String placeholder="$$CLASSNAME$$";
-  String minorPrefix;
-  
-  private Log logger = LogFactory.getLog(this.getClass().getName());
-
-  /**
-   * Create a scratchfile, open it for writing, return its name.
-   * Relies on the filesystem to provide us with uniqueness testing.
-   * NOTE THAT uniqueFileOffset continues to count; we don't want to
-   * risk reusing a classname we have previously loaded in this session
-   * even if the classfile has been deleted.
-   */
-  private int uniqueFileOffset=-1;
-  private class GeneratedFile 
-  {
-       File file=null;
-       FileOutputStream fos=null;
-       String className=null;
-       GeneratedFile(File file,FileOutputStream fos,String className) 
-       {
-         this.file=file;
-         this.fos=fos;
-         this.className=className;
-       }
-  }
-  /**
-   * Constructor.
-   */
-  public JavaEngine ()
-  {
-       // Do compilation-possible check here??????????????
-  }
-  public Object call (Object object, String method, Object[] args) 
-          throws BSFException
-  {
-       throw new BSFException (BSFException.REASON_UNSUPPORTED_FEATURE,
-                           "call() is not currently supported by JavaEngine");
-  }
-  public void compileScript (String source, int lineNo, int columnNo,
-                 Object script, CodeBuffer cb) throws BSFException {
-       ObjInfo oldRet = cb.getFinalServiceMethodStatement ();
-
-       if (oldRet != null && oldRet.isExecutable ()) {
-         cb.addServiceMethodStatement (oldRet.objName + ";");
-       }
-
-       cb.addServiceMethodStatement (script.toString ());
-       cb.setFinalServiceMethodStatement (null);
-  }
-  /**
-   * This is used by an application to evaluate a string containing
-   * some expression. It should store the "bsf" handle where the
-   * script can get to it, for callback purposes.
-   * <p>
-   * Note that Java compilation imposes serious overhead,
-   * but in exchange you get full Java performance
-   * once the classes have been created (minus the cache lookup cost).
-   * <p>
-   * Nobody knows whether javac is threadsafe.
-   * I'm going to serialize access to protect it.
-   * <p>
-   * There is no published API for invoking javac as a class. There's a trick
-   * that seems to work for Java 1.1.x, but it stopped working in Java 1.2.
-   * We will attempt to use it, then if necessary fall back on invoking
-   * javac via the command line.
-   */
-  public Object eval (String source, int lineNo, int columnNo, 
-                     Object oscript) throws BSFException
-  {
-       Object retval=null;
-       String classname=null;
-       GeneratedFile gf=null;
-
-       String basescript=oscript.toString();
-       String script=basescript;       // May be altered by $$CLASSNAME$$ 
expansion
-
-       try {
-         // Do we already have a class exactly matching this code?
-         javaclass=(Class)codeToClass.get(basescript);
-         
-         if(javaclass!=null)
-       {
-         classname=javaclass.getName();
-       }
-         else
-       {
-         gf=openUniqueFile(tempDir, "BSFJava",".java");
-         if(gf==null)
-           throw new BSFException("couldn't create JavaEngine scratchfile");
-         
-         // Obtain classname
-         classname=gf.className;
-
-         // Write the kluge header to the file.
-         gf.fos.write(("import java.lang.*;"+
-                       "import java.util.*;"+
-                       "public class "+classname+" {\n" +
-                                               "  static public Object 
BSFJavaEngineEntry(org.apache.bsf.BSFManager bsf) {\n")
-                      .getBytes());
-
-         // Edit the script to replace placeholder with the generated
-         // classname. Note that this occurs _after_ the cache was checked!
-         int startpoint,endpoint;
-         if((startpoint=script.indexOf(placeholder))>=0)
-           {
-             StringBuffer changed=new StringBuffer();
-             for(;
-                 startpoint>=0;
-                 startpoint=script.indexOf(placeholder,startpoint))
-               {
-                 changed.setLength(0); // Reset for 2nd pass or later
-                 if(startpoint>0)
-                   changed.append(script.substring(0,startpoint));
-                 changed.append(classname);
-                 endpoint=startpoint+placeholder.length();
-                 if(endpoint<script.length())
-                   changed.append(script.substring(endpoint));
-                 script=changed.toString();
-               }
-           }
-
-         // MJD - debug
-//    BSFDeclaredBean tempBean;
-//    String          className;
-//
-//    for (int i = 0; i < declaredBeans.size (); i++) {
-//      tempBean  = (BSFDeclaredBean) declaredBeans.elementAt (i);
-//      className = StringUtils.getClassName (tempBean.bean.getClass ());
-//
-//      gf.fos.write ((className + " " +
-//                     tempBean.name + " = (" + className +
-//                     ")bsf.lookupBean(\"" +
-//                     tempBean.name + "\");").getBytes ());
-//    }
-       // MJD - debug
-
-       // Copy the input to the file.
-         // Assumes all available -- probably mistake, but same as other 
engines.
-         gf.fos.write(script.getBytes());
-         // Close the method and class
-         gf.fos.write(("\n  }\n}\n").getBytes());
-         gf.fos.close();
-         
-         // Compile through Java to .class file
-         // May not be threadsafe. Serialize access on static object:
-         synchronized(serializeCompilation)
-           {
-             JavaUtils.JDKcompile(gf.file.getPath(), classPath);
-           }
-         
-         // Load class.
-         javaclass=EngineUtils.loadClass (mgr, classname);
-
-         // Stash class for reuse
-         codeToClass.put(basescript,javaclass);
-       }
-         
-         Object[] callArgs={mgr};      
-         retval=internal_call(this,"BSFJavaEngineEntry",callArgs);
-       }
-       
-       
-       catch(Exception e)
-         {
-       e.printStackTrace ();
-       throw new BSFException (BSFException.REASON_IO_ERROR, e.getMessage ());
-         }
-       finally
-         {
-       // Cleanup: delete the .java and .class files
-
-//  if(gf!=null && gf.file!=null && gf.file.exists())
-//    gf.file.delete();  // .java file
-
-
-  if(classname!=null)
-       {
-         // Generated class
-         File file=new File(tempDir+File.separatorChar+classname+".class");
-//      if(file.exists())
-//        file.delete();
-
-         // Search for and clean up minor classes, classname$xxx.class
-         file=new File(tempDir);  // ***** Is this required?
-         minorPrefix=classname+"$"; // Indirect arg to filter
-         String[] minor_classfiles=
-               file.list(new FilenameFilter()
-         {
-               // Starts with classname$ and ends with .class
-               public boolean accept(File dir,String name)
-                 {
-                       return
-               (0==name.indexOf(minorPrefix))
-               &&
-               (name.lastIndexOf(".class")==name.length()-6)
-               ;
-                 }
-         });
-         for(int i=0;i<minor_classfiles.length;++i)
-               {
-       file=new File(minor_classfiles[i]);
-//    file.delete();
-               }
-       }
-         }
-
-       return retval;
-  }
-  public void initialize (BSFManager mgr, String lang,
-                                                 Vector declaredBeans) throws 
BSFException {
-       super.initialize (mgr, lang, declaredBeans);
-  }
-  /**
-   * Return an object from an extension.
-   * @param object Object on which to make the internal_call (ignored).
-   * @param method The name of the method to internal_call.
-   * @param args an array of arguments to be
-   * passed to the extension, which may be either
-   * Vectors of Nodes, or Strings.
-   */
-  Object internal_call (Object object, String method, Object[] args) 
-                                                                               
                                  throws BSFException
-  {
-       //***** ISSUE: Only static methods are currently supported
-       Object retval=null;
-       try
-         {
-       if(javaclass!=null)
-         {
-           //***** This should call the lookup used in BML, for typesafety
-           Class[] argtypes=new Class[args.length];
-           for(int i=0;i<args.length;++i)
-             argtypes[i]=args[i].getClass();
-           
-           Method m=MethodUtils.getMethod(javaclass,method,argtypes);
-           retval=m.invoke(null,args);
-         }
-         }
-       catch(Exception e)
-         {
-       throw new BSFException (BSFException.REASON_IO_ERROR, e.getMessage ());
-         }
-       return retval;
-  }
-  private GeneratedFile openUniqueFile(String directory,String prefix,String 
suffix)
-  {
-       File file=null;
-       FileOutputStream fos=null;
-       int max=1000;           // Don't try forever
-       GeneratedFile gf=null;
-       int i;
-       String className = null;
-       for(i=max,++uniqueFileOffset;
-       fos==null && i>0;
-       --i,++uniqueFileOffset) 
-         {
-       // Probably a timing hazard here... ***************
-       try
-         {
-           className = prefix+uniqueFileOffset;
-           file=new File(directory+File.separatorChar+className+suffix);
-           if(file!=null && !file.exists())
-             fos=new FileOutputStream(file);
-         }
-       catch(Exception e)
-         {
-           // File could not be opened for write, or Security Exception
-           // was thrown. If someone else created the file before we could
-           // open it, that's probably a threading conflict and we don't
-           // bother reporting it.
-           if(!file.exists())
-             {
-               logger.error("openUniqueFile: unexpected ", e);
-             }
-         }
-         }
-       if(fos==null)
-               logger.error("openUniqueFile: Failed "+max+"attempts.");
-       else
-         gf=new GeneratedFile(file,fos,className);
-       return gf;
-  }
-}
+public class JavaEngine extends BSFEngineImpl {
+    Class javaclass = null;
+    static Hashtable codeToClass = new Hashtable();
+    static String serializeCompilation = "";
+    static String placeholder = "$$CLASSNAME$$";
+    String minorPrefix;
+        
+    private Log logger = LogFactory.getLog(this.getClass().getName());
+    
+    /**
+     * Create a scratchfile, open it for writing, return its name.
+     * Relies on the filesystem to provide us with uniqueness testing.
+     * NOTE THAT uniqueFileOffset continues to count; we don't want to
+     * risk reusing a classname we have previously loaded in this session
+     * even if the classfile has been deleted.
+     */
+    private int uniqueFileOffset = -1;
+    
+    private class GeneratedFile {
+        File file = null;
+        FileOutputStream fos = null;
+        String className = null;
+        GeneratedFile(File file, FileOutputStream fos, String className) {
+            this.file = file;
+            this.fos = fos;
+            this.className = className;
+        }
+    }
+    
+    /**
+     * Constructor.
+     */
+    public JavaEngine () {
+        // Do compilation-possible check here??????????????
+    }
+    
+    public Object call (Object object, String method, Object[] args) 
+    throws BSFException
+    {
+        throw new BSFException (BSFException.REASON_UNSUPPORTED_FEATURE,
+        "call() is not currently supported by JavaEngine");
+    }
+    
+    public void compileScript (String source, int lineNo, int columnNo,
+            Object script, CodeBuffer cb) throws BSFException {
+        ObjInfo oldRet = cb.getFinalServiceMethodStatement ();
+        
+        if (oldRet != null && oldRet.isExecutable ()) {
+            cb.addServiceMethodStatement (oldRet.objName + ";");
+        }
+        
+        cb.addServiceMethodStatement (script.toString ());
+        cb.setFinalServiceMethodStatement (null);
+    }
+    
+    /**
+     * This is used by an application to evaluate a string containing
+     * some expression. It should store the "bsf" handle where the
+     * script can get to it, for callback purposes.
+     * <p>
+     * Note that Java compilation imposes serious overhead,
+     * but in exchange you get full Java performance
+     * once the classes have been created (minus the cache lookup cost).
+     * <p>
+     * Nobody knows whether javac is threadsafe.
+     * I'm going to serialize access to protect it.
+     * <p>
+     * There is no published API for invoking javac as a class. There's a trick
+     * that seems to work for Java 1.1.x, but it stopped working in Java 1.2.
+     * We will attempt to use it, then if necessary fall back on invoking
+     * javac via the command line.
+     */
+    public Object eval (String source, int lineNo, int columnNo, 
+            Object oscript) throws BSFException
+            {
+        Object retval = null;
+        String classname = null;
+        GeneratedFile gf = null;
+        
+        String basescript = oscript.toString();
+        String script = basescript;    // May be altered by $$CLASSNAME$$ 
expansion
+        
+        try {
+            // Do we already have a class exactly matching this code?
+            javaclass = (Class)codeToClass.get(basescript);
+            
+            if(javaclass != null) {
+                classname=javaclass.getName();
+            } else {
+                gf = openUniqueFile(tempDir, "BSFJava",".java");
+                if( gf == null) {
+                    throw new BSFException("couldn't create JavaEngine 
scratchfile");
+                }
+                // Obtain classname
+                classname = gf.className;
+                
+                // Write the kluge header to the file.
+                gf.fos.write(("import java.lang.*;"+
+                        "import java.util.*;"+
+                        "public class "+classname+" {\n" +
+                "  static public Object 
BSFJavaEngineEntry(org.apache.bsf.BSFManager bsf) {\n")
+                .getBytes());
+                
+                // Edit the script to replace placeholder with the generated
+                // classname. Note that this occurs _after_ the cache was 
checked!
+                int startpoint = script.indexOf(placeholder);
+                int endpoint;
+                if(startpoint >= 0) {
+                    StringBuffer changed = new StringBuffer();
+                    for(; startpoint >=0; startpoint = 
script.indexOf(placeholder,startpoint)) {
+                        changed.setLength(0);  // Reset for 2nd pass or later
+                        if(startpoint > 0) {
+                            changed.append(script.substring(0,startpoint));
+                        }
+                        changed.append(classname);
+                        endpoint = startpoint+placeholder.length();
+                        if(endpoint < script.length()) {
+                            changed.append(script.substring(endpoint));
+                        }
+                        script = changed.toString();
+                    }
+                }
+                
+                // MJD - debug
+//              BSFDeclaredBean tempBean;
+//              String          className;
+//              
+//              for (int i = 0; i < declaredBeans.size (); i++) {
+//              tempBean  = (BSFDeclaredBean) declaredBeans.elementAt (i);
+//              className = StringUtils.getClassName (tempBean.bean.getClass 
());
+//              
+//              gf.fos.write ((className + " " +
+//              tempBean.name + " = (" + className +
+//              ")bsf.lookupBean(\"" +
+//              tempBean.name + "\");").getBytes ());
+//              }
+                // MJD - debug
+                
+                // Copy the input to the file.
+                // Assumes all available -- probably mistake, but same as 
other engines.
+                gf.fos.write(script.getBytes());
+                // Close the method and class
+                gf.fos.write(("\n  }\n}\n").getBytes());
+                gf.fos.close();
+                
+                // Compile through Java to .class file
+                // May not be threadsafe. Serialize access on static object:
+                synchronized(serializeCompilation) {
+                    JavaUtils.JDKcompile(gf.file.getPath(), classPath);
+                }
+                
+                // Load class.
+                javaclass = EngineUtils.loadClass(mgr, classname);
+                
+                // Stash class for reuse
+                codeToClass.put(basescript, javaclass);
+            }
+            
+            Object[] callArgs = {mgr};      
+            retval = internalCall(this,"BSFJavaEngineEntry",callArgs);
+        }
+        
+        
+        catch(Exception e) {
+            e.printStackTrace ();
+            throw new BSFException (BSFException.REASON_IO_ERROR, e.getMessage 
());
+        } finally {
+            // Cleanup: delete the .java and .class files
+            
+//          if(gf!=null && gf.file!=null && gf.file.exists())
+//          gf.file.delete();  // .java file
+            
+            
+            if(classname!=null) {
+                // Generated class
+                File file = new 
File(tempDir+File.separatorChar+classname+".class");
+//              if(file.exists())
+//              file.delete();
+                
+                // Search for and clean up minor classes, classname$xxx.class
+                file = new File(tempDir);  // ***** Is this required?
+                minorPrefix = classname+"$"; // Indirect arg to filter
+                String[] minorClassfiles = file.list(new FilenameFilter()
+                            {
+                        // Starts with classname$ and ends with .class
+                        public boolean accept(File dir,String name) {
+                            return
+                            (0 == name.indexOf(minorPrefix))
+                            &&
+                            (name.lastIndexOf(".class") == name.length()-6);
+                        }
+                            });
+                for(int i = 0; i < minorClassfiles.length; ++i) {
+                    file = new File(minorClassfiles[i]);
+//                  file.delete();
+                }
+            }
+        }
+        return retval;
+    }
+    
+    public void initialize (BSFManager mgr, String lang,
+            Vector declaredBeans) throws BSFException {
+        super.initialize (mgr, lang, declaredBeans);
+    }
+    /**
+     * Return an object from an extension.
+     * @param object Object on which to make the internal_call (ignored).
+     * @param method The name of the method to internal_call.
+     * @param args an array of arguments to be
+     * passed to the extension, which may be either
+     * Vectors of Nodes, or Strings.
+     */
+    Object internalCall (Object object, String method, Object[] args) 
+    throws BSFException
+    {
+        //***** ISSUE: Only static methods are currently supported
+        Object retval = null;
+        try {
+            if(javaclass != null) {
+                //***** This should call the lookup used in BML, for typesafety
+                Class[] argtypes = new Class[args.length];
+                for(int i=0; i<args.length; ++i) {
+                    argtypes[i]=args[i].getClass();
+                }
+                Method m = MethodUtils.getMethod(javaclass, method, argtypes);
+                retval = m.invoke(null, args);
+            }
+        }
+        catch(Exception e) {
+            throw new BSFException (BSFException.REASON_IO_ERROR, e.getMessage 
());
+        }
+        return retval;
+    }
+    
+    private GeneratedFile openUniqueFile(String directory,String prefix,String 
suffix) {
+        File file = null;
+        FileOutputStream fos = null;
+        int max = 1000;                // Don't try forever
+        GeneratedFile gf = null;
+        int i;
+        String className = null;
+        for(i=max,++uniqueFileOffset; fos==null && i>0;--i,++uniqueFileOffset) 
{
+            // Probably a timing hazard here... ***************
+            try {
+                className = prefix+uniqueFileOffset;
+                file = new File(directory+File.separatorChar+className+suffix);
+                if(file != null && !file.exists()) {
+                    fos = new FileOutputStream(file);
+                }
+            }
+            catch(Exception e) {
+                // File could not be opened for write, or Security Exception
+                // was thrown. If someone else created the file before we could
+                // open it, that's probably a threading conflict and we don't
+                // bother reporting it.
+                if(!file.exists()) {
+                    logger.error("openUniqueFile: unexpected ", e);
+                }
+            }
+        }
+        if(fos==null) {
+            logger.error("openUniqueFile: Failed "+max+"attempts.");
+        } else {
+            gf = new GeneratedFile(file,fos,className);
+        }
+        return gf;
+    }
\ No newline at end of file



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to