Java.java
Go to the documentation of this file.
00001 package com.rosalfred.core.ia.rivescript.lang;
00002 
00003 import java.util.ArrayList;
00004 import java.util.Arrays;
00005 import java.util.List;
00006 
00007 import javax.tools.JavaCompiler;
00008 import javax.tools.JavaFileManager;
00009 import javax.tools.JavaFileObject;
00010 import javax.tools.ToolProvider;
00011 
00012 import com.google.common.base.Strings;
00013 import com.rosalfred.core.ia.rivescript.RiveScript;
00014 import com.rosalfred.core.ia.rivescript.lang.java.CharSequenceJavaFileObject;
00015 import com.rosalfred.core.ia.rivescript.lang.java.ClassFileManager;
00016 import com.rosalfred.core.ia.rivescript.lang.java.JavaHandler;
00017 import com.rosalfred.core.ia.rivescript.lang.java.RunRiver;
00018 
00019 public class Java extends JavaHandler {
00020 
00021     private JavaCompiler compiler;
00022     private JavaFileManager fileManager;
00023 
00024     private String classpath;
00025     private String classname;
00026 
00027     public Java(RiveScript rs) {
00028         this(rs, null);
00029     }
00030 
00031     public Java(RiveScript rs, String classpath) {
00032         super(rs);
00033 
00034         this.classpath = classpath;
00035 
00036         // We get an instance of JavaCompiler.
00037         this.compiler = ToolProvider.getSystemJavaCompiler();
00038 
00039         // We create a file manager
00040         // (our custom implementation of it)
00041         this.fileManager = new
00042                 ClassFileManager(
00043                         this.compiler.getStandardFileManager(null, null, null));
00044 
00045     }
00046 
00047     @Override
00048     public boolean onLoad(String name, String[] code) {
00049         StringBuilder src = new StringBuilder();
00050 
00051         this.loadFromRive(name, code, src);
00052 
00053         // Dynamic compiling requires specifying
00054         // a list of "files" to compile. In our case
00055         // this is a list containing one "file" which is in our case
00056         // our own implementation (see details below)
00057         CharSequenceJavaFileObject javafile =
00058                         new CharSequenceJavaFileObject(name, src);
00059         List<JavaFileObject> jfiles = new ArrayList<JavaFileObject>();
00060         jfiles.add(javafile);
00061 
00062         List<String> optionList = null;
00063 
00064         if (this.classpath != null) {
00065             optionList = new ArrayList<String>();
00066             // set compiler's classpath to be same as the runtime's
00067             optionList.addAll(Arrays.asList("-classpath",
00068                      System.getProperty("java.class.path") + ":" + classpath));
00069         }
00070 
00071         // We specify a task to the compiler. Compiler should use our file
00072         // manager and our list of "files".
00073         // Then we run the compilation with call()
00074         this.compiler.getTask(null, this.fileManager, null, optionList,
00075                 null, jfiles).call();
00076 
00077         this.classname = javafile.getQualifiedName();
00078 
00079         return false;
00080     }
00081 
00082     public String getLastCompiledClassName() {
00083         return classname;
00084     }
00085 
00091     private void loadFromRive(String name, String[] code, StringBuilder src) {
00092         StringBuilder srcInner = new StringBuilder();
00093         StringBuilder srcImport = new StringBuilder();
00094         StringBuilder srcfinal = new StringBuilder();
00095         String cdLast = "";
00096         boolean isInner = true;
00097 
00098         for (String cd : code) {
00099             cdLast = cd;
00100 
00101             if (cd.startsWith("public")) {
00102                 isInner = false;
00103             }
00104 
00105             if (cd.startsWith("import")) {
00106                 srcImport.append(cd);
00107             } else {
00108                 srcInner.append(cd);
00109             }
00110 
00111             srcfinal.append(cd + "\n");
00112         }
00113 
00114         if (isInner) {
00115             // Append import package
00116             if (srcImport.length() > 0) {
00117                 src.append("\n" + srcImport + "\n\n");
00118             }
00119 
00120             src.append("\nimport " + RiveScript.class.getName() + ";\n" +
00121                     "import " + RunRiver.class.getName() + ";\n");
00122 
00123             // Append inner code
00124             src.append("public class " + name +
00125                     " implements " + RunRiver.class.getSimpleName() + " {\n\n");
00126             src.append("    @Override\n");
00127             src.append("    public String invoke(" +
00128                     RiveScript.class.getSimpleName() +
00129                     " rs, String user, String[] args) {\n\n");
00130 
00131             // Append inner code
00132             src.append("        " + srcInner + "\n");
00133 
00134             // Check if return exist
00135             if (!Strings.isNullOrEmpty(cdLast) && !cdLast.contains("return"))
00136                 src.append("\n    return \"\";\n");
00137 
00138             src.append("    }\n");
00139             src.append("}\n");
00140         } else {
00141             src.append(srcfinal);
00142         }
00143     }
00144 
00145     @Override
00146     protected ClassLoader getClassLoader() {
00147         return this.fileManager.getClassLoader(null);
00148     }
00149 }


alfred_bot
Author(s): Mickael Gaillard , Erwan Le Huitouze
autogenerated on Tue Jun 14 2016 01:34:50