package center.app.common;
import center.task.AProcessor;
import center.task.Context;
import center.task.State;
import center.task.TaskException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Set;
import java.util.HashSet;
import org.w3c.dom.Element;
import ru.vassaev.core.base.Null;
import ru.vassaev.core.container.AppInfo;
import ru.vassaev.core.container.ApplicationManager;
import ru.vassaev.core.db.Manager;
import ru.vassaev.core.db.Sttmnt;
import ru.vassaev.core.exception.SysException;
import ru.vassaev.core.CallBackInterface;
import ru.vassaev.core.Pool;
import ru.vassaev.core.thread.Processed;
import ru.vassaev.core.util.Strings;
import com.javaparts.dde.*;
/**
* Процессор получения и обработки данных от DDE-сервера
*/
public class DDEResponseProcessor extends AProcessor implements
DDEEventListener {
public static enum EnumAction {
ON_CHANGE, ON_CLOSE, ON_TRANS
};
// Очередь
private ru.vassaev.core.Queue<Action> q = new ru.vassaev.core.Queue<Action>();
private long id_seq = 0;
private Pool<Action> act_pool = new Pool<Action>(Action.class);
// Объект
private static class Action {
public EnumAction action;
public DDEEvent obj;
public long local_time;
public long id = 0;
public Action(EnumAction action, DDEEvent e, long id) {
super();
this.action = action;
this.obj = e;
this.local_time = System.currentTimeMillis();
this.id = id;
}
}
private String poolProcessName = null;
private Pool<ru.vassaev.core.thread.Process> prcs = null;
private String dateFormat = null;
/**
* Проверка установки параметров
* @throws SysException
*/
public void paramsValidateAndPrepare(Context cntx) throws SysException {
poolProcessName = cntx.getPrmString("process_pool");
if (Null.equ(poolProcessName))
throw new SysException("Parameter process_pool isn't set");
ru.vassaev.core.thread.Process prc =
ru.vassaev.core.thread.Process.currentProcess();
AppInfo ai = ApplicationManager.getCurrentAppInfo();
Pool<?> poolprc = ai.getContainer().getRM().getPool(poolProcessName);
if (Null.equ(poolprc))
throw new SysException("There is no pool by name " + poolProcessName);
try {
prcs = (Pool<ru.vassaev.core.thread.Process>) poolprc;
} catch(Throwable e) {
throw new SysException("The pool by name " + poolProcessName + " dosn't contain process' object");
}
dateFormat = cntx.getPrmString("date_format");
if (dateFormat == null)
dateFormat = "dd.MM.yyyy HH:mm:ss.SSS";
}
private Sttmnt stmt = null;
public class TargetUpdate implements Processed
, CallBackInterface<ru.vassaev.core.thread.Process, Object> {
/**
* Обработка в потоке
*/
public void processing(Object prms) throws Throwable {
Action a = (Action) prms;
ItemChangedEvent e = (ItemChangedEvent) a.obj;
String nm = e.getItemName();
String value = new String(e.getItemValue());
ru.vassaev.core.thread.Process prc = ru.vassaev.core.thread.Process.currentProcess();
SimpleDateFormat df = new SimpleDateFormat();
df.applyPattern(dateFormat);
String dt = df.format(new Timestamp(a.local_time));
// Установка параметров к текущему потоку
prc.regResourceName(dt, "DT");
prc.regResourceName(value, "VALUE");
prc.regResourceName(nm, "NAME");
prc.regResourceName(a.id, "ID");
Context cntx = getContext();
Connection con = Manager.getConnection(stmt.getAliasDB());
PreparedStatement st = null;
try {
System.out.println("\t"+a.id + " : " + dt + " : " + nm + " = " + value);
st = stmt.getCallStatement(con);
ArrayList<String> names = stmt.getBindParamNames();
for (String name : names) {
Object val = cntx.getPrmByFullName(name);
stmt.setParam(st, name, val, java.sql.Types.VARCHAR);
}
st.execute();
con.commit();
} catch(SQLException ex) {
ex.printStackTrace();
} finally {
if (st != null)
stmt.clearStatement(st);
Manager.freeConnection(con);
}
}
/**
* Вернуть в пул поток после его завершения
*/
public Object callBack(ru.vassaev.core.thread.Process prc) {
prcs.free(prc);
return null;
}
}
public TargetUpdate targetUpdate = new TargetUpdate();
public State process(Context cntx) throws TaskException, SysException,
InterruptedException {
paramsValidateAndPrepare(cntx);
boolean trim_advice = Strings.parseBooleanNvl(cntx.getPrmByFullName("trim_advice"), true);
Object update = cntx.getPrmByFullName("update");
String db = cntx.getPrmString("db");
Element up = (Element) update;
stmt = new Sttmnt(db, up, "i", "b", "o");
DDEClient client;
Conversation serv_top = null;
client = DDEClient.getInstance();
client.addDDEEventListener(this);
try {
ru.vassaev.core.thread.Process x = null;
while (true)
try {
if (serv_top == null) {
String service = cntx.getPrmString("service");
String topic = cntx.getPrmString("topic");
serv_top = client.connect(service, topic);
String advice = cntx.getPrmString("advice");
System.out.println("starting advices...");
String[] advices = Strings.parseXVSLine(advice, '/', ',');
for (String adv : advices) {
if (trim_advice)
adv = adv.trim();
System.out.print("adv = " + adv + " : ");
try {
byte[] obj = serv_top.request(adv);
serv_top.startAdvice(adv);
System.out.println(new String(obj));
} catch (DDEException e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
}
if (x == null)
x = prcs.occupyWait();
Object o = null;
System.out.println("Busy size / queue size = " + prcs.getBusySize() + " / " + q.size());
o = q.get(100000);//!!! нужен параметр
if (o == null)
continue;
//System.out.println(System.currentTimeMillis());
if (o instanceof Action) {
Action a = (Action) o;
//System.out.println("!!!" + a.id);
if (EnumAction.ON_CLOSE.equals(a.action)) {
System.out.println("Server has closed connection");
serv_top.close();
serv_top = null;
} else if (EnumAction.ON_CHANGE.equals(a.action)) {
x.setName("CHANGE - " + a.id + " - " + ((ItemChangedEvent)(a.obj)).getItemName());
x.setTarget(targetUpdate);
x.setCallBackOnEndProcess(targetUpdate);
x.start(a);
x = null;
} else if (EnumAction.ON_TRANS.equals(a.action)) {
AsyncCompletedEvent e = (AsyncCompletedEvent) a.obj;
System.out.println("<= Async Completed =>");
System.out.println("ID:" + e.getTransactionId());
System.out.println("Success:" + e.isSuccessful());
if (e.isDataAvailable()) {
System.out.println("Result:"
+ new String(e.getTransactionResult()));
}
}
} else {
prcs.free(x);
break;
}
} catch (DDEException e) {
e.printStackTrace();
Thread.sleep(1000);
}
} finally {
try {
serv_top.close();
} catch (Exception e) {
}
client.close();
}
return State.BROKEN;
}
public void onAsyncCompleted(AsyncCompletedEvent e) {
AsyncCompletedEvent x = new AsyncCompletedEvent(e.getConversation(), e
.getTransactionId(), e.isSuccessful());
q.put(new Action(EnumAction.ON_TRANS, x, id_seq++));
}
public void onDisconnect(DDEEvent e) {
DDEEvent x = new DDEEvent(e.getConversation());
q.put(new Action(EnumAction.ON_CLOSE, x, id_seq++));
}
public void onItemChanged(ItemChangedEvent e) {
ItemChangedEvent x = new ItemChangedEvent(e.getConversation(), e
.getItemName(), e.getItemValue());
q.put(new Action(EnumAction.ON_CHANGE, x, id_seq++));
}
public Set<String> dependentOn() {
Set<String> s = new HashSet<String>();
return s;
}
public Set<String> loopDependentOn() {
Set<String> s = new HashSet<String>();
return s;
}
}