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(); } }