package net.sourceforge.pain;
import net.sourceforge.pain.data.*;
import net.sourceforge.pain.util.*;
import net.sourceforge.pain.logic.*;
import net.sourceforge.pain.db.*;
import java.util.*;
import java.lang.reflect.*;
/**
* User: fmike Date: Mar 7, 2004 Time: 1:58:28 AM
*/
public class AffectProcessor extends PeriodOfTimeListener implements LogicReloadListener {
private final TimedAffectsQueue tq;
private static final String AFFECTS_PACKAGE = AffectData.AFFECT_LOGIC_PACKAGE_PREFIX;
private HashMap cache = new HashMap();
private Class[] affectArgsTypes = new Class[]{AffectData.class};
private Object[] affectArgsValues = new Object[1];
public AffectProcessor(TimedAffectsQueue tq) {
super(1, PERIOD_IN_SECONDS);
this.tq = tq;
Core.getLogicLoader().addLogicReloadListener(this);
}
protected void onPeriod(int time) {
TimedAffectData aff = tq.getFirstOff();
if (aff != null) {
final int affectOffTime = aff.getAffectOffTime();
Log.debug("Off time:" + affectOffTime + " time:" + time);
if (affectOffTime <= time) {
processExpired(aff);
}
}
}
private void processExpired(TimedAffectData aff) {
try {
final TimedAffect affLogic = getAffectInstance(aff);
DbTransaction t = new DbTransaction() {
public Object execute(Object[] params) throws Exception {
affLogic.onAffectTimeExpired();
return null;
}
};
Core.getDB().execute(t);
} catch (Exception e) {
Log.error(e);
} finally {
//this is upper level, no active transaction here
if (!aff.isDetached() && aff.getAffectOffTime() <= Core.getTime().getTime()) {
aff.delete();//deletes affect and detaches object from db
}
}
}
private TimedAffect getAffectInstance(TimedAffectData aff) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
String classSuffix = aff.getAffectClassName();
TimedAffect affLogic = (TimedAffect) cache.get(classSuffix);
if (affLogic == null) {
affectArgsValues[0] = aff;
Class c = Core.getLogicLoader().provideClass(AFFECTS_PACKAGE + aff.getAffectClassName());
affLogic = (TimedAffect) c.getDeclaredConstructor(affectArgsTypes).newInstance(affectArgsValues);
cache.put(classSuffix, affLogic);
affectArgsValues[0] = null;
}
return (TimedAffect) affLogic.newInstance(aff);
}
public void onLogicReloading() {
cache.clear();
}
}