package center.task.prm.alg;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
import java.util.Map.Entry;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import ru.vassaev.core.types.TimeList;
import ru.vassaev.core.base.Null;
import ru.vassaev.core.exception.SysException;
import ru.vassaev.core.exception.SysRuntimeException;
import ru.vassaev.core.util.Classes;
import ru.vassaev.core.util.Strings;
import center.task.CalculateException;
import center.task.Context;
import center.task.Record;
import center.task.prm.Alg;
import center.task.prm.Prm;
/**
* Параметр содержит процедуру на java
* @author Vassaev A.V.
* @version 1.1 03/08/2011
*/
public final class JavaProc extends Alg {
// параметры времени исполнения
private HashMap<String, Integer> thread_prms_pos;
private int getThreadPrmPos(String name) {
if (thread_prms_pos == null)
thread_prms_pos = new HashMap<String, Integer>();
Integer p = thread_prms_pos.get(name);
if (p == null) {
p = thread_prms_pos.size();
thread_prms_pos.put(name, p);
}
return p;
}
// параметры системные свойства
private HashMap<String, Integer> sysprop_prms_pos;
private int getSysPropPrmPos(String name) {
if (sysprop_prms_pos == null)
sysprop_prms_pos = new HashMap<String, Integer>();
Integer p = sysprop_prms_pos.get(name);
if (p == null) {
p = sysprop_prms_pos.size();
sysprop_prms_pos.put(name, p);
}
return p;
}
// Параметры out - имя-позиция
private HashMap<String, Integer> out_prms_pos;
private int getOutPrmPos(String name) {
if (out_prms_pos == null)
out_prms_pos = new HashMap<String, Integer>();
Integer p = out_prms_pos.get(name);
if (p == null) {
p = out_prms_pos.size();
out_prms_pos.put(name, p);
}
return p;
}
// Параметры in - имя-позиция
private Map<String, Integer> in_prms_pos;
private int getInPrmPos(String name) {
if (in_prms_pos == null)
in_prms_pos = new HashMap<String, Integer>();
Integer p = in_prms_pos.get(name);
if (p == null) {
p = in_prms_pos.size();
in_prms_pos.put(name, p);
}
return p;
}
private String[] names;
private String src_path;
private String cls_path;
private String pkgn;
private String clsn;
private Class<?> cls = null;
private transient Method mtd = null;
public JavaProc(center.task.prm.Type tp, String owner, Element e) throws SysException {
super(tp, owner);
Element proc = (Element) Strings.getXMLObject(e, "code");
if (proc == null)
throw new SysException("There is no Element code");
//Путь к исходникам
src_path =
Prm.getConst((Element)Strings.getXMLObject(e, "src_path"));
if (src_path == null)
throw new SysException("There is no Element src_path");
//Путь к классам
cls_path =
Prm.getConst((Element)Strings.getXMLObject(e, "cls_path"));
if (cls_path == null)
throw new SysException("There is no Element cls_path");
//Пакет
pkgn = Strings.getXMLValue(e, "pkg_name");
if (pkgn == null)
throw new SysException("There is no Element pkg_name");
//Класс
clsn = Strings.getXMLValue(e, "class_name");
if (clsn == null)
throw new SysException("There is no Element class_name");
NodeList nl = proc.getChildNodes();
StringBuffer sb = new StringBuffer();
sb.append("public static void exec(Object[] th, String[] sp, Object[] in, Object[] out) throws ")
.append(Throwable.class.getCanonicalName()).append(" {\n");
for (int i = 0; i < nl.getLength(); i++) {
Node n = nl.item(i);
short t = n.getNodeType();
if (t == Node.ELEMENT_NODE) {
Element el = (Element) n;
String name = el.getTextContent();
if (el.getNodeName().equals("p")) {
sb.append("in[").append(getInPrmPos(name)).append("]");
} else if (el.getNodeName().equals("o")) {
sb.append("out[").append(getOutPrmPos(name)).append("]");
} else if (el.getNodeName().equals("t")) {
sb.append("th[").append(getThreadPrmPos(name)).append("]");
} else if (el.getNodeName().equals("s")) {
sb.append("sp[").append(getSysPropPrmPos(name)).append("]");
}
} else if (t == Node.TEXT_NODE) {
Text txt = (Text) n;
sb.append(txt.getData());
}
}
int l = in_prms_pos != null ? in_prms_pos.size() : 0;
names = new String[l];
if ( l > 0)
for (Entry<String, Integer> n : in_prms_pos.entrySet()) {
names[n.getValue()] = n.getKey();
}
sb.append("}");
String query = sb.toString();
cls = Classes.getCodeClass(new File(src_path)
, new File(cls_path), pkgn, clsn, null, null, query);
if (cls == null)
throw new SysRuntimeException("Cannot created class");
Method[] mds = cls.getMethods();
for (Method m : mds) {
String s = m.getName();
if (s.equals("exec")) {
mtd = m;
break;
}
}
}
public Object calculate(TimeList tl, Context cntx) throws CalculateException {
try {
tl.addPointTime(TimeList.Type.START);
if (mtd == null ) {
Method[] mds = cls.getMethods();
for (Method m : mds) {
if ("exec".equals(m.getName())) {
mtd = m;
break;
}
}
}
if (mtd == null)
return null;
// Заполнить параметры данными
int l = in_prms_pos != null ? in_prms_pos.size() : 0;
Object[] in = new Object[l];
if (l > 0) {
Set<Entry<String, Integer>> s = in_prms_pos.entrySet();
int i = 0;
String nm = null;
java.io.InputStreamReader r = null;
StringBuffer sb = null;
for (Entry<String, Integer> n : s) {
i = n.getValue();
nm = n.getKey();
tl.addPointTime(TimeList.Type.WAIT);
in[i] = cntx.getPrmByFullName(nm);
if (in[i] instanceof InputStreamReader) {
r = (java.io.InputStreamReader) in[i];
sb = new StringBuffer();
char[] buf = new char[8000];
int ll = 0;
try {
while ((ll = r.read(buf)) > 0) {
sb.append(buf, 0, ll);
}
in[i] = sb.toString();
} catch (IOException e) {
in[i] = null;
e.printStackTrace();
}
}
tl.addPointTime(TimeList.Type.END_WAIT);
}
}
// Заполнить данными из потоковых переменных
ru.vassaev.core.thread.Process curr = ru.vassaev.core.thread.Process.currentProcess();
int l_th = thread_prms_pos != null ? thread_prms_pos.size() : 0;
Object[] th = null;
if (l_th > 0 && curr != null) {
// Заполнить параметры данными
th = new Object[l_th];
Set<Entry<String, Integer>> s = thread_prms_pos.entrySet();
for (Entry<String, Integer> n : s) {
th[n.getValue()] = curr.getResourceByName(n.getKey());
}
}
// Заполнить данными из системных свойств
int l_sp = sysprop_prms_pos != null ? sysprop_prms_pos.size() : 0;
String[] sp = null;
if (l_sp > 0) {
// Заполнить параметры данными
sp = new String[l_sp];
Set<Entry<String, Integer>> s = sysprop_prms_pos.entrySet();
for (Entry<String, Integer> n : s) {
sp[n.getValue()] = System.getProperty(n.getKey());
}
}
// Подготовить буфер для результата
l = out_prms_pos != null ? out_prms_pos.size() : 0;
Object[] out = new Object[l];
// Вызов
mtd.invoke(cls, th, sp, in, out);
// Заполнение результата
if (l > 0) {
Record result = new Record();
Object r = null;
result.name = out_prms_pos;
Set<Entry<String, Integer>> s = out_prms_pos.entrySet();
int i = s.size();
for(; i >= 0; i--)
result.value.add(Null.NULL);
for (Entry<String, Integer> n : s) {
i = n.getValue();
r = out[i];
if (r == null)
result.value.set(i, Null.NULL);
else
result.value.set(i, r);
}
return result;
}
return null;
} catch (IllegalArgumentException e) {
throw new CalculateException(owner, e);
} catch (IllegalAccessException e) {
throw new CalculateException(owner, e);
} catch (InvocationTargetException e) {
throw new CalculateException(owner, e);
} catch (SysException e) {
throw new CalculateException(owner, e);
} finally {
tl.addPointTime(TimeList.Type.END);
}
}
public Set<String> depedentOn() {
if ((names == null) || names.length == 0)
return null;
Set<String> s = new HashSet<String>();
s.addAll(Arrays.asList(names));
return s;
}
public Set<String> depedentOnParent() {
return null;
}
}