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
00037 this.compiler = ToolProvider.getSystemJavaCompiler();
00038
00039
00040
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
00054
00055
00056
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
00067 optionList.addAll(Arrays.asList("-classpath",
00068 System.getProperty("java.class.path") + ":" + classpath));
00069 }
00070
00071
00072
00073
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
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
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
00132 src.append(" " + srcInner + "\n");
00133
00134
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 }