package center.task.prm.alg;
import center.task.prm.Alg;
import center.task.prm.Prm;
import center.task.CalculateException;
import center.task.Context;
import ru.vassaev.core.types.TimeList;
import ru.vassaev.core.util.Classes;
import ru.vassaev.core.util.Strings;
import ru.vassaev.core.util.Xml;
import ru.vassaev.core.exception.SysException;
import java.util.Set;
import java.util.ArrayList;
import java.util.HashSet;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
/**
* Параметр для вызова статической функции на java
* @author Vassaev A.V.
* @version 1.1 24/08/2011
*/
public final class JavaFunc extends Alg {
private String clsn = null;
private Class<?> cls = null;
private String mtdn = null;
private Method mtd = null;
private ArrayList<Object> params;
private Class<?>[] cls_;
public JavaFunc(center.task.prm.Type tp, String owner, Element e) throws SysException {
super(tp, owner);
//Класс
clsn = Strings.getXMLValue(e, "class_name");
if (clsn == null)
throw new SysException("There is no Element class_name");
try {
cls = Class.forName(clsn);
} catch (ClassNotFoundException e1) {
throw new SysException(e1);
}
//Method
mtdn = Strings.getXMLValue(e, "func_name");
if (mtdn == null)
throw new SysException("There is no Element func_name");
NodeList le = Xml.getElementsByTagName(e, "param");
params = new ArrayList<Object>();
int l = le.getLength();
cls_ = new Class[l];
for (int i = 0; i < l; i++) {
Element el = (Element) le.item(i);
String type = el.getAttribute("type");
if (type != null)
try {
cls_[i] = Class.forName(type);
} catch (ClassNotFoundException e1) {
throw new SysException(e1);
}
else
cls_[i] = String.class;
Object p = Prm.getPrm(el);
params.add(p);
}
try {
mtd = cls.getMethod(mtdn, cls_);
} catch (NoSuchMethodException e1) {
throw new SysException(e1);
}
}
protected Object calculate(TimeList tl, Context cntx) throws CalculateException {
try {
tl.addPointTime(TimeList.Type.START);
Object[] o = new Object[params.size()];
Object p = null;
for(int i = 0; i < o.length; i++) {
p = params.get(i);
if (p instanceof Prm) {
tl.addPointTime(TimeList.Type.WAIT);
o[i] = ((Prm) p).getObject(cntx);
tl.addPointTime(TimeList.Type.END_WAIT);
} else {
o[i] = p;
}
o[i] = Classes.castAs(o[i], cls_[i]);
}
return mtd.invoke(cls, o);
} catch (SysException e) {
throw new CalculateException(getOwner(),e);
} catch (InvocationTargetException e) {
throw new CalculateException(getOwner(),e);
} catch (IllegalAccessException e) {
throw new CalculateException(getOwner(),e);
} finally {
tl.addPointTime(TimeList.Type.END);
}
}
public Set<String> depedentOn() {
Set<String> r = new HashSet<String>();
for(Object p : params)
if ((p instanceof Prm) && !((Prm)p).isParent)
r.add(((Prm) p).fullname);
return r;
}
public Set<String> depedentOnParent() {
Set<String> r = new HashSet<String>();
for(Object p : params)
if ((p instanceof Prm) && ((Prm)p).isParent)
r.add(((Prm) p).fullname);
return r;
}
}