package center.task.prm.alg;
import java.util.*;
import java.util.Map.Entry;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import center.task.CalculateException;
import center.task.Context;
import center.task.prm.Alg;
import center.task.prm.Prm;
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.Strings;
import ru.vassaev.core.util.Xml;
/**
* Параметр группы расчета - выбор варианта <sw
* parent="true/false"><name>NAME</name><grp>GRP</grp></sw> <case
* value=KEY">PRM... <case><eq>KEY</eq><then>PRM</then>... ... <else>PRM...
* <isnull>PRM...
*
* @author Vassaev A.V.
* @version 1.1 15/09/2011
*/
public final class Switch extends Alg {
// Параметр для сравнения
private Prm sw;
// Соответствие типа String -> String/Prm
private Map<String, Object> equals;
// Соответствие типа Prm -> String/Prm
private Map<Prm, Object> equals_full_scan;
// Иначе
private Object els = null;
// Null
private Object isnull = null;
// Исключение при при расчёте sw
private Object when_exception = null;
public Switch(center.task.prm.Type tp, String owner, Element e) {
super(tp, owner);
equals = new HashMap<String, Object>();
equals_full_scan = new HashMap<Prm, Object>();
sw = Prm.getPrmChild(e, "sw");
if (Null.equ(sw))
throw new SysRuntimeException("There is no 'sw' tag");
NodeList le = Xml.getElementsByTagName(e, "case");
for (int i = le.getLength() - 1; i >= 0; i--) {
Element c = (Element) le.item(i);
Attr akey = c.getAttributeNode("value");
if (akey != null) {
equals.put(akey.getValue(), Prm.getPrm(c));
} else {
Element eq = (Element) Strings.getXMLObject(c, "eq");
if (eq == null)
continue;
Object k = Prm.getPrm(eq);
Element then = (Element) Strings.getXMLObject(c, "then");
Object v = Null.NULL;
if (then != null) {
v = Prm.getPrm(then);
}
if (k instanceof String)
equals.put((String) k, v);
else if (k instanceof Prm) {
equals_full_scan.put((Prm) k, v);
} else if (Null.equ(k)) {
isnull = v;
}
}
}
Element els_el = (Element) Strings.getXMLObject(e, "else");
if (els_el != null)
els = Prm.getPrm(els_el);
Element isnull_el = (Element) Strings.getXMLObject(e, "isnull");
if (isnull_el != null)
isnull = Prm.getPrm(isnull_el);
Element isexcept_el = (Element) Strings.getXMLObject(e, "exception");
if (isexcept_el != null)
when_exception = Prm.getPrm(isexcept_el);
}
public Object calculate(TimeList tl, Context cntx) throws CalculateException {
try {
tl.addPointTime(TimeList.Type.START);
Object o = null;
Exception ex = null;
try {
tl.addPointTime(TimeList.Type.WAIT);
o = sw.getObject(cntx);
} catch (SysException e) {
if (when_exception != null) ex = e;
else throw new CalculateException(owner, e);
} catch (CalculateException e) {
if (when_exception != null) ex = e;
else throw e;
} finally {
tl.addPointTime(TimeList.Type.END_WAIT);
}
if (ex != null) {
if (when_exception instanceof Prm)
try {
return ((Prm) when_exception).getObject(cntx);
} catch (SysException e) {
throw new CalculateException(owner, e);
}
return when_exception;
}
if (Null.equ(o)) {
Object v;
if (isnull != null)
v = isnull;
else
v = els;
if (v instanceof Prm)
try {
return ((Prm) v).getObject(cntx);
} catch (SysException e) {
throw new CalculateException(owner, e);
}
return v;
}
String k = o.toString();
Object v = equals.get(k);
if (v == null) {
for (Entry<Prm, Object> m : equals_full_scan.entrySet()) {
try {
if (k.equals(m.getKey().getString(cntx))) {
v = m.getValue();
if (v instanceof Prm)
try {
return ((Prm) v).getObject(cntx);
} catch (SysException e) {
throw new SysRuntimeException(e);
}
return v;
}
} catch (SysException e) {
e.printStackTrace(); // TODO To change body of catch statement use
// File | Settings | File Templates.
}
}
v = els;
if (v instanceof Prm)
try {
return ((Prm) v).getObject(cntx);
} catch (SysException e) {
throw new CalculateException(owner, e);
}
return v;
}
if (v instanceof Prm)
try {
return ((Prm) v).getObject(cntx);
} catch (SysException e) {
throw new CalculateException(owner, e);
}
return v;
} finally {
tl.addPointTime(TimeList.Type.END);
}
}
public Set<String> depedentOn() {
HashSet<String> s = new HashSet<String>();
Set<Prm> l = equals_full_scan.keySet();
for (Prm e : l) {
if (!e.isParent)
s.add(e.fullname);
}
Collection<Object> v = equals.values();
for (Object e : v) {
if ((e instanceof Prm) && !((Prm) e).isParent)
s.add(((Prm) e).fullname);
}
if ((els != null) && (els instanceof Prm) && !((Prm) els).isParent)
s.add(((Prm) els).fullname);
if ((isnull != null) && (isnull instanceof Prm) && !((Prm) isnull).isParent)
s.add(((Prm) isnull).fullname);
if (!sw.isParent)
s.add(sw.fullname);
return s;
}
public Set<String> depedentOnParent() {
HashSet<String> s = new HashSet<String>();
Set<Prm> l = equals_full_scan.keySet();
for (Prm e : l) {
if (e.isParent)
s.add(e.fullname);
}
Collection<Object> v = equals.values();
for (Object e : v) {
if ((e instanceof Prm) && ((Prm) e).isParent)
s.add(((Prm) e).fullname);
}
if ((els != null) && (els instanceof Prm) && ((Prm) els).isParent)
s.add(((Prm) els).fullname);
if ((isnull != null) && (isnull instanceof Prm) && ((Prm) isnull).isParent)
s.add(((Prm) isnull).fullname);
if (sw.isParent)
s.add(sw.fullname);
return s;
}
}