package net.sourceforge.pain; import net.sourceforge.pain.data.*; import net.sourceforge.pain.db.*; import net.sourceforge.pain.logic.*; import net.sourceforge.pain.util.*; import java.lang.reflect.*; import java.util.*; /** * User: fmike Date: Mar 7, 2004 Time: 1:58:28 AM */ final class AffectProcessor extends PulsePeriodListener implements LogicReloadListener { private final TimedAffectsQueue tq; 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; Codebase.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; } }; Codebase.getDB().execute(t); } catch (Exception e) { Log.error(e); } finally { //this is upper level, no active transaction here if (!aff.isDetached() && aff.getAffectOffTime() <= Codebase.getPulse().currentTime()) { 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 = Codebase.getLogicLoader().provideClass(Codebase.AFFECTS_LOGIC_PACKAGE_PREFIX + 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(); } }