您的位置:首页 > 编程语言 > Java开发

动态编译,远端调用Windchill方法

2015-06-09 14:17 821 查看
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.net.URI;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.tools.Diagnostic;
import javax.tools.DiagnosticCollector;
import javax.tools.FileObject;
import javax.tools.ForwardingJavaFileManager;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;

import org.apache.log4j.Logger;
import org.json.JSONArray;

import wt.method.RemoteAccess;
import wt.method.RemoteMethodServer;

/**
* 动态编译测试类.
* @author wb_lixiang
* @version V1.0
*/
public class RemoteComplieUtil implements RemoteAccess{

private static Logger log = Logger.getLogger(RemoteComplieUtil.class);

public static Object test(HttpServletRequest request) throws Exception {

String classContent = StringUtil.notNull(request.getParameter("classContent"));
String className = StringUtil.notNull(request.getParameter("className"));
String methodName = StringUtil.notNull(request.getParameter("methodName"));
String params = StringUtil.notNull(request.getParameter("params"));
return remoteTest(classContent, className, methodName, params);
}

/**
* 这里用一句话描述这个类的作用,简述.
* <p>
* 详细说明
* <p>
* @param classContent
* @param className
* @param methodName
* @param params
* @return Object
* @throws Exception
*/
public static Object remoteTest(String classContent, String className, String methodName, String params)
throws Exception {

if (!RemoteMethodServer.ServerFlag) {
RemoteMethodServer r = RemoteMethodServer.getDefault();
Class[] cls = new Class[] {String.class, String.class, String.class, String.class};
Object[] obj = new Object[] {classContent, className, methodName, params};
Object result = r.invoke("remoteTest", "ext.higer.util.RemoteComplieUtil", null, cls, obj);
return result;
} else {
return (new RemoteComplieUtil()).doTest(classContent, className, methodName, params);
}
}

public Object doTest(String classContent, String className, String methodName, String params) {

Class instanceClass = null;
Object resultObj = null;
if (!"".equals(classContent)) {
try {
DynamicEngine de = new DynamicEngine();
instanceClass = de.javaCodeToClass(className, classContent);
} catch (Exception e) {
e.printStackTrace();
log.error("", e);
return e;
}
}
if ("".equals(className) || "".equals(methodName)) {

} else {
try {
Class[] classes = null;
Object[] objs = null;
ArrayList<Class> classesArray = new ArrayList<Class>();
ArrayList objsArray = new ArrayList();
try {
JSONArray paramArrayJson = new JSONArray(params);
if (paramArrayJson.length() > 0) {
for (int i = 0; i < paramArrayJson.length(); i++) {

String paramClassName = StringUtil.notNull(paramArrayJson.getJSONObject(i).getString("className"));
if (paramClassName.endsWith("[]")) {
paramClassName = paramClassName.substring(0, paramClassName.indexOf("[]"));
Class paramClass = Class.forName(paramClassName);
classesArray.add(Array.newInstance(paramClass, 1).getClass());
JSONArray o = (JSONArray) paramArrayJson.getJSONObject(i).get("value");
Object oo = Array.newInstance(paramClass, o.length());
for (int j = 0; j < o.length(); j++) {
Array.set(oo, j, o.get(j));
}
objsArray.add(oo);
} else {
classesArray.add(Class.forName(paramClassName));
objsArray.add(paramArrayJson.getJSONObject(i).get("value"));
}

}
}
} catch (Exception e) {
e.printStackTrace();
log.error("", e);
}
if (classesArray.size() > 0) {
classes = new Class[classesArray.size()];
for (int i = 0; i < classesArray.size(); i++) {
classes[i] = classesArray.get(i);
}
} else {
classes = new Class[] {};
}
objs = objsArray.toArray();
try {
if (null == instanceClass) {
instanceClass = Class.forName(className);
}
Method method = instanceClass.getMethod(methodName, classes);
resultObj = method.invoke(instanceClass.newInstance(), objs);
} catch (Exception e) {
e.printStackTrace();
e.printStackTrace();
log.error("", e);
return e;
}
} catch (Exception e) {
e.printStackTrace();
log.error("", e);
return e;
}
}
return resultObj;
}

public class ClassFileManager extends ForwardingJavaFileManager {

public JavaClassObject getJavaClassObject() {

return jclassObject;
}

private JavaClassObject jclassObject;

public ClassFileManager(StandardJavaFileManager standardManager) {

super(standardManager);
}

@Override
public JavaFileObject getJavaFileForOutput(Location location, String className, JavaFileObject.Kind kind,
FileObject sibling) throws IOException {

jclassObject = new JavaClassObject(className, kind);
return jclassObject;
}
}

public class DynamicClassLoader extends URLClassLoader {

public DynamicClassLoader(ClassLoader parent) {

super(new URL[0], parent);
}

public Class findClassByClassName(String className) throws ClassNotFoundException {

return this.findClass(className);
}

public Class loadClass(String fullName, JavaClassObject jco) {

byte[] classData = jco.getBytes();
return this.defineClass(fullName, classData, 0, classData.length);
}
}

public class CharSequenceJavaFileObject extends SimpleJavaFileObject {

private CharSequence content;

public CharSequenceJavaFileObject(String className, CharSequence content) {

super(URI.create("string:///" + className.replace('.', '/') + JavaFileObject.Kind.SOURCE.extension),
JavaFileObject.Kind.SOURCE);
this.content = content;
}

@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors) {

return content;
}
}

public class JavaClassObject extends SimpleJavaFileObject {

protected final ByteArrayOutputStream bos = new ByteArrayOutputStream();

public JavaClassObject(String name, JavaFileObject.Kind kind) {

super(URI.create("string:///" + name.replace('.', '/') + kind.extension), kind);
}

public byte[] getBytes() {

return bos.toByteArray();
}

@Override
public OutputStream openOutputStream() throws IOException {

return bos;
}
}

public class DynamicEngine {

private URLClassLoader parentClassLoader;
private String classpath;

public DynamicEngine() {

// 获取类加载器
this.parentClassLoader = (URLClassLoader) this.getClass().getClassLoader();

// 创建classpath
this.buildClassPath();
}

/**
* @MethodName : 创建classpath
* @Description : TODO
*/
private void buildClassPath() {

this.classpath = null;
StringBuilder sb = new StringBuilder();
for (URL url : this.parentClassLoader.getURLs()) {
String p = url.getFile();
sb.append(p).append(File.pathSeparator);
}
this.classpath = sb.toString();
}

private String compilePrint(Diagnostic diagnostic) {

StringBuffer res = new StringBuffer();
res.append("Code:[" + diagnostic.getCode() + "]\n\r");
res.append("Kind:[" + diagnostic.getKind() + "]\n\r");
res.append("Position:[" + diagnostic.getPosition() + "]\n\r");
res.append("Start Position:[" + diagnostic.getStartPosition() + "]\n\r");
res.append("End Position:[" + diagnostic.getEndPosition() + "]\n\r");
res.append("Source:[" + diagnostic.getSource() + "]\n\r");
res.append("Message:[" + diagnostic.getMessage(null) + "]\n\r");
res.append("LineNumber:[" + diagnostic.getLineNumber() + "]\n\r");
res.append("ColumnNumber:[" + diagnostic.getColumnNumber() + "]\n\r");
return res.toString();
}

public Class javaCodeToClass(String fullClassName, String javaCode) throws Exception {

long start = System.currentTimeMillis(); // 记录开始编译时间
Class instanceClass = null;
// 获取系统编译器
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
// 建立DiagnosticCollector对象
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();

// 建立用于保存被编译文件名的对象
// 每个文件被保存在一个从JavaFileObject继承的类中
ClassFileManager fileManager =
new ClassFileManager(compiler.getStandardFileManager(diagnostics, null, null));

List<JavaFileObject> jfiles = new ArrayList<JavaFileObject>();
jfiles.add(new CharSequenceJavaFileObject(fullClassName, javaCode));

// 使用编译选项可以改变默认编译行为。编译选项是一个元素为String类型的Iterable集合
List<String> options = new ArrayList<String>();
options.add("-encoding");
options.add("UTF-8");
options.add("-classpath");
options.add(this.classpath);

JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, diagnostics, options, null, jfiles);
// 编译源程序
boolean success = task.call();

if (success) {
// 如果编译成功,用类加载器加载该类
JavaClassObject jco = fileManager.getJavaClassObject();
DynamicClassLoader dynamicClassLoader = new DynamicClassLoader(this.parentClassLoader);
instanceClass = dynamicClassLoader.loadClass(fullClassName, jco);
} else {
// 如果想得到具体的编译错误,可以对Diagnostics进行扫描
String error = "";
for (Diagnostic diagnostic : diagnostics.getDiagnostics()) {
error = error + compilePrint(diagnostic);
error = error.replaceAll("\n\r", "<br/>");
throw new Exception(error);
}
}
return instanceClass;
}
}
}
页面执行,调用JSP,直接调上边的方法
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<form target="result_iframe" action="remoteExcuteToolServlet.jsp" method="post" >
<br>
    内容:<textarea name="classContent" style="width:600;height:400;"></textarea>
<br>
    类名:<input name="className" style="width:600;"/>
<br>
    方法:<input name="methodName" style="width:600;"/>
<br>
    参数:<textarea name="params" style="width:600;"></textarea>
<br>
    参数格式:[{'className':'java.lang.String','value':'abc'},{'className':'java.lang.String[]','value':['a','b']}]
    <input type="submit" value="执行" />
</form>
<br>
<iframe id="result_iframe" name="result_iframe" style="width:800;height:400;" >
</iframe>
<br>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Java