/* JFox, the OpenSource J2EE Application Server
 *
 * Distributable under GNU LGPL license by gun.org
 * more details please visit http://www.huihoo.org/jfox
 */

package org.jfox.system;

import org.jfox.framework.Component;
import org.jfox.framework.ComponentContext;
import org.jfox.framework.extra.Destroyable;
import org.jfox.framework.extra.Initializable;
import org.jfox.framework.logger.Logger;


/**
 * @author <a href="mailto:young_yy@hotmail.com">Young Yang</a>
 */

public abstract class AbstractComponent implements Component, Initializable, Destroyable {
    /**
     * system name of the system
     */
    protected String name = null;
    /**
     * the status value of the system
     */
    protected volatile State state = State.ORIGINAL;

    protected transient Logger logger = Logger.getLogger(getClass().getName());
    protected volatile long sequence = 0L;

    protected Object proxyInstance = null;

    protected ComponentContext context = null;

    public AbstractComponent() {
        setName(parseName(this.getClass().getName()));
    }

    public AbstractComponent(String name) {
        setName(name);
    }

    public void setComponentContext(ComponentContext ctx) {
        this.context = ctx;
    }

    public String getName() {
        return name;
    }

    protected void setName(String name) {
        this.name = name;
    }

    public State getState() {
        return state;
    }

    public Logger getLogger() {
        return logger;
    }

    protected void setLogger(Logger logger) {
        this.logger = logger;
    }

    public boolean isInitialized() {
        return state.equals(State.INITIALIZED)
                || state.equals(State.STARTING)
                || state.equals(State.STARTED)
                || state.equals(State.STOPPING)
                || state.equals(State.STOPPED);
    }

    public void init() throws Exception {
        if(!State.canInit(state)) {
            logger.warn(name + " can not initialize, state = " + state);
            return;
        }

//    if(logger == null) logger = Logger.getLogger(getClass().getName());
        logger.info("initializing...");
        state = State.INITIALIZING;

        try {
            doInit();
        }
        catch(Exception e) {
            state = State.INTERRUPTED;
            logger.error("initialze failed", e);
        }

        state = State.INITIALIZED;
        logger.info("initialized.");

    }


    public void destroy() throws Exception {
        if(!State.canDestroy(state)) {
            logger.warn(name + " can not destroy, state = " + state);
            return;
        }

        logger.info("destroying...");
        state = State.DESTROYING;
        try {
            doDestroy();
        }
        catch(Exception e) {
            state = State.INTERRUPTED;
            logger.error("stopping failed", e);
            throw e;
        }
        state = State.DESTROYED;
        logger.info("destroyed");

    }

    /**
     * do actually create action
     */
    protected abstract void doInit() throws Exception;

    /**
     * do actually destory action
     */
    protected abstract void doDestroy() throws Exception;

    // trip the ServiceName from it's class nameSpace
    protected static String parseName(String className) {
        int lastDotIndex = className.lastIndexOf(".");
        return className.substring(lastDotIndex + 1);
    }


}
