-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Applied.

Thanks,
Sanka

Kev Jackson wrote:
> Hi,
>
> Another one: - change style to Java style (braces, spacing general
> layout) - remove extra lines
>
> For this one the code makes use of a tempdir specified as "." -
> wouldn't it make sense to use java.io.tmpdir?  If the generated
> files were created in a subdirectory of the real tmpdir, then it
> would be possible to simply rmdir after instead of using the much
> more complicated Filter code.
>
> Kev
>
> ----------------------------------------------------------------------
>
>
> Index: .
> ===================================================================
>  --- .    (revision 438751) +++ .    (working copy) @@ -81,291 +81,272 @@
>  * <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; +    } }
>
>
> ----------------------------------------------------------------------
>
>
> ---------------------------------------------------------------------
>  To unsubscribe, e-mail: [EMAIL PROTECTED] For
> additional commands, e-mail: [EMAIL PROTECTED]


- --
Sanka Samaranayake
WSO2 Inc.
T:+94-77-3506382 F:+94-11-2424304

http://sankas.blogspot.com/
http://www.wso2.net/
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2.1 (GNU/Linux)

iD8DBQFE+dRq/Hd0ETKdgNIRAmjMAJ4kVRwsfhC64A4SiXo41uxoU5h7qQCfb3oB
+bnId39GGWmi/PkuW2lkgOY=
=6Ehm
-----END PGP SIGNATURE-----


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

Reply via email to