/
codebase/
codebase/area/
codebase/doc/
codebase/etc/
codebase/src/net/sourceforge/pain/data/trigger/
codebase/src/net/sourceforge/pain/logic/
codebase/src/net/sourceforge/pain/logic/affect/
codebase/src/net/sourceforge/pain/logic/event/
codebase/src/net/sourceforge/pain/logic/event/deploy/
codebase/src/net/sourceforge/pain/logic/event/guitool/
codebase/src/net/sourceforge/pain/logic/event/guitool/event/
codebase/src/net/sourceforge/pain/logic/fn/util/
codebase/src/net/sourceforge/pain/logic/trigger/
codebase/src/net/sourceforge/pain/logic/trigger/impl/
codebase/src/net/sourceforge/pain/network/console/
codebase/src/net/sourceforge/pain/network/console/telnet/
codebase/src/net/sourceforge/pain/network/guitool/
codebase/src/net/sourceforge/pain/plugin/
codebase/src/net/sourceforge/pain/plugin/command/
codebase/src/net/sourceforge/pain/plugin/reset/
codebase/src/net/sourceforge/pain/plugin/shutdown/
codebase/src/net/sourceforge/pain/plugin/social/
codebase/src/net/sourceforge/pain/util/
db/doc/javadoc/resources/
db/src/net/sourceforge/pain/util/
gui/
gui/lib/
gui/src/net/sourceforge/pain/tools/guitool/dbbrowse/
gui/src/net/sourceforge/pain/tools/guitool/dialog/
gui/src/net/sourceforge/pain/tools/guitool/menu/
gui/src/net/sourceforge/pain/tools/guitool/resources/
gui/src/net/sourceforge/pain/tools/guitool/resources/images/
gui/src/net/sourceforge/pain/tools/guitool/resources/images/explorer/
tests/
tests/src/
tests/src/net/sourceforge/pain/db/data/
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();
    }
}