/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE 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.jackrabbit.core.jndi.provider; import javax.naming.Binding; import javax.naming.CompositeName; import javax.naming.CompoundName; 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.NotContextException; import javax.naming.OperationNotSupportedException; import java.util.Enumeration; import java.util.Hashtable; import java.util.Properties; /** * <code>DummyContext</code> is a simple service provider that * implements a flat namespace in memory. It is intended to be used for * testing purposes only. */ class DummyContext extends Hashtable implements Context, Cloneable { private transient Hashtable environment; private static final NameParser nameParser = new FlatNameParser(); /** * Constructs a new <code>DummyContext</code> instance */ DummyContext() { this(null); } /** * Constructs a new <code>DummyContext</code> instance * * @param environment */ DummyContext(Hashtable environment) { if (environment == null) { this.environment = new Hashtable(); } else { this.environment = (Hashtable) environment.clone(); } } protected String getComponentName(Name name) throws NamingException { if (name instanceof CompositeName) { if (name.size() > 1) { throw new InvalidNameException(name.toString() + " has more components than namespace can handle"); } return name.get(0); } else { // compound name return name.toString(); } } protected Object getBoundObject(String name) throws NamingException { Object obj = get(name); if (obj == null) { throw new NameNotFoundException(); } else { return obj; } } public Object clone() { Object obj = super.clone(); ((DummyContext) obj).environment = (Hashtable) environment.clone(); return obj; } //--------------------------------------------------------------< Context > /** * {@inheritDoc} */ public void bind(Name name, Object obj) throws NamingException { if (name.isEmpty()) { throw new InvalidNameException("empty name"); } String n = getComponentName(name); if (containsKey(n)) { throw new NameAlreadyBoundException(); } put(n, obj); } /** * {@inheritDoc} */ public void bind(String name, Object obj) throws NamingException { bind(new CompositeName(name), obj); } /** * {@inheritDoc} */ public void close() throws NamingException { } /** * {@inheritDoc} */ public Name composeName(Name name, Name prefix) throws NamingException { Name newName = (Name) prefix.clone(); return newName.addAll(name); } /** * {@inheritDoc} */ public String composeName(String name, String prefix) throws NamingException { return composeName(new CompositeName(name), new CompositeName(prefix)).toString(); } /** * {@inheritDoc} */ public Context createSubcontext(Name name) throws NamingException { throw new OperationNotSupportedException("subcontexts are not supported"); } /** * {@inheritDoc} */ public Context createSubcontext(String name) throws NamingException { return createSubcontext(new CompositeName(name)); } /** * {@inheritDoc} */ public void destroySubcontext(Name name) throws NamingException { throw new OperationNotSupportedException("subcontexts are not supported"); } /** * {@inheritDoc} */ public void destroySubcontext(String name) throws NamingException { destroySubcontext(new CompositeName(name)); } /** * {@inheritDoc} */ public Hashtable getEnvironment() throws NamingException { return (Hashtable) environment.clone(); } /** * {@inheritDoc} */ public String getNameInNamespace() throws NamingException { throw new OperationNotSupportedException(); } /** * {@inheritDoc} */ public NameParser getNameParser(Name name) throws NamingException { return nameParser; } /** * {@inheritDoc} */ public NameParser getNameParser(String name) throws NamingException { return nameParser; } /** * {@inheritDoc} */ public NamingEnumeration list(Name name) throws NamingException { if (name.isEmpty()) { return new NamingEnum(this); } String n = getComponentName(name); Object obj = getBoundObject(n); if (obj instanceof Context) { return ((Context) obj).list(""); } else { throw new NotContextException(name + " is not bound to a context"); } } /** * {@inheritDoc} */ public NamingEnumeration list(String name) throws NamingException { return list(new CompositeName(name)); } /** * {@inheritDoc} */ public NamingEnumeration listBindings(Name name) throws NamingException { if (name.isEmpty()) { return new BindingEnum(this); } String n = getComponentName(name); Object obj = getBoundObject(n); if (obj instanceof Context) { return ((Context) obj).listBindings(""); } else { throw new NotContextException(name + " is not bound to a context"); } } /** * {@inheritDoc} */ public NamingEnumeration listBindings(String name) throws NamingException { return listBindings(new CompositeName(name)); } /** * {@inheritDoc} */ public Object lookup(Name name) throws NamingException { if (name.isEmpty()) { return clone(); } String n = getComponentName(name); return getBoundObject(n); } /** * {@inheritDoc} */ public Object lookup(String name) throws NamingException { return lookup(new CompositeName(name)); } /** * {@inheritDoc} */ public Object lookupLink(Name name) throws NamingException { // no special handling of links, delegate to lookup(Name) return lookup(name); } /** * {@inheritDoc} */ public Object lookupLink(String name) throws NamingException { return lookupLink(new CompositeName(name)); } /** * {@inheritDoc} */ public void rebind(Name name, Object obj) throws NamingException { if (name.isEmpty()) { throw new InvalidNameException("empty name"); } String n = getComponentName(name); put(n, obj); } /** * {@inheritDoc} */ public void rebind(String name, Object obj) throws NamingException { rebind(new CompositeName(name), obj); } /** * {@inheritDoc} */ public Object removeFromEnvironment(String propName) throws NamingException { return environment.remove(propName); } /** * {@inheritDoc} */ public void rename(Name oldName, Name newName) throws NamingException { if (oldName.isEmpty() || newName.isEmpty()) { throw new InvalidNameException("empty name"); } else { Object obj = lookup(oldName); bind(newName, obj); unbind(oldName); } } /** * {@inheritDoc} */ public void rename(String oldName, String newName) throws NamingException { rename(new CompositeName(oldName), new CompositeName(newName)); } /** * {@inheritDoc} */ public void unbind(Name name) throws NamingException { if (name.isEmpty()) { throw new InvalidNameException("empty name"); } String n = getComponentName(name); remove(n); } /** * {@inheritDoc} */ public void unbind(String name) throws NamingException { unbind(new CompositeName(name)); } /** * {@inheritDoc} */ public Object addToEnvironment(String propName, Object propVal) throws NamingException { return environment.put(propName, propVal); } //--------------------------------------------------------< inner classes > /** * <code>FlatNameParser</code> ... */ static class FlatNameParser implements NameParser { private static final Properties syntax = new Properties(); static { syntax.put("jndi.syntax.direction", "flat"); syntax.put("jndi.syntax.ignorecase", "false"); } /** * @see NameParser#parse(String) */ public Name parse(String name) throws NamingException { return new CompoundName(name, syntax); } } /** * <code>NamingEnum</code> ... */ class NamingEnum implements NamingEnumeration { protected Enumeration namesEnum; protected Hashtable bindings; NamingEnum(Hashtable bindings) { namesEnum = bindings.keys(); this.bindings = bindings; } public boolean hasMoreElements() { return namesEnum.hasMoreElements(); } public boolean hasMore() throws NamingException { return hasMoreElements(); } public Object next() throws NamingException { return nextElement(); } public Object nextElement() { String name = (String) namesEnum.nextElement(); String className = bindings.get(name).getClass().getName(); return new NameClassPair(name, className); } public void close() throws NamingException { } } /** * <code>BindingEnum</code> ... */ class BindingEnum extends NamingEnum { BindingEnum(Hashtable bindings) { super(bindings); } public Object nextElement() { String name = (String) namesEnum.nextElement(); return new Binding(name, bindings.get(name)); } } }