Package speculoos.jndi

Source Code of speculoos.jndi.JNDISource

/*---------------------------------------------------------------------------
* 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 27 sept. 2005
* Author: Arnaud Bailly
* --------------------------------------------------------------------------*/
package speculoos.jndi;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.naming.NamingException;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;

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

import speculoos.core.Mapper;
import speculoos.core.MapperCollector;
import speculoos.core.MapperException;
import speculoos.jndi.mappers.JNDIMapper;
import speculoos.manager.MapperConfigurationException;
import speculoos.spi.MapperTechnicalException;
import speculoos.spi.Source;
import speculoos.utils.VariableSubstitution;

/**
* Base implementation for accessing JNDI/LDAP data source.
* <p>
* This base implementation uses on demand binding to directory context for
* providing connections to mappers. Subclasses may override this behavior by
* providing their own implementations of {@link #connect()} and
* {@link #close(DirContext)}: The former provides DirContext instance for use
* by the mapper while the latter releases this instance when it is released by
* the mapper.
* </p>
* <p>
* Methods {@link #create(String, Map)} and {@link #release(Mapper)} are
* synchronized to provide minimal thread isolation. Please note howerver that
* {@link speculoos.core.Mapper} instances are not supposed to be thread safe so
* it is up to the client to ensure proper concurrency management.
* </p>
* <p>
* Method {@link #add(String, JNDIMapper)} associates a symbolic name to a
* Mapper instance. This instance will then be used as <em>Prototype</em>
* object when JNDISource will be asked for creating a Mapper through method
* {@link #create(String, Map)}: Base object is <code>cloned</code> and
* initialized with a connection before being returned to the client. The method
* {@link #release(Mapper)} must be invoked at some later point in order for
* this source to release associated resources.
* </p>
* <p>
* Environment management is provided through the method
* {@link #addParameters(Map)} which allows incremental configuration of the
* environment this source operates in.
* </p>
*
* @author nono
* @version $Id: JNDISource.java 76 2005-10-26 14:12:23 +0200 (Wed, 26 Oct 2005)
*          /C=FR/ST=Nord/L=Lille/O=Norsys SA/OU=UE/CN=Arnaud
*          Bailly/emailAddress=abailly@norsys.fr $
*/
public class JNDISource implements Source, MapperCollector {

  private static final Log log = LogFactory.getLog(JNDISource.class);

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

  /* environment for variables substitution */
  private Map parameters = new HashMap();

  /* mappers map */
  private Map mapperMatrix = new HashMap();

  private VariableSubstitution subst = new VariableSubstitution();

  /* current environment */
  private Map current;

  private String name;

  /*
   * store unassigned mappers - used in chains
   */
  private List mappers = new ArrayList();

  /**
   * Create a new named JNDISource.
   *
   * @param name
   *            the name of the source. May not be null.
   */
  public JNDISource(String name) {
    this.name = name;
  }

  /**
   * Default constructor for creating anonymous source.
   *
   */
  public JNDISource() {
    this("");
  }

  /*
   * (non-Javadoc)
   *
   * @see speculoos.core.core.spi.Source#start(java.util.Map)
   */
  public void start(Map env) throws MapperConfigurationException {
    /* instanciate parameters */
    this.current = new HashMap(parameters);
    /* instanciate this environment */
    for (Iterator i = this.current.entrySet().iterator(); i.hasNext();) {
      Map.Entry me = (Map.Entry) i.next();
      String v = subst.replaceVars(env, (String) me.getValue());
      me.setValue(v);
    }
    if (log.isDebugEnabled())
      log.debug("[" + name + "] starting with environment " + current);
    if (log.isInfoEnabled())
      log.info("[" + name + "] started");
    bound = true;
  }

  /**
   * Create a context from this source. This method simply calls creation of a
   * new initial context. It may be overriden in subclasses to offer more
   * sophisticated connection handling (eg. pooling).
   *
   * @return a DirContext representing base node for operation on this source.
   * @throws MapperTechnicalException
   */
  protected JNDIConnection connect() throws MapperTechnicalException {
    try {
      return new SimpleJNDIConnectionImpl(new InitialDirContext(new Hashtable(current)));
    } catch (NamingException e) {
      throw new MapperTechnicalException(
          "Error while trying to connect to source ", e);
    }
  }

  /*
   * (non-Javadoc)
   *
   * @see speculoos.core.core.spi.Source#stop()
   */
  public void stop() {
    bound = false;
    current = null;
    if (log.isInfoEnabled())
      log.info("[" + name + "] stopped");
  }

  /*
   * (non-Javadoc)
   *
   * @see speculoos.core.core.spi.Source#create(String, java.util.Map)
   */
  public synchronized Mapper create(String m, Map environment)
      throws MapperException {
    if (!bound)
      throw new IllegalStateException(
          "This source is not opened for business. Come back later");
    JNDIMapper base = (JNDIMapper) mapperMatrix.get(m);
    if (base == null)
      throw new IllegalArgumentException("Mapper named " + m
          + " is unknown");
    JNDIMapper jm = (JNDIMapper) (base).clone();
    /* sets the directory object to use for operations */
    JNDIConnection dirc;
    if (log.isDebugEnabled())
      log.info("[" + name + "] creating mapper " + m);
    try {
      dirc = connect();
      jm.setDirectory(dirc);
    } catch (NamingException e) {
      throw new MapperTechnicalException(
          "Cannot instantiate mapper " + m, e);
    }
    /* sets the environment */
    Map env = new HashMap(environment);
    env.putAll(current);
    jm.setEnvironment(env);
    if (log.isDebugEnabled())
      log.info("[" + name + "] created mapper " + m + " with env " + env);
    return jm;
  }

  /*
   * (non-Javadoc)
   *
   * @see speculoos.core.core.spi.Source#release(speculoos.core.core.Mapper)
   */
  public void release(Mapper mapper) throws MapperException {
    JNDIMapper jm = (JNDIMapper) mapper;
    if (!mapperMatrix.containsKey(jm.getName()))
      throw new MapperException("[" + name + "] unknown mapper " + jm
          + " in this source ");
    jm.getDirectory().close();
    /* clean state of object */
    jm.clearDirectory();
    /* clear environment */
    jm.getEnvironment().clear();
    if (log.isDebugEnabled())
      log.info("[" + name + "] released mapper " + mapper.getName());
  }


  /**
   * Adds a new mapper to this source with given identifier. This method
   * automatically adds all validation rules in this source to given mapper.
   *
   * @param string
   *            identifier must be unique within this source or else previous
   *            mapper is replaced by this one.
   * @param jm
   *            the mapper
   */
  public void add(String string, JNDIMapper jm) {
    mapperMatrix.put(string, jm);
    jm.getInputChain().addMappers(mappers);
  }

  /*
   * (non-Javadoc)
   *
   * @see speculoos.spi.Source#addParameters(java.util.Map)
   */
  public void addParameters(Map env2) {
    this.parameters.putAll(env2);
  }

  /**
   * Returns the name of this source.
   *
   * @return name of the source.
   */
  public String getName() {
    return name;
  }

  /*
   * (non-Javadoc)
   *
   * @see speculoos.core.MapperCollector#addMapper(speculoos.core.Mapper)
   */
  public void addMapper(Mapper m) {
    mappers.add(m);
  }

  /*
   * (non-Javadoc)
   *
   * @see speculoos.core.MapperCollector#addMappers(java.util.Collection)
   */
  public void addMappers(Collection col) {
    mappers.addAll(col);
  }

  /*
   * (non-Javadoc)
   *
   * @see speculoos.core.MapperCollector#getMappers()
   */
  public Collection getMappers() {
    return Collections.unmodifiableList(mappers);
  }

  /*
   * Returns current environment. For internal use only.
   */
  protected Map getCurrent() {
    return current;
  }

}
TOP

Related Classes of speculoos.jndi.JNDISource

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.