Package speculoos.manager

Source Code of speculoos.manager.MapperManager

/*---------------------------------------------------------------------------
* Speculoos, LDAP to objet mapping.
* Copyright (C) 2006  Norsys and oQube
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*
* Created on 26 sept. 2005
* Author: Arnaud Bailly
* --------------------------------------------------------------------------*/
package speculoos.manager;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import speculoos.core.Mapper;
import speculoos.core.MapperException;
import speculoos.spi.Source;


/**
* Base entry point for a business component.
* <p>
* There should be a single instance of MapperManager per instance of the
* business component. This would normally imply that we must use a
* <strong>Singleton </strong> pattern but we follow the widely accepted wisdom
* that <quote>Singleton is Evil! </quote>. It is the responsibility of the
* application developer to ensure that he uses one manager. If this is not the
* case, behavior is unspecified as there may be conflicts with resources
* associated with the manager that <em>are</em> statically allocated.
* </p>
* <p>
* As its name implies, a <code>MapperManager</code> manages a collection of
* <code>Mapper</code> objects. A manager can be in the following states:
* <ul>
* <li><strong>not configured </strong>: configuration has not completed</li>
* <li><strong>configured </strong>: configuration has been completed but
* manager has not been started</li>
* <li><strong>ready </strong>: configuration has been completed and manager is
* operating correctly</li>
* </ul>
* </p>
* <p>
* The design documentation gives a picture of the manager's life-cycle as an
* automaton. See also the documentation of the interfaces {@link Manage}and
* {@link Configure}for a description of their behavior as an automaton.
* </p>
* <h3>Constructor Issue</h3>
* <p>
* Following a run of JDepend, I found a cyclic dependency between Configurator and
* Manager due to constructor parameterized by Configurator. I removed the
* constructor.
* </p>
*
* @author nono
* @version $Id: MapperManager.java 259 2006-05-23 10:34:50Z /C=FR/ST=Nord/L=Lille/O=Norsys SA/OU=UE/CN=Arnaud Bailly/emailAddress=abailly@norsys.fr $
* @see <a href="http://c2.com/cgi-bin/wiki?SingletonsAreEvil">Singletons Are
*      Evil </a>
* @see <a
*      href="https://srvue.norsys.fr/doc/DAA_PTC_v410_FrameworkLDAP_v1maj0.doc">Architecture
*      applicative </a>
*/
public class MapperManager implements Manage, Configure {

    /*
     * this manager's logger. Defaults to a logger named with this classes'name
     */
    private static final Log log = LogFactory.getLog(MapperManager.class);

    /*
     * are we configured ?
     */
    private boolean configured;

    /*
     * are we ready to operate ?
     */
    private boolean ready;

    /*
     * mappers
     */
    private Map /* < String, Mapper > */mappers = new HashMap();

    /*
     * data sources
     */
    private Map /* < String, Source > */sources = new HashMap();

    /*
     * mappers-ds association
     */
    private Map /* < Mapper, Source > */mapperToSource = new HashMap();

    /*
     * default parameter values
     */
    private Map /* < String, Object > */parameters = new HashMap();

    /*
     * current parameter values
     */
    private Map /* < String, Object > */environment = new HashMap();


    /**
     * Default constructor. Produces an unconfigured manager that cannot operate
     * properly without being configured.
     *
     */
    public MapperManager() {
        this.configured = false;
        this.ready = false;
    }


    /**
     * Starts operating the manager.
     *
     * @throws MapperException
     *
     * @throws MapperConfigurationException
     */
    public void start() throws MapperException {
        this.configured = true;
        /* multiple calls to start do nothing */
        if (this.ready)
            return;
        /* allocate resources */
        for (Iterator it = sources.values().iterator(); it.hasNext();) {
            Map env = new HashMap(parameters);
            env.putAll(environment);
            ((Source) it.next()).start(env);
        }
        log.info("MapperManager started");
        /* done */
        this.ready = true;
    }

    /**
     * Returns the mapper associated with the given name in this manager.
     *
     * @param name
     *            name identifying mapper. May not be null.
     * @return a mapper that is ready to operate.
     * @throws MapperConfigurationException
     */
    public Mapper getMapper(String name) throws MapperException {
        if (!configured || !ready)
            throw new MapperConfigurationException(
                    "Manager is not ready to operate.");
        Mapper mapper = (Mapper) mappers.get(name);
        if (mapper == null)
            throw new MapperConfigurationException("No mapper named " + name
                    + " in this manager");
        /* configure mapper through source */
        Source src = (Source) mapperToSource.get(mapper.getName());
        if (src == null)
            throw new MapperConfigurationException(
                    "No source is associated with mapper " + name);
        /* delegate preparation */
        Mapper niou = src.create(name, environment);
        return niou;
    }

    /**
     * Releases a mapper object which allows clean up and reuse of its
     * associated resources.
     *
     * @param mapper
     *            the mapper object to release.
     */
    public void release(Mapper mapper) throws MapperException {
        if (mapper == null)
            throw new IllegalArgumentException("Cannot release null mapper !");
        /* configure mapper through source */
        Source src = (Source) mapperToSource.get(mapper.getName());
        if (src == null)
            throw new MapperConfigurationException(
                    "No source is associated with mapper " + mapper);
        /* delegate release */
        src.release(mapper);
    }

    /**
     * Stops the manager.
     *
     */
    public void stop() {
        if(!ready)
            return;
        /* deallocate resources */
        /* allocate resources */
        for (Iterator it = sources.values().iterator(); it.hasNext();) {
            ((Source) it.next()).stop();
        }
        /* done */
        this.ready = false;
        log.info("MapperManager stopped");
    }

    /*
     * (non-Javadoc)
     *
     * @see speculoos.core.core.Configure#addMapper(java.lang.String,
     *      speculoos.core.core.Mapper)
     */
    public void addMapper(String name, Mapper mapper)
            throws MapperConfigurationException {
        if (configured == true)
            throw new MapperConfigurationException("Manager is configured");
        if (mapper == null || name == null || "".equals(name))
            throw new IllegalArgumentException(
                    "Invalid arguments :"+name+", " +mapper);
        Object o = mappers.get(name);
        if (o != null)
            throw new MapperConfigurationException(name
                    + " is already defined as a mapper in this context");
        mappers.put(name, mapper);
        if(log.isDebugEnabled())
          log.debug("adding mapper "+name+", class "+mapper.getClass());
    }

    /*
     * (non-Javadoc)
     *
     * @see speculoos.core.core.Configure#addParameter(java.lang.String,
     *      java.lang.Object)
     */
    public void addParameter(String param, Object value)
            throws MapperConfigurationException {
        if (configured == true)
            throw new MapperConfigurationException("Manager is configured");
        if (param == null || "".equals(param) || value == null)
            throw new IllegalArgumentException(
                    "Invalid arguments :"+param);
        /* check */
        Object o = parameters.get(param);
        if (o != null)
            throw new MapperConfigurationException(param
                    + " is already defined in this context");
        parameters.put(param, value);
        if(log.isDebugEnabled())
          log.debug("adding parameter "+param+", value="+value);
    }

    /*
     * (non-Javadoc)
     *
     * @see speculoos.core.core.Configure#reset()
     */
    public void reset() throws MapperConfigurationException {
        if (ready)
            throw new MapperConfigurationException(
                    "Cannot reset this manager: stop it first");
        configured = false;
        ready = false;
        /* clear all maps */
        parameters.clear();
        sources.clear();
        environment.clear();
        mappers.clear();
        mapperToSource.clear();
        log.info("MapperManager reset");
    }

    /*
     * (non-Javadoc)
     *
     * @see speculoos.core.core.Configure#set(java.lang.String,
     *      java.lang.Object)
     */
    public Object set(String param, Object value)
            throws MapperConfigurationException {
        if(this.configured || this.ready)
          throw new MapperConfigurationException("Cannot set a variable after configuration is set");
        Object v;
        try {
            v = lookup(param);
        } catch (MapperException e) {
            throw new MapperConfigurationException("Name " + param
                    + " is not a valid parameter in this context");
        }
        this.environment.put(param, value);
        if(log.isDebugEnabled())
          log.debug("setting parameter "+param+", value="+value);
        return v;
    }

    /**
     * Lookup name in this context. First name is looked up in
     * <code>environment</code>, if not found, it is looked up in
     * <code>parameters</code>. If not found, an exception is thrown.
     *
     * @param param
     *            the name of the parameter to look up
     * @return value of this parameter in this environment
     * @throws MapperException
     *             if <code>param</code> is not defined in this context.
     */
    public Object lookup(String param) throws MapperException {
        Object o = environment.get(param);
        if (o == null) {
            o = parameters.get(param);
            if (o == null)
                throw new MapperConfigurationException("Name " + param
                        + " has not been found in this context");
        }
        return o;
    }

    /*
     * (non-Javadoc)
     *
     * @see speculoos.core.core.Configure#setConfigured()
     */
    public void setConfigured() throws MapperConfigurationException {
        if (this.ready == true)
            throw new MapperConfigurationException("Manager already configured");
        this.configured = true;
        log.info("MapperManager configured");
    }

    /*
     * (non-Javadoc)
     *
     * @see speculoos.core.core.Configure#unset(java.lang.String)
     */
    public Object unset(String param) throws MapperConfigurationException {
        Object o;
        try {
            o = lookup(param);
        } catch (MapperException e) {
            throw new MapperConfigurationException(e.getMessage());
        }
        environment.remove(param);
        if(log.isDebugEnabled())
          log.debug("unsetting parameter "+param);
        return o;
    }

    /*
     * (non-Javadoc)
     *
     * @see speculoos.core.core.Configure#addSource(java.lang.String,
     *      speculoos.core.core.spi.Source)
     */
    public void addSource(String name, Source source)
            throws MapperConfigurationException {
        if (configured == true)
            throw new MapperConfigurationException("Manager is configured");
        if (source == null || name == null || "".equals(name))
            throw new IllegalArgumentException(
                    "Incorrect arguments :"+name+", "+source);
        Object o = sources.get(name);
        if (o != null)
            throw new MapperConfigurationException("Name " + name
                    + " is already used for a source");
        /* store source */
        sources.put(name, source);
        if(log.isDebugEnabled())
          log.debug("adding source "+name+", class="+source.getClass());
    }

    /*
     * (non-Javadoc)
     *
     * @see speculoos.core.core.Configure#link(java.lang.String,
     *      java.lang.String)
     */
    public void link(String mapName, String srcName)
            throws MapperConfigurationException {
        Mapper m = (Mapper) mappers.get(mapName);
        if (m == null)
            throw new MapperConfigurationException(mapName
                    + " is not the name of a mapper");
        Source src = (Source) sources.get(srcName);
        if (src == null)
            throw new MapperConfigurationException(srcName
                    + " is not the name of a source");
        /* link */
        mapperToSource.put(m.getName(), src);
        if(log.isDebugEnabled())
            log.debug("linking map "+mapName+" to source "+src);
    }
}
TOP

Related Classes of speculoos.manager.MapperManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.