Package org.apache.oodt.commons.object.jndi

Source Code of org.apache.oodt.commons.object.jndi.ObjectContext

// Licensed to the Apache Software Foundation (ASF) under one or more contributor
// license agreements.  See the NOTICE.txt file distributed with this work for
// additional information regarding copyright ownership.  The ASF licenses this
// file to you under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License.  You may obtain a copy of
// the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
// License for the specific language governing permissions and limitations under
// the License.

package org.apache.oodt.commons.object.jndi;

import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.net.URI;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Properties;
import javax.naming.CompositeName;
import javax.naming.Context;
import javax.naming.InvalidNameException;
import javax.naming.Name;
import javax.naming.NameAlreadyBoundException;
import javax.naming.NameClassPair;
import javax.naming.NameNotFoundException;
import javax.naming.NameParser;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.OperationNotSupportedException;
import org.apache.oodt.commons.util.Utility;

/**
* Context for binding and looking up distributed objects.
*
* @author Kelly
* @version $Revision: 1.5 $
*/
class ObjectContext implements Context {
  /**
   * Construct the object context.
   *
   * @param environment Its environment, currently unused.
   */
  ObjectContext(Hashtable environment) {
    this.environment = environment != null? (Hashtable) environment.clone() : new Hashtable();

    // Add the CORBA context, but by name so we don't get a compile-time
    // coupling with the edm-corba component, and only if CORBA's available.
    try {
      Class clazz = Class.forName("org.apache.oodt.commons.object.jndi.CORBAContext");
      Constructor ctor = clazz.getConstructor(new Class[]{Hashtable.class});
      Object corbaContext = ctor.newInstance(new Object[]{this.environment});
      contexts.add(corbaContext);
    } catch (Throwable ex) {}

    String registryList = (String) environment.get("rmiregistries");
    if (registryList != null) for (Iterator i = Utility.parseCommaList(registryList); i.hasNext();) {
      Hashtable rmiEnv = (Hashtable) this.environment.clone();
      URI uri = URI.create((String) i.next());
      rmiEnv.put("host", uri.getHost());
      rmiEnv.put("port", new Integer(uri.getPort()));
      contexts.add(new RMIContext(rmiEnv));
    }

    Hashtable httpEnv = (Hashtable) this.environment.clone();
    contexts.add(new HTTPContext(httpEnv));

    String className = null;
    for (Iterator i = org.apache.oodt.commons.util.Utility.parseCommaList(System.getProperty("org.apache.oodt.commons.object.contexts", ""));
            i.hasNext();) try {
      className = (String) i.next();
      Class clazz = Class.forName(className);
      contexts.add(clazz.newInstance());
    } catch (ClassNotFoundException ex) {
      System.err.println("Ignoring not-found context class `" + className + "': " + ex.getMessage());
    } catch (InstantiationException ex) {
      System.err.println("Ignoring non-instantiable context class `" + className + "': " + ex.getMessage());
    } catch (IllegalAccessException ex) {
      System.err.println("Ignoring context class `" + className + "' with non-accessible no-args c'tor: "
        + ex.getMessage());
    }

    installAliases();
    System.err.println("Object context ready; delegating to: " + contexts);
  }

  /**
   * Creates a new <code>ObjectContext</code> instance.  This constructor takes a
   * list of delegate contexts instead of building them from a passed-in
   * environment.  Currently, it's used solely for this class's {@link
   * ObjectContextTest unit test}.
   *
   * @param contexts a <code>List</code> of {@link Context}s.
   */
  ObjectContext(List contexts) {
    this.contexts = contexts;
    installAliases();
  }

  /**
   * Returns the object to which the given name is bound.  Because this context
   * delegates to multiple other contexts, the lookup returns the first successful
   * match.
   *
   * @param name a <code>String</code> value.
   * @return an <code>Object</code> value.
   * @throws NamingException if an error occurs.
   */
  public Object lookup(String name) throws NamingException {
    if (name == null) throw new IllegalArgumentException("Name required");
    if (name.length() == 0) return this;

    // Let alias redirection do its magic
    String alias = aliases.getProperty(name);
    if (alias != null) name = alias;

    for (Iterator i = contexts.iterator(); i.hasNext();) {
      Context c = (Context) i.next();
      try {
        return c.lookup(name);
      } catch (InvalidNameException ignore) {
      } catch (NameNotFoundException ignore) {
      } catch (NamingException ignore){}
    }
    throw new NameNotFoundException(name + " not found in any managed subcontext");
  }

  public Object lookup(Name name) throws NamingException {
    return lookup(name.toString());
  }

  public synchronized void bind(String name, Object obj) throws NamingException {
    if (name == null) throw new IllegalArgumentException("Name required");
    if (name.length() == 0) throw new InvalidNameException("Cannot bind object named after context");

    // If it's an alias name, stop here.
    if (aliases.containsKey(name))
      throw new NameAlreadyBoundException("Name \"" + name + "\" already bound as an aliased name");

    // Make sure it isn't bound anywhere
    for (NamingEnumeration e = list(""); e.hasMore();) {
      NameClassPair nameClassPair = (NameClassPair) e.next();
      if (name.equals(nameClassPair.getName()))
        throw new NameAlreadyBoundException("Name \"" + name + "\" already bound by a managed subcontext");
    }
    doRebind(name, obj);
  }

  public void bind(Name name, Object obj) throws NamingException {
    bind(name.toString(), obj);
  }

  /** {@inheritDoc} */
  public synchronized void rebind(String name, Object obj) throws NamingException {
    if (name == null) throw new IllegalArgumentException("Name required");
    if (name.length() == 0) throw new InvalidNameException("Cannot rebind object named after context");

    // If it's an alias name, remove the alias
    if (aliases.containsKey(name))
      aliases.remove(name);

    doRebind(name, obj);
  }

  /**
   * Rebind the given name to the given object.
   *
   * @param name Name to rebind
   * @param obj Object to which it's bound
   * @throws NamingException if an error occurs.
   */
  private void doRebind(String name, Object obj) throws NamingException {
    boolean bound = false;
    for (Iterator i = contexts.iterator(); i.hasNext();) {
      Context c = (Context) i.next();
      try {
        c.rebind(name, obj);
        bound = true;
      } catch (NamingException ex) {}
    }
    if (!bound) throw new InvalidNameException("Name \"" + name + "\" not compatible with any managed subcontext");
  }

  public void rebind(Name name, Object obj) throws NamingException {
    rebind(name.toString(), obj);
  }

  public void unbind(String name) throws NamingException {
    if (name == null) throw new IllegalArgumentException("Name required");
    if (name.length() == 0) throw new InvalidNameException("Cannot unbind object named after context");

    // See if it's an aliased name
    if (aliases.containsKey(name)) {
      aliases.remove(name);
      return;
    }

    boolean unbound = false;
    for (Iterator i = contexts.iterator(); i.hasNext();) {
      Context c = (Context) i.next();
      try {
        c.unbind(name);
        unbound = true;
      } catch (NamingException ignore) {}
    }
    if (!unbound) throw new InvalidNameException("Name \"" + name + "\" not compatible with any managed subcontext");
  }

  public void unbind(Name name) throws NamingException {
    unbind(name.toString());
  }

  public void rename(String oldName, String newName) throws NamingException {
    if (oldName == null || newName == null)
      throw new IllegalArgumentException("Name required");
    if (oldName.length() == 0 || newName.length() == 0)
      throw new InvalidNameException("Cannot rename object named after context");

    // See if it's an aliased name
    String oldValue = (String) aliases.remove(oldName);
    if (oldValue != null) {
      aliases.setProperty(newName, oldName);
      return;
    }

    boolean renamed = false;
    for (Iterator i = contexts.iterator(); i.hasNext();) {
      Context c = (Context) i.next();
      try {
        c.rename(oldName, newName);
        renamed = true;
      } catch (NamingException ignore) {}
    }
    if (!renamed) throw new InvalidNameException("Names not compatible with any managed subcontext");
  }

  public void rename(Name oldName, Name newName) throws NamingException {
    rename(oldName.toString(), newName.toString());
  }

  public NamingEnumeration list(final String name) throws NamingException {
    final Iterator eachContext = contexts.iterator();
    return new NamingEnumeration() {
      private NamingEnumeration enumeration
        = eachContext.hasNext()? ((Context) eachContext.next()).list(name) : null;
      private boolean open = true;
      public Object next() throws NamingException {
        if (!open) throw new NamingException("closed");
        if (enumeration != null && enumeration.hasMore())
          return enumeration.next();
        else if (eachContext.hasNext()) {
          enumeration = ((Context) eachContext.next()).list(name);
          if (enumeration.hasMore())
            return enumeration.next();
        }
        throw new NoSuchElementException("No more objects in context");
      }
      public Object nextElement() {
        Object rc = null;
        try {
          rc = next();
        } catch (NamingException ignore) {}
        return rc;
      }
      public boolean hasMore() throws NamingException {
        if (!open) return false;
        if (enumeration == null)
          return false;
        else if (enumeration.hasMore())
          return true;
        else if (eachContext.hasNext()) {
          enumeration = ((Context) eachContext.next()).list(name);
          return hasMore();
        }
        return false;
      }
      public boolean hasMoreElements() {
        boolean h = false;
        try {
          h = hasMore();
        } catch (NamingException ignore) {}
        return h;
      }
      public void close() throws NamingException {
        open = false;
        if (enumeration != null)
          enumeration.close();
      }
    };
  }
   
  public NamingEnumeration list(Name name) throws NamingException {
    return list(name.toString());
  }

  public NamingEnumeration listBindings(final String name) throws NamingException {
    final Iterator eachContext = contexts.iterator();
    return new NamingEnumeration() {
      private NamingEnumeration enumeration
        = eachContext.hasNext()? ((Context) eachContext.next()).listBindings(name) : null;
      private boolean open = true;
      public Object next() throws NamingException {
        if (!open) throw new NamingException("closed");
        if (enumeration != null && enumeration.hasMore())
          return enumeration.next();
        else if (eachContext.hasNext()) {
          enumeration = ((Context) eachContext.next()).listBindings(name);
          if (enumeration.hasMore())
            return enumeration.next();
        }
        throw new NoSuchElementException("No more objects in context");
      }
      public Object nextElement() {
        Object rc = null;
        try {
          rc = next();
        } catch (NamingException ignore) {}
        return rc;
      }
      public boolean hasMore() throws NamingException {
        if (!open) return false;
        if (enumeration == null)
          return false;
        else if (enumeration.hasMore())
          return true;
        else if (eachContext.hasNext()) {
          enumeration = ((Context) eachContext.next()).listBindings(name);
          return hasMore();
        }
        return false;
      }
      public boolean hasMoreElements() {
        boolean h = false;
        try {
          h = hasMore();
        } catch (NamingException ignore) {}
        return h;
      }
      public void close() throws NamingException {
        open = false;
        if (enumeration != null)
          enumeration.close();
      }
    };
  }

  public NamingEnumeration listBindings(Name name) throws NamingException {
    return listBindings(name.toString());
  }

  public void destroySubcontext(String name) throws NamingException {
    throw new OperationNotSupportedException("Subcontexts not supported by ObjectContext");
  }

  public void destroySubcontext(Name name) throws NamingException {
    destroySubcontext(name.toString());
  }

  public Context createSubcontext(String name) throws NamingException {
    throw new OperationNotSupportedException("Subcontexts not supported by ObjectContext");
  }

  public Context createSubcontext(Name name) throws NamingException {
    return createSubcontext(name.toString());
  }

  public Object lookupLink(String name) throws NamingException {
    return lookup(name);
  }

  public Object lookupLink(Name name) throws NamingException {
    return lookupLink(name.toString());
  }

  public NameParser getNameParser(String name) throws NamingException {
    return nameParser;
  }

  public NameParser getNameParser(Name name) throws NamingException {
    return getNameParser(name.toString());
  }

  public String composeName(String name, String prefix) throws NamingException {
    Name result = composeName(new CompositeName(name), new CompositeName(prefix));
    return result.toString();
  }

  public Name composeName(Name name, Name prefix) throws NamingException {
    Name result = (Name) prefix.clone();
    result.addAll(name);
    return result;
  }

  public Object addToEnvironment(String propName, Object propVal) throws NamingException {
    if (environment == null) environment = new Hashtable();
    return environment.put(propName, propVal);
  }

  public Object removeFromEnvironment(String propName) throws NamingException {
    if (environment == null) return null;
    return environment.remove(propName);
  }

  public Hashtable getEnvironment() throws NamingException {
    if (environment == null) return new Hashtable();
    return (Hashtable) environment.clone();
  }

  public String getNameInNamespace() throws NamingException {
    return "";
  }

  public void close() throws NamingException {
    environment = null;
  }

  /**
   * Install aliases specified in the properties file.  The properties file simply
   * maps a string object name to a new object name.  Use the system property
   * <code>org.apache.oodt.commons.object.jndi.aliases</code> (preferred) or simply
   * <code>aliases</code> to tell the location of the properties file.
   */
  private void installAliases() {
    String aliasFileName = System.getProperty("org.apache.oodt.commons.object.jndi.aliases", System.getProperty("aliases"));
    if (aliasFileName != null && aliasFileName.length() > 0) {
      FileInputStream in = null;
      try {
        in = new FileInputStream(aliasFileName);
        aliases.load(in);
      } catch (IOException ex) {
        throw new IllegalStateException("Cannot handle I/O exception reading alias file " + aliasFileName
          + ": " + ex.getMessage());
      } finally {
        if (in != null) try {
          in.close();
        } catch (IOException ignore) {}
      }
    }
  }

  /** Context's environment; currently unused. */
  private Hashtable environment;

  /** Parser for object names. */
  private static final NameParser nameParser = new ObjectNameParser();

  /** List of {@link Context}s to which we "multiplex". */
  private List contexts = new ArrayList();

  /** Aliased names. */
  private Properties aliases = new Properties();
}
TOP

Related Classes of org.apache.oodt.commons.object.jndi.ObjectContext

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.