feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
301
jdkSrc/jdk8/com/sun/jndi/toolkit/corba/CorbaUtils.java
Normal file
301
jdkSrc/jdk8/com/sun/jndi/toolkit/corba/CorbaUtils.java
Normal file
@@ -0,0 +1,301 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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 General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.jndi.toolkit.corba;
|
||||
|
||||
// Needed for RMI/IIOP
|
||||
import java.rmi.Remote;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Properties;
|
||||
import java.util.Enumeration;
|
||||
|
||||
import org.omg.CORBA.ORB;
|
||||
|
||||
import javax.naming.*;
|
||||
|
||||
import com.sun.jndi.cosnaming.CNCtx;
|
||||
|
||||
/**
|
||||
* Contains utilities for performing CORBA-related tasks:
|
||||
* 1. Get the org.omg.CORBA.Object for a java.rmi.Remote object.
|
||||
* 2. Create an ORB to use for a given host/port, and environment properties.
|
||||
*
|
||||
* @author Simon Nash
|
||||
* @author Bryan Atsatt
|
||||
*/
|
||||
|
||||
public class CorbaUtils {
|
||||
/**
|
||||
* Returns the CORBA object reference associated with a Remote
|
||||
* object by using the javax.rmi.CORBA package.
|
||||
*<p>
|
||||
* Use reflection to avoid hard dependencies on javax.rmi.CORBA package.
|
||||
* This method effective does the following:
|
||||
*<blockquote><pre>
|
||||
* java.lang.Object stub;
|
||||
* try {
|
||||
* stub = PortableRemoteObject.toStub(remoteObj);
|
||||
* } catch (Exception e) {
|
||||
* throw new ConfigurationException("Object not exported or not found");
|
||||
* }
|
||||
* if (!(stub instanceof javax.rmi.CORBA.Stub)) {
|
||||
* return null; // JRMP impl or JRMP stub
|
||||
* }
|
||||
* try {
|
||||
* ((javax.rmi.CORBA.Stub)stub).connect(orb); // try to connect IIOP stub
|
||||
* } catch (RemoteException e) {
|
||||
* // ignore 'already connected' error
|
||||
* }
|
||||
* return (javax.rmi.CORBA.Stub)stub;
|
||||
*
|
||||
* @param remoteObj The non-null remote object for
|
||||
* @param orb The non-null ORB to connect the remote object to
|
||||
* @return The CORBA Object for remoteObj; null if <tt>remoteObj</tt>
|
||||
* is a JRMP implementation or JRMP stub.
|
||||
* @exception ClassNotFoundException The RMI-IIOP package is not available
|
||||
* @exception ConfigurationException The CORBA Object cannot be obtained
|
||||
* because of configuration problems.
|
||||
*/
|
||||
public static org.omg.CORBA.Object remoteToCorba(Remote remoteObj, ORB orb)
|
||||
throws ClassNotFoundException, ConfigurationException {
|
||||
synchronized (CorbaUtils.class) {
|
||||
if (toStubMethod == null) {
|
||||
initMethodHandles();
|
||||
}
|
||||
}
|
||||
|
||||
// First, get remoteObj's stub
|
||||
|
||||
// javax.rmi.CORBA.Stub stub = PortableRemoteObject.toStub(remoteObj);
|
||||
|
||||
java.lang.Object stub;
|
||||
|
||||
try {
|
||||
stub = toStubMethod.invoke(null, new java.lang.Object[]{remoteObj});
|
||||
|
||||
} catch (InvocationTargetException e) {
|
||||
Throwable realException = e.getTargetException();
|
||||
// realException.printStackTrace();
|
||||
|
||||
ConfigurationException ce = new ConfigurationException(
|
||||
"Problem with PortableRemoteObject.toStub(); object not exported or stub not found");
|
||||
ce.setRootCause(realException);
|
||||
throw ce;
|
||||
|
||||
} catch (IllegalAccessException e) {
|
||||
ConfigurationException ce = new ConfigurationException(
|
||||
"Cannot invoke javax.rmi.PortableRemoteObject.toStub(java.rmi.Remote)");
|
||||
|
||||
ce.setRootCause(e);
|
||||
throw ce;
|
||||
}
|
||||
|
||||
// Next, make sure that the stub is javax.rmi.CORBA.Stub
|
||||
|
||||
if (!corbaStubClass.isInstance(stub)) {
|
||||
return null; // JRMP implementation or JRMP stub
|
||||
}
|
||||
|
||||
// Next, make sure that the stub is connected
|
||||
// Invoke stub.connect(orb)
|
||||
try {
|
||||
connectMethod.invoke(stub, new java.lang.Object[]{orb});
|
||||
|
||||
} catch (InvocationTargetException e) {
|
||||
Throwable realException = e.getTargetException();
|
||||
// realException.printStackTrace();
|
||||
|
||||
if (!(realException instanceof java.rmi.RemoteException)) {
|
||||
ConfigurationException ce = new ConfigurationException(
|
||||
"Problem invoking javax.rmi.CORBA.Stub.connect()");
|
||||
ce.setRootCause(realException);
|
||||
throw ce;
|
||||
}
|
||||
// ignore RemoteException because stub might have already
|
||||
// been connected
|
||||
} catch (IllegalAccessException e) {
|
||||
ConfigurationException ce = new ConfigurationException(
|
||||
"Cannot invoke javax.rmi.CORBA.Stub.connect()");
|
||||
ce.setRootCause(e);
|
||||
throw ce;
|
||||
}
|
||||
// Finally, return stub
|
||||
return (org.omg.CORBA.Object)stub;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ORB using given server and port number, and properties from environment.
|
||||
*
|
||||
* @param server Possibly null server; if null means use default;
|
||||
* For applet, it is the applet host; for app, it is localhost.
|
||||
* @param port Port number, -1 means default port
|
||||
* @param env Possibly null environment. Contains environment properties.
|
||||
* Could contain ORB itself; or applet used for initializing ORB.
|
||||
* Use all String properties from env for initializing ORB
|
||||
* @return A non-null ORB.
|
||||
*/
|
||||
public static ORB getOrb(String server, int port, Hashtable<?,?> env) {
|
||||
// See if we can get info from environment
|
||||
Properties orbProp;
|
||||
|
||||
// Extract any org.omg.CORBA properties from environment
|
||||
if (env != null) {
|
||||
if (env instanceof Properties) {
|
||||
// Already a Properties, just clone
|
||||
orbProp = (Properties) env.clone();
|
||||
} else {
|
||||
// Get all String properties
|
||||
Enumeration<?> envProp;
|
||||
orbProp = new Properties();
|
||||
for (envProp = env.keys(); envProp.hasMoreElements();) {
|
||||
String key = (String)envProp.nextElement();
|
||||
Object val = env.get(key);
|
||||
if (val instanceof String) {
|
||||
orbProp.put(key, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
orbProp = new Properties();
|
||||
}
|
||||
|
||||
if (server != null) {
|
||||
orbProp.put("org.omg.CORBA.ORBInitialHost", server);
|
||||
}
|
||||
if (port >= 0) {
|
||||
orbProp.put("org.omg.CORBA.ORBInitialPort", ""+port);
|
||||
}
|
||||
|
||||
// Get Applet from environment
|
||||
if (env != null) {
|
||||
Object applet = env.get(Context.APPLET);
|
||||
if (applet != null) {
|
||||
// Create ORBs for an applet
|
||||
return initAppletORB(applet, orbProp);
|
||||
}
|
||||
}
|
||||
|
||||
// Create ORBs using orbProp for a standalone application
|
||||
return ORB.init(new String[0], orbProp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether object factory code base is trusted.
|
||||
* Classes may only be loaded from an arbitrary URL code base when
|
||||
* the system property com.sun.jndi.rmi.object.trustURLCodebase
|
||||
* has been set to "true".
|
||||
*/
|
||||
public static boolean isObjectFactoryTrusted(Object obj)
|
||||
throws NamingException {
|
||||
|
||||
// Extract Reference, if possible
|
||||
Reference ref = null;
|
||||
if (obj instanceof Reference) {
|
||||
ref = (Reference) obj;
|
||||
} else if (obj instanceof Referenceable) {
|
||||
ref = ((Referenceable)(obj)).getReference();
|
||||
}
|
||||
|
||||
if (ref != null && ref.getFactoryClassLocation() != null &&
|
||||
!CNCtx.trustURLCodebase) {
|
||||
throw new ConfigurationException(
|
||||
"The object factory is untrusted. Set the system property" +
|
||||
" 'com.sun.jndi.cosnaming.object.trustURLCodebase' to 'true'.");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a new ORB instance for the given applet
|
||||
* without creating a static dependency on java.applet.
|
||||
*/
|
||||
private static ORB initAppletORB(Object applet, Properties orbProp) {
|
||||
try {
|
||||
Class<?> appletClass = Class.forName("java.applet.Applet", true, null);
|
||||
if (!appletClass.isInstance(applet)) {
|
||||
throw new ClassCastException(applet.getClass().getName());
|
||||
}
|
||||
|
||||
// invoke the static method ORB.init(applet, orbProp);
|
||||
Method method = ORB.class.getMethod("init", appletClass, Properties.class);
|
||||
return (ORB) method.invoke(null, applet, orbProp);
|
||||
} catch (ClassNotFoundException e) {
|
||||
// java.applet.Applet doesn't exist and the applet parameter is
|
||||
// non-null; so throw CCE
|
||||
throw new ClassCastException(applet.getClass().getName());
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new AssertionError(e);
|
||||
} catch (InvocationTargetException e) {
|
||||
Throwable cause = e.getCause();
|
||||
if (cause instanceof RuntimeException) {
|
||||
throw (RuntimeException) cause;
|
||||
} else if (cause instanceof Error) {
|
||||
throw (Error) cause;
|
||||
}
|
||||
throw new AssertionError(e);
|
||||
} catch (IllegalAccessException iae) {
|
||||
throw new AssertionError(iae);
|
||||
}
|
||||
}
|
||||
|
||||
// Fields used for reflection of RMI-IIOP
|
||||
private static Method toStubMethod = null;
|
||||
private static Method connectMethod = null;
|
||||
private static Class<?> corbaStubClass = null;
|
||||
/**
|
||||
* Initializes reflection method handles for RMI-IIOP.
|
||||
* @exception ClassNotFoundException javax.rmi.CORBA.* not available
|
||||
*/
|
||||
private static void initMethodHandles() throws ClassNotFoundException {
|
||||
// Get javax.rmi.CORBA.Stub class
|
||||
corbaStubClass = Class.forName("javax.rmi.CORBA.Stub");
|
||||
|
||||
// Get javax.rmi.CORBA.Stub.connect(org.omg.CORBA.ORB) method
|
||||
|
||||
try {
|
||||
connectMethod = corbaStubClass.getMethod("connect",
|
||||
new Class<?>[] {org.omg.CORBA.ORB.class});
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new IllegalStateException(
|
||||
"No method definition for javax.rmi.CORBA.Stub.connect(org.omg.CORBA.ORB)");
|
||||
}
|
||||
|
||||
// Get javax.rmi.PortableRemoteObject class
|
||||
Class<?> proClass = Class.forName("javax.rmi.PortableRemoteObject");
|
||||
|
||||
// Get javax.rmi.PortableRemoteObject.toStub(java.rmi.Remote) method
|
||||
try {
|
||||
toStubMethod = proClass.getMethod("toStub",
|
||||
new Class<?>[] {java.rmi.Remote.class});
|
||||
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new IllegalStateException(
|
||||
"No method definition for javax.rmi.PortableRemoteObject.toStub(java.rmi.Remote)");
|
||||
}
|
||||
}
|
||||
}
|
||||
692
jdkSrc/jdk8/com/sun/jndi/toolkit/ctx/AtomicContext.java
Normal file
692
jdkSrc/jdk8/com/sun/jndi/toolkit/ctx/AtomicContext.java
Normal file
@@ -0,0 +1,692 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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 General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.jndi.toolkit.ctx;
|
||||
|
||||
import javax.naming.*;
|
||||
|
||||
/**
|
||||
* Clients: deal only with names for its own naming service
|
||||
* and deals with single contexts that can be built up into
|
||||
* hierarchical naming systems.
|
||||
* Direct subclasses of AtomicContext must provide implementations for
|
||||
* the abstract a_ Context methods, and c_parseComponent().
|
||||
*
|
||||
* If the subclass implements the notion of implicit nns,
|
||||
* it must override the a_*_nns Context methods as well.
|
||||
*
|
||||
* @author Rosanna Lee
|
||||
*
|
||||
*/
|
||||
|
||||
public abstract class AtomicContext extends ComponentContext {
|
||||
private static int debug = 0;
|
||||
|
||||
protected AtomicContext () {
|
||||
_contextType = _ATOMIC;
|
||||
}
|
||||
|
||||
// ------ Abstract methods whose implementation are provided by subclasses
|
||||
|
||||
|
||||
/* Equivalent to Context methods */
|
||||
protected abstract Object a_lookup(String name, Continuation cont)
|
||||
throws NamingException;
|
||||
protected abstract Object a_lookupLink(String name, Continuation cont)
|
||||
throws NamingException;
|
||||
|
||||
protected abstract NamingEnumeration<NameClassPair> a_list(
|
||||
Continuation cont) throws NamingException;
|
||||
protected abstract NamingEnumeration<Binding> a_listBindings(
|
||||
Continuation cont) throws NamingException;
|
||||
protected abstract void a_bind(String name, Object obj, Continuation cont)
|
||||
throws NamingException;
|
||||
protected abstract void a_rebind(String name, Object obj, Continuation cont)
|
||||
throws NamingException;
|
||||
protected abstract void a_unbind(String name, Continuation cont)
|
||||
throws NamingException;
|
||||
protected abstract void a_destroySubcontext(String name, Continuation cont)
|
||||
throws NamingException;
|
||||
protected abstract Context a_createSubcontext(String name,
|
||||
Continuation cont) throws NamingException;
|
||||
protected abstract void a_rename(String oldname, Name newname,
|
||||
Continuation cont) throws NamingException;
|
||||
protected abstract NameParser a_getNameParser(Continuation cont)
|
||||
throws NamingException;
|
||||
|
||||
/* Parsing */
|
||||
/**
|
||||
* Parse 'inputName' into two parts:
|
||||
* head: the first component in this name
|
||||
* tail: the rest of the unused name.
|
||||
*
|
||||
* Subclasses should provide an implementation for this method
|
||||
* which parses inputName using its own name syntax.
|
||||
*/
|
||||
protected abstract StringHeadTail c_parseComponent(String inputName,
|
||||
Continuation cont) throws NamingException;
|
||||
|
||||
|
||||
// ------ Methods that need to be overridden by subclass
|
||||
|
||||
/* Resolution method for supporting federation */
|
||||
/**
|
||||
* Resolves the nns for 'name' when the named context is acting
|
||||
* as an intermediate context.
|
||||
*
|
||||
* For a system that supports junctions, this would be equilvalent to
|
||||
* a_lookup(name, cont);
|
||||
* because for junctions, an intermediate slash simply signifies
|
||||
* a syntactic separator.
|
||||
*
|
||||
* For a system that supports implicit nns, this would be equivalent to
|
||||
* a_lookup_nns(name, cont);
|
||||
* because for implicit nns, a slash always signifies the implicit nns,
|
||||
* regardless of whether it is intermediate or trailing.
|
||||
*
|
||||
* By default this method supports junctions, and also allows for an
|
||||
* implicit nns to be dynamically determined through the use of the
|
||||
* "nns" reference (see a_processJunction_nns()).
|
||||
* Contexts that implement implicit nns directly should provide an
|
||||
* appropriate override.
|
||||
*/
|
||||
protected Object a_resolveIntermediate_nns(String name, Continuation cont)
|
||||
throws NamingException {
|
||||
try {
|
||||
final Object obj = a_lookup(name, cont);
|
||||
|
||||
// Do not append "" to Continuation 'cont' even if set
|
||||
// because the intention is to ignore the nns
|
||||
|
||||
//
|
||||
if (obj != null && getClass().isInstance(obj)) {
|
||||
// If "obj" is in the same type as this object, it must
|
||||
// not be a junction. Continue the lookup with "/".
|
||||
|
||||
cont.setContinueNNS(obj, name, this);
|
||||
return null;
|
||||
|
||||
} else if (obj != null && !(obj instanceof Context)) {
|
||||
// obj is not even a context, so try to find its nns
|
||||
// dynamically by constructing a Reference containing obj.
|
||||
RefAddr addr = new RefAddr("nns") {
|
||||
public Object getContent() {
|
||||
return obj;
|
||||
}
|
||||
private static final long serialVersionUID =
|
||||
-3399518522645918499L;
|
||||
};
|
||||
Reference ref = new Reference("java.lang.Object", addr);
|
||||
|
||||
// Resolved name has trailing slash to indicate nns
|
||||
CompositeName resName = new CompositeName();
|
||||
resName.add(name);
|
||||
resName.add(""); // add trailing slash
|
||||
|
||||
// Set continuation leave it to
|
||||
// PartialCompositeContext.getPCContext() to throw CPE.
|
||||
// Do not use setContinueNNS() because we've already
|
||||
// consumed "/" (i.e., moved it to resName).
|
||||
|
||||
cont.setContinue(ref, resName, this);
|
||||
return null;
|
||||
|
||||
} else {
|
||||
return obj;
|
||||
}
|
||||
|
||||
} catch (NamingException e) {
|
||||
e.appendRemainingComponent(""); // add nns back
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/* Equivalent of Context Methods for supporting nns */
|
||||
|
||||
// The following methods are called when the DirContext methods
|
||||
// are invoked with a name that has a trailing slash.
|
||||
// For naming systems that support implicit nns,
|
||||
// the trailing slash signifies the implicit nns.
|
||||
// For such naming systems, override these a_*_nns methods.
|
||||
//
|
||||
// For naming systems that support junctions (explicit nns),
|
||||
// the trailing slash is meaningless because a junction does not
|
||||
// have an implicit nns. The default implementation here
|
||||
// throws a NameNotFoundException for such names.
|
||||
// If a context wants to accept a trailing slash as having
|
||||
// the same meaning as the same name without a trailing slash,
|
||||
// then it should override these a_*_nns methods.
|
||||
|
||||
|
||||
protected Object a_lookup_nns(String name, Continuation cont)
|
||||
throws NamingException {
|
||||
a_processJunction_nns(name, cont);
|
||||
return null;
|
||||
}
|
||||
|
||||
protected Object a_lookupLink_nns(String name, Continuation cont)
|
||||
throws NamingException {
|
||||
a_processJunction_nns(name, cont);
|
||||
return null;
|
||||
}
|
||||
|
||||
protected NamingEnumeration<NameClassPair> a_list_nns(Continuation cont)
|
||||
throws NamingException {
|
||||
a_processJunction_nns(cont);
|
||||
return null;
|
||||
}
|
||||
protected NamingEnumeration<Binding> a_listBindings_nns(Continuation cont)
|
||||
throws NamingException {
|
||||
a_processJunction_nns(cont);
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void a_bind_nns(String name, Object obj, Continuation cont)
|
||||
throws NamingException {
|
||||
a_processJunction_nns(name, cont);
|
||||
}
|
||||
|
||||
protected void a_rebind_nns(String name, Object obj, Continuation cont)
|
||||
throws NamingException {
|
||||
a_processJunction_nns(name, cont);
|
||||
}
|
||||
|
||||
protected void a_unbind_nns(String name, Continuation cont)
|
||||
throws NamingException {
|
||||
a_processJunction_nns(name, cont);
|
||||
}
|
||||
|
||||
protected Context a_createSubcontext_nns(String name, Continuation cont)
|
||||
throws NamingException {
|
||||
a_processJunction_nns(name, cont);
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void a_destroySubcontext_nns(String name, Continuation cont)
|
||||
throws NamingException {
|
||||
a_processJunction_nns(name, cont);
|
||||
}
|
||||
|
||||
protected void a_rename_nns(String oldname, Name newname, Continuation cont)
|
||||
throws NamingException {
|
||||
a_processJunction_nns(oldname, cont);
|
||||
}
|
||||
|
||||
protected NameParser a_getNameParser_nns(Continuation cont)
|
||||
throws NamingException {
|
||||
a_processJunction_nns(cont);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected boolean isEmpty(String name) {
|
||||
return name == null || name.equals("");
|
||||
}
|
||||
|
||||
// ------ implementations of c_ and c_*_nns methods using
|
||||
// ------ the corresponding a_ and a_*_nns methods
|
||||
|
||||
/* Equivalent to methods in Context interface */
|
||||
|
||||
protected Object c_lookup(Name name, Continuation cont)
|
||||
throws NamingException {
|
||||
Object ret = null;
|
||||
if (resolve_to_penultimate_context(name, cont)) {
|
||||
ret = a_lookup(name.toString(), cont);
|
||||
if (ret != null && ret instanceof LinkRef) {
|
||||
cont.setContinue(ret, name, this);
|
||||
ret = null;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
protected Object c_lookupLink(Name name, Continuation cont)
|
||||
throws NamingException {
|
||||
if (resolve_to_penultimate_context(name, cont)) {
|
||||
return a_lookupLink(name.toString(), cont);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected NamingEnumeration<NameClassPair> c_list(Name name,
|
||||
Continuation cont) throws NamingException {
|
||||
if (resolve_to_context(name, cont)) {
|
||||
return a_list(cont);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected NamingEnumeration<Binding> c_listBindings(Name name,
|
||||
Continuation cont) throws NamingException {
|
||||
if (resolve_to_context(name, cont)) {
|
||||
return a_listBindings(cont);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void c_bind(Name name, Object obj, Continuation cont)
|
||||
throws NamingException {
|
||||
if (resolve_to_penultimate_context(name, cont))
|
||||
a_bind(name.toString(), obj, cont);
|
||||
}
|
||||
|
||||
protected void c_rebind(Name name, Object obj, Continuation cont)
|
||||
throws NamingException {
|
||||
if (resolve_to_penultimate_context(name, cont))
|
||||
a_rebind(name.toString(), obj, cont);
|
||||
}
|
||||
|
||||
protected void c_unbind(Name name, Continuation cont)
|
||||
throws NamingException {
|
||||
if (resolve_to_penultimate_context(name, cont))
|
||||
a_unbind(name.toString(), cont);
|
||||
}
|
||||
|
||||
protected void c_destroySubcontext(Name name, Continuation cont)
|
||||
throws NamingException {
|
||||
if (resolve_to_penultimate_context(name, cont))
|
||||
a_destroySubcontext(name.toString(), cont);
|
||||
}
|
||||
|
||||
protected Context c_createSubcontext(Name name,
|
||||
Continuation cont) throws NamingException {
|
||||
if (resolve_to_penultimate_context(name, cont))
|
||||
return a_createSubcontext(name.toString(), cont);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void c_rename(Name oldname, Name newname,
|
||||
Continuation cont) throws NamingException {
|
||||
if (resolve_to_penultimate_context(oldname, cont))
|
||||
a_rename(oldname.toString(), newname, cont);
|
||||
}
|
||||
|
||||
protected NameParser c_getNameParser(Name name,
|
||||
Continuation cont) throws NamingException {
|
||||
if (resolve_to_context(name, cont))
|
||||
return a_getNameParser(cont);
|
||||
return null;
|
||||
}
|
||||
|
||||
/* The following are overridden only for AtomicContexts.
|
||||
* AtomicContext is used by PartialCompositeDirContext and ComponentDirContext
|
||||
* in the inheritance tree to make use of methods in
|
||||
* PartialCompositeContext and ComponentContext. We only want to use the
|
||||
* atomic forms when we're actually an atomic context.
|
||||
*/
|
||||
|
||||
/* From ComponentContext */
|
||||
|
||||
protected Object c_resolveIntermediate_nns(Name name, Continuation cont)
|
||||
throws NamingException {
|
||||
if (_contextType == _ATOMIC) {
|
||||
Object ret = null;
|
||||
if (resolve_to_penultimate_context_nns(name, cont)) {
|
||||
ret = a_resolveIntermediate_nns(name.toString(), cont);
|
||||
if (ret != null && ret instanceof LinkRef) {
|
||||
cont.setContinue(ret, name, this);
|
||||
ret = null;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
} else {
|
||||
// use ComponentContext
|
||||
return super.c_resolveIntermediate_nns(name, cont);
|
||||
}
|
||||
}
|
||||
|
||||
/* Equivalent to methods in Context interface for nns */
|
||||
|
||||
protected Object c_lookup_nns(Name name, Continuation cont)
|
||||
throws NamingException {
|
||||
if (_contextType == _ATOMIC) {
|
||||
Object ret = null;
|
||||
if (resolve_to_penultimate_context_nns(name, cont)) {
|
||||
ret = a_lookup_nns(name.toString(), cont);
|
||||
if (ret != null && ret instanceof LinkRef) {
|
||||
cont.setContinue(ret, name, this);
|
||||
ret = null;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
} else {
|
||||
return super.c_lookup_nns(name, cont);
|
||||
}
|
||||
}
|
||||
|
||||
protected Object c_lookupLink_nns(Name name, Continuation cont)
|
||||
throws NamingException {
|
||||
if (_contextType == _ATOMIC) {
|
||||
// %%% check logic
|
||||
resolve_to_nns_and_continue(name, cont);
|
||||
return null;
|
||||
} else {
|
||||
// use ComponentContext
|
||||
return super.c_lookupLink_nns(name, cont);
|
||||
}
|
||||
}
|
||||
|
||||
protected NamingEnumeration<NameClassPair> c_list_nns(Name name,
|
||||
Continuation cont) throws NamingException {
|
||||
if (_contextType == _ATOMIC) {
|
||||
resolve_to_nns_and_continue(name, cont);
|
||||
return null;
|
||||
} else {
|
||||
// use ComponentContext
|
||||
return super.c_list_nns(name, cont);
|
||||
}
|
||||
}
|
||||
|
||||
protected NamingEnumeration<Binding> c_listBindings_nns(Name name,
|
||||
Continuation cont) throws NamingException {
|
||||
if (_contextType == _ATOMIC) {
|
||||
resolve_to_nns_and_continue(name, cont);
|
||||
return null;
|
||||
} else {
|
||||
// use ComponentContext
|
||||
return super.c_listBindings_nns(name, cont);
|
||||
}
|
||||
}
|
||||
|
||||
protected void c_bind_nns(Name name, Object obj, Continuation cont)
|
||||
throws NamingException {
|
||||
if (_contextType == _ATOMIC) {
|
||||
if (resolve_to_penultimate_context_nns(name, cont))
|
||||
a_bind_nns(name.toString(), obj, cont);
|
||||
} else {
|
||||
// use ComponentContext
|
||||
super.c_bind_nns(name, obj, cont);
|
||||
}
|
||||
}
|
||||
|
||||
protected void c_rebind_nns(Name name, Object obj, Continuation cont)
|
||||
throws NamingException {
|
||||
if (_contextType == _ATOMIC) {
|
||||
if (resolve_to_penultimate_context_nns(name, cont))
|
||||
a_rebind_nns(name.toString(), obj, cont);
|
||||
} else {
|
||||
// use ComponentContext
|
||||
super.c_rebind_nns(name, obj, cont);
|
||||
}
|
||||
}
|
||||
|
||||
protected void c_unbind_nns(Name name, Continuation cont)
|
||||
throws NamingException {
|
||||
if (_contextType == _ATOMIC) {
|
||||
if (resolve_to_penultimate_context_nns(name, cont))
|
||||
a_unbind_nns(name.toString(), cont);
|
||||
} else {
|
||||
// use ComponentContext
|
||||
super.c_unbind_nns(name, cont);
|
||||
}
|
||||
}
|
||||
|
||||
protected Context c_createSubcontext_nns(Name name,
|
||||
Continuation cont) throws NamingException {
|
||||
if (_contextType == _ATOMIC) {
|
||||
if (resolve_to_penultimate_context_nns(name, cont))
|
||||
return a_createSubcontext_nns(name.toString(), cont);
|
||||
else
|
||||
return null;
|
||||
} else {
|
||||
// use ComponentContext
|
||||
return super.c_createSubcontext_nns(name, cont);
|
||||
}
|
||||
}
|
||||
|
||||
protected void c_destroySubcontext_nns(Name name, Continuation cont)
|
||||
throws NamingException {
|
||||
if (_contextType == _ATOMIC) {
|
||||
if (resolve_to_penultimate_context_nns(name, cont))
|
||||
a_destroySubcontext_nns(name.toString(), cont);
|
||||
} else {
|
||||
// use ComponentContext
|
||||
super.c_destroySubcontext_nns(name, cont);
|
||||
}
|
||||
}
|
||||
|
||||
protected void c_rename_nns(Name oldname, Name newname, Continuation cont)
|
||||
throws NamingException {
|
||||
if (_contextType == _ATOMIC) {
|
||||
if (resolve_to_penultimate_context_nns(oldname, cont))
|
||||
a_rename_nns(oldname.toString(), newname, cont);
|
||||
} else {
|
||||
// use ComponentContext
|
||||
super.c_rename_nns(oldname, newname, cont);
|
||||
}
|
||||
}
|
||||
|
||||
protected NameParser c_getNameParser_nns(Name name, Continuation cont)
|
||||
throws NamingException {
|
||||
if (_contextType == _ATOMIC) {
|
||||
resolve_to_nns_and_continue(name, cont);
|
||||
return null;
|
||||
} else {
|
||||
// use COmponentContext
|
||||
return super.c_getNameParser_nns(name, cont);
|
||||
}
|
||||
}
|
||||
|
||||
// -------------- internal methods used by this class
|
||||
|
||||
/* Handles nns for junctions */
|
||||
/**
|
||||
* This function is used when implementing a naming system that
|
||||
* supports junctions. For example, when the a_bind_nns(name, newobj)
|
||||
* method is invoked, that means the caller is attempting to bind the
|
||||
* object 'newobj' to the nns of 'name'. For context that supports
|
||||
* junctions, 'name' names a junction and is pointing to the root
|
||||
* of another naming system, which in turn might have an nns.
|
||||
* This means that a_bind_nns() should first resolve 'name' and attempt to
|
||||
* continue the operation in the context named by 'name'. (i.e. bind
|
||||
* to the nns of the context named by 'name').
|
||||
* If name is already empty, then throw NameNotFoundException because
|
||||
* this context by default does not have any nns.
|
||||
*/
|
||||
protected void a_processJunction_nns(String name, Continuation cont)
|
||||
throws NamingException {
|
||||
if (name.equals("")) {
|
||||
NameNotFoundException e = new NameNotFoundException();
|
||||
cont.setErrorNNS(this, name);
|
||||
throw cont.fillInException(e);
|
||||
}
|
||||
try {
|
||||
// lookup name to continue operation in nns
|
||||
Object target = a_lookup(name, cont);
|
||||
if (cont.isContinue())
|
||||
cont.appendRemainingComponent(""); // add nns back
|
||||
else {
|
||||
cont.setContinueNNS(target, name, this);
|
||||
}
|
||||
} catch (NamingException e) {
|
||||
e.appendRemainingComponent(""); // add nns back
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is used when implementing a naming system that
|
||||
* supports junctions. For example, when the a_list_nns(newobj)
|
||||
* method is invoked, that means the caller is attempting to list the
|
||||
* the nns context of of this context. For a context that supports
|
||||
* junctions, it by default does not have any nns. Consequently,
|
||||
* a NameNotFoundException is thrown.
|
||||
*/
|
||||
protected void a_processJunction_nns(Continuation cont) throws NamingException {
|
||||
|
||||
// Construct a new Reference that contains this context.
|
||||
RefAddr addr = new RefAddr("nns") {
|
||||
public Object getContent() {
|
||||
return AtomicContext.this;
|
||||
}
|
||||
private static final long serialVersionUID = 3449785852664978312L;
|
||||
};
|
||||
Reference ref = new Reference("java.lang.Object", addr);
|
||||
|
||||
// Set continuation leave it to PartialCompositeContext.getPCContext()
|
||||
// to throw the exception.
|
||||
// Do not use setContinueNNS() because we've are
|
||||
// setting relativeResolvedName to "/".
|
||||
cont.setContinue(ref, _NNS_NAME, this);
|
||||
}
|
||||
|
||||
/* *********** core resolution routines ******************* */
|
||||
|
||||
/** Resolve to context named by 'name'.
|
||||
* Returns true if at named context (i.e. 'name' is empty name).
|
||||
* Returns false otherwise, and sets Continuation on parts of 'name'
|
||||
* not yet resolved.
|
||||
*/
|
||||
protected boolean resolve_to_context(Name name, Continuation cont)
|
||||
throws NamingException {
|
||||
String target = name.toString();
|
||||
|
||||
|
||||
StringHeadTail ht = c_parseComponent(target, cont);
|
||||
String tail = ht.getTail();
|
||||
String head = ht.getHead();
|
||||
|
||||
if (debug > 0)
|
||||
System.out.println("RESOLVE TO CONTEXT(" + target + ") = {" +
|
||||
head + ", " + tail + "}");
|
||||
|
||||
if (head == null) {
|
||||
// something is wrong; no name at all
|
||||
InvalidNameException e = new InvalidNameException();
|
||||
throw cont.fillInException(e);
|
||||
}
|
||||
if (!isEmpty(head)) {
|
||||
// if there is head is a non-empty name
|
||||
// this means more resolution to be done
|
||||
try {
|
||||
Object headCtx = a_lookup(head, cont);
|
||||
// System.out.println("answer " + headCtx);
|
||||
if (headCtx != null)
|
||||
cont.setContinue(headCtx, head, this, (tail == null ? "" : tail));
|
||||
else if (cont.isContinue())
|
||||
cont.appendRemainingComponent(tail);
|
||||
} catch (NamingException e) {
|
||||
e.appendRemainingComponent(tail);
|
||||
throw e;
|
||||
}
|
||||
} else {
|
||||
cont.setSuccess(); // clear
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves to penultimate context named by 'name'.
|
||||
* Returns true if penultimate context has been reached (i.e. name
|
||||
* only has one atomic component left).
|
||||
* Returns false otherwise, and sets Continuation to parts of name
|
||||
* not yet resolved.
|
||||
*/
|
||||
protected boolean resolve_to_penultimate_context(Name name, Continuation cont)
|
||||
throws NamingException {
|
||||
String target = name.toString();
|
||||
|
||||
if (debug > 0)
|
||||
System.out.println("RESOLVE TO PENULTIMATE" + target);
|
||||
|
||||
StringHeadTail ht = c_parseComponent(target, cont);
|
||||
String tail = ht.getTail();
|
||||
String head = ht.getHead();
|
||||
if (head == null) {
|
||||
// something is wrong; no name at all
|
||||
InvalidNameException e = new InvalidNameException();
|
||||
throw cont.fillInException(e);
|
||||
}
|
||||
|
||||
if (!isEmpty(tail)) {
|
||||
// more components; hence not at penultimate context yet
|
||||
try {
|
||||
Object headCtx = a_lookup(head, cont);
|
||||
if (headCtx != null)
|
||||
cont.setContinue(headCtx, head, this, tail);
|
||||
else if (cont.isContinue())
|
||||
cont.appendRemainingComponent(tail);
|
||||
} catch (NamingException e) {
|
||||
e.appendRemainingComponent(tail);
|
||||
throw e;
|
||||
}
|
||||
} else {
|
||||
// already at penultimate context
|
||||
cont.setSuccess(); // clear
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is similar to resolve_to_penultimate_context()
|
||||
* except it should only be called by the nns() functions.
|
||||
* This function fixes any exception or continuations so that
|
||||
* it will have the proper nns name.
|
||||
*/
|
||||
protected boolean resolve_to_penultimate_context_nns(Name name,
|
||||
Continuation cont)
|
||||
throws NamingException {
|
||||
try {
|
||||
if (debug > 0)
|
||||
System.out.println("RESOLVE TO PENULTIMATE NNS" + name.toString());
|
||||
boolean answer = resolve_to_penultimate_context(name, cont);
|
||||
|
||||
// resolve_to_penultimate_context() only calls a_lookup().
|
||||
// Any continuation it sets is lacking the nns, so
|
||||
// we need to add it back
|
||||
if (cont.isContinue())
|
||||
cont.appendRemainingComponent("");
|
||||
|
||||
return answer;
|
||||
} catch (NamingException e) {
|
||||
// resolve_to_penultimate_context() only calls a_lookup().
|
||||
// Any exceptions it throws is lacking the nns, so
|
||||
// we need to add it back.
|
||||
e.appendRemainingComponent("");
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves to nns associated with 'name' and set Continuation
|
||||
* to the result.
|
||||
*/
|
||||
protected void resolve_to_nns_and_continue(Name name, Continuation cont)
|
||||
throws NamingException {
|
||||
if (debug > 0)
|
||||
System.out.println("RESOLVE TO NNS AND CONTINUE" + name.toString());
|
||||
|
||||
if (resolve_to_penultimate_context_nns(name, cont)) {
|
||||
Object nns = a_lookup_nns(name.toString(), cont);
|
||||
if (nns != null)
|
||||
cont.setContinue(nns, name, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
393
jdkSrc/jdk8/com/sun/jndi/toolkit/ctx/AtomicDirContext.java
Normal file
393
jdkSrc/jdk8/com/sun/jndi/toolkit/ctx/AtomicDirContext.java
Normal file
@@ -0,0 +1,393 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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 General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.jndi.toolkit.ctx;
|
||||
|
||||
import javax.naming.*;
|
||||
import javax.naming.directory.*;
|
||||
|
||||
/**
|
||||
* Direct subclasses of AtomicDirContext must provide implementations for
|
||||
* the abstract a_ DirContext methods, and override the a_ Context methods
|
||||
* (which are no longer abstract because they have been overriden by
|
||||
* PartialCompositeDirContext with dummy implementations).
|
||||
*
|
||||
* If the subclass implements the notion of implicit nns,
|
||||
* it must override the a_*_nns DirContext and Context methods as well.
|
||||
*
|
||||
* @author Rosanna Lee
|
||||
*
|
||||
*/
|
||||
|
||||
public abstract class AtomicDirContext extends ComponentDirContext {
|
||||
|
||||
protected AtomicDirContext() {
|
||||
_contextType = _ATOMIC;
|
||||
}
|
||||
|
||||
// ------ Abstract methods whose implementations come from subclass
|
||||
|
||||
protected abstract Attributes a_getAttributes(String name, String[] attrIds,
|
||||
Continuation cont)
|
||||
throws NamingException;
|
||||
|
||||
protected abstract void a_modifyAttributes(String name, int mod_op,
|
||||
Attributes attrs,
|
||||
Continuation cont)
|
||||
throws NamingException;
|
||||
|
||||
protected abstract void a_modifyAttributes(String name,
|
||||
ModificationItem[] mods,
|
||||
Continuation cont)
|
||||
throws NamingException;
|
||||
|
||||
protected abstract void a_bind(String name, Object obj,
|
||||
Attributes attrs,
|
||||
Continuation cont)
|
||||
throws NamingException;
|
||||
|
||||
protected abstract void a_rebind(String name, Object obj,
|
||||
Attributes attrs,
|
||||
Continuation cont)
|
||||
throws NamingException;
|
||||
|
||||
protected abstract DirContext a_createSubcontext(String name,
|
||||
Attributes attrs,
|
||||
Continuation cont)
|
||||
throws NamingException;
|
||||
|
||||
protected abstract NamingEnumeration<SearchResult> a_search(
|
||||
Attributes matchingAttributes,
|
||||
String[] attributesToReturn,
|
||||
Continuation cont)
|
||||
throws NamingException;
|
||||
|
||||
protected abstract NamingEnumeration<SearchResult> a_search(
|
||||
String name,
|
||||
String filterExpr,
|
||||
Object[] filterArgs,
|
||||
SearchControls cons,
|
||||
Continuation cont)
|
||||
throws NamingException;
|
||||
|
||||
protected abstract NamingEnumeration<SearchResult> a_search(
|
||||
String name,
|
||||
String filter,
|
||||
SearchControls cons,
|
||||
Continuation cont)
|
||||
throws NamingException;
|
||||
|
||||
protected abstract DirContext a_getSchema(Continuation cont)
|
||||
throws NamingException;
|
||||
|
||||
protected abstract DirContext a_getSchemaClassDefinition(Continuation cont)
|
||||
throws NamingException;
|
||||
|
||||
// ------ Methods that need to be overridden by subclass
|
||||
|
||||
// default implementations of a_*_nns methods
|
||||
|
||||
// The following methods are called when the DirContext methods
|
||||
// are invoked with a name that has a trailing slash.
|
||||
// For naming systems that support implicit nns,
|
||||
// the trailing slash signifies the implicit nns.
|
||||
// For such naming systems, override these a_*_nns methods.
|
||||
//
|
||||
// For naming systems that support junctions (explicit nns),
|
||||
// the trailing slash is meaningless because a junction does not
|
||||
// have an implicit nns. The default implementation here
|
||||
// throws a NameNotFoundException for such names.
|
||||
// If a context wants to accept a trailing slash as having
|
||||
// the same meaning as the same name without a trailing slash,
|
||||
// then it should override these a_*_nns methods.
|
||||
|
||||
protected Attributes a_getAttributes_nns(String name,
|
||||
String[] attrIds,
|
||||
Continuation cont)
|
||||
throws NamingException {
|
||||
a_processJunction_nns(name, cont);
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void a_modifyAttributes_nns(String name, int mod_op,
|
||||
Attributes attrs,
|
||||
Continuation cont)
|
||||
throws NamingException {
|
||||
a_processJunction_nns(name, cont);
|
||||
}
|
||||
|
||||
protected void a_modifyAttributes_nns(String name,
|
||||
ModificationItem[] mods,
|
||||
Continuation cont)
|
||||
throws NamingException {
|
||||
a_processJunction_nns(name, cont);
|
||||
}
|
||||
|
||||
protected void a_bind_nns(String name, Object obj,
|
||||
Attributes attrs,
|
||||
Continuation cont)
|
||||
throws NamingException {
|
||||
a_processJunction_nns(name, cont);
|
||||
}
|
||||
|
||||
protected void a_rebind_nns(String name, Object obj,
|
||||
Attributes attrs,
|
||||
Continuation cont)
|
||||
throws NamingException {
|
||||
a_processJunction_nns(name, cont);
|
||||
}
|
||||
|
||||
protected DirContext a_createSubcontext_nns(String name,
|
||||
Attributes attrs,
|
||||
Continuation cont)
|
||||
throws NamingException {
|
||||
a_processJunction_nns(name, cont);
|
||||
return null;
|
||||
}
|
||||
|
||||
protected NamingEnumeration<SearchResult> a_search_nns(
|
||||
Attributes matchingAttributes,
|
||||
String[] attributesToReturn,
|
||||
Continuation cont)
|
||||
throws NamingException {
|
||||
a_processJunction_nns(cont);
|
||||
return null;
|
||||
}
|
||||
|
||||
protected NamingEnumeration<SearchResult> a_search_nns(String name,
|
||||
String filterExpr,
|
||||
Object[] filterArgs,
|
||||
SearchControls cons,
|
||||
Continuation cont)
|
||||
throws NamingException {
|
||||
a_processJunction_nns(name, cont);
|
||||
return null;
|
||||
}
|
||||
|
||||
protected NamingEnumeration<SearchResult> a_search_nns(String name,
|
||||
String filter,
|
||||
SearchControls cons,
|
||||
Continuation cont)
|
||||
throws NamingException {
|
||||
a_processJunction_nns(name, cont);
|
||||
return null;
|
||||
}
|
||||
|
||||
protected DirContext a_getSchema_nns(Continuation cont) throws NamingException {
|
||||
a_processJunction_nns(cont);
|
||||
return null;
|
||||
}
|
||||
|
||||
protected DirContext a_getSchemaDefinition_nns(Continuation cont)
|
||||
throws NamingException {
|
||||
a_processJunction_nns(cont);
|
||||
return null;
|
||||
}
|
||||
|
||||
// ------- implementations of c_ DirContext methods using corresponding
|
||||
// ------- a_ and a_*_nns methods
|
||||
|
||||
protected Attributes c_getAttributes(Name name, String[] attrIds,
|
||||
Continuation cont)
|
||||
throws NamingException {
|
||||
if (resolve_to_penultimate_context(name, cont))
|
||||
return a_getAttributes(name.toString(), attrIds, cont);
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void c_modifyAttributes(Name name, int mod_op,
|
||||
Attributes attrs, Continuation cont)
|
||||
throws NamingException {
|
||||
if (resolve_to_penultimate_context(name, cont))
|
||||
a_modifyAttributes(name.toString(), mod_op, attrs, cont);
|
||||
}
|
||||
|
||||
protected void c_modifyAttributes(Name name, ModificationItem[] mods,
|
||||
Continuation cont)
|
||||
throws NamingException {
|
||||
if (resolve_to_penultimate_context(name, cont))
|
||||
a_modifyAttributes(name.toString(), mods, cont);
|
||||
}
|
||||
|
||||
protected void c_bind(Name name, Object obj,
|
||||
Attributes attrs, Continuation cont)
|
||||
throws NamingException {
|
||||
if (resolve_to_penultimate_context(name, cont))
|
||||
a_bind(name.toString(), obj, attrs, cont);
|
||||
}
|
||||
|
||||
protected void c_rebind(Name name, Object obj,
|
||||
Attributes attrs, Continuation cont)
|
||||
throws NamingException {
|
||||
if (resolve_to_penultimate_context(name, cont))
|
||||
a_rebind(name.toString(), obj, attrs, cont);
|
||||
}
|
||||
|
||||
protected DirContext c_createSubcontext(Name name,
|
||||
Attributes attrs,
|
||||
Continuation cont)
|
||||
throws NamingException {
|
||||
if (resolve_to_penultimate_context(name, cont))
|
||||
return a_createSubcontext(name.toString(),
|
||||
attrs, cont);
|
||||
return null;
|
||||
}
|
||||
|
||||
protected NamingEnumeration<SearchResult> c_search(Name name,
|
||||
Attributes matchingAttributes,
|
||||
String[] attributesToReturn,
|
||||
Continuation cont)
|
||||
throws NamingException {
|
||||
if (resolve_to_context(name, cont))
|
||||
return a_search(matchingAttributes, attributesToReturn, cont);
|
||||
return null;
|
||||
}
|
||||
|
||||
protected NamingEnumeration<SearchResult> c_search(Name name,
|
||||
String filter,
|
||||
SearchControls cons,
|
||||
Continuation cont)
|
||||
throws NamingException {
|
||||
if (resolve_to_penultimate_context(name, cont))
|
||||
return a_search(name.toString(), filter, cons, cont);
|
||||
return null;
|
||||
}
|
||||
|
||||
protected NamingEnumeration<SearchResult> c_search(Name name,
|
||||
String filterExpr,
|
||||
Object[] filterArgs,
|
||||
SearchControls cons,
|
||||
Continuation cont)
|
||||
throws NamingException {
|
||||
if (resolve_to_penultimate_context(name, cont))
|
||||
return a_search(name.toString(), filterExpr, filterArgs, cons, cont);
|
||||
return null;
|
||||
}
|
||||
|
||||
protected DirContext c_getSchema(Name name, Continuation cont)
|
||||
throws NamingException {
|
||||
if (resolve_to_context(name, cont))
|
||||
return a_getSchema(cont);
|
||||
return null;
|
||||
}
|
||||
|
||||
protected DirContext c_getSchemaClassDefinition(Name name, Continuation cont)
|
||||
throws NamingException {
|
||||
if (resolve_to_context(name, cont))
|
||||
return a_getSchemaClassDefinition(cont);
|
||||
return null;
|
||||
}
|
||||
|
||||
/* equivalent to methods in DirContext interface for nns */
|
||||
|
||||
protected Attributes c_getAttributes_nns(Name name, String[] attrIds,
|
||||
Continuation cont)
|
||||
throws NamingException {
|
||||
if (resolve_to_penultimate_context_nns(name, cont))
|
||||
return a_getAttributes_nns(name.toString(), attrIds, cont);
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void c_modifyAttributes_nns(Name name, int mod_op,
|
||||
Attributes attrs, Continuation cont)
|
||||
throws NamingException {
|
||||
if (resolve_to_penultimate_context_nns(name, cont))
|
||||
a_modifyAttributes_nns(name.toString(), mod_op, attrs, cont);
|
||||
}
|
||||
|
||||
protected void c_modifyAttributes_nns(Name name, ModificationItem[] mods,
|
||||
Continuation cont)
|
||||
throws NamingException {
|
||||
if (resolve_to_penultimate_context_nns(name, cont))
|
||||
a_modifyAttributes_nns(name.toString(), mods, cont);
|
||||
}
|
||||
|
||||
protected void c_bind_nns(Name name, Object obj,
|
||||
Attributes attrs, Continuation cont)
|
||||
throws NamingException {
|
||||
if (resolve_to_penultimate_context_nns(name, cont))
|
||||
a_bind_nns(name.toString(), obj, attrs, cont);
|
||||
}
|
||||
|
||||
protected void c_rebind_nns(Name name, Object obj,
|
||||
Attributes attrs, Continuation cont)
|
||||
throws NamingException {
|
||||
if (resolve_to_penultimate_context_nns(name, cont))
|
||||
a_rebind_nns(name.toString(), obj, attrs, cont);
|
||||
}
|
||||
|
||||
protected DirContext c_createSubcontext_nns(Name name,
|
||||
Attributes attrs,
|
||||
Continuation cont)
|
||||
throws NamingException {
|
||||
if (resolve_to_penultimate_context_nns(name, cont))
|
||||
return a_createSubcontext_nns(name.toString(), attrs, cont);
|
||||
return null;
|
||||
}
|
||||
|
||||
protected NamingEnumeration<SearchResult> c_search_nns(
|
||||
Name name,
|
||||
Attributes matchingAttributes,
|
||||
String[] attributesToReturn,
|
||||
Continuation cont)
|
||||
throws NamingException {
|
||||
resolve_to_nns_and_continue(name, cont);
|
||||
return null;
|
||||
}
|
||||
|
||||
protected NamingEnumeration<SearchResult> c_search_nns(Name name,
|
||||
String filter,
|
||||
SearchControls cons,
|
||||
Continuation cont)
|
||||
throws NamingException {
|
||||
if (resolve_to_penultimate_context_nns(name, cont))
|
||||
return a_search_nns(name.toString(), filter, cons, cont);
|
||||
return null;
|
||||
}
|
||||
|
||||
protected NamingEnumeration<SearchResult> c_search_nns(Name name,
|
||||
String filterExpr,
|
||||
Object[] filterArgs,
|
||||
SearchControls cons,
|
||||
Continuation cont)
|
||||
throws NamingException {
|
||||
if (resolve_to_penultimate_context_nns(name, cont))
|
||||
return a_search_nns(name.toString(), filterExpr, filterArgs,
|
||||
cons, cont);
|
||||
return null;
|
||||
}
|
||||
|
||||
protected DirContext c_getSchema_nns(Name name, Continuation cont)
|
||||
throws NamingException {
|
||||
resolve_to_nns_and_continue(name, cont);
|
||||
return null;
|
||||
}
|
||||
|
||||
protected DirContext c_getSchemaClassDefinition_nns(Name name, Continuation cont)
|
||||
throws NamingException {
|
||||
resolve_to_nns_and_continue(name, cont);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
805
jdkSrc/jdk8/com/sun/jndi/toolkit/ctx/ComponentContext.java
Normal file
805
jdkSrc/jdk8/com/sun/jndi/toolkit/ctx/ComponentContext.java
Normal file
@@ -0,0 +1,805 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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 General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.jndi.toolkit.ctx;
|
||||
|
||||
import javax.naming.*;
|
||||
import javax.naming.spi.ResolveResult;
|
||||
|
||||
/**
|
||||
* Provides implementation of p_* operations using
|
||||
* c_* operations provided by subclasses.
|
||||
*
|
||||
* Clients: deal only with names for its own naming service. Must
|
||||
* provide implementations for c_* methods, and for p_parseComponent()
|
||||
* and the c_*_nns methods if the defaults are not appropriate.
|
||||
*
|
||||
* @author Rosanna Lee
|
||||
* @author Scott Seligman
|
||||
*/
|
||||
|
||||
public abstract class ComponentContext extends PartialCompositeContext {
|
||||
private static int debug = 0;
|
||||
|
||||
protected ComponentContext() {
|
||||
_contextType = _COMPONENT;
|
||||
}
|
||||
|
||||
// ------ Abstract methods whose implementation are provided by subclass
|
||||
|
||||
/* Equivalent methods in Context interface */
|
||||
protected abstract Object c_lookup(Name name, Continuation cont)
|
||||
throws NamingException;
|
||||
protected abstract Object c_lookupLink(Name name, Continuation cont)
|
||||
throws NamingException;
|
||||
|
||||
protected abstract NamingEnumeration<NameClassPair> c_list(Name name,
|
||||
Continuation cont) throws NamingException;
|
||||
protected abstract NamingEnumeration<Binding> c_listBindings(Name name,
|
||||
Continuation cont) throws NamingException;
|
||||
protected abstract void c_bind(Name name, Object obj, Continuation cont)
|
||||
throws NamingException;
|
||||
protected abstract void c_rebind(Name name, Object obj, Continuation cont)
|
||||
throws NamingException;
|
||||
protected abstract void c_unbind(Name name, Continuation cont)
|
||||
throws NamingException;
|
||||
protected abstract void c_destroySubcontext(Name name, Continuation cont)
|
||||
throws NamingException;
|
||||
protected abstract Context c_createSubcontext(Name name,
|
||||
Continuation cont) throws NamingException;
|
||||
protected abstract void c_rename(Name oldname, Name newname,
|
||||
Continuation cont) throws NamingException;
|
||||
protected abstract NameParser c_getNameParser(Name name, Continuation cont)
|
||||
throws NamingException;
|
||||
|
||||
// ------ Methods that may need to be overridden by subclass
|
||||
|
||||
/* Parsing method */
|
||||
/**
|
||||
* Determines which of the first components of 'name' belong
|
||||
* to this naming system.
|
||||
* If no components belong to this naming system, return
|
||||
* the empty name (new CompositeName()) as the head,
|
||||
* and the entire name as the tail.
|
||||
*
|
||||
* The default implementation supports strong separation.
|
||||
* If the name is empty or if the first component is empty,
|
||||
* head is the empty name and tail is the entire name.
|
||||
* (This means that this context does not have any name to work with).
|
||||
* Otherwise, it returns the first component as head, and the rest of
|
||||
* the components as tail.
|
||||
*
|
||||
* Subclass should override this method according its own policies.
|
||||
*
|
||||
* For example, a weakly separated system with dynamic boundary
|
||||
* determination would simply return as head 'name'.
|
||||
* A weakly separated with static boundary
|
||||
* determination would select the components in the front of 'name'
|
||||
* that conform to some syntax rules. (e.g. in X.500 syntax, perhaps
|
||||
* select front components that have a equal sign).
|
||||
* If none conforms, return an empty name.
|
||||
*/
|
||||
protected HeadTail p_parseComponent(Name name, Continuation cont)
|
||||
throws NamingException {
|
||||
int separator;
|
||||
// if no name to parse, or if we're already at boundary
|
||||
if (name.isEmpty() || name.get(0).equals("")) {
|
||||
separator = 0;
|
||||
} else {
|
||||
separator = 1;
|
||||
}
|
||||
Name head, tail;
|
||||
|
||||
if (name instanceof CompositeName) {
|
||||
head = name.getPrefix(separator);
|
||||
tail = name.getSuffix(separator);
|
||||
} else {
|
||||
// treat like compound name
|
||||
head = new CompositeName().add(name.toString());
|
||||
tail = null;
|
||||
}
|
||||
|
||||
if (debug > 2) {
|
||||
System.err.println("ORIG: " + name);
|
||||
System.err.println("PREFIX: " + name);
|
||||
System.err.println("SUFFIX: " + null);
|
||||
}
|
||||
return new HeadTail(head, tail);
|
||||
}
|
||||
|
||||
|
||||
/* Resolution method for supporting federation */
|
||||
|
||||
/**
|
||||
* Resolves the nns for 'name' when the named context is acting
|
||||
* as an intermediate context.
|
||||
*
|
||||
* For a system that supports only junctions, this would be
|
||||
* equilvalent to
|
||||
* c_lookup(name, cont);
|
||||
* because for junctions, an intermediate slash simply signifies
|
||||
* a syntactic separator.
|
||||
*
|
||||
* For a system that supports only implicit nns, this would be
|
||||
* equivalent to
|
||||
* c_lookup_nns(name, cont);
|
||||
* because for implicit nns, a slash always signifies the implicit nns,
|
||||
* regardless of whether it is intermediate or trailing.
|
||||
*
|
||||
* By default this method supports junctions, and also allows for an
|
||||
* implicit nns to be dynamically determined through the use of the
|
||||
* "nns" reference (see c_processJunction_nns()).
|
||||
* Contexts that implement implicit nns directly should provide an
|
||||
* appropriate override.
|
||||
*
|
||||
* A junction, by definition, is a binding of a name in one
|
||||
* namespace to an object in another. The default implementation
|
||||
* of this method detects the crossover into another namespace
|
||||
* using the following heuristic: there is a junction when "name"
|
||||
* resolves to a context that is not an instance of
|
||||
* this.getClass(). Contexts supporting junctions for which this
|
||||
* heuristic is inappropriate should override this method.
|
||||
*/
|
||||
protected Object c_resolveIntermediate_nns(Name name, Continuation cont)
|
||||
throws NamingException {
|
||||
try {
|
||||
final Object obj = c_lookup(name, cont);
|
||||
|
||||
// Do not append "" to Continuation 'cont' even if set
|
||||
// because the intention is to ignore the nns
|
||||
|
||||
if (obj != null && getClass().isInstance(obj)) {
|
||||
// If "obj" is in the same type as this object, it must
|
||||
// not be a junction. Continue the lookup with "/".
|
||||
|
||||
cont.setContinueNNS(obj, name, this);
|
||||
return null;
|
||||
|
||||
} else if (obj != null && !(obj instanceof Context)) {
|
||||
// obj is not even a context, so try to find its nns
|
||||
// dynamically by constructing a Reference containing obj.
|
||||
RefAddr addr = new RefAddr("nns") {
|
||||
public Object getContent() {
|
||||
return obj;
|
||||
}
|
||||
private static final long serialVersionUID =
|
||||
-8831204798861786362L;
|
||||
};
|
||||
Reference ref = new Reference("java.lang.Object", addr);
|
||||
|
||||
// Resolved name has trailing slash to indicate nns
|
||||
CompositeName resName = (CompositeName)name.clone();
|
||||
resName.add(""); // add trailing slash
|
||||
|
||||
// Set continuation leave it to
|
||||
// PartialCompositeContext.getPCContext() to throw CPE.
|
||||
// Do not use setContinueNNS() because we've already
|
||||
// consumed "/" (i.e., moved it to resName).
|
||||
|
||||
cont.setContinue(ref, resName, this);
|
||||
return null;
|
||||
} else {
|
||||
// Consume "/" and continue
|
||||
return obj;
|
||||
}
|
||||
|
||||
} catch (NamingException e) {
|
||||
e.appendRemainingComponent(""); // add nns back
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/* Equivalent of Context Methods for supporting nns */
|
||||
|
||||
// The following methods are called when the Context methods
|
||||
// are invoked with a name that has a trailing slash.
|
||||
// For naming systems that support implicit nns,
|
||||
// the trailing slash signifies the implicit nns.
|
||||
// For such naming systems, override these c_*_nns methods.
|
||||
//
|
||||
// For naming systems that do not support implicit nns, the
|
||||
// default implementations here throw an exception. See
|
||||
// c_processJunction_nns() for details.
|
||||
|
||||
protected Object c_lookup_nns(Name name, Continuation cont)
|
||||
throws NamingException {
|
||||
c_processJunction_nns(name, cont);
|
||||
return null;
|
||||
}
|
||||
|
||||
protected Object c_lookupLink_nns(Name name, Continuation cont)
|
||||
throws NamingException {
|
||||
c_processJunction_nns(name, cont);
|
||||
return null;
|
||||
}
|
||||
|
||||
protected NamingEnumeration<NameClassPair> c_list_nns(Name name,
|
||||
Continuation cont) throws NamingException {
|
||||
c_processJunction_nns(name, cont);
|
||||
return null;
|
||||
}
|
||||
|
||||
protected NamingEnumeration<Binding> c_listBindings_nns(Name name,
|
||||
Continuation cont) throws NamingException {
|
||||
c_processJunction_nns(name, cont);
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void c_bind_nns(Name name, Object obj, Continuation cont)
|
||||
throws NamingException {
|
||||
c_processJunction_nns(name, cont);
|
||||
}
|
||||
|
||||
protected void c_rebind_nns(Name name, Object obj, Continuation cont)
|
||||
throws NamingException {
|
||||
c_processJunction_nns(name, cont);
|
||||
}
|
||||
|
||||
protected void c_unbind_nns(Name name, Continuation cont)
|
||||
throws NamingException {
|
||||
c_processJunction_nns(name, cont);
|
||||
}
|
||||
|
||||
protected Context c_createSubcontext_nns(Name name,
|
||||
Continuation cont) throws NamingException {
|
||||
c_processJunction_nns(name, cont);
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void c_destroySubcontext_nns(Name name, Continuation cont)
|
||||
throws NamingException {
|
||||
c_processJunction_nns(name, cont);
|
||||
}
|
||||
|
||||
|
||||
protected void c_rename_nns(Name oldname, Name newname, Continuation cont)
|
||||
throws NamingException {
|
||||
c_processJunction_nns(oldname, cont);
|
||||
}
|
||||
|
||||
protected NameParser c_getNameParser_nns(Name name, Continuation cont)
|
||||
throws NamingException {
|
||||
c_processJunction_nns(name, cont);
|
||||
return null;
|
||||
}
|
||||
|
||||
// ------ internal method used by ComponentContext
|
||||
|
||||
/**
|
||||
* Locates the nns using the default policy. This policy fully
|
||||
* handles junctions, but otherwise throws an exception when an
|
||||
* attempt is made to resolve an implicit nns.
|
||||
*
|
||||
* The default policy is as follows: If there is a junction in
|
||||
* the namespace, then resolve to the junction and continue the
|
||||
* operation there (thus deferring to that context to find its own
|
||||
* nns). Otherwise, resolve as far as possible and then throw
|
||||
* CannotProceedException with the resolved object being a reference:
|
||||
* the address type is "nns", and the address contents is this
|
||||
* context.
|
||||
*
|
||||
* For example, when c_bind_nns(name, obj, ...) is invoked, the
|
||||
* caller is attempting to bind the object "obj" to the nns of
|
||||
* "name". If "name" is a junction, it names an object in another
|
||||
* naming system that (presumably) has an nns. c_bind_nns() will
|
||||
* first resolve "name" to a context and then attempt to continue
|
||||
* the bind operation there, (thus binding to the nns of the
|
||||
* context named by "name"). If "name" is empty then throw an
|
||||
* exception, since this context does not by default support an
|
||||
* implicit nns.
|
||||
*
|
||||
* To implement a context that does support an implicit nns, it is
|
||||
* necessary to override this default policy. This is done by
|
||||
* overriding the c_*_nns() methods (which each call this method
|
||||
* by default).
|
||||
*/
|
||||
protected void c_processJunction_nns(Name name, Continuation cont)
|
||||
throws NamingException
|
||||
{
|
||||
if (name.isEmpty()) {
|
||||
// Construct a new Reference that contains this context.
|
||||
RefAddr addr = new RefAddr("nns") {
|
||||
public Object getContent() {
|
||||
return ComponentContext.this;
|
||||
}
|
||||
private static final long serialVersionUID =
|
||||
-1389472957988053402L;
|
||||
};
|
||||
Reference ref = new Reference("java.lang.Object", addr);
|
||||
|
||||
// Set continuation leave it to PartialCompositeContext.getPCContext()
|
||||
// to throw the exception.
|
||||
// Do not use setContinueNNS() because we've are
|
||||
// setting relativeResolvedName to "/".
|
||||
cont.setContinue(ref, _NNS_NAME, this);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// lookup name to continue operation in nns
|
||||
Object target = c_lookup(name, cont);
|
||||
if (cont.isContinue())
|
||||
cont.appendRemainingComponent("");
|
||||
else {
|
||||
cont.setContinueNNS(target, name, this);
|
||||
}
|
||||
} catch (NamingException e) {
|
||||
e.appendRemainingComponent(""); // add nns back
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
protected static final byte USE_CONTINUATION = 1;
|
||||
protected static final byte TERMINAL_COMPONENT = 2;
|
||||
protected static final byte TERMINAL_NNS_COMPONENT = 3;
|
||||
|
||||
/**
|
||||
* Determine whether 'name' is a terminal component in
|
||||
* this naming system.
|
||||
* If so, return status indicating so, so that caller
|
||||
* can perform context operation on this name.
|
||||
*
|
||||
* If not, then the first component(s) of 'name' names
|
||||
* an intermediate context. In that case, resolve these components
|
||||
* and set Continuation to be the object named.
|
||||
*
|
||||
* see test cases at bottom of file.
|
||||
*/
|
||||
|
||||
protected HeadTail p_resolveIntermediate(Name name, Continuation cont)
|
||||
throws NamingException {
|
||||
int ret = USE_CONTINUATION;
|
||||
cont.setSuccess(); // initialize
|
||||
HeadTail p = p_parseComponent(name, cont);
|
||||
Name tail = p.getTail();
|
||||
Name head = p.getHead();
|
||||
|
||||
if (tail == null || tail.isEmpty()) {
|
||||
//System.out.println("terminal : " + head);
|
||||
ret = TERMINAL_COMPONENT;
|
||||
} else if (!tail.get(0).equals("")) {
|
||||
// tail does not begin with "/"
|
||||
/*
|
||||
if (head.isEmpty()) {
|
||||
// Context could not find name that it can use
|
||||
// illegal syntax error or name not found
|
||||
//System.out.println("nnf exception : " + head);
|
||||
NamingException e = new NameNotFoundException();
|
||||
cont.setError(this, name);
|
||||
throw cont.fillInException(e);
|
||||
} else {
|
||||
*/
|
||||
// head is being used as intermediate context,
|
||||
// resolve head and set Continuation with tail
|
||||
try {
|
||||
Object obj = c_resolveIntermediate_nns(head, cont);
|
||||
//System.out.println("resInter : " + head + "=" + obj);
|
||||
if (obj != null)
|
||||
cont.setContinue(obj, head, this, tail);
|
||||
else if (cont.isContinue()) {
|
||||
checkAndAdjustRemainingName(cont.getRemainingName());
|
||||
cont.appendRemainingName(tail);
|
||||
}
|
||||
} catch (NamingException e) {
|
||||
checkAndAdjustRemainingName(e.getRemainingName());
|
||||
e.appendRemainingName(tail);
|
||||
throw e;
|
||||
}
|
||||
/*
|
||||
}
|
||||
*/
|
||||
} else {
|
||||
// tail begins with "/"
|
||||
if (tail.size() == 1) {
|
||||
ret = TERMINAL_NNS_COMPONENT;
|
||||
//System.out.println("terminal_nns : " + head);
|
||||
} else if (head.isEmpty() || isAllEmpty(tail)) {
|
||||
// resolve nns of head and continue with tail.getSuffix(1)
|
||||
Name newTail = tail.getSuffix(1);
|
||||
try {
|
||||
Object obj = c_lookup_nns(head, cont);
|
||||
//System.out.println("lookup_nns : " + head + "=" + obj);
|
||||
if (obj != null)
|
||||
cont.setContinue(obj, head, this, newTail);
|
||||
else if (cont.isContinue()) {
|
||||
cont.appendRemainingName(newTail);
|
||||
// Name rname = cont.getRemainingName();
|
||||
//System.out.println("cont.rname" + rname);
|
||||
}
|
||||
} catch (NamingException e) {
|
||||
e.appendRemainingName(newTail);
|
||||
throw e;
|
||||
}
|
||||
} else {
|
||||
// head is being used as intermediate context
|
||||
// resolve and set continuation to tail
|
||||
try {
|
||||
Object obj = c_resolveIntermediate_nns(head, cont);
|
||||
//System.out.println("resInter2 : " + head + "=" + obj);
|
||||
if (obj != null)
|
||||
cont.setContinue(obj, head, this, tail);
|
||||
else if (cont.isContinue()) {
|
||||
checkAndAdjustRemainingName(cont.getRemainingName());
|
||||
cont.appendRemainingName(tail);
|
||||
}
|
||||
} catch (NamingException e) {
|
||||
checkAndAdjustRemainingName(e.getRemainingName());
|
||||
e.appendRemainingName(tail);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
p.setStatus(ret);
|
||||
return p;
|
||||
}
|
||||
|
||||
// When c_resolveIntermediate_nns() or c_lookup_nns() sets up
|
||||
// its continuation, to indicate "nns", it appends an empty
|
||||
// component to the remaining name (e.g. "eng/"). If last
|
||||
// component of remaining name is empty; delete empty component
|
||||
// before appending tail so that composition of the names work
|
||||
// correctly. For example, when merging "eng/" and "c.b.a", we want
|
||||
// the result to be "eng/c.b.a" because the trailing slash in eng
|
||||
// is extraneous. When merging "" and "c.b.a", we want the result
|
||||
// to be "/c.b.a" and so must keep the trailing slash (empty name).
|
||||
void checkAndAdjustRemainingName(Name rname) throws InvalidNameException {
|
||||
int count;
|
||||
if (rname != null && (count=rname.size()) > 1 &&
|
||||
rname.get(count-1).equals("")) {
|
||||
rname.remove(count-1);
|
||||
}
|
||||
}
|
||||
|
||||
// Returns true if n contains only empty components
|
||||
protected boolean isAllEmpty(Name n) {
|
||||
int count = n.size();
|
||||
for (int i =0; i < count; i++ ) {
|
||||
if (!n.get(i).equals("")) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ------ implementations of p_ Resolver and Context methods using
|
||||
// ------ corresponding c_ and c_*_nns methods
|
||||
|
||||
|
||||
/* implementation for Resolver method */
|
||||
|
||||
protected ResolveResult p_resolveToClass(Name name,
|
||||
Class<?> contextType,
|
||||
Continuation cont)
|
||||
throws NamingException {
|
||||
|
||||
if (contextType.isInstance(this)) {
|
||||
cont.setSuccess();
|
||||
return (new ResolveResult(this, name));
|
||||
}
|
||||
|
||||
ResolveResult ret = null;
|
||||
HeadTail res = p_resolveIntermediate(name, cont);
|
||||
switch (res.getStatus()) {
|
||||
case TERMINAL_NNS_COMPONENT:
|
||||
Object obj = p_lookup(name, cont);
|
||||
if (!cont.isContinue() && contextType.isInstance(obj)) {
|
||||
ret = new ResolveResult(obj, _EMPTY_NAME);
|
||||
}
|
||||
break;
|
||||
|
||||
case TERMINAL_COMPONENT:
|
||||
cont.setSuccess(); // no contextType found; return null
|
||||
break;
|
||||
|
||||
default:
|
||||
/* USE_CONTINUATION */
|
||||
/* pcont already set or exception thrown */
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* implementations of p_ Context methods */
|
||||
|
||||
protected Object p_lookup(Name name, Continuation cont) throws NamingException {
|
||||
Object ret = null;
|
||||
HeadTail res = p_resolveIntermediate(name, cont);
|
||||
switch (res.getStatus()) {
|
||||
case TERMINAL_NNS_COMPONENT:
|
||||
ret = c_lookup_nns(res.getHead(), cont);
|
||||
if (ret instanceof LinkRef) {
|
||||
cont.setContinue(ret, res.getHead(), this);
|
||||
ret = null;
|
||||
}
|
||||
break;
|
||||
|
||||
case TERMINAL_COMPONENT:
|
||||
ret = c_lookup(res.getHead(), cont);
|
||||
if (ret instanceof LinkRef) {
|
||||
cont.setContinue(ret, res.getHead(), this);
|
||||
ret = null;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
/* USE_CONTINUATION */
|
||||
/* pcont already set or exception thrown */
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
protected NamingEnumeration<NameClassPair> p_list(Name name, Continuation cont)
|
||||
throws NamingException {
|
||||
NamingEnumeration<NameClassPair> ret = null;
|
||||
HeadTail res = p_resolveIntermediate(name, cont);
|
||||
switch (res.getStatus()) {
|
||||
case TERMINAL_NNS_COMPONENT:
|
||||
if (debug > 0)
|
||||
System.out.println("c_list_nns(" + res.getHead() + ")");
|
||||
ret = c_list_nns(res.getHead(), cont);
|
||||
break;
|
||||
|
||||
case TERMINAL_COMPONENT:
|
||||
if (debug > 0)
|
||||
System.out.println("c_list(" + res.getHead() + ")");
|
||||
ret = c_list(res.getHead(), cont);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* USE_CONTINUATION */
|
||||
/* cont already set or exception thrown */
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
protected NamingEnumeration<Binding> p_listBindings(Name name, Continuation cont) throws
|
||||
NamingException {
|
||||
NamingEnumeration<Binding> ret = null;
|
||||
HeadTail res = p_resolveIntermediate(name, cont);
|
||||
switch (res.getStatus()) {
|
||||
case TERMINAL_NNS_COMPONENT:
|
||||
ret = c_listBindings_nns(res.getHead(), cont);
|
||||
break;
|
||||
|
||||
case TERMINAL_COMPONENT:
|
||||
ret = c_listBindings(res.getHead(), cont);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* USE_CONTINUATION */
|
||||
/* cont already set or exception thrown */
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
protected void p_bind(Name name, Object obj, Continuation cont) throws
|
||||
NamingException {
|
||||
HeadTail res = p_resolveIntermediate(name, cont);
|
||||
switch (res.getStatus()) {
|
||||
case TERMINAL_NNS_COMPONENT:
|
||||
c_bind_nns(res.getHead(), obj, cont);
|
||||
break;
|
||||
|
||||
case TERMINAL_COMPONENT:
|
||||
c_bind(res.getHead(), obj, cont);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* USE_CONTINUATION */
|
||||
/* cont already set or exception thrown */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected void p_rebind(Name name, Object obj, Continuation cont) throws
|
||||
NamingException {
|
||||
HeadTail res = p_resolveIntermediate(name, cont);
|
||||
switch (res.getStatus()) {
|
||||
case TERMINAL_NNS_COMPONENT:
|
||||
c_rebind_nns(res.getHead(), obj, cont);
|
||||
break;
|
||||
|
||||
case TERMINAL_COMPONENT:
|
||||
c_rebind(res.getHead(), obj, cont);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* USE_CONTINUATION */
|
||||
/* cont already set or exception thrown */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected void p_unbind(Name name, Continuation cont) throws
|
||||
NamingException {
|
||||
HeadTail res = p_resolveIntermediate(name, cont);
|
||||
switch (res.getStatus()) {
|
||||
case TERMINAL_NNS_COMPONENT:
|
||||
c_unbind_nns(res.getHead(), cont);
|
||||
break;
|
||||
|
||||
case TERMINAL_COMPONENT:
|
||||
c_unbind(res.getHead(), cont);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* USE_CONTINUATION */
|
||||
/* cont already set or exception thrown */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected void p_destroySubcontext(Name name, Continuation cont) throws
|
||||
NamingException {
|
||||
HeadTail res = p_resolveIntermediate(name, cont);
|
||||
switch (res.getStatus()) {
|
||||
case TERMINAL_NNS_COMPONENT:
|
||||
c_destroySubcontext_nns(res.getHead(), cont);
|
||||
break;
|
||||
|
||||
case TERMINAL_COMPONENT:
|
||||
c_destroySubcontext(res.getHead(), cont);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* USE_CONTINUATION */
|
||||
/* cont already set or exception thrown */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected Context p_createSubcontext(Name name, Continuation cont) throws
|
||||
NamingException {
|
||||
Context ret = null;
|
||||
HeadTail res = p_resolveIntermediate(name, cont);
|
||||
switch (res.getStatus()) {
|
||||
case TERMINAL_NNS_COMPONENT:
|
||||
ret = c_createSubcontext_nns(res.getHead(), cont);
|
||||
break;
|
||||
|
||||
case TERMINAL_COMPONENT:
|
||||
ret = c_createSubcontext(res.getHead(), cont);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* USE_CONTINUATION */
|
||||
/* cont already set or exception thrown */
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
protected void p_rename(Name oldName, Name newName, Continuation cont) throws
|
||||
NamingException {
|
||||
HeadTail res = p_resolveIntermediate(oldName, cont);
|
||||
switch (res.getStatus()) {
|
||||
case TERMINAL_NNS_COMPONENT:
|
||||
c_rename_nns(res.getHead(), newName, cont);
|
||||
break;
|
||||
|
||||
case TERMINAL_COMPONENT:
|
||||
c_rename(res.getHead(), newName, cont);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* USE_CONTINUATION */
|
||||
/* cont already set or exception thrown */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected NameParser p_getNameParser(Name name, Continuation cont) throws
|
||||
NamingException {
|
||||
NameParser ret = null;
|
||||
HeadTail res = p_resolveIntermediate(name, cont);
|
||||
switch (res.getStatus()) {
|
||||
case TERMINAL_NNS_COMPONENT:
|
||||
ret = c_getNameParser_nns(res.getHead(), cont);
|
||||
break;
|
||||
|
||||
case TERMINAL_COMPONENT:
|
||||
ret = c_getNameParser(res.getHead(), cont);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* USE_CONTINUATION */
|
||||
/* cont already set or exception thrown */
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
protected Object p_lookupLink(Name name, Continuation cont)
|
||||
throws NamingException {
|
||||
Object ret = null;
|
||||
HeadTail res = p_resolveIntermediate(name, cont);
|
||||
switch (res.getStatus()) {
|
||||
case TERMINAL_NNS_COMPONENT:
|
||||
ret = c_lookupLink_nns(res.getHead(), cont);
|
||||
break;
|
||||
|
||||
case TERMINAL_COMPONENT:
|
||||
ret = c_lookupLink(res.getHead(), cont);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* USE_CONTINUATION */
|
||||
/* cont already set or exception thrown */
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* How p_resolveIntermediate() should behave for various test cases
|
||||
|
||||
a.b/x {a.b, x}
|
||||
c_resolveIntermediate_nns(a.b)
|
||||
continue(x)
|
||||
{x,}
|
||||
terminal(x)
|
||||
|
||||
a.b/ {a.b, ""}
|
||||
terminal_nns(a.b);
|
||||
|
||||
a.b//
|
||||
{a.b, ("", "")}
|
||||
c_lookup_nns(a.b)
|
||||
continue({""})
|
||||
{,""}
|
||||
terminal_nns({})
|
||||
|
||||
/x {{}, {"", x}}
|
||||
c_lookup_nns({})
|
||||
continue(x)
|
||||
{x,}
|
||||
terminal(x)
|
||||
|
||||
//y {{}, {"", "", y}}
|
||||
c_lookup_nns({})
|
||||
continue({"", y})
|
||||
{{}, {"", y}}
|
||||
c_lookup_nns({})
|
||||
continue(y)
|
||||
{y,}
|
||||
terminal(y)
|
||||
|
||||
a.b//y {a.b, {"", y}}
|
||||
c_resolveIntermediate_nns(a.b)
|
||||
continue({"", y})
|
||||
{{}, {"",y}}
|
||||
c_lookup_nns({});
|
||||
continue(y)
|
||||
{y,}
|
||||
terminal(y);
|
||||
*
|
||||
*/
|
||||
470
jdkSrc/jdk8/com/sun/jndi/toolkit/ctx/ComponentDirContext.java
Normal file
470
jdkSrc/jdk8/com/sun/jndi/toolkit/ctx/ComponentDirContext.java
Normal file
@@ -0,0 +1,470 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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 General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.jndi.toolkit.ctx;
|
||||
|
||||
import javax.naming.*;
|
||||
import javax.naming.directory.*;
|
||||
|
||||
/* Direct subclasses of ComponentDirContext must provide implementations for
|
||||
* the abstract c_ DirContext methods, and override the c_ Context methods
|
||||
* (which are no longer abstract because they have been overriden by
|
||||
* AtomicContext, the direct superclass of PartialDSCompositeContext).
|
||||
*
|
||||
* If the subclass is supports implicit nns, it must override all the
|
||||
* c_*_nns methods corresponding to those in DirContext and Context.
|
||||
* See ComponentContext for details.
|
||||
*
|
||||
* @author Rosanna Lee
|
||||
*/
|
||||
|
||||
public abstract class ComponentDirContext extends PartialCompositeDirContext {
|
||||
|
||||
protected ComponentDirContext () {
|
||||
_contextType = _COMPONENT;
|
||||
}
|
||||
|
||||
// ------ Abstract methods whose implementations are provided by subclass
|
||||
|
||||
/* Equivalent to methods in DirContext */
|
||||
protected abstract Attributes c_getAttributes(Name name,
|
||||
String[] attrIds,
|
||||
Continuation cont)
|
||||
throws NamingException;
|
||||
|
||||
protected abstract void c_modifyAttributes(Name name, int mod_op,
|
||||
Attributes attrs,
|
||||
Continuation cont)
|
||||
throws NamingException;
|
||||
|
||||
protected abstract void c_modifyAttributes(Name name,
|
||||
ModificationItem[] mods,
|
||||
Continuation cont)
|
||||
throws NamingException;
|
||||
|
||||
protected abstract void c_bind(Name name, Object obj,
|
||||
Attributes attrs,
|
||||
Continuation cont)
|
||||
throws NamingException;
|
||||
|
||||
protected abstract void c_rebind(Name name, Object obj,
|
||||
Attributes attrs,
|
||||
Continuation cont)
|
||||
throws NamingException;
|
||||
|
||||
protected abstract DirContext c_createSubcontext(Name name,
|
||||
Attributes attrs,
|
||||
Continuation cont)
|
||||
throws NamingException;
|
||||
|
||||
protected abstract NamingEnumeration<SearchResult> c_search(
|
||||
Name name,
|
||||
Attributes matchingAttributes,
|
||||
String[] attributesToReturn,
|
||||
Continuation cont)
|
||||
throws NamingException;
|
||||
|
||||
protected abstract NamingEnumeration<SearchResult> c_search(
|
||||
Name name,
|
||||
String filter,
|
||||
SearchControls cons,
|
||||
Continuation cont)
|
||||
throws NamingException;
|
||||
|
||||
protected abstract NamingEnumeration<SearchResult> c_search(
|
||||
Name name,
|
||||
String filterExpr,
|
||||
Object[] filterArgs,
|
||||
SearchControls cons,
|
||||
Continuation cont)
|
||||
throws NamingException;
|
||||
|
||||
protected abstract DirContext c_getSchema(Name name, Continuation cont)
|
||||
throws NamingException;
|
||||
|
||||
protected abstract DirContext c_getSchemaClassDefinition(Name name,
|
||||
Continuation cont)
|
||||
throws NamingException;
|
||||
|
||||
// ------- default implementations of c_*_nns methods from DirContext
|
||||
|
||||
// The following methods are called when the DirContext methods
|
||||
// are invoked with a name that has a trailing slash.
|
||||
// For naming systems that support implicit nns,
|
||||
// the trailing slash signifies the implicit nns.
|
||||
// For such naming systems, override these c_*_nns methods.
|
||||
//
|
||||
// For naming systems that support junctions (explicit nns),
|
||||
// the trailing slash is meaningless because a junction does not
|
||||
// have an implicit nns. The default implementation here
|
||||
// throws a NameNotFoundException for such names.
|
||||
// If a context wants to accept a trailing slash as having
|
||||
// the same meaning as the same name without a trailing slash,
|
||||
// then it should override these c_*_nns methods.
|
||||
|
||||
// See ComponentContext for details.
|
||||
|
||||
protected Attributes c_getAttributes_nns(Name name,
|
||||
String[] attrIds,
|
||||
Continuation cont)
|
||||
throws NamingException {
|
||||
c_processJunction_nns(name, cont);
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void c_modifyAttributes_nns(Name name,
|
||||
int mod_op,
|
||||
Attributes attrs,
|
||||
Continuation cont)
|
||||
throws NamingException {
|
||||
c_processJunction_nns(name, cont);
|
||||
}
|
||||
|
||||
protected void c_modifyAttributes_nns(Name name,
|
||||
ModificationItem[] mods,
|
||||
Continuation cont)
|
||||
throws NamingException {
|
||||
c_processJunction_nns(name, cont);
|
||||
}
|
||||
|
||||
protected void c_bind_nns(Name name,
|
||||
Object obj,
|
||||
Attributes attrs,
|
||||
Continuation cont)
|
||||
throws NamingException {
|
||||
c_processJunction_nns(name, cont);
|
||||
}
|
||||
|
||||
protected void c_rebind_nns(Name name,
|
||||
Object obj,
|
||||
Attributes attrs,
|
||||
Continuation cont)
|
||||
throws NamingException {
|
||||
c_processJunction_nns(name, cont);
|
||||
}
|
||||
|
||||
protected DirContext c_createSubcontext_nns(Name name,
|
||||
Attributes attrs,
|
||||
Continuation cont)
|
||||
throws NamingException {
|
||||
c_processJunction_nns(name, cont);
|
||||
return null;
|
||||
}
|
||||
|
||||
protected NamingEnumeration<SearchResult> c_search_nns(
|
||||
Name name,
|
||||
Attributes matchingAttributes,
|
||||
String[] attributesToReturn,
|
||||
Continuation cont)
|
||||
throws NamingException {
|
||||
c_processJunction_nns(name, cont);
|
||||
return null;
|
||||
}
|
||||
|
||||
protected NamingEnumeration<SearchResult> c_search_nns(
|
||||
Name name,
|
||||
String filter,
|
||||
SearchControls cons,
|
||||
Continuation cont)
|
||||
throws NamingException {
|
||||
c_processJunction_nns(name, cont);
|
||||
return null;
|
||||
}
|
||||
|
||||
protected NamingEnumeration<SearchResult> c_search_nns(
|
||||
Name name,
|
||||
String filterExpr,
|
||||
Object[] filterArgs,
|
||||
SearchControls cons,
|
||||
Continuation cont)
|
||||
throws NamingException {
|
||||
c_processJunction_nns(name, cont);
|
||||
return null;
|
||||
}
|
||||
|
||||
protected DirContext c_getSchema_nns(Name name, Continuation cont)
|
||||
throws NamingException {
|
||||
c_processJunction_nns(name, cont);
|
||||
return null;
|
||||
}
|
||||
|
||||
protected DirContext c_getSchemaClassDefinition_nns(Name name, Continuation cont)
|
||||
throws NamingException {
|
||||
c_processJunction_nns(name, cont);
|
||||
return null;
|
||||
}
|
||||
|
||||
// ------- implementations of p_ DirContext methods using corresponding
|
||||
// ------- DirContext c_ and c_*_nns methods
|
||||
|
||||
/* Implements for abstract methods declared in PartialCompositeDirContext */
|
||||
protected Attributes p_getAttributes(Name name,
|
||||
String[] attrIds,
|
||||
Continuation cont)
|
||||
throws NamingException {
|
||||
HeadTail res = p_resolveIntermediate(name, cont);
|
||||
Attributes answer = null;
|
||||
switch (res.getStatus()) {
|
||||
case TERMINAL_NNS_COMPONENT:
|
||||
answer = c_getAttributes_nns(res.getHead(), attrIds, cont);
|
||||
break;
|
||||
|
||||
case TERMINAL_COMPONENT:
|
||||
answer = c_getAttributes(res.getHead(), attrIds, cont);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* USE_CONTINUATION */
|
||||
/* cont already set or exception thrown */
|
||||
break;
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
protected void p_modifyAttributes(Name name, int mod_op,
|
||||
Attributes attrs,
|
||||
Continuation cont)
|
||||
throws NamingException {
|
||||
HeadTail res = p_resolveIntermediate(name, cont);
|
||||
switch (res.getStatus()) {
|
||||
case TERMINAL_NNS_COMPONENT:
|
||||
c_modifyAttributes_nns(res.getHead(), mod_op, attrs, cont);
|
||||
break;
|
||||
|
||||
case TERMINAL_COMPONENT:
|
||||
c_modifyAttributes(res.getHead(), mod_op, attrs, cont);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* USE_CONTINUATION */
|
||||
/* cont already set or exception thrown */
|
||||
break;
|
||||
}
|
||||
}
|
||||
protected void p_modifyAttributes(Name name,
|
||||
ModificationItem[] mods,
|
||||
Continuation cont)
|
||||
throws NamingException {
|
||||
HeadTail res = p_resolveIntermediate(name, cont);
|
||||
switch (res.getStatus()) {
|
||||
case TERMINAL_NNS_COMPONENT:
|
||||
c_modifyAttributes_nns(res.getHead(), mods, cont);
|
||||
break;
|
||||
|
||||
case TERMINAL_COMPONENT:
|
||||
c_modifyAttributes(res.getHead(), mods, cont);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* USE_CONTINUATION */
|
||||
/* cont already set or exception thrown */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected void p_bind(Name name,
|
||||
Object obj,
|
||||
Attributes attrs,
|
||||
Continuation cont)
|
||||
throws NamingException {
|
||||
HeadTail res = p_resolveIntermediate(name, cont);
|
||||
switch (res.getStatus()) {
|
||||
case TERMINAL_NNS_COMPONENT:
|
||||
c_bind_nns(res.getHead(), obj, attrs, cont);
|
||||
break;
|
||||
|
||||
case TERMINAL_COMPONENT:
|
||||
c_bind(res.getHead(), obj, attrs, cont);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* USE_CONTINUATION */
|
||||
/* cont already set or exception thrown */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected void p_rebind(Name name, Object obj,
|
||||
Attributes attrs, Continuation cont)
|
||||
throws NamingException {
|
||||
HeadTail res = p_resolveIntermediate(name, cont);
|
||||
switch (res.getStatus()) {
|
||||
case TERMINAL_NNS_COMPONENT:
|
||||
c_rebind_nns(res.getHead(), obj, attrs, cont);
|
||||
break;
|
||||
|
||||
case TERMINAL_COMPONENT:
|
||||
c_rebind(res.getHead(), obj, attrs, cont);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* USE_CONTINUATION */
|
||||
/* cont already set or exception thrown */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected DirContext p_createSubcontext(Name name,
|
||||
Attributes attrs,
|
||||
Continuation cont)
|
||||
throws NamingException {
|
||||
HeadTail res = p_resolveIntermediate(name, cont);
|
||||
DirContext answer = null;
|
||||
switch (res.getStatus()) {
|
||||
case TERMINAL_NNS_COMPONENT:
|
||||
answer = c_createSubcontext_nns(res.getHead(), attrs, cont);
|
||||
break;
|
||||
|
||||
case TERMINAL_COMPONENT:
|
||||
answer = c_createSubcontext(res.getHead(), attrs, cont);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* USE_CONTINUATION */
|
||||
/* cont already set or exception thrown */
|
||||
break;
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
protected NamingEnumeration<SearchResult> p_search(
|
||||
Name name,
|
||||
Attributes matchingAttributes,
|
||||
String[] attributesToReturn,
|
||||
Continuation cont)
|
||||
throws NamingException {
|
||||
HeadTail res = p_resolveIntermediate(name, cont);
|
||||
NamingEnumeration<SearchResult> answer = null;
|
||||
switch (res.getStatus()) {
|
||||
case TERMINAL_NNS_COMPONENT:
|
||||
answer = c_search_nns(res.getHead(), matchingAttributes,
|
||||
attributesToReturn, cont);
|
||||
break;
|
||||
|
||||
case TERMINAL_COMPONENT:
|
||||
answer = c_search(res.getHead(), matchingAttributes,
|
||||
attributesToReturn, cont);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* USE_CONTINUATION */
|
||||
/* cont already set or exception thrown */
|
||||
break;
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
protected NamingEnumeration<SearchResult> p_search(Name name,
|
||||
String filter,
|
||||
SearchControls cons,
|
||||
Continuation cont)
|
||||
throws NamingException {
|
||||
HeadTail res = p_resolveIntermediate(name, cont);
|
||||
NamingEnumeration<SearchResult> answer = null;
|
||||
switch (res.getStatus()) {
|
||||
case TERMINAL_NNS_COMPONENT:
|
||||
answer = c_search_nns(res.getHead(), filter, cons, cont);
|
||||
break;
|
||||
|
||||
case TERMINAL_COMPONENT:
|
||||
answer = c_search(res.getHead(), filter, cons, cont);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* USE_CONTINUATION */
|
||||
/* cont already set or exception thrown */
|
||||
break;
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
protected NamingEnumeration<SearchResult> p_search(Name name,
|
||||
String filterExpr,
|
||||
Object[] filterArgs,
|
||||
SearchControls cons,
|
||||
Continuation cont)
|
||||
throws NamingException {
|
||||
HeadTail res = p_resolveIntermediate(name, cont);
|
||||
NamingEnumeration<SearchResult> answer = null;
|
||||
switch (res.getStatus()) {
|
||||
case TERMINAL_NNS_COMPONENT:
|
||||
answer = c_search_nns(res.getHead(),
|
||||
filterExpr, filterArgs, cons, cont);
|
||||
break;
|
||||
|
||||
case TERMINAL_COMPONENT:
|
||||
answer = c_search(res.getHead(), filterExpr, filterArgs, cons, cont);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* USE_CONTINUATION */
|
||||
/* cont already set or exception thrown */
|
||||
break;
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
protected DirContext p_getSchema(Name name, Continuation cont)
|
||||
throws NamingException {
|
||||
DirContext answer = null;
|
||||
HeadTail res = p_resolveIntermediate(name, cont);
|
||||
switch (res.getStatus()) {
|
||||
case TERMINAL_NNS_COMPONENT:
|
||||
answer = c_getSchema_nns(res.getHead(), cont);
|
||||
break;
|
||||
|
||||
case TERMINAL_COMPONENT:
|
||||
answer = c_getSchema(res.getHead(), cont);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* USE_CONTINUATION */
|
||||
/* cont already set or exception thrown */
|
||||
break;
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
protected DirContext p_getSchemaClassDefinition(Name name, Continuation cont)
|
||||
throws NamingException {
|
||||
DirContext answer = null;
|
||||
HeadTail res = p_resolveIntermediate(name, cont);
|
||||
switch (res.getStatus()) {
|
||||
case TERMINAL_NNS_COMPONENT:
|
||||
answer = c_getSchemaClassDefinition_nns(res.getHead(), cont);
|
||||
break;
|
||||
|
||||
case TERMINAL_COMPONENT:
|
||||
answer = c_getSchemaClassDefinition(res.getHead(), cont);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* USE_CONTINUATION */
|
||||
/* cont already set or exception thrown */
|
||||
break;
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
}
|
||||
442
jdkSrc/jdk8/com/sun/jndi/toolkit/ctx/Continuation.java
Normal file
442
jdkSrc/jdk8/com/sun/jndi/toolkit/ctx/Continuation.java
Normal file
@@ -0,0 +1,442 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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 General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.jndi.toolkit.ctx;
|
||||
|
||||
import javax.naming.*;
|
||||
import javax.naming.spi.ResolveResult;
|
||||
import java.util.Hashtable;
|
||||
|
||||
/**
|
||||
* This class contains information required to continue
|
||||
* the method (place where it left off, and remaining name to
|
||||
* continue).
|
||||
*
|
||||
* @author Rosanna Lee
|
||||
*/
|
||||
|
||||
public class Continuation extends ResolveResult {
|
||||
/**
|
||||
* The name that we started out with. It is initialized by the constructor
|
||||
* and used to calculate to "resolved name" in NamingException in
|
||||
* fillInException().
|
||||
* %%% Note that this approach does not always do the calculation
|
||||
* correctly with respect to absence or presence of the trailing slash
|
||||
* for resolved name.
|
||||
*/
|
||||
protected Name starter;
|
||||
|
||||
/**
|
||||
* Whether links were encountered.
|
||||
*/
|
||||
protected Object followingLink = null;
|
||||
|
||||
/**
|
||||
* The environment used by the caller. Initialized by constructor and
|
||||
* used when filling out a CannotProceedException.
|
||||
*/
|
||||
protected Hashtable<?,?> environment = null;
|
||||
|
||||
/**
|
||||
* Indicates whether the Continuation instance indicates that the operation
|
||||
* should be continued using the data in the Continuation.
|
||||
* Typically, this is only false if an error has been encountered or if
|
||||
* the operation has succeeded.
|
||||
*/
|
||||
protected boolean continuing = false;
|
||||
|
||||
/**
|
||||
* The last resolved context. Used to set the "AltNameCtx" in a
|
||||
* CannotProceedException.
|
||||
*/
|
||||
protected Context resolvedContext = null;
|
||||
|
||||
/**
|
||||
* The resolved name relative to resolvedContext. Used to set the
|
||||
* "AltName" in a CannotProceedException.
|
||||
*/
|
||||
protected Name relativeResolvedName = null;
|
||||
|
||||
/**
|
||||
* Constructs a new instance of Continuation.
|
||||
* Used as dummy for contexts that do not do federation (e.g. for schema ops)
|
||||
*/
|
||||
public Continuation() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new instance of Continuation.
|
||||
* @param top The name of the object that is to be resolved/operated upon.
|
||||
* This becomes the Continuation's 'starter' and is used to
|
||||
* calculate the "resolved name" when filling in a NamingException.
|
||||
* @param environment The environment used by the caller. It is used
|
||||
* when setting the "environment" of a CannotProceedException.
|
||||
*/
|
||||
@SuppressWarnings("unchecked") // For Hashtable clone: environment.clone()
|
||||
public Continuation(Name top, Hashtable<?,?> environment) {
|
||||
super();
|
||||
starter = top;
|
||||
this.environment = (Hashtable<?,?>)
|
||||
((environment == null) ? null : environment.clone());
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether this Continuation contains data that should be
|
||||
* used to continue the operation.
|
||||
*
|
||||
* @return true if operation should continue; false if operation has
|
||||
* completed (successfully or unsuccessfully).
|
||||
*/
|
||||
public boolean isContinue() {
|
||||
return continuing;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this Continuation to indicate successful completion.
|
||||
* Subsequent calls to isContinue() will return false.
|
||||
* This method is different from the setError() methods only from
|
||||
* the standpoint that this method does not set any of the other
|
||||
* fields such as resolved object or resolved context. This is because
|
||||
* this method is typically called when the context recognizes that
|
||||
* the operation has successfully completed and that the continuation
|
||||
* already contains the appropriately set fields.
|
||||
* @see setError
|
||||
* @see setErrorNNS
|
||||
*/
|
||||
public void setSuccess() {
|
||||
continuing = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills in an exception's fields using data from this Continuation.
|
||||
* The resolved name is set by subtracting remainingName from starter.
|
||||
* %%% This might not not always produce the correct answer wrt trailing "/".
|
||||
* If the exception is a CannotProceedException, its environment,
|
||||
* altName, and altNameCtx fields are set using this continuation's
|
||||
* environment, relativeResolvedName, and resolvedContext.
|
||||
*
|
||||
* @param e The non-null naming exception to fill.
|
||||
* @return The non-null naming exception with its fields set using
|
||||
* data from this Continuation.
|
||||
*/
|
||||
public NamingException fillInException(NamingException e) {
|
||||
e.setRemainingName(remainingName);
|
||||
e.setResolvedObj(resolvedObj);
|
||||
|
||||
if (starter == null || starter.isEmpty())
|
||||
e.setResolvedName(null);
|
||||
else if (remainingName == null)
|
||||
e.setResolvedName(starter);
|
||||
else
|
||||
e.setResolvedName(
|
||||
starter.getPrefix(starter.size() -
|
||||
remainingName.size()));
|
||||
|
||||
if ((e instanceof CannotProceedException)) {
|
||||
CannotProceedException cpe = (CannotProceedException)e;
|
||||
Hashtable<?,?> env = (environment == null ?
|
||||
new Hashtable<>(11) : (Hashtable<?,?>)environment.clone());
|
||||
cpe.setEnvironment(env);
|
||||
cpe.setAltNameCtx(resolvedContext);
|
||||
cpe.setAltName(relativeResolvedName);
|
||||
}
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this Continuation to indicated that an error has occurred,
|
||||
* and that the remaining name is rename + "/".
|
||||
*
|
||||
* This method is typically called by _nns methods that have been
|
||||
* given a name to process. It might process part of that name but
|
||||
* encountered some error. Consequenetly, it would call setErrorNNS()
|
||||
* with the remaining name. Since the _nns method was expected to
|
||||
* operate upon the "nns" of the original name, the remaining name
|
||||
* must include the "nns". That's why this method adds a trailing "/".
|
||||
*<p>
|
||||
* After this method is called, isContinuing() returns false.
|
||||
*
|
||||
* @param resObj The possibly null object that was resolved to.
|
||||
* @param remain The non-null remaining name.
|
||||
*/
|
||||
public void setErrorNNS(Object resObj, Name remain) {
|
||||
Name nm = (Name)(remain.clone());
|
||||
try {
|
||||
nm.add("");
|
||||
} catch (InvalidNameException e) {
|
||||
// ignore; can't happen for composite name
|
||||
}
|
||||
setErrorAux(resObj, nm);
|
||||
}
|
||||
|
||||
/**
|
||||
* Form that accepts a String name instead of a Name name.
|
||||
|
||||
* @param resObj The possibly null object that was resolved to.
|
||||
* @param remain The possibly String remaining name.
|
||||
*
|
||||
* @see #setErrorNNS(java.lang.Object, javax.naming.Name)
|
||||
*/
|
||||
public void setErrorNNS(Object resObj, String remain) {
|
||||
CompositeName rname = new CompositeName();
|
||||
try {
|
||||
if (remain != null && !remain.equals(""))
|
||||
rname.add(remain);
|
||||
|
||||
rname.add("");
|
||||
} catch (InvalidNameException e) {
|
||||
// ignore, can't happen for composite name
|
||||
}
|
||||
setErrorAux(resObj, rname);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this Continuation to indicated that an error has occurred
|
||||
* and supply resolved information.
|
||||
*
|
||||
* This method is typically called by methods that have been
|
||||
* given a name to process. It might process part of that name but
|
||||
* encountered some error. Consequenetly, it would call setError()
|
||||
* with the resolved object and the remaining name.
|
||||
*<p>
|
||||
* After this method is called, isContinuing() returns false.
|
||||
*
|
||||
* @param resObj The possibly null object that was resolved to.
|
||||
* @param remain The possibly null remaining name.
|
||||
*/
|
||||
public void setError(Object resObj, Name remain) {
|
||||
if (remain != null)
|
||||
remainingName = (Name)(remain.clone());
|
||||
else
|
||||
remainingName = null;
|
||||
|
||||
setErrorAux(resObj, remainingName);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Form that accepts a String name instead of a Name name.
|
||||
|
||||
* @param resObj The possibly null object that was resolved to.
|
||||
* @param remain The possibly String remaining name.
|
||||
*
|
||||
* @see #setError(java.lang.Object, javax.naming.Name)
|
||||
*/
|
||||
public void setError(Object resObj, String remain) {
|
||||
CompositeName rname = new CompositeName();
|
||||
if (remain != null && !remain.equals("")) {
|
||||
try {
|
||||
rname.add(remain);
|
||||
} catch (InvalidNameException e) {
|
||||
// ignore; can't happen for composite name
|
||||
}
|
||||
}
|
||||
setErrorAux(resObj, rname);
|
||||
}
|
||||
|
||||
private void setErrorAux(Object resObj, Name rname) {
|
||||
remainingName = rname;
|
||||
resolvedObj = resObj;
|
||||
continuing = false;
|
||||
}
|
||||
|
||||
private void setContinueAux(Object resObj,
|
||||
Name relResName, Context currCtx, Name remain) {
|
||||
if (resObj instanceof LinkRef) {
|
||||
setContinueLink(resObj, relResName, currCtx, remain);
|
||||
} else {
|
||||
remainingName = remain;
|
||||
resolvedObj = resObj;
|
||||
|
||||
relativeResolvedName = relResName;
|
||||
resolvedContext = currCtx;
|
||||
|
||||
continuing = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this Continuation with the supplied data, and set remaining name
|
||||
* to be "/".
|
||||
* This method is typically called by _nns methods that have been
|
||||
* given a name to process. It might the name (without the nns) and
|
||||
* continue process of the nns elsewhere.
|
||||
* Consequently, it would call this form of the setContinueNNS().
|
||||
* This method supplies "/" as the remaining name.
|
||||
*<p>
|
||||
* After this method is called, isContinuing() returns true.
|
||||
*
|
||||
* @param resObj The possibly null resolved object.
|
||||
* @param relResName The non-null resolved name relative to currCtx.
|
||||
* @param currCtx The non-null context from which relResName is to be resolved.
|
||||
*/
|
||||
public void setContinueNNS(Object resObj, Name relResName, Context currCtx) {
|
||||
CompositeName rname = new CompositeName();
|
||||
|
||||
setContinue(resObj, relResName, currCtx, PartialCompositeContext._NNS_NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overloaded form that accesses String names.
|
||||
*
|
||||
* @param resObj The possibly null resolved object.
|
||||
* @param relResName The non-null resolved name relative to currCtx.
|
||||
* @param currCtx The non-null context from which relResName is to be resolved.
|
||||
* @see #setContinueNNS(java.lang.Object, javax.naming.Name, javax.naming.Context)
|
||||
*/
|
||||
public void setContinueNNS(Object resObj, String relResName, Context currCtx) {
|
||||
CompositeName relname = new CompositeName();
|
||||
try {
|
||||
relname.add(relResName);
|
||||
} catch (NamingException e) {}
|
||||
|
||||
setContinue(resObj, relname, currCtx, PartialCompositeContext._NNS_NAME);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets this Continuation with the supplied data, and set remaining name
|
||||
* to be the empty name.
|
||||
* This method is typically called by list-style methods
|
||||
* in which the target context implementing list() expects an
|
||||
* empty name. For example when c_list() is given a non-empty name to
|
||||
* process, it would resolve that name, and then call setContinue()
|
||||
* with the resolved object so that the target context to be listed
|
||||
* would be called with the empty name (i.e. list the target context itself).
|
||||
*<p>
|
||||
* After this method is called, isContinuing() returns true.
|
||||
*
|
||||
* @param resObj The possibly null resolved object.
|
||||
* @param relResName The non-null resolved name relative to currCtx.
|
||||
* @param currCtx The non-null context from which relResName is to be resolved.
|
||||
*/
|
||||
public void setContinue(Object obj, Name relResName, Context currCtx) {
|
||||
setContinueAux(obj, relResName, currCtx,
|
||||
(Name)PartialCompositeContext._EMPTY_NAME.clone());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this Continuation with the supplied data.
|
||||
|
||||
* This method is typically called by a method that has been asked
|
||||
* to operate on a name. The method resolves part of the name
|
||||
* (relResName) to obj and sets the unprocessed part to rename.
|
||||
* It calls setContinue() so that the operation can be continued
|
||||
* using this data.
|
||||
*<p>
|
||||
* After this method is called, isContinuing() returns true.
|
||||
*
|
||||
* @param resObj The possibly null resolved object.
|
||||
* @param relResName The non-null resolved name relative to currCtx.
|
||||
* @param currCtx The non-null context from which relResName is to be resolved.
|
||||
* @param remain The non-null remaining name.
|
||||
*/
|
||||
public void setContinue(Object obj, Name relResName, Context currCtx, Name remain) {
|
||||
if (remain != null)
|
||||
this.remainingName = (Name)(remain.clone());
|
||||
else
|
||||
this.remainingName = new CompositeName();
|
||||
|
||||
setContinueAux(obj, relResName, currCtx, remainingName);
|
||||
}
|
||||
|
||||
/**
|
||||
* String overload.
|
||||
*
|
||||
* @param resObj The possibly null resolved object.
|
||||
* @param relResName The non-null resolved name relative to currCtx.
|
||||
* @param currCtx The non-null context from which relResName is to be resolved.
|
||||
* @param remain The non-null remaining name.
|
||||
* @see #setContinue(java.lang.Object, java.lang.String, javax.naming.Context, java.lang.String)
|
||||
*/
|
||||
public void setContinue(Object obj, String relResName,
|
||||
Context currCtx, String remain) {
|
||||
CompositeName relname = new CompositeName();
|
||||
if (!relResName.equals("")) {
|
||||
try {
|
||||
relname.add(relResName);
|
||||
} catch (NamingException e){}
|
||||
}
|
||||
|
||||
CompositeName rname = new CompositeName();
|
||||
if (!remain.equals("")) {
|
||||
try {
|
||||
rname.add(remain);
|
||||
} catch (NamingException e) {
|
||||
}
|
||||
}
|
||||
|
||||
setContinueAux(obj, relname, currCtx, rname);
|
||||
}
|
||||
|
||||
/**
|
||||
* %%% This method is kept only for backward compatibility. Delete when
|
||||
* old implementations updated.
|
||||
*
|
||||
* Replaced by setContinue(obj, relResName, (Context)currCtx);
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
@Deprecated
|
||||
public void setContinue(Object obj, Object currCtx) {
|
||||
setContinue(obj, null, (Context)currCtx);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets this Continuation to process a linkRef.
|
||||
* %%% Not working yet.
|
||||
*/
|
||||
private void setContinueLink(Object linkRef, Name relResName,
|
||||
Context resolvedCtx, Name rname) {
|
||||
this.followingLink = linkRef;
|
||||
|
||||
this.remainingName = rname;
|
||||
this.resolvedObj = resolvedCtx;
|
||||
|
||||
this.relativeResolvedName = PartialCompositeContext._EMPTY_NAME;
|
||||
this.resolvedContext = resolvedCtx;
|
||||
|
||||
this.continuing = true;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
if (remainingName != null)
|
||||
return starter.toString() + "; remainingName: '" + remainingName + "'";
|
||||
else
|
||||
return starter.toString();
|
||||
}
|
||||
|
||||
public String toString(boolean detail) {
|
||||
if (!detail || this.resolvedObj == null)
|
||||
return this.toString();
|
||||
return this.toString() + "; resolvedObj: " + this.resolvedObj +
|
||||
"; relativeResolvedName: " + relativeResolvedName +
|
||||
"; resolvedContext: " + resolvedContext;
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 8162530656132624308L;
|
||||
}
|
||||
65
jdkSrc/jdk8/com/sun/jndi/toolkit/ctx/HeadTail.java
Normal file
65
jdkSrc/jdk8/com/sun/jndi/toolkit/ctx/HeadTail.java
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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 General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.jndi.toolkit.ctx;
|
||||
|
||||
import javax.naming.Name;
|
||||
|
||||
/**
|
||||
* A class for returning the result of p_parseComponent();
|
||||
*
|
||||
* @author Rosanna Lee
|
||||
*/
|
||||
public class HeadTail {
|
||||
private int status;
|
||||
private Name head;
|
||||
private Name tail;
|
||||
|
||||
public HeadTail(Name head, Name tail) {
|
||||
this(head, tail, 0);
|
||||
}
|
||||
|
||||
public HeadTail(Name head, Name tail, int status) {
|
||||
this.status = status;
|
||||
this.head = head;
|
||||
this.tail = tail;
|
||||
}
|
||||
|
||||
public void setStatus(int status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public Name getHead() {
|
||||
return this.head;
|
||||
}
|
||||
|
||||
public Name getTail() {
|
||||
return this.tail;
|
||||
}
|
||||
|
||||
public int getStatus() {
|
||||
return this.status;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,523 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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 General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.jndi.toolkit.ctx;
|
||||
|
||||
import java.util.Hashtable;
|
||||
import java.util.Enumeration;
|
||||
|
||||
import javax.naming.*;
|
||||
import javax.naming.spi.Resolver;
|
||||
import javax.naming.spi.ResolveResult;
|
||||
import javax.naming.spi.NamingManager;
|
||||
|
||||
/**
|
||||
* PartialCompositeContext implements Context operations on
|
||||
* composite names using implementations of the p_ interfaces
|
||||
* defined by its subclasses.
|
||||
*
|
||||
* The main purpose provided by this class is that it deals with
|
||||
* partial resolutions and continuations, so that callers of the
|
||||
* Context operation don't have to.
|
||||
*
|
||||
* Types of clients that will be direct subclasses of
|
||||
* PartialCompositeContext may be service providers that implement
|
||||
* one of the JNDI protocols, but which do not deal with
|
||||
* continuations. Usually, service providers will be using
|
||||
* one of the subclasses of PartialCompositeContext.
|
||||
*
|
||||
* @author Rosanna Lee
|
||||
*/
|
||||
|
||||
|
||||
public abstract class PartialCompositeContext implements Context, Resolver {
|
||||
protected static final int _PARTIAL = 1;
|
||||
protected static final int _COMPONENT = 2;
|
||||
protected static final int _ATOMIC = 3;
|
||||
|
||||
protected int _contextType = _PARTIAL;
|
||||
|
||||
static final CompositeName _EMPTY_NAME = new CompositeName();
|
||||
static CompositeName _NNS_NAME;
|
||||
|
||||
static {
|
||||
try {
|
||||
_NNS_NAME = new CompositeName("/");
|
||||
} catch (InvalidNameException e) {
|
||||
// Should never happen
|
||||
}
|
||||
}
|
||||
|
||||
protected PartialCompositeContext() {
|
||||
}
|
||||
|
||||
// ------ Abstract methods whose implementations come from subclasses
|
||||
|
||||
/* Equivalent to method in Resolver interface */
|
||||
protected abstract ResolveResult p_resolveToClass(Name name,
|
||||
Class<?> contextType, Continuation cont) throws NamingException;
|
||||
|
||||
/* Equivalent to methods in Context interface */
|
||||
protected abstract Object p_lookup(Name name, Continuation cont)
|
||||
throws NamingException;
|
||||
protected abstract Object p_lookupLink(Name name, Continuation cont)
|
||||
throws NamingException;
|
||||
protected abstract NamingEnumeration<NameClassPair> p_list(Name name,
|
||||
Continuation cont) throws NamingException;
|
||||
protected abstract NamingEnumeration<Binding> p_listBindings(Name name,
|
||||
Continuation cont) throws NamingException;
|
||||
protected abstract void p_bind(Name name, Object obj, Continuation cont)
|
||||
throws NamingException;
|
||||
protected abstract void p_rebind(Name name, Object obj, Continuation cont)
|
||||
throws NamingException;
|
||||
protected abstract void p_unbind(Name name, Continuation cont)
|
||||
throws NamingException;
|
||||
protected abstract void p_destroySubcontext(Name name, Continuation cont)
|
||||
throws NamingException;
|
||||
protected abstract Context p_createSubcontext(Name name, Continuation cont)
|
||||
throws NamingException;
|
||||
protected abstract void p_rename(Name oldname, Name newname,
|
||||
Continuation cont)
|
||||
throws NamingException;
|
||||
protected abstract NameParser p_getNameParser(Name name, Continuation cont)
|
||||
throws NamingException;
|
||||
|
||||
// ------ should be overridden by subclass;
|
||||
// ------ not abstract only for backward compatibility
|
||||
|
||||
/**
|
||||
* A cheap way of getting the environment.
|
||||
* Default implementation is NOT cheap because it simply calls
|
||||
* getEnvironment(), which most implementations clone before returning.
|
||||
* Subclass should ALWAYS override this with the cheapest possible way.
|
||||
* The toolkit knows to clone when necessary.
|
||||
* @return The possibly null environment of the context.
|
||||
*/
|
||||
protected Hashtable<?,?> p_getEnvironment() throws NamingException {
|
||||
return getEnvironment();
|
||||
}
|
||||
|
||||
|
||||
// ------ implementations of methods in Resolver and Context
|
||||
// ------ using corresponding p_ methods provided by subclass
|
||||
|
||||
/* implementations for method in Resolver interface using p_ method */
|
||||
|
||||
public ResolveResult resolveToClass(String name,
|
||||
Class<? extends Context> contextType)
|
||||
throws NamingException
|
||||
{
|
||||
return resolveToClass(new CompositeName(name), contextType);
|
||||
}
|
||||
|
||||
public ResolveResult resolveToClass(Name name,
|
||||
Class<? extends Context> contextType)
|
||||
throws NamingException
|
||||
{
|
||||
PartialCompositeContext ctx = this;
|
||||
Hashtable<?,?> env = p_getEnvironment();
|
||||
Continuation cont = new Continuation(name, env);
|
||||
ResolveResult answer;
|
||||
Name nm = name;
|
||||
|
||||
try {
|
||||
answer = ctx.p_resolveToClass(nm, contextType, cont);
|
||||
while (cont.isContinue()) {
|
||||
nm = cont.getRemainingName();
|
||||
ctx = getPCContext(cont);
|
||||
answer = ctx.p_resolveToClass(nm, contextType, cont);
|
||||
}
|
||||
} catch (CannotProceedException e) {
|
||||
Context cctx = NamingManager.getContinuationContext(e);
|
||||
if (!(cctx instanceof Resolver)) {
|
||||
throw e;
|
||||
}
|
||||
answer = ((Resolver)cctx).resolveToClass(e.getRemainingName(),
|
||||
contextType);
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
/* implementations for methods in Context interface using p_ methods */
|
||||
|
||||
public Object lookup(String name) throws NamingException {
|
||||
return lookup(new CompositeName(name));
|
||||
}
|
||||
|
||||
public Object lookup(Name name) throws NamingException {
|
||||
PartialCompositeContext ctx = this;
|
||||
Hashtable<?,?> env = p_getEnvironment();
|
||||
Continuation cont = new Continuation(name, env);
|
||||
Object answer;
|
||||
Name nm = name;
|
||||
|
||||
try {
|
||||
answer = ctx.p_lookup(nm, cont);
|
||||
while (cont.isContinue()) {
|
||||
nm = cont.getRemainingName();
|
||||
ctx = getPCContext(cont);
|
||||
answer = ctx.p_lookup(nm, cont);
|
||||
}
|
||||
} catch (CannotProceedException e) {
|
||||
Context cctx = NamingManager.getContinuationContext(e);
|
||||
answer = cctx.lookup(e.getRemainingName());
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
public void bind(String name, Object newObj) throws NamingException {
|
||||
bind(new CompositeName(name), newObj);
|
||||
}
|
||||
|
||||
public void bind(Name name, Object newObj) throws NamingException {
|
||||
PartialCompositeContext ctx = this;
|
||||
Name nm = name;
|
||||
Hashtable<?,?> env = p_getEnvironment();
|
||||
Continuation cont = new Continuation(name, env);
|
||||
|
||||
try {
|
||||
ctx.p_bind(nm, newObj, cont);
|
||||
while (cont.isContinue()) {
|
||||
nm = cont.getRemainingName();
|
||||
ctx = getPCContext(cont);
|
||||
ctx.p_bind(nm, newObj, cont);
|
||||
}
|
||||
} catch (CannotProceedException e) {
|
||||
Context cctx = NamingManager.getContinuationContext(e);
|
||||
cctx.bind(e.getRemainingName(), newObj);
|
||||
}
|
||||
}
|
||||
|
||||
public void rebind(String name, Object newObj) throws NamingException {
|
||||
rebind(new CompositeName(name), newObj);
|
||||
}
|
||||
public void rebind(Name name, Object newObj) throws NamingException {
|
||||
PartialCompositeContext ctx = this;
|
||||
Name nm = name;
|
||||
Hashtable<?,?> env = p_getEnvironment();
|
||||
Continuation cont = new Continuation(name, env);
|
||||
|
||||
try {
|
||||
ctx.p_rebind(nm, newObj, cont);
|
||||
while (cont.isContinue()) {
|
||||
nm = cont.getRemainingName();
|
||||
ctx = getPCContext(cont);
|
||||
ctx.p_rebind(nm, newObj, cont);
|
||||
}
|
||||
} catch (CannotProceedException e) {
|
||||
Context cctx = NamingManager.getContinuationContext(e);
|
||||
cctx.rebind(e.getRemainingName(), newObj);
|
||||
}
|
||||
}
|
||||
|
||||
public void unbind(String name) throws NamingException {
|
||||
unbind(new CompositeName(name));
|
||||
}
|
||||
public void unbind(Name name) throws NamingException {
|
||||
PartialCompositeContext ctx = this;
|
||||
Name nm = name;
|
||||
Hashtable<?,?> env = p_getEnvironment();
|
||||
Continuation cont = new Continuation(name, env);
|
||||
|
||||
try {
|
||||
ctx.p_unbind(nm, cont);
|
||||
while (cont.isContinue()) {
|
||||
nm = cont.getRemainingName();
|
||||
ctx = getPCContext(cont);
|
||||
ctx.p_unbind(nm, cont);
|
||||
}
|
||||
} catch (CannotProceedException e) {
|
||||
Context cctx = NamingManager.getContinuationContext(e);
|
||||
cctx.unbind(e.getRemainingName());
|
||||
}
|
||||
}
|
||||
|
||||
public void rename(String oldName, String newName) throws NamingException {
|
||||
rename(new CompositeName(oldName), new CompositeName(newName));
|
||||
}
|
||||
public void rename(Name oldName, Name newName)
|
||||
throws NamingException
|
||||
{
|
||||
PartialCompositeContext ctx = this;
|
||||
Name nm = oldName;
|
||||
Hashtable<?,?> env = p_getEnvironment();
|
||||
Continuation cont = new Continuation(oldName, env);
|
||||
|
||||
try {
|
||||
ctx.p_rename(nm, newName, cont);
|
||||
while (cont.isContinue()) {
|
||||
nm = cont.getRemainingName();
|
||||
ctx = getPCContext(cont);
|
||||
ctx.p_rename(nm, newName, cont);
|
||||
}
|
||||
} catch (CannotProceedException e) {
|
||||
Context cctx = NamingManager.getContinuationContext(e);
|
||||
if (e.getRemainingNewName() != null) {
|
||||
// %%% e.getRemainingNewName() should never be null
|
||||
newName = e.getRemainingNewName();
|
||||
}
|
||||
cctx.rename(e.getRemainingName(), newName);
|
||||
}
|
||||
}
|
||||
|
||||
public NamingEnumeration<NameClassPair> list(String name)
|
||||
throws NamingException
|
||||
{
|
||||
return list(new CompositeName(name));
|
||||
}
|
||||
|
||||
public NamingEnumeration<NameClassPair> list(Name name)
|
||||
throws NamingException
|
||||
{
|
||||
PartialCompositeContext ctx = this;
|
||||
Name nm = name;
|
||||
NamingEnumeration<NameClassPair> answer;
|
||||
Hashtable<?,?> env = p_getEnvironment();
|
||||
Continuation cont = new Continuation(name, env);
|
||||
|
||||
try {
|
||||
answer = ctx.p_list(nm, cont);
|
||||
while (cont.isContinue()) {
|
||||
nm = cont.getRemainingName();
|
||||
ctx = getPCContext(cont);
|
||||
answer = ctx.p_list(nm, cont);
|
||||
}
|
||||
} catch (CannotProceedException e) {
|
||||
Context cctx = NamingManager.getContinuationContext(e);
|
||||
answer = cctx.list(e.getRemainingName());
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
public NamingEnumeration<Binding> listBindings(String name)
|
||||
throws NamingException
|
||||
{
|
||||
return listBindings(new CompositeName(name));
|
||||
}
|
||||
|
||||
public NamingEnumeration<Binding> listBindings(Name name)
|
||||
throws NamingException
|
||||
{
|
||||
PartialCompositeContext ctx = this;
|
||||
Name nm = name;
|
||||
NamingEnumeration<Binding> answer;
|
||||
Hashtable<?,?> env = p_getEnvironment();
|
||||
Continuation cont = new Continuation(name, env);
|
||||
|
||||
try {
|
||||
answer = ctx.p_listBindings(nm, cont);
|
||||
while (cont.isContinue()) {
|
||||
nm = cont.getRemainingName();
|
||||
ctx = getPCContext(cont);
|
||||
answer = ctx.p_listBindings(nm, cont);
|
||||
}
|
||||
} catch (CannotProceedException e) {
|
||||
Context cctx = NamingManager.getContinuationContext(e);
|
||||
answer = cctx.listBindings(e.getRemainingName());
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
public void destroySubcontext(String name) throws NamingException {
|
||||
destroySubcontext(new CompositeName(name));
|
||||
}
|
||||
|
||||
public void destroySubcontext(Name name) throws NamingException {
|
||||
PartialCompositeContext ctx = this;
|
||||
Name nm = name;
|
||||
Hashtable<?,?> env = p_getEnvironment();
|
||||
Continuation cont = new Continuation(name, env);
|
||||
|
||||
try {
|
||||
ctx.p_destroySubcontext(nm, cont);
|
||||
while (cont.isContinue()) {
|
||||
nm = cont.getRemainingName();
|
||||
ctx = getPCContext(cont);
|
||||
ctx.p_destroySubcontext(nm, cont);
|
||||
}
|
||||
} catch (CannotProceedException e) {
|
||||
Context cctx = NamingManager.getContinuationContext(e);
|
||||
cctx.destroySubcontext(e.getRemainingName());
|
||||
}
|
||||
}
|
||||
|
||||
public Context createSubcontext(String name) throws NamingException {
|
||||
return createSubcontext(new CompositeName(name));
|
||||
}
|
||||
|
||||
public Context createSubcontext(Name name) throws NamingException {
|
||||
PartialCompositeContext ctx = this;
|
||||
Name nm = name;
|
||||
Context answer;
|
||||
Hashtable<?,?> env = p_getEnvironment();
|
||||
Continuation cont = new Continuation(name, env);
|
||||
|
||||
try {
|
||||
answer = ctx.p_createSubcontext(nm, cont);
|
||||
while (cont.isContinue()) {
|
||||
nm = cont.getRemainingName();
|
||||
ctx = getPCContext(cont);
|
||||
answer = ctx.p_createSubcontext(nm, cont);
|
||||
}
|
||||
} catch (CannotProceedException e) {
|
||||
Context cctx = NamingManager.getContinuationContext(e);
|
||||
answer = cctx.createSubcontext(e.getRemainingName());
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
public Object lookupLink(String name) throws NamingException {
|
||||
return lookupLink(new CompositeName(name));
|
||||
}
|
||||
|
||||
public Object lookupLink(Name name) throws NamingException {
|
||||
PartialCompositeContext ctx = this;
|
||||
Hashtable<?,?> env = p_getEnvironment();
|
||||
Continuation cont = new Continuation(name, env);
|
||||
Object answer;
|
||||
Name nm = name;
|
||||
|
||||
try {
|
||||
answer = ctx.p_lookupLink(nm, cont);
|
||||
while (cont.isContinue()) {
|
||||
nm = cont.getRemainingName();
|
||||
ctx = getPCContext(cont);
|
||||
answer = ctx.p_lookupLink(nm, cont);
|
||||
}
|
||||
} catch (CannotProceedException e) {
|
||||
Context cctx = NamingManager.getContinuationContext(e);
|
||||
answer = cctx.lookupLink(e.getRemainingName());
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
public NameParser getNameParser(String name) throws NamingException {
|
||||
return getNameParser(new CompositeName(name));
|
||||
}
|
||||
|
||||
public NameParser getNameParser(Name name) throws NamingException {
|
||||
PartialCompositeContext ctx = this;
|
||||
Name nm = name;
|
||||
NameParser answer;
|
||||
Hashtable<?,?> env = p_getEnvironment();
|
||||
Continuation cont = new Continuation(name, env);
|
||||
|
||||
try {
|
||||
answer = ctx.p_getNameParser(nm, cont);
|
||||
while (cont.isContinue()) {
|
||||
nm = cont.getRemainingName();
|
||||
ctx = getPCContext(cont);
|
||||
answer = ctx.p_getNameParser(nm, cont);
|
||||
}
|
||||
} catch (CannotProceedException e) {
|
||||
Context cctx = NamingManager.getContinuationContext(e);
|
||||
answer = cctx.getNameParser(e.getRemainingName());
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
public String composeName(String name, String prefix)
|
||||
throws NamingException {
|
||||
Name fullName = composeName(new CompositeName(name),
|
||||
new CompositeName(prefix));
|
||||
return fullName.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* This default implementation simply concatenates the two names.
|
||||
* There's one twist when the "java.naming.provider.compose.elideEmpty"
|
||||
* environment setting is set to "true": if each name contains a
|
||||
* nonempty component, and if 'prefix' ends with an empty component or
|
||||
* 'name' starts with one, then one empty component is dropped.
|
||||
* For example:
|
||||
* <pre>
|
||||
* elideEmpty=false elideEmpty=true
|
||||
* {"a"} + {"b"} => {"a", "b"} {"a", "b"}
|
||||
* {"a"} + {""} => {"a", ""} {"a", ""}
|
||||
* {"a"} + {"", "b"} => {"a", "", "b"} {"a", "b"}
|
||||
* {"a", ""} + {"b", ""} => {"a", "", "b", ""} {"a", "b", ""}
|
||||
* {"a", ""} + {"", "b"} => {"a", "", "", "b"} {"a", "", "b"}
|
||||
* </pre>
|
||||
*/
|
||||
public Name composeName(Name name, Name prefix) throws NamingException {
|
||||
Name res = (Name)prefix.clone();
|
||||
if (name == null) {
|
||||
return res;
|
||||
}
|
||||
res.addAll(name);
|
||||
|
||||
String elide = (String)
|
||||
p_getEnvironment().get("java.naming.provider.compose.elideEmpty");
|
||||
if (elide == null || !elide.equalsIgnoreCase("true")) {
|
||||
return res;
|
||||
}
|
||||
|
||||
int len = prefix.size();
|
||||
|
||||
if (!allEmpty(prefix) && !allEmpty(name)) {
|
||||
if (res.get(len - 1).equals("")) {
|
||||
res.remove(len - 1);
|
||||
} else if (res.get(len).equals("")) {
|
||||
res.remove(len);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
// ------ internal methods used by PartialCompositeContext
|
||||
|
||||
/**
|
||||
* Tests whether a name contains a nonempty component.
|
||||
*/
|
||||
protected static boolean allEmpty(Name name) {
|
||||
Enumeration<String> enum_ = name.getAll();
|
||||
while (enum_.hasMoreElements()) {
|
||||
if (!enum_.nextElement().isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a PartialCompositeContext for the resolved object in
|
||||
* cont. Throws CannotProceedException if not successful.
|
||||
*/
|
||||
protected static PartialCompositeContext getPCContext(Continuation cont)
|
||||
throws NamingException {
|
||||
|
||||
Object obj = cont.getResolvedObj();
|
||||
PartialCompositeContext pctx = null;
|
||||
|
||||
if (obj instanceof PartialCompositeContext) {
|
||||
// Just cast if octx already is PartialCompositeContext
|
||||
// %%% ignoring environment for now
|
||||
return (PartialCompositeContext)obj;
|
||||
} else {
|
||||
throw cont.fillInException(new CannotProceedException());
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,576 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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 General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.jndi.toolkit.ctx;
|
||||
|
||||
import java.util.Hashtable;
|
||||
|
||||
import javax.naming.*;
|
||||
import javax.naming.directory.*;
|
||||
import javax.naming.spi.DirectoryManager;
|
||||
|
||||
/*
|
||||
* Inherit from AtomicContext so that subclasses of PartialCompositeDirContext
|
||||
* can get the ns methods defined in subclasses of PartialCompositeContext.
|
||||
*
|
||||
* Direct subclasses of DirContext should provide implementations for
|
||||
* the p_ abstract DirContext methods and override the p_ Context methods
|
||||
* (not abstract anymore because they are overridden by ComponentContext
|
||||
* (the superclass of AtomicContext)).
|
||||
*
|
||||
* @author Rosanna Lee
|
||||
*/
|
||||
|
||||
public abstract class PartialCompositeDirContext
|
||||
extends AtomicContext implements DirContext {
|
||||
|
||||
protected PartialCompositeDirContext() {
|
||||
_contextType = _PARTIAL;
|
||||
}
|
||||
|
||||
// ------ Abstract methods whose implementation come from subclasses
|
||||
|
||||
/* Equivalent to DirContext methods */
|
||||
protected abstract Attributes p_getAttributes(Name name, String[] attrIds,
|
||||
Continuation cont)
|
||||
throws NamingException;
|
||||
|
||||
protected abstract void p_modifyAttributes(Name name, int mod_op,
|
||||
Attributes attrs,
|
||||
Continuation cont)
|
||||
throws NamingException;
|
||||
|
||||
protected abstract void p_modifyAttributes(Name name,
|
||||
ModificationItem[] mods,
|
||||
Continuation cont)
|
||||
throws NamingException;
|
||||
|
||||
protected abstract void p_bind(Name name, Object obj,
|
||||
Attributes attrs,
|
||||
Continuation cont)
|
||||
throws NamingException;
|
||||
|
||||
protected abstract void p_rebind(Name name, Object obj,
|
||||
Attributes attrs,
|
||||
Continuation cont)
|
||||
throws NamingException;
|
||||
|
||||
protected abstract DirContext p_createSubcontext(Name name,
|
||||
Attributes attrs,
|
||||
Continuation cont)
|
||||
throws NamingException;
|
||||
|
||||
protected abstract NamingEnumeration<SearchResult> p_search(
|
||||
Name name,
|
||||
Attributes matchingAttributes,
|
||||
String[] attributesToReturn,
|
||||
Continuation cont)
|
||||
throws NamingException;
|
||||
|
||||
protected abstract NamingEnumeration<SearchResult> p_search(
|
||||
Name name,
|
||||
String filter,
|
||||
SearchControls cons,
|
||||
Continuation cont)
|
||||
throws NamingException;
|
||||
|
||||
protected abstract NamingEnumeration<SearchResult> p_search(
|
||||
Name name,
|
||||
String filterExpr,
|
||||
Object[] filterArgs,
|
||||
SearchControls cons,
|
||||
Continuation cont)
|
||||
throws NamingException;
|
||||
|
||||
protected abstract DirContext p_getSchema(Name name, Continuation cont)
|
||||
throws NamingException;
|
||||
|
||||
protected abstract DirContext p_getSchemaClassDefinition(Name name,
|
||||
Continuation cont)
|
||||
throws NamingException;
|
||||
|
||||
// ------ implementation for DirContext methods using
|
||||
// ------ corresponding p_ methods
|
||||
|
||||
public Attributes getAttributes(String name)
|
||||
throws NamingException {
|
||||
return getAttributes(name, null);
|
||||
}
|
||||
|
||||
public Attributes getAttributes(Name name)
|
||||
throws NamingException {
|
||||
return getAttributes(name, null);
|
||||
}
|
||||
|
||||
public Attributes getAttributes(String name, String[] attrIds)
|
||||
throws NamingException {
|
||||
return getAttributes(new CompositeName(name), attrIds);
|
||||
}
|
||||
|
||||
public Attributes getAttributes(Name name, String[] attrIds)
|
||||
throws NamingException {
|
||||
PartialCompositeDirContext ctx = this;
|
||||
Hashtable<?,?> env = p_getEnvironment();
|
||||
Continuation cont = new Continuation(name, env);
|
||||
Attributes answer;
|
||||
Name nm = name;
|
||||
|
||||
try {
|
||||
answer = ctx.p_getAttributes(nm, attrIds, cont);
|
||||
while (cont.isContinue()) {
|
||||
nm = cont.getRemainingName();
|
||||
ctx = getPCDirContext(cont);
|
||||
answer = ctx.p_getAttributes(nm, attrIds, cont);
|
||||
}
|
||||
} catch (CannotProceedException e) {
|
||||
DirContext cctx = DirectoryManager.getContinuationDirContext(e);
|
||||
answer = cctx.getAttributes(e.getRemainingName(), attrIds);
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
public void modifyAttributes(String name, int mod_op, Attributes attrs)
|
||||
throws NamingException {
|
||||
modifyAttributes(new CompositeName(name), mod_op, attrs);
|
||||
}
|
||||
|
||||
public void modifyAttributes(Name name, int mod_op, Attributes attrs)
|
||||
throws NamingException {
|
||||
PartialCompositeDirContext ctx = this;
|
||||
Hashtable<?,?> env = p_getEnvironment();
|
||||
Continuation cont = new Continuation(name, env);
|
||||
Name nm = name;
|
||||
|
||||
try {
|
||||
ctx.p_modifyAttributes(nm, mod_op, attrs, cont);
|
||||
while (cont.isContinue()) {
|
||||
nm = cont.getRemainingName();
|
||||
ctx = getPCDirContext(cont);
|
||||
ctx.p_modifyAttributes(nm, mod_op, attrs, cont);
|
||||
}
|
||||
} catch (CannotProceedException e) {
|
||||
DirContext cctx = DirectoryManager.getContinuationDirContext(e);
|
||||
cctx.modifyAttributes(e.getRemainingName(), mod_op, attrs);
|
||||
}
|
||||
}
|
||||
|
||||
public void modifyAttributes(String name, ModificationItem[] mods)
|
||||
throws NamingException {
|
||||
modifyAttributes(new CompositeName(name), mods);
|
||||
}
|
||||
|
||||
public void modifyAttributes(Name name, ModificationItem[] mods)
|
||||
throws NamingException {
|
||||
PartialCompositeDirContext ctx = this;
|
||||
Hashtable<?,?> env = p_getEnvironment();
|
||||
Continuation cont = new Continuation(name, env);
|
||||
Name nm = name;
|
||||
|
||||
try {
|
||||
ctx.p_modifyAttributes(nm, mods, cont);
|
||||
while (cont.isContinue()) {
|
||||
nm = cont.getRemainingName();
|
||||
ctx = getPCDirContext(cont);
|
||||
ctx.p_modifyAttributes(nm, mods, cont);
|
||||
}
|
||||
} catch (CannotProceedException e) {
|
||||
DirContext cctx = DirectoryManager.getContinuationDirContext(e);
|
||||
cctx.modifyAttributes(e.getRemainingName(), mods);
|
||||
}
|
||||
}
|
||||
|
||||
public void bind(String name, Object obj, Attributes attrs)
|
||||
throws NamingException {
|
||||
bind(new CompositeName(name), obj, attrs);
|
||||
}
|
||||
|
||||
public void bind(Name name, Object obj, Attributes attrs)
|
||||
throws NamingException {
|
||||
PartialCompositeDirContext ctx = this;
|
||||
Hashtable<?,?> env = p_getEnvironment();
|
||||
Continuation cont = new Continuation(name, env);
|
||||
Name nm = name;
|
||||
|
||||
try {
|
||||
ctx.p_bind(nm, obj, attrs, cont);
|
||||
while (cont.isContinue()) {
|
||||
nm = cont.getRemainingName();
|
||||
ctx = getPCDirContext(cont);
|
||||
ctx.p_bind(nm, obj, attrs, cont);
|
||||
}
|
||||
} catch (CannotProceedException e) {
|
||||
DirContext cctx = DirectoryManager.getContinuationDirContext(e);
|
||||
cctx.bind(e.getRemainingName(), obj, attrs);
|
||||
}
|
||||
}
|
||||
|
||||
public void rebind(String name, Object obj, Attributes attrs)
|
||||
throws NamingException {
|
||||
rebind(new CompositeName(name), obj, attrs);
|
||||
}
|
||||
|
||||
public void rebind(Name name, Object obj, Attributes attrs)
|
||||
throws NamingException {
|
||||
PartialCompositeDirContext ctx = this;
|
||||
Hashtable<?,?> env = p_getEnvironment();
|
||||
Continuation cont = new Continuation(name, env);
|
||||
Name nm = name;
|
||||
|
||||
try {
|
||||
ctx.p_rebind(nm, obj, attrs, cont);
|
||||
while (cont.isContinue()) {
|
||||
nm = cont.getRemainingName();
|
||||
ctx = getPCDirContext(cont);
|
||||
ctx.p_rebind(nm, obj, attrs, cont);
|
||||
}
|
||||
} catch (CannotProceedException e) {
|
||||
DirContext cctx = DirectoryManager.getContinuationDirContext(e);
|
||||
cctx.rebind(e.getRemainingName(), obj, attrs);
|
||||
}
|
||||
}
|
||||
|
||||
public DirContext createSubcontext(String name, Attributes attrs)
|
||||
throws NamingException {
|
||||
return createSubcontext(new CompositeName(name), attrs);
|
||||
}
|
||||
|
||||
public DirContext createSubcontext(Name name, Attributes attrs)
|
||||
throws NamingException {
|
||||
PartialCompositeDirContext ctx = this;
|
||||
Hashtable<?,?> env = p_getEnvironment();
|
||||
Continuation cont = new Continuation(name, env);
|
||||
DirContext answer;
|
||||
Name nm = name;
|
||||
|
||||
try {
|
||||
answer = ctx.p_createSubcontext(nm, attrs, cont);
|
||||
while (cont.isContinue()) {
|
||||
nm = cont.getRemainingName();
|
||||
ctx = getPCDirContext(cont);
|
||||
answer = ctx.p_createSubcontext(nm, attrs, cont);
|
||||
}
|
||||
} catch (CannotProceedException e) {
|
||||
DirContext cctx = DirectoryManager.getContinuationDirContext(e);
|
||||
answer = cctx.createSubcontext(e.getRemainingName(), attrs);
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
public NamingEnumeration<SearchResult>
|
||||
search(String name, Attributes matchingAttributes)
|
||||
throws NamingException
|
||||
{
|
||||
return search(name, matchingAttributes, null);
|
||||
}
|
||||
|
||||
public NamingEnumeration<SearchResult>
|
||||
search(Name name, Attributes matchingAttributes)
|
||||
throws NamingException
|
||||
{
|
||||
return search(name, matchingAttributes, null);
|
||||
}
|
||||
|
||||
public NamingEnumeration<SearchResult>
|
||||
search(String name,
|
||||
Attributes matchingAttributes,
|
||||
String[] attributesToReturn)
|
||||
throws NamingException
|
||||
{
|
||||
return search(new CompositeName(name),
|
||||
matchingAttributes, attributesToReturn);
|
||||
}
|
||||
|
||||
public NamingEnumeration<SearchResult>
|
||||
search(Name name,
|
||||
Attributes matchingAttributes,
|
||||
String[] attributesToReturn)
|
||||
throws NamingException
|
||||
{
|
||||
|
||||
PartialCompositeDirContext ctx = this;
|
||||
Hashtable<?,?> env = p_getEnvironment();
|
||||
Continuation cont = new Continuation(name, env);
|
||||
NamingEnumeration<SearchResult> answer;
|
||||
Name nm = name;
|
||||
|
||||
try {
|
||||
answer = ctx.p_search(nm, matchingAttributes,
|
||||
attributesToReturn, cont);
|
||||
while (cont.isContinue()) {
|
||||
nm = cont.getRemainingName();
|
||||
ctx = getPCDirContext(cont);
|
||||
answer = ctx.p_search(nm, matchingAttributes,
|
||||
attributesToReturn, cont);
|
||||
}
|
||||
} catch (CannotProceedException e) {
|
||||
DirContext cctx = DirectoryManager.getContinuationDirContext(e);
|
||||
answer = cctx.search(e.getRemainingName(), matchingAttributes,
|
||||
attributesToReturn);
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
public NamingEnumeration<SearchResult>
|
||||
search(String name,
|
||||
String filter,
|
||||
SearchControls cons)
|
||||
throws NamingException
|
||||
{
|
||||
return search(new CompositeName(name), filter, cons);
|
||||
}
|
||||
|
||||
public NamingEnumeration<SearchResult>
|
||||
search(Name name,
|
||||
String filter,
|
||||
SearchControls cons)
|
||||
throws NamingException
|
||||
{
|
||||
|
||||
PartialCompositeDirContext ctx = this;
|
||||
Hashtable<?,?> env = p_getEnvironment();
|
||||
Continuation cont = new Continuation(name, env);
|
||||
NamingEnumeration<SearchResult> answer;
|
||||
Name nm = name;
|
||||
|
||||
try {
|
||||
answer = ctx.p_search(nm, filter, cons, cont);
|
||||
while (cont.isContinue()) {
|
||||
nm = cont.getRemainingName();
|
||||
ctx = getPCDirContext(cont);
|
||||
answer = ctx.p_search(nm, filter, cons, cont);
|
||||
}
|
||||
} catch (CannotProceedException e) {
|
||||
DirContext cctx = DirectoryManager.getContinuationDirContext(e);
|
||||
answer = cctx.search(e.getRemainingName(), filter, cons);
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
public NamingEnumeration<SearchResult>
|
||||
search(String name,
|
||||
String filterExpr,
|
||||
Object[] filterArgs,
|
||||
SearchControls cons)
|
||||
throws NamingException
|
||||
{
|
||||
return search(new CompositeName(name), filterExpr, filterArgs, cons);
|
||||
}
|
||||
|
||||
public NamingEnumeration<SearchResult>
|
||||
search(Name name,
|
||||
String filterExpr,
|
||||
Object[] filterArgs,
|
||||
SearchControls cons)
|
||||
throws NamingException
|
||||
{
|
||||
|
||||
PartialCompositeDirContext ctx = this;
|
||||
Hashtable<?,?> env = p_getEnvironment();
|
||||
Continuation cont = new Continuation(name, env);
|
||||
NamingEnumeration<SearchResult> answer;
|
||||
Name nm = name;
|
||||
|
||||
try {
|
||||
answer = ctx.p_search(nm, filterExpr, filterArgs, cons, cont);
|
||||
while (cont.isContinue()) {
|
||||
nm = cont.getRemainingName();
|
||||
ctx = getPCDirContext(cont);
|
||||
answer = ctx.p_search(nm, filterExpr, filterArgs, cons, cont);
|
||||
}
|
||||
} catch (CannotProceedException e) {
|
||||
DirContext cctx = DirectoryManager.getContinuationDirContext(e);
|
||||
answer = cctx.search(e.getRemainingName(), filterExpr, filterArgs,
|
||||
cons);
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
public DirContext getSchema(String name) throws NamingException {
|
||||
return getSchema(new CompositeName(name));
|
||||
}
|
||||
|
||||
public DirContext getSchema(Name name) throws NamingException {
|
||||
PartialCompositeDirContext ctx = this;
|
||||
Hashtable<?,?> env = p_getEnvironment();
|
||||
Continuation cont = new Continuation(name, env);
|
||||
DirContext answer;
|
||||
Name nm = name;
|
||||
|
||||
try {
|
||||
answer = ctx.p_getSchema(nm, cont);
|
||||
while (cont.isContinue()) {
|
||||
nm = cont.getRemainingName();
|
||||
ctx = getPCDirContext(cont);
|
||||
answer = ctx.p_getSchema(nm, cont);
|
||||
}
|
||||
} catch (CannotProceedException e) {
|
||||
DirContext cctx = DirectoryManager.getContinuationDirContext(e);
|
||||
answer = cctx.getSchema(e.getRemainingName());
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
public DirContext getSchemaClassDefinition(String name)
|
||||
throws NamingException {
|
||||
return getSchemaClassDefinition(new CompositeName(name));
|
||||
}
|
||||
|
||||
public DirContext getSchemaClassDefinition(Name name)
|
||||
throws NamingException {
|
||||
PartialCompositeDirContext ctx = this;
|
||||
Hashtable<?,?> env = p_getEnvironment();
|
||||
Continuation cont = new Continuation(name, env);
|
||||
DirContext answer;
|
||||
Name nm = name;
|
||||
|
||||
try {
|
||||
answer = ctx.p_getSchemaClassDefinition(nm, cont);
|
||||
while (cont.isContinue()) {
|
||||
nm = cont.getRemainingName();
|
||||
ctx = getPCDirContext(cont);
|
||||
answer = ctx.p_getSchemaClassDefinition(nm, cont);
|
||||
}
|
||||
} catch (CannotProceedException e) {
|
||||
DirContext cctx = DirectoryManager.getContinuationDirContext(e);
|
||||
answer = cctx.getSchemaClassDefinition(e.getRemainingName());
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
// ------ internal method used by PartialCompositeDirContext
|
||||
|
||||
/**
|
||||
* Retrieves a PartialCompositeDirContext for the resolved object in
|
||||
* cont. Throws CannotProceedException if not successful.
|
||||
*/
|
||||
protected static PartialCompositeDirContext getPCDirContext(Continuation cont)
|
||||
throws NamingException {
|
||||
|
||||
PartialCompositeContext pctx =
|
||||
PartialCompositeContext.getPCContext(cont);
|
||||
|
||||
if (!(pctx instanceof PartialCompositeDirContext)) {
|
||||
throw cont.fillInException(
|
||||
new NotContextException(
|
||||
"Resolved object is not a DirContext."));
|
||||
}
|
||||
|
||||
return (PartialCompositeDirContext)pctx;
|
||||
}
|
||||
|
||||
|
||||
//------ Compensation for inheriting from AtomicContext
|
||||
|
||||
/*
|
||||
* Dummy implementations defined here so that direct subclasses
|
||||
* of PartialCompositeDirContext or ComponentDirContext do not
|
||||
* have to provide dummy implementations for these.
|
||||
* Override these for subclasses of AtomicDirContext.
|
||||
*/
|
||||
|
||||
protected StringHeadTail c_parseComponent(String inputName,
|
||||
Continuation cont) throws NamingException {
|
||||
OperationNotSupportedException e = new
|
||||
OperationNotSupportedException();
|
||||
throw cont.fillInException(e);
|
||||
}
|
||||
|
||||
protected Object a_lookup(String name, Continuation cont)
|
||||
throws NamingException {
|
||||
OperationNotSupportedException e = new
|
||||
OperationNotSupportedException();
|
||||
throw cont.fillInException(e);
|
||||
}
|
||||
|
||||
protected Object a_lookupLink(String name, Continuation cont)
|
||||
throws NamingException {
|
||||
OperationNotSupportedException e = new
|
||||
OperationNotSupportedException();
|
||||
throw cont.fillInException(e);
|
||||
}
|
||||
|
||||
protected NamingEnumeration<NameClassPair> a_list(
|
||||
Continuation cont) throws NamingException {
|
||||
OperationNotSupportedException e = new
|
||||
OperationNotSupportedException();
|
||||
throw cont.fillInException(e);
|
||||
}
|
||||
|
||||
protected NamingEnumeration<Binding> a_listBindings(
|
||||
Continuation cont) throws NamingException {
|
||||
OperationNotSupportedException e = new
|
||||
OperationNotSupportedException();
|
||||
throw cont.fillInException(e);
|
||||
}
|
||||
|
||||
protected void a_bind(String name, Object obj, Continuation cont)
|
||||
throws NamingException {
|
||||
OperationNotSupportedException e = new
|
||||
OperationNotSupportedException();
|
||||
throw cont.fillInException(e);
|
||||
}
|
||||
|
||||
protected void a_rebind(String name, Object obj, Continuation cont)
|
||||
throws NamingException {
|
||||
OperationNotSupportedException e = new
|
||||
OperationNotSupportedException();
|
||||
throw cont.fillInException(e);
|
||||
}
|
||||
|
||||
protected void a_unbind(String name, Continuation cont)
|
||||
throws NamingException {
|
||||
OperationNotSupportedException e = new
|
||||
OperationNotSupportedException();
|
||||
throw cont.fillInException(e);
|
||||
}
|
||||
|
||||
protected void a_destroySubcontext(String name, Continuation cont)
|
||||
throws NamingException {
|
||||
OperationNotSupportedException e = new
|
||||
OperationNotSupportedException();
|
||||
throw cont.fillInException(e);
|
||||
}
|
||||
|
||||
protected Context a_createSubcontext(String name, Continuation cont)
|
||||
throws NamingException {
|
||||
OperationNotSupportedException e = new
|
||||
OperationNotSupportedException();
|
||||
throw cont.fillInException(e);
|
||||
}
|
||||
|
||||
protected void a_rename(String oldname, Name newname,
|
||||
Continuation cont) throws NamingException {
|
||||
OperationNotSupportedException e = new
|
||||
OperationNotSupportedException();
|
||||
throw cont.fillInException(e);
|
||||
}
|
||||
|
||||
protected NameParser a_getNameParser(Continuation cont)
|
||||
throws NamingException {
|
||||
OperationNotSupportedException e = new
|
||||
OperationNotSupportedException();
|
||||
throw cont.fillInException(e);
|
||||
}
|
||||
}
|
||||
63
jdkSrc/jdk8/com/sun/jndi/toolkit/ctx/StringHeadTail.java
Normal file
63
jdkSrc/jdk8/com/sun/jndi/toolkit/ctx/StringHeadTail.java
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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 General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.jndi.toolkit.ctx;
|
||||
|
||||
/**
|
||||
* A class for returning the result of c_parseComponent().
|
||||
*
|
||||
* @author Rosanna Lee
|
||||
*/
|
||||
public class StringHeadTail {
|
||||
private int status;
|
||||
private String head;
|
||||
private String tail;
|
||||
|
||||
public StringHeadTail(String head, String tail) {
|
||||
this(head, tail, 0);
|
||||
}
|
||||
|
||||
public StringHeadTail(String head, String tail, int status) {
|
||||
this.status = status;
|
||||
this.head = head;
|
||||
this.tail = tail;
|
||||
}
|
||||
|
||||
public void setStatus(int status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getHead() {
|
||||
return this.head;
|
||||
}
|
||||
|
||||
public String getTail() {
|
||||
return this.tail;
|
||||
}
|
||||
|
||||
public int getStatus() {
|
||||
return this.status;
|
||||
}
|
||||
}
|
||||
41
jdkSrc/jdk8/com/sun/jndi/toolkit/dir/AttrFilter.java
Normal file
41
jdkSrc/jdk8/com/sun/jndi/toolkit/dir/AttrFilter.java
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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 General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package com.sun.jndi.toolkit.dir;
|
||||
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.directory.Attributes;
|
||||
|
||||
/**
|
||||
* Is implemented by classes that can perform filter checks on
|
||||
* an attribute set.
|
||||
*/
|
||||
|
||||
public interface AttrFilter {
|
||||
|
||||
/**
|
||||
* Determines whether an attribute passes the filter.
|
||||
*/
|
||||
public boolean check(Attributes targetAttrs) throws NamingException;
|
||||
}
|
||||
83
jdkSrc/jdk8/com/sun/jndi/toolkit/dir/ContainmentFilter.java
Normal file
83
jdkSrc/jdk8/com/sun/jndi/toolkit/dir/ContainmentFilter.java
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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 General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Supports checking an attribute set satisfies a filter
|
||||
* that is specified as a set of "matching" attributes.
|
||||
* Checking is done by determining whether the given attribute set
|
||||
* is a superset of the matching ones.
|
||||
*
|
||||
* @author Rosanna Lee
|
||||
*/
|
||||
|
||||
package com.sun.jndi.toolkit.dir;
|
||||
|
||||
import javax.naming.*;
|
||||
import javax.naming.directory.*;
|
||||
|
||||
public class ContainmentFilter implements AttrFilter {
|
||||
private Attributes matchingAttrs;
|
||||
|
||||
public ContainmentFilter(Attributes match) {
|
||||
matchingAttrs = match;
|
||||
}
|
||||
|
||||
public boolean check(Attributes attrs) throws NamingException {
|
||||
return matchingAttrs == null ||
|
||||
matchingAttrs.size() == 0 ||
|
||||
contains(attrs, matchingAttrs);
|
||||
}
|
||||
|
||||
// returns true if superset contains subset
|
||||
public static boolean contains(Attributes superset, Attributes subset)
|
||||
throws NamingException {
|
||||
if (subset == null)
|
||||
return true; // an empty set is always a subset
|
||||
|
||||
NamingEnumeration<? extends Attribute> m = subset.getAll();
|
||||
while (m.hasMore()) {
|
||||
if (superset == null) {
|
||||
return false; // contains nothing
|
||||
}
|
||||
Attribute target = m.next();
|
||||
Attribute fromSuper = superset.get(target.getID());
|
||||
if (fromSuper == null) {
|
||||
return false;
|
||||
} else {
|
||||
// check whether attribute values match
|
||||
if (target.size() > 0) {
|
||||
NamingEnumeration<?> vals = target.getAll();
|
||||
while (vals.hasMore()) {
|
||||
if (!fromSuper.contains(vals.next())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
235
jdkSrc/jdk8/com/sun/jndi/toolkit/dir/ContextEnumerator.java
Normal file
235
jdkSrc/jdk8/com/sun/jndi/toolkit/dir/ContextEnumerator.java
Normal file
@@ -0,0 +1,235 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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 General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package com.sun.jndi.toolkit.dir;
|
||||
|
||||
import javax.naming.*;
|
||||
import javax.naming.directory.SearchControls;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* A class for recursively enumerating the contents of a Context;
|
||||
*
|
||||
* @author Jon Ruiz
|
||||
*/
|
||||
public class ContextEnumerator implements NamingEnumeration<Binding> {
|
||||
|
||||
private static boolean debug = false;
|
||||
private NamingEnumeration<Binding> children = null;
|
||||
private Binding currentChild = null;
|
||||
private boolean currentReturned = false;
|
||||
private Context root;
|
||||
private ContextEnumerator currentChildEnum = null;
|
||||
private boolean currentChildExpanded = false;
|
||||
private boolean rootProcessed = false;
|
||||
private int scope = SearchControls.SUBTREE_SCOPE;
|
||||
private String contextName = "";
|
||||
|
||||
public ContextEnumerator(Context context) throws NamingException {
|
||||
this(context, SearchControls.SUBTREE_SCOPE);
|
||||
}
|
||||
|
||||
public ContextEnumerator(Context context, int scope)
|
||||
throws NamingException {
|
||||
// return this object except when searching single-level
|
||||
this(context, scope, "", scope != SearchControls.ONELEVEL_SCOPE);
|
||||
}
|
||||
|
||||
protected ContextEnumerator(Context context, int scope, String contextName,
|
||||
boolean returnSelf)
|
||||
throws NamingException {
|
||||
if(context == null) {
|
||||
throw new IllegalArgumentException("null context passed");
|
||||
}
|
||||
|
||||
root = context;
|
||||
|
||||
// No need to list children if we're only searching object
|
||||
if (scope != SearchControls.OBJECT_SCOPE) {
|
||||
children = getImmediateChildren(context);
|
||||
}
|
||||
this.scope = scope;
|
||||
this.contextName = contextName;
|
||||
// pretend root is processed, if we're not supposed to return ourself
|
||||
rootProcessed = !returnSelf;
|
||||
prepNextChild();
|
||||
}
|
||||
|
||||
// Subclass should override if it wants to avoid calling obj factory
|
||||
protected NamingEnumeration<Binding> getImmediateChildren(Context ctx)
|
||||
throws NamingException {
|
||||
return ctx.listBindings("");
|
||||
}
|
||||
|
||||
// Subclass should override so that instance is of same type as subclass
|
||||
protected ContextEnumerator newEnumerator(Context ctx, int scope,
|
||||
String contextName, boolean returnSelf) throws NamingException {
|
||||
return new ContextEnumerator(ctx, scope, contextName, returnSelf);
|
||||
}
|
||||
|
||||
public boolean hasMore() throws NamingException {
|
||||
return !rootProcessed ||
|
||||
(scope != SearchControls.OBJECT_SCOPE && hasMoreDescendants());
|
||||
}
|
||||
|
||||
public boolean hasMoreElements() {
|
||||
try {
|
||||
return hasMore();
|
||||
} catch (NamingException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public Binding nextElement() {
|
||||
try {
|
||||
return next();
|
||||
} catch (NamingException e) {
|
||||
throw new NoSuchElementException(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public Binding next() throws NamingException {
|
||||
if (!rootProcessed) {
|
||||
rootProcessed = true;
|
||||
return new Binding("", root.getClass().getName(),
|
||||
root, true);
|
||||
}
|
||||
|
||||
if (scope != SearchControls.OBJECT_SCOPE && hasMoreDescendants()) {
|
||||
return getNextDescendant();
|
||||
}
|
||||
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
|
||||
public void close() throws NamingException {
|
||||
root = null;
|
||||
}
|
||||
|
||||
private boolean hasMoreChildren() throws NamingException {
|
||||
return children != null && children.hasMore();
|
||||
}
|
||||
|
||||
private Binding getNextChild() throws NamingException {
|
||||
Binding oldBinding = children.next();
|
||||
Binding newBinding = null;
|
||||
|
||||
// if the name is relative, we need to add it to the name of this
|
||||
// context to keep it relative w.r.t. the root context we are
|
||||
// enumerating
|
||||
if(oldBinding.isRelative() && !contextName.equals("")) {
|
||||
NameParser parser = root.getNameParser("");
|
||||
Name newName = parser.parse(contextName);
|
||||
newName.add(oldBinding.getName());
|
||||
if(debug) {
|
||||
System.out.println("ContextEnumerator: adding " + newName);
|
||||
}
|
||||
newBinding = new Binding(newName.toString(),
|
||||
oldBinding.getClassName(),
|
||||
oldBinding.getObject(),
|
||||
oldBinding.isRelative());
|
||||
} else {
|
||||
if(debug) {
|
||||
System.out.println("ContextEnumerator: using old binding");
|
||||
}
|
||||
newBinding = oldBinding;
|
||||
}
|
||||
|
||||
return newBinding;
|
||||
}
|
||||
|
||||
private boolean hasMoreDescendants() throws NamingException {
|
||||
// if the current child is expanded, see if it has more elements
|
||||
if (!currentReturned) {
|
||||
if(debug) {System.out.println("hasMoreDescendants returning " +
|
||||
(currentChild != null) ); }
|
||||
return currentChild != null;
|
||||
} else if (currentChildExpanded && currentChildEnum.hasMore()) {
|
||||
|
||||
if(debug) {System.out.println("hasMoreDescendants returning " +
|
||||
"true");}
|
||||
|
||||
return true;
|
||||
} else {
|
||||
if(debug) {System.out.println("hasMoreDescendants returning " +
|
||||
"hasMoreChildren");}
|
||||
return hasMoreChildren();
|
||||
}
|
||||
}
|
||||
|
||||
private Binding getNextDescendant() throws NamingException {
|
||||
|
||||
if (!currentReturned) {
|
||||
// returning parent
|
||||
if(debug) {System.out.println("getNextDescedant: simple case");}
|
||||
|
||||
currentReturned = true;
|
||||
return currentChild;
|
||||
|
||||
} else if (currentChildExpanded && currentChildEnum.hasMore()) {
|
||||
|
||||
if(debug) {System.out.println("getNextDescedant: expanded case");}
|
||||
|
||||
// if the current child is expanded, use it's enumerator
|
||||
return currentChildEnum.next();
|
||||
|
||||
} else {
|
||||
|
||||
// Ready to go onto next child
|
||||
if(debug) {System.out.println("getNextDescedant: next case");}
|
||||
|
||||
prepNextChild();
|
||||
return getNextDescendant();
|
||||
}
|
||||
}
|
||||
|
||||
private void prepNextChild() throws NamingException {
|
||||
if(hasMoreChildren()) {
|
||||
try {
|
||||
currentChild = getNextChild();
|
||||
currentReturned = false;
|
||||
} catch (NamingException e){
|
||||
if (debug) System.out.println(e);
|
||||
if (debug) e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
currentChild = null;
|
||||
return;
|
||||
}
|
||||
|
||||
if(scope == SearchControls.SUBTREE_SCOPE &&
|
||||
currentChild.getObject() instanceof Context) {
|
||||
currentChildEnum = newEnumerator(
|
||||
(Context)(currentChild.getObject()),
|
||||
scope, currentChild.getName(),
|
||||
false);
|
||||
currentChildExpanded = true;
|
||||
if(debug) {System.out.println("prepNextChild: expanded");}
|
||||
} else {
|
||||
currentChildExpanded = false;
|
||||
currentChildEnum = null;
|
||||
if(debug) {System.out.println("prepNextChild: normal");}
|
||||
}
|
||||
}
|
||||
}
|
||||
70
jdkSrc/jdk8/com/sun/jndi/toolkit/dir/DirSearch.java
Normal file
70
jdkSrc/jdk8/com/sun/jndi/toolkit/dir/DirSearch.java
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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 General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.jndi.toolkit.dir;
|
||||
|
||||
import javax.naming.*;
|
||||
import javax.naming.directory.*;
|
||||
|
||||
/**
|
||||
* A class for searching DirContexts
|
||||
*
|
||||
* @author Jon Ruiz
|
||||
*/
|
||||
public class DirSearch {
|
||||
public static NamingEnumeration<SearchResult> search(DirContext ctx,
|
||||
Attributes matchingAttributes,
|
||||
String[] attributesToReturn) throws NamingException {
|
||||
SearchControls cons = new SearchControls(
|
||||
SearchControls.ONELEVEL_SCOPE,
|
||||
0, 0, attributesToReturn,
|
||||
false, false);
|
||||
|
||||
return new LazySearchEnumerationImpl(
|
||||
new ContextEnumerator(ctx, SearchControls.ONELEVEL_SCOPE),
|
||||
new ContainmentFilter(matchingAttributes),
|
||||
cons);
|
||||
}
|
||||
|
||||
public static NamingEnumeration<SearchResult> search(DirContext ctx,
|
||||
String filter, SearchControls cons) throws NamingException {
|
||||
|
||||
if (cons == null)
|
||||
cons = new SearchControls();
|
||||
|
||||
return new LazySearchEnumerationImpl(
|
||||
new ContextEnumerator(ctx, cons.getSearchScope()),
|
||||
new SearchFilter(filter),
|
||||
cons);
|
||||
}
|
||||
|
||||
public static NamingEnumeration<SearchResult> search(DirContext ctx,
|
||||
String filterExpr, Object[] filterArgs, SearchControls cons)
|
||||
throws NamingException {
|
||||
|
||||
String strfilter = SearchFilter.format(filterExpr, filterArgs);
|
||||
return search(ctx, strfilter, cons);
|
||||
}
|
||||
}
|
||||
962
jdkSrc/jdk8/com/sun/jndi/toolkit/dir/HierMemDirCtx.java
Normal file
962
jdkSrc/jdk8/com/sun/jndi/toolkit/dir/HierMemDirCtx.java
Normal file
@@ -0,0 +1,962 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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 General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package com.sun.jndi.toolkit.dir;
|
||||
|
||||
import javax.naming.*;
|
||||
import javax.naming.directory.*;
|
||||
import javax.naming.spi.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* A sample service provider that implements a hierarchical directory in memory.
|
||||
* Every operation begins by doing a lookup on the name passed to it and then
|
||||
* calls a corresponding "do<OperationName>" on the result of the lookup. The
|
||||
* "do<OperationName>" does the work without any further resolution (it assumes
|
||||
* that it is the target context).
|
||||
*/
|
||||
|
||||
public class HierMemDirCtx implements DirContext {
|
||||
|
||||
static private final boolean debug = false;
|
||||
private static final NameParser defaultParser = new HierarchicalNameParser();
|
||||
|
||||
protected Hashtable<String, Object> myEnv;
|
||||
protected Hashtable<Name, Object> bindings;
|
||||
protected Attributes attrs;
|
||||
protected boolean ignoreCase = false;
|
||||
protected NamingException readOnlyEx = null;
|
||||
protected NameParser myParser = defaultParser;
|
||||
|
||||
private boolean alwaysUseFactory;
|
||||
|
||||
public void close() throws NamingException {
|
||||
myEnv = null;
|
||||
bindings = null;
|
||||
attrs = null;
|
||||
}
|
||||
|
||||
public String getNameInNamespace() throws NamingException {
|
||||
throw new OperationNotSupportedException(
|
||||
"Cannot determine full name");
|
||||
}
|
||||
|
||||
public HierMemDirCtx() {
|
||||
this(null, false, false);
|
||||
}
|
||||
|
||||
public HierMemDirCtx(boolean ignoreCase) {
|
||||
this(null, ignoreCase, false);
|
||||
}
|
||||
|
||||
public HierMemDirCtx(Hashtable<String, Object> environment, boolean ignoreCase) {
|
||||
this(environment, ignoreCase, false);
|
||||
}
|
||||
|
||||
protected HierMemDirCtx(Hashtable<String, Object> environment,
|
||||
boolean ignoreCase, boolean useFac) {
|
||||
myEnv = environment;
|
||||
this.ignoreCase = ignoreCase;
|
||||
init();
|
||||
this.alwaysUseFactory = useFac;
|
||||
}
|
||||
|
||||
private void init() {
|
||||
attrs = new BasicAttributes(ignoreCase);
|
||||
bindings = new Hashtable<>(11, 0.75f);
|
||||
}
|
||||
|
||||
public Object lookup(String name) throws NamingException {
|
||||
return lookup(myParser.parse(name));
|
||||
}
|
||||
|
||||
public Object lookup(Name name) throws NamingException {
|
||||
return doLookup(name, alwaysUseFactory);
|
||||
}
|
||||
|
||||
public Object doLookup(Name name, boolean useFactory)
|
||||
throws NamingException {
|
||||
|
||||
Object target = null;
|
||||
name = canonizeName(name);
|
||||
|
||||
switch(name.size()) {
|
||||
case 0:
|
||||
// name is empty, caller wants this object
|
||||
target = this;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
// name is atomic, caller wants one of this object's bindings
|
||||
target = bindings.get(name);
|
||||
break;
|
||||
|
||||
default:
|
||||
// name is compound, delegate to child context
|
||||
HierMemDirCtx ctx = (HierMemDirCtx)bindings.get(name.getPrefix(1));
|
||||
if(ctx == null) {
|
||||
target = null;
|
||||
} else {
|
||||
target = ctx.doLookup(name.getSuffix(1), false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if(target == null) {
|
||||
throw new NameNotFoundException(name.toString());
|
||||
}
|
||||
|
||||
if (useFactory) {
|
||||
try {
|
||||
return DirectoryManager.getObjectInstance(target,
|
||||
name, this, myEnv,
|
||||
(target instanceof HierMemDirCtx) ?
|
||||
((HierMemDirCtx)target).attrs : null);
|
||||
} catch (NamingException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
NamingException e2 = new NamingException(
|
||||
"Problem calling getObjectInstance");
|
||||
e2.setRootCause(e);
|
||||
throw e2;
|
||||
}
|
||||
} else {
|
||||
return target;
|
||||
}
|
||||
}
|
||||
|
||||
public void bind(String name, Object obj) throws NamingException {
|
||||
bind(myParser.parse(name), obj);
|
||||
}
|
||||
|
||||
public void bind(Name name, Object obj) throws NamingException {
|
||||
doBind(name, obj, null, alwaysUseFactory);
|
||||
}
|
||||
|
||||
public void bind(String name, Object obj, Attributes attrs)
|
||||
throws NamingException {
|
||||
bind(myParser.parse(name), obj, attrs);
|
||||
}
|
||||
|
||||
public void bind(Name name, Object obj, Attributes attrs)
|
||||
throws NamingException {
|
||||
doBind(name, obj, attrs, alwaysUseFactory);
|
||||
}
|
||||
|
||||
protected void doBind(Name name, Object obj, Attributes attrs,
|
||||
boolean useFactory) throws NamingException {
|
||||
if (name.isEmpty()) {
|
||||
throw new InvalidNameException("Cannot bind empty name");
|
||||
}
|
||||
|
||||
if (useFactory) {
|
||||
DirStateFactory.Result res = DirectoryManager.getStateToBind(
|
||||
obj, name, this, myEnv, attrs);
|
||||
obj = res.getObject();
|
||||
attrs = res.getAttributes();
|
||||
}
|
||||
|
||||
HierMemDirCtx ctx= (HierMemDirCtx) doLookup(getInternalName(name), false);
|
||||
ctx.doBindAux(getLeafName(name), obj);
|
||||
|
||||
if (attrs != null && attrs.size() > 0) {
|
||||
modifyAttributes(name, ADD_ATTRIBUTE, attrs);
|
||||
}
|
||||
}
|
||||
|
||||
protected void doBindAux(Name name, Object obj) throws NamingException {
|
||||
if (readOnlyEx != null) {
|
||||
throw (NamingException) readOnlyEx.fillInStackTrace();
|
||||
}
|
||||
|
||||
if (bindings.get(name) != null) {
|
||||
throw new NameAlreadyBoundException(name.toString());
|
||||
}
|
||||
if(obj instanceof HierMemDirCtx) {
|
||||
bindings.put(name, obj);
|
||||
} else {
|
||||
throw new SchemaViolationException(
|
||||
"This context only supports binding objects of it's own kind");
|
||||
}
|
||||
}
|
||||
|
||||
public void rebind(String name, Object obj) throws NamingException {
|
||||
rebind(myParser.parse(name), obj);
|
||||
}
|
||||
|
||||
public void rebind(Name name, Object obj) throws NamingException {
|
||||
doRebind(name, obj, null, alwaysUseFactory);
|
||||
}
|
||||
|
||||
public void rebind(String name, Object obj, Attributes attrs)
|
||||
throws NamingException {
|
||||
rebind(myParser.parse(name), obj, attrs);
|
||||
}
|
||||
|
||||
public void rebind(Name name, Object obj, Attributes attrs)
|
||||
throws NamingException {
|
||||
doRebind(name, obj, attrs, alwaysUseFactory);
|
||||
}
|
||||
|
||||
protected void doRebind(Name name, Object obj, Attributes attrs,
|
||||
boolean useFactory) throws NamingException {
|
||||
if (name.isEmpty()) {
|
||||
throw new InvalidNameException("Cannot rebind empty name");
|
||||
}
|
||||
|
||||
if (useFactory) {
|
||||
DirStateFactory.Result res = DirectoryManager.getStateToBind(
|
||||
obj, name, this, myEnv, attrs);
|
||||
obj = res.getObject();
|
||||
attrs = res.getAttributes();
|
||||
}
|
||||
|
||||
HierMemDirCtx ctx= (HierMemDirCtx) doLookup(getInternalName(name), false);
|
||||
ctx.doRebindAux(getLeafName(name), obj);
|
||||
|
||||
//
|
||||
// attrs == null -> use attrs from obj
|
||||
// attrs != null -> use attrs
|
||||
//
|
||||
// %%% Strictly speaking, when attrs is non-null, we should
|
||||
// take the explicit step of removing obj's attrs.
|
||||
// We don't do that currently.
|
||||
|
||||
if (attrs != null && attrs.size() > 0) {
|
||||
modifyAttributes(name, ADD_ATTRIBUTE, attrs);
|
||||
}
|
||||
}
|
||||
|
||||
protected void doRebindAux(Name name, Object obj) throws NamingException {
|
||||
if (readOnlyEx != null) {
|
||||
throw (NamingException) readOnlyEx.fillInStackTrace();
|
||||
}
|
||||
if(obj instanceof HierMemDirCtx) {
|
||||
bindings.put(name, obj);
|
||||
|
||||
} else {
|
||||
throw new SchemaViolationException(
|
||||
"This context only supports binding objects of it's own kind");
|
||||
}
|
||||
}
|
||||
|
||||
public void unbind(String name) throws NamingException {
|
||||
unbind(myParser.parse(name));
|
||||
}
|
||||
|
||||
public void unbind(Name name) throws NamingException {
|
||||
if (name.isEmpty()) {
|
||||
throw new InvalidNameException("Cannot unbind empty name");
|
||||
} else {
|
||||
HierMemDirCtx ctx=
|
||||
(HierMemDirCtx) doLookup(getInternalName(name), false);
|
||||
ctx.doUnbind(getLeafName(name));
|
||||
}
|
||||
}
|
||||
|
||||
protected void doUnbind(Name name) throws NamingException {
|
||||
if (readOnlyEx != null) {
|
||||
throw (NamingException) readOnlyEx.fillInStackTrace();
|
||||
}
|
||||
|
||||
bindings.remove(name); // attrs will also be removed along with ctx
|
||||
}
|
||||
|
||||
public void rename(String oldname, String newname)
|
||||
throws NamingException {
|
||||
rename(myParser.parse(oldname), myParser.parse(newname));
|
||||
}
|
||||
|
||||
public void rename(Name oldname, Name newname)
|
||||
throws NamingException {
|
||||
|
||||
if(newname.isEmpty() || oldname.isEmpty()) {
|
||||
throw new InvalidNameException("Cannot rename empty name");
|
||||
}
|
||||
|
||||
if (!getInternalName(newname).equals(getInternalName(oldname))) {
|
||||
throw new InvalidNameException("Cannot rename across contexts");
|
||||
}
|
||||
|
||||
HierMemDirCtx ctx =
|
||||
(HierMemDirCtx) doLookup(getInternalName(newname), false);
|
||||
ctx.doRename(getLeafName(oldname), getLeafName(newname));
|
||||
}
|
||||
|
||||
protected void doRename(Name oldname, Name newname) throws NamingException {
|
||||
if (readOnlyEx != null) {
|
||||
throw (NamingException) readOnlyEx.fillInStackTrace();
|
||||
}
|
||||
|
||||
oldname = canonizeName(oldname);
|
||||
newname = canonizeName(newname);
|
||||
|
||||
// Check if new name exists
|
||||
if (bindings.get(newname) != null) {
|
||||
throw new NameAlreadyBoundException(newname.toString());
|
||||
}
|
||||
|
||||
// Check if old name is bound
|
||||
Object oldBinding = bindings.remove(oldname);
|
||||
if (oldBinding == null) {
|
||||
throw new NameNotFoundException(oldname.toString());
|
||||
}
|
||||
|
||||
bindings.put(newname, oldBinding);
|
||||
}
|
||||
|
||||
public NamingEnumeration<NameClassPair> list(String name) throws NamingException {
|
||||
return list(myParser.parse(name));
|
||||
}
|
||||
|
||||
public NamingEnumeration<NameClassPair> list(Name name) throws NamingException {
|
||||
HierMemDirCtx ctx = (HierMemDirCtx) doLookup(name, false);
|
||||
return ctx.doList();
|
||||
}
|
||||
|
||||
protected NamingEnumeration<NameClassPair> doList () throws NamingException {
|
||||
return new FlatNames(bindings.keys());
|
||||
}
|
||||
|
||||
|
||||
public NamingEnumeration<Binding> listBindings(String name) throws NamingException {
|
||||
return listBindings(myParser.parse(name));
|
||||
}
|
||||
|
||||
public NamingEnumeration<Binding> listBindings(Name name) throws NamingException {
|
||||
HierMemDirCtx ctx = (HierMemDirCtx)doLookup(name, false);
|
||||
return ctx.doListBindings(alwaysUseFactory);
|
||||
}
|
||||
|
||||
protected NamingEnumeration<Binding> doListBindings(boolean useFactory)
|
||||
throws NamingException {
|
||||
return new FlatBindings(bindings, myEnv, useFactory);
|
||||
}
|
||||
|
||||
public void destroySubcontext(String name) throws NamingException {
|
||||
destroySubcontext(myParser.parse(name));
|
||||
}
|
||||
|
||||
public void destroySubcontext(Name name) throws NamingException {
|
||||
HierMemDirCtx ctx =
|
||||
(HierMemDirCtx) doLookup(getInternalName(name), false);
|
||||
ctx.doDestroySubcontext(getLeafName(name));
|
||||
}
|
||||
|
||||
protected void doDestroySubcontext(Name name) throws NamingException {
|
||||
|
||||
if (readOnlyEx != null) {
|
||||
throw (NamingException) readOnlyEx.fillInStackTrace();
|
||||
}
|
||||
name = canonizeName(name);
|
||||
bindings.remove(name);
|
||||
}
|
||||
|
||||
public Context createSubcontext(String name) throws NamingException {
|
||||
return createSubcontext(myParser.parse(name));
|
||||
}
|
||||
|
||||
public Context createSubcontext(Name name) throws NamingException {
|
||||
return createSubcontext(name, null);
|
||||
}
|
||||
|
||||
public DirContext createSubcontext(String name, Attributes attrs)
|
||||
throws NamingException {
|
||||
return createSubcontext(myParser.parse(name), attrs);
|
||||
}
|
||||
|
||||
public DirContext createSubcontext(Name name, Attributes attrs)
|
||||
throws NamingException {
|
||||
HierMemDirCtx ctx =
|
||||
(HierMemDirCtx) doLookup(getInternalName(name), false);
|
||||
return ctx.doCreateSubcontext(getLeafName(name), attrs);
|
||||
}
|
||||
|
||||
protected DirContext doCreateSubcontext(Name name, Attributes attrs)
|
||||
throws NamingException {
|
||||
if (readOnlyEx != null) {
|
||||
throw (NamingException) readOnlyEx.fillInStackTrace();
|
||||
}
|
||||
|
||||
name = canonizeName(name);
|
||||
|
||||
if (bindings.get(name) != null) {
|
||||
throw new NameAlreadyBoundException(name.toString());
|
||||
}
|
||||
HierMemDirCtx newCtx = createNewCtx();
|
||||
bindings.put(name, newCtx);
|
||||
if(attrs != null) {
|
||||
newCtx.modifyAttributes("", ADD_ATTRIBUTE, attrs);
|
||||
}
|
||||
return newCtx;
|
||||
}
|
||||
|
||||
|
||||
public Object lookupLink(String name) throws NamingException {
|
||||
// This context does not treat links specially
|
||||
return lookupLink(myParser.parse(name));
|
||||
}
|
||||
|
||||
public Object lookupLink(Name name) throws NamingException {
|
||||
// Flat namespace; no federation; just call string version
|
||||
return lookup(name);
|
||||
}
|
||||
|
||||
public NameParser getNameParser(String name) throws NamingException {
|
||||
return myParser;
|
||||
}
|
||||
|
||||
public NameParser getNameParser(Name name) throws NamingException {
|
||||
return myParser;
|
||||
}
|
||||
|
||||
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 = canonizeName(name);
|
||||
prefix = canonizeName(prefix);
|
||||
Name result = (Name)(prefix.clone());
|
||||
result.addAll(name);
|
||||
return result;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked") // clone()
|
||||
public Object addToEnvironment(String propName, Object propVal)
|
||||
throws NamingException {
|
||||
myEnv = (myEnv == null)
|
||||
? new Hashtable<String, Object>(11, 0.75f)
|
||||
: (Hashtable<String, Object>)myEnv.clone();
|
||||
|
||||
return myEnv.put(propName, propVal);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked") // clone()
|
||||
public Object removeFromEnvironment(String propName)
|
||||
throws NamingException {
|
||||
if (myEnv == null)
|
||||
return null;
|
||||
|
||||
myEnv = (Hashtable<String, Object>)myEnv.clone();
|
||||
return myEnv.remove(propName);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked") // clone()
|
||||
public Hashtable<String, Object> getEnvironment() throws NamingException {
|
||||
if (myEnv == null) {
|
||||
return new Hashtable<>(5, 0.75f);
|
||||
} else {
|
||||
return (Hashtable<String, Object>)myEnv.clone();
|
||||
}
|
||||
}
|
||||
|
||||
public Attributes getAttributes(String name)
|
||||
throws NamingException {
|
||||
return getAttributes(myParser.parse(name));
|
||||
}
|
||||
|
||||
public Attributes getAttributes(Name name)
|
||||
throws NamingException {
|
||||
HierMemDirCtx ctx = (HierMemDirCtx) doLookup(name, false);
|
||||
return ctx.doGetAttributes();
|
||||
}
|
||||
|
||||
protected Attributes doGetAttributes() throws NamingException {
|
||||
return (Attributes)attrs.clone();
|
||||
}
|
||||
|
||||
public Attributes getAttributes(String name, String[] attrIds)
|
||||
throws NamingException {
|
||||
return getAttributes(myParser.parse(name), attrIds);
|
||||
}
|
||||
|
||||
public Attributes getAttributes(Name name, String[] attrIds)
|
||||
throws NamingException {
|
||||
HierMemDirCtx ctx = (HierMemDirCtx) doLookup(name, false);
|
||||
return ctx.doGetAttributes(attrIds);
|
||||
}
|
||||
|
||||
protected Attributes doGetAttributes(String[] attrIds)
|
||||
throws NamingException {
|
||||
|
||||
if (attrIds == null) {
|
||||
return doGetAttributes();
|
||||
}
|
||||
Attributes attrs = new BasicAttributes(ignoreCase);
|
||||
Attribute attr = null;
|
||||
for(int i=0; i<attrIds.length; i++) {
|
||||
attr = this.attrs.get(attrIds[i]);
|
||||
if (attr != null) {
|
||||
attrs.put(attr);
|
||||
}
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
public void modifyAttributes(String name, int mod_op, Attributes attrs)
|
||||
throws NamingException {
|
||||
modifyAttributes(myParser.parse(name), mod_op, attrs);
|
||||
}
|
||||
|
||||
public void modifyAttributes(Name name, int mod_op, Attributes attrs)
|
||||
throws NamingException {
|
||||
|
||||
if (attrs == null || attrs.size() == 0) {
|
||||
throw new IllegalArgumentException(
|
||||
"Cannot modify without an attribute");
|
||||
}
|
||||
|
||||
// turn it into a modification Enumeration and pass it on
|
||||
NamingEnumeration<? extends Attribute> attrEnum = attrs.getAll();
|
||||
ModificationItem[] mods = new ModificationItem[attrs.size()];
|
||||
for (int i = 0; i < mods.length && attrEnum.hasMoreElements(); i++) {
|
||||
mods[i] = new ModificationItem(mod_op, attrEnum.next());
|
||||
}
|
||||
|
||||
modifyAttributes(name, mods);
|
||||
}
|
||||
|
||||
public void modifyAttributes(String name, ModificationItem[] mods)
|
||||
throws NamingException {
|
||||
modifyAttributes(myParser.parse(name), mods);
|
||||
}
|
||||
|
||||
public void modifyAttributes(Name name, ModificationItem[] mods)
|
||||
throws NamingException {
|
||||
HierMemDirCtx ctx = (HierMemDirCtx) doLookup(name, false);
|
||||
ctx.doModifyAttributes(mods);
|
||||
}
|
||||
|
||||
protected void doModifyAttributes(ModificationItem[] mods)
|
||||
throws NamingException {
|
||||
|
||||
if (readOnlyEx != null) {
|
||||
throw (NamingException) readOnlyEx.fillInStackTrace();
|
||||
}
|
||||
|
||||
applyMods(mods, attrs);
|
||||
}
|
||||
|
||||
protected static Attributes applyMods(ModificationItem[] mods,
|
||||
Attributes orig) throws NamingException {
|
||||
|
||||
ModificationItem mod;
|
||||
Attribute existingAttr, modAttr;
|
||||
NamingEnumeration<?> modVals;
|
||||
|
||||
for (int i = 0; i < mods.length; i++) {
|
||||
mod = mods[i];
|
||||
modAttr = mod.getAttribute();
|
||||
|
||||
switch(mod.getModificationOp()) {
|
||||
case ADD_ATTRIBUTE:
|
||||
if (debug) {
|
||||
System.out.println("HierMemDSCtx: adding " +
|
||||
mod.getAttribute().toString());
|
||||
}
|
||||
existingAttr = orig.get(modAttr.getID());
|
||||
if (existingAttr == null) {
|
||||
orig.put((Attribute)modAttr.clone());
|
||||
} else {
|
||||
// Add new attribute values to existing attribute
|
||||
modVals = modAttr.getAll();
|
||||
while (modVals.hasMore()) {
|
||||
existingAttr.add(modVals.next());
|
||||
}
|
||||
}
|
||||
break;
|
||||
case REPLACE_ATTRIBUTE:
|
||||
if (modAttr.size() == 0) {
|
||||
orig.remove(modAttr.getID());
|
||||
} else {
|
||||
orig.put((Attribute)modAttr.clone());
|
||||
}
|
||||
break;
|
||||
case REMOVE_ATTRIBUTE:
|
||||
existingAttr = orig.get(modAttr.getID());
|
||||
if (existingAttr != null) {
|
||||
if (modAttr.size() == 0) {
|
||||
orig.remove(modAttr.getID());
|
||||
} else {
|
||||
// Remove attribute values from existing attribute
|
||||
modVals = modAttr.getAll();
|
||||
while (modVals.hasMore()) {
|
||||
existingAttr.remove(modVals.next());
|
||||
}
|
||||
if (existingAttr.size() == 0) {
|
||||
orig.remove(modAttr.getID());
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new AttributeModificationException("Unknown mod_op");
|
||||
}
|
||||
}
|
||||
|
||||
return orig;
|
||||
}
|
||||
|
||||
public NamingEnumeration<SearchResult> search(String name,
|
||||
Attributes matchingAttributes)
|
||||
throws NamingException {
|
||||
return search(name, matchingAttributes, null);
|
||||
}
|
||||
|
||||
public NamingEnumeration<SearchResult> search(Name name,
|
||||
Attributes matchingAttributes)
|
||||
throws NamingException {
|
||||
return search(name, matchingAttributes, null);
|
||||
}
|
||||
|
||||
public NamingEnumeration<SearchResult> search(String name,
|
||||
Attributes matchingAttributes,
|
||||
String[] attributesToReturn)
|
||||
throws NamingException {
|
||||
return search(myParser.parse(name), matchingAttributes,
|
||||
attributesToReturn);
|
||||
}
|
||||
|
||||
public NamingEnumeration<SearchResult> search(Name name,
|
||||
Attributes matchingAttributes,
|
||||
String[] attributesToReturn)
|
||||
throws NamingException {
|
||||
|
||||
HierMemDirCtx target = (HierMemDirCtx) doLookup(name, false);
|
||||
|
||||
SearchControls cons = new SearchControls();
|
||||
cons.setReturningAttributes(attributesToReturn);
|
||||
|
||||
return new LazySearchEnumerationImpl(
|
||||
target.doListBindings(false),
|
||||
new ContainmentFilter(matchingAttributes),
|
||||
cons, this, myEnv,
|
||||
false); // alwaysUseFactory ignored because objReturnFlag == false
|
||||
}
|
||||
|
||||
public NamingEnumeration<SearchResult> search(Name name,
|
||||
String filter,
|
||||
SearchControls cons)
|
||||
throws NamingException {
|
||||
DirContext target = (DirContext) doLookup(name, false);
|
||||
|
||||
SearchFilter stringfilter = new SearchFilter(filter);
|
||||
return new LazySearchEnumerationImpl(
|
||||
new HierContextEnumerator(target,
|
||||
(cons != null) ? cons.getSearchScope() :
|
||||
SearchControls.ONELEVEL_SCOPE),
|
||||
stringfilter,
|
||||
cons, this, myEnv, alwaysUseFactory);
|
||||
}
|
||||
|
||||
public NamingEnumeration<SearchResult> search(Name name,
|
||||
String filterExpr,
|
||||
Object[] filterArgs,
|
||||
SearchControls cons)
|
||||
throws NamingException {
|
||||
|
||||
String strfilter = SearchFilter.format(filterExpr, filterArgs);
|
||||
return search(name, strfilter, cons);
|
||||
}
|
||||
|
||||
public NamingEnumeration<SearchResult> search(String name,
|
||||
String filter,
|
||||
SearchControls cons)
|
||||
throws NamingException {
|
||||
return search(myParser.parse(name), filter, cons);
|
||||
}
|
||||
|
||||
public NamingEnumeration<SearchResult> search(String name,
|
||||
String filterExpr,
|
||||
Object[] filterArgs,
|
||||
SearchControls cons)
|
||||
throws NamingException {
|
||||
return search(myParser.parse(name), filterExpr, filterArgs, cons);
|
||||
}
|
||||
|
||||
// This function is called whenever a new object needs to be created.
|
||||
// this is used so that if anyone subclasses us, they can override this
|
||||
// and return object of their own kind.
|
||||
protected HierMemDirCtx createNewCtx() throws NamingException {
|
||||
return new HierMemDirCtx(myEnv, ignoreCase);
|
||||
}
|
||||
|
||||
// If the supplied name is a composite name, return the name that
|
||||
// is its first component.
|
||||
protected Name canonizeName(Name name) throws NamingException {
|
||||
Name canonicalName = name;
|
||||
|
||||
if(!(name instanceof HierarchicalName)) {
|
||||
// If name is not of the correct type, make copy
|
||||
canonicalName = new HierarchicalName();
|
||||
int n = name.size();
|
||||
for(int i = 0; i < n; i++) {
|
||||
canonicalName.add(i, name.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
return canonicalName;
|
||||
}
|
||||
|
||||
protected Name getInternalName(Name name) throws NamingException {
|
||||
return (name.getPrefix(name.size() - 1));
|
||||
}
|
||||
|
||||
protected Name getLeafName(Name name) throws NamingException {
|
||||
return (name.getSuffix(name.size() - 1));
|
||||
}
|
||||
|
||||
|
||||
public DirContext getSchema(String name) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public DirContext getSchema(Name name) throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public DirContext getSchemaClassDefinition(String name)
|
||||
throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
public DirContext getSchemaClassDefinition(Name name)
|
||||
throws NamingException {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
// Set context in readonly mode; throw e when update operation attempted.
|
||||
public void setReadOnly(NamingException e) {
|
||||
readOnlyEx = e;
|
||||
}
|
||||
|
||||
// Set context to support case-insensitive names
|
||||
public void setIgnoreCase(boolean ignoreCase) {
|
||||
this.ignoreCase = ignoreCase;
|
||||
}
|
||||
|
||||
public void setNameParser(NameParser parser) {
|
||||
myParser = parser;
|
||||
}
|
||||
|
||||
/*
|
||||
* Common base class for FlatNames and FlatBindings.
|
||||
*/
|
||||
private abstract class BaseFlatNames<T> implements NamingEnumeration<T> {
|
||||
Enumeration<Name> names;
|
||||
|
||||
BaseFlatNames (Enumeration<Name> names) {
|
||||
this.names = names;
|
||||
}
|
||||
|
||||
public final boolean hasMoreElements() {
|
||||
try {
|
||||
return hasMore();
|
||||
} catch (NamingException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public final boolean hasMore() throws NamingException {
|
||||
return names.hasMoreElements();
|
||||
}
|
||||
|
||||
public final T nextElement() {
|
||||
try {
|
||||
return next();
|
||||
} catch (NamingException e) {
|
||||
throw new NoSuchElementException(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public abstract T next() throws NamingException;
|
||||
|
||||
public final void close() {
|
||||
names = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Class for enumerating name/class pairs
|
||||
private final class FlatNames extends BaseFlatNames<NameClassPair> {
|
||||
FlatNames (Enumeration<Name> names) {
|
||||
super(names);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NameClassPair next() throws NamingException {
|
||||
Name name = names.nextElement();
|
||||
String className = bindings.get(name).getClass().getName();
|
||||
return new NameClassPair(name.toString(), className);
|
||||
}
|
||||
}
|
||||
|
||||
// Class for enumerating bindings
|
||||
private final class FlatBindings extends BaseFlatNames<Binding> {
|
||||
private Hashtable<Name, Object> bds;
|
||||
private Hashtable<String, Object> env;
|
||||
private boolean useFactory;
|
||||
|
||||
FlatBindings(Hashtable<Name, Object> bindings,
|
||||
Hashtable<String, Object> env,
|
||||
boolean useFactory) {
|
||||
super(bindings.keys());
|
||||
this.env = env;
|
||||
this.bds = bindings;
|
||||
this.useFactory = useFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Binding next() throws NamingException {
|
||||
Name name = names.nextElement();
|
||||
|
||||
HierMemDirCtx obj = (HierMemDirCtx)bds.get(name);
|
||||
|
||||
Object answer = obj;
|
||||
if (useFactory) {
|
||||
Attributes attrs = obj.getAttributes(""); // only method available
|
||||
try {
|
||||
answer = DirectoryManager.getObjectInstance(obj,
|
||||
name, HierMemDirCtx.this, env, attrs);
|
||||
} catch (NamingException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
NamingException e2 = new NamingException(
|
||||
"Problem calling getObjectInstance");
|
||||
e2.setRootCause(e);
|
||||
throw e2;
|
||||
}
|
||||
}
|
||||
|
||||
return new Binding(name.toString(), answer);
|
||||
}
|
||||
}
|
||||
|
||||
public class HierContextEnumerator extends ContextEnumerator {
|
||||
public HierContextEnumerator(Context context, int scope)
|
||||
throws NamingException {
|
||||
super(context, scope);
|
||||
}
|
||||
|
||||
protected HierContextEnumerator(Context context, int scope,
|
||||
String contextName, boolean returnSelf) throws NamingException {
|
||||
super(context, scope, contextName, returnSelf);
|
||||
}
|
||||
|
||||
protected NamingEnumeration<Binding> getImmediateChildren(Context ctx)
|
||||
throws NamingException {
|
||||
return ((HierMemDirCtx)ctx).doListBindings(false);
|
||||
}
|
||||
|
||||
protected ContextEnumerator newEnumerator(Context ctx, int scope,
|
||||
String contextName, boolean returnSelf) throws NamingException {
|
||||
return new HierContextEnumerator(ctx, scope, contextName,
|
||||
returnSelf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// CompundNames's HashCode() method isn't good enough for many string.
|
||||
// The only prupose of this subclass is to have a more discerning
|
||||
// hash function. We'll make up for the performance hit by caching
|
||||
// the hash value.
|
||||
|
||||
final class HierarchicalName extends CompoundName {
|
||||
private int hashValue = -1;
|
||||
|
||||
// Creates an empty name
|
||||
HierarchicalName() {
|
||||
super(new Enumeration<String>() {
|
||||
public boolean hasMoreElements() {return false;}
|
||||
public String nextElement() {throw new NoSuchElementException();}
|
||||
},
|
||||
HierarchicalNameParser.mySyntax);
|
||||
}
|
||||
|
||||
HierarchicalName(Enumeration<String> comps, Properties syntax) {
|
||||
super(comps, syntax);
|
||||
}
|
||||
|
||||
HierarchicalName(String n, Properties syntax) throws InvalidNameException {
|
||||
super(n, syntax);
|
||||
}
|
||||
|
||||
// just like String.hashCode, only it pays no attention to length
|
||||
public int hashCode() {
|
||||
if (hashValue == -1) {
|
||||
|
||||
String name = toString().toUpperCase(Locale.ENGLISH);
|
||||
int len = name.length();
|
||||
int off = 0;
|
||||
char val[] = new char[len];
|
||||
|
||||
name.getChars(0, len, val, 0);
|
||||
|
||||
for (int i = len; i > 0; i--) {
|
||||
hashValue = (hashValue * 37) + val[off++];
|
||||
}
|
||||
}
|
||||
|
||||
return hashValue;
|
||||
}
|
||||
|
||||
public Name getPrefix(int posn) {
|
||||
Enumeration<String> comps = super.getPrefix(posn).getAll();
|
||||
return (new HierarchicalName(comps, mySyntax));
|
||||
}
|
||||
|
||||
public Name getSuffix(int posn) {
|
||||
Enumeration<String> comps = super.getSuffix(posn).getAll();
|
||||
return (new HierarchicalName(comps, mySyntax));
|
||||
}
|
||||
|
||||
public Object clone() {
|
||||
return (new HierarchicalName(getAll(), mySyntax));
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = -6717336834584573168L;
|
||||
}
|
||||
|
||||
// This is the default name parser (used if setNameParser is not called)
|
||||
final class HierarchicalNameParser implements NameParser {
|
||||
static final Properties mySyntax = new Properties();
|
||||
static {
|
||||
mySyntax.put("jndi.syntax.direction", "left_to_right");
|
||||
mySyntax.put("jndi.syntax.separator", "/");
|
||||
mySyntax.put("jndi.syntax.ignorecase", "true");
|
||||
mySyntax.put("jndi.syntax.escape", "\\");
|
||||
mySyntax.put("jndi.syntax.beginquote", "\"");
|
||||
//mySyntax.put("jndi.syntax.separator.ava", "+");
|
||||
//mySyntax.put("jndi.syntax.separator.typeval", "=");
|
||||
mySyntax.put("jndi.syntax.trimblanks", "false");
|
||||
};
|
||||
|
||||
public Name parse(String name) throws NamingException {
|
||||
return new HierarchicalName(name, mySyntax);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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 General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Given an enumeration of candidates, check whether each
|
||||
* item in enumeration satifies the given filter.
|
||||
* Each item is a Binding and the following is used to get its
|
||||
* attributes for used by the filter:
|
||||
*
|
||||
* ((DirContext)item.getObject()).getAttributes("").
|
||||
* If item.getObject() is not an DirContext, the item is skipped
|
||||
*
|
||||
* The items in the enumeration are obtained one at a time as
|
||||
* items from the search enumeration are requested.
|
||||
*
|
||||
* @author Rosanna Lee
|
||||
*/
|
||||
|
||||
package com.sun.jndi.toolkit.dir;
|
||||
|
||||
import javax.naming.*;
|
||||
import javax.naming.directory.*;
|
||||
import javax.naming.spi.DirectoryManager;
|
||||
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Hashtable;
|
||||
|
||||
final public class LazySearchEnumerationImpl
|
||||
implements NamingEnumeration<SearchResult> {
|
||||
private NamingEnumeration<Binding> candidates;
|
||||
private SearchResult nextMatch = null;
|
||||
private SearchControls cons;
|
||||
private AttrFilter filter;
|
||||
private Context context;
|
||||
private Hashtable<String, Object> env;
|
||||
private boolean useFactory = true;
|
||||
|
||||
public LazySearchEnumerationImpl(NamingEnumeration<Binding> candidates,
|
||||
AttrFilter filter, SearchControls cons) throws NamingException {
|
||||
this.candidates = candidates;
|
||||
this.filter = filter;
|
||||
|
||||
if(cons == null) {
|
||||
this.cons = new SearchControls();
|
||||
} else {
|
||||
this.cons = cons;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked") // For Hashtable clone: env.clone()
|
||||
public LazySearchEnumerationImpl(NamingEnumeration<Binding> candidates,
|
||||
AttrFilter filter, SearchControls cons,
|
||||
Context ctx, Hashtable<String, Object> env, boolean useFactory)
|
||||
throws NamingException {
|
||||
|
||||
this.candidates = candidates;
|
||||
this.filter = filter;
|
||||
this.env = (Hashtable<String, Object>)
|
||||
((env == null) ? null : env.clone());
|
||||
this.context = ctx;
|
||||
this.useFactory = useFactory;
|
||||
|
||||
if(cons == null) {
|
||||
this.cons = new SearchControls();
|
||||
} else {
|
||||
this.cons = cons;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public LazySearchEnumerationImpl(NamingEnumeration<Binding> candidates,
|
||||
AttrFilter filter, SearchControls cons,
|
||||
Context ctx, Hashtable<String, Object> env) throws NamingException {
|
||||
this(candidates, filter, cons, ctx, env, true);
|
||||
}
|
||||
|
||||
public boolean hasMore() throws NamingException {
|
||||
// find and do not remove from list
|
||||
return findNextMatch(false) != null;
|
||||
}
|
||||
|
||||
public boolean hasMoreElements() {
|
||||
try {
|
||||
return hasMore();
|
||||
} catch (NamingException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public SearchResult nextElement() {
|
||||
try {
|
||||
return findNextMatch(true);
|
||||
} catch (NamingException e) {
|
||||
throw new NoSuchElementException(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public SearchResult next() throws NamingException {
|
||||
// find and remove from list
|
||||
return (findNextMatch(true));
|
||||
}
|
||||
|
||||
public void close() throws NamingException {
|
||||
if (candidates != null) {
|
||||
candidates.close();
|
||||
}
|
||||
}
|
||||
|
||||
private SearchResult findNextMatch(boolean remove) throws NamingException {
|
||||
SearchResult answer;
|
||||
if (nextMatch != null) {
|
||||
answer = nextMatch;
|
||||
if (remove) {
|
||||
nextMatch = null;
|
||||
}
|
||||
return answer;
|
||||
} else {
|
||||
// need to find next match
|
||||
Binding next;
|
||||
Object obj;
|
||||
Attributes targetAttrs;
|
||||
while (candidates.hasMore()) {
|
||||
next = candidates.next();
|
||||
obj = next.getObject();
|
||||
if (obj instanceof DirContext) {
|
||||
targetAttrs = ((DirContext)(obj)).getAttributes("");
|
||||
if (filter.check(targetAttrs)) {
|
||||
if (!cons.getReturningObjFlag()) {
|
||||
obj = null;
|
||||
} else if (useFactory) {
|
||||
try {
|
||||
// Give name only if context non-null,
|
||||
// otherewise, name will be interpreted relative
|
||||
// to initial context (not what we want)
|
||||
Name nm = (context != null ?
|
||||
new CompositeName(next.getName()) : null);
|
||||
obj = DirectoryManager.getObjectInstance(obj,
|
||||
nm, context, env, targetAttrs);
|
||||
} catch (NamingException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
NamingException e2 = new NamingException(
|
||||
"problem generating object using object factory");
|
||||
e2.setRootCause(e);
|
||||
throw e2;
|
||||
}
|
||||
}
|
||||
answer = new SearchResult(next.getName(),
|
||||
next.getClassName(), obj,
|
||||
SearchFilter.selectAttributes(targetAttrs,
|
||||
cons.getReturningAttributes()),
|
||||
true);
|
||||
if (!remove)
|
||||
nextMatch = answer;
|
||||
return answer;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
677
jdkSrc/jdk8/com/sun/jndi/toolkit/dir/SearchFilter.java
Normal file
677
jdkSrc/jdk8/com/sun/jndi/toolkit/dir/SearchFilter.java
Normal file
@@ -0,0 +1,677 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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 General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package com.sun.jndi.toolkit.dir;
|
||||
|
||||
import javax.naming.*;
|
||||
import javax.naming.directory.*;
|
||||
import java.util.Enumeration;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.Vector;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* A class for parsing LDAP search filters (defined in RFC 1960, 2254)
|
||||
*
|
||||
* @author Jon Ruiz
|
||||
* @author Rosanna Lee
|
||||
*/
|
||||
public class SearchFilter implements AttrFilter {
|
||||
|
||||
interface StringFilter extends AttrFilter {
|
||||
public void parse() throws InvalidSearchFilterException;
|
||||
}
|
||||
|
||||
// %%% "filter" and "pos" are not declared "private" due to bug 4064984.
|
||||
String filter;
|
||||
int pos;
|
||||
private StringFilter rootFilter;
|
||||
|
||||
protected static final boolean debug = false;
|
||||
|
||||
protected static final char BEGIN_FILTER_TOKEN = '(';
|
||||
protected static final char END_FILTER_TOKEN = ')';
|
||||
protected static final char AND_TOKEN = '&';
|
||||
protected static final char OR_TOKEN = '|';
|
||||
protected static final char NOT_TOKEN = '!';
|
||||
protected static final char EQUAL_TOKEN = '=';
|
||||
protected static final char APPROX_TOKEN = '~';
|
||||
protected static final char LESS_TOKEN = '<';
|
||||
protected static final char GREATER_TOKEN = '>';
|
||||
protected static final char EXTEND_TOKEN = ':';
|
||||
protected static final char WILDCARD_TOKEN = '*';
|
||||
|
||||
public SearchFilter(String filter) throws InvalidSearchFilterException {
|
||||
this.filter = filter;
|
||||
pos = 0;
|
||||
normalizeFilter();
|
||||
rootFilter = this.createNextFilter();
|
||||
}
|
||||
|
||||
// Returns true if targetAttrs passes the filter
|
||||
public boolean check(Attributes targetAttrs) throws NamingException {
|
||||
if (targetAttrs == null)
|
||||
return false;
|
||||
|
||||
return rootFilter.check(targetAttrs);
|
||||
}
|
||||
|
||||
/*
|
||||
* Utility routines used by member classes
|
||||
*/
|
||||
|
||||
// does some pre-processing on the string to make it look exactly lik
|
||||
// what the parser expects. This only needs to be called once.
|
||||
protected void normalizeFilter() {
|
||||
skipWhiteSpace(); // get rid of any leading whitespaces
|
||||
|
||||
// Sometimes, search filters don't have "(" and ")" - add them
|
||||
if(getCurrentChar() != BEGIN_FILTER_TOKEN) {
|
||||
filter = BEGIN_FILTER_TOKEN + filter + END_FILTER_TOKEN;
|
||||
}
|
||||
// this would be a good place to strip whitespace if desired
|
||||
|
||||
if(debug) {System.out.println("SearchFilter: normalized filter:" +
|
||||
filter);}
|
||||
}
|
||||
|
||||
private void skipWhiteSpace() {
|
||||
while (Character.isWhitespace(getCurrentChar())) {
|
||||
consumeChar();
|
||||
}
|
||||
}
|
||||
|
||||
protected StringFilter createNextFilter()
|
||||
throws InvalidSearchFilterException {
|
||||
StringFilter filter;
|
||||
|
||||
skipWhiteSpace();
|
||||
|
||||
try {
|
||||
// make sure every filter starts with "("
|
||||
if(getCurrentChar() != BEGIN_FILTER_TOKEN) {
|
||||
throw new InvalidSearchFilterException("expected \"" +
|
||||
BEGIN_FILTER_TOKEN +
|
||||
"\" at position " +
|
||||
pos);
|
||||
}
|
||||
|
||||
// skip past the "("
|
||||
this.consumeChar();
|
||||
|
||||
skipWhiteSpace();
|
||||
|
||||
// use the next character to determine the type of filter
|
||||
switch(getCurrentChar()) {
|
||||
case AND_TOKEN:
|
||||
if (debug) {System.out.println("SearchFilter: creating AND");}
|
||||
filter = new CompoundFilter(true);
|
||||
filter.parse();
|
||||
break;
|
||||
case OR_TOKEN:
|
||||
if (debug) {System.out.println("SearchFilter: creating OR");}
|
||||
filter = new CompoundFilter(false);
|
||||
filter.parse();
|
||||
break;
|
||||
case NOT_TOKEN:
|
||||
if (debug) {System.out.println("SearchFilter: creating OR");}
|
||||
filter = new NotFilter();
|
||||
filter.parse();
|
||||
break;
|
||||
default:
|
||||
if (debug) {System.out.println("SearchFilter: creating SIMPLE");}
|
||||
filter = new AtomicFilter();
|
||||
filter.parse();
|
||||
break;
|
||||
}
|
||||
|
||||
skipWhiteSpace();
|
||||
|
||||
// make sure every filter ends with ")"
|
||||
if(getCurrentChar() != END_FILTER_TOKEN) {
|
||||
throw new InvalidSearchFilterException("expected \"" +
|
||||
END_FILTER_TOKEN +
|
||||
"\" at position " +
|
||||
pos);
|
||||
}
|
||||
|
||||
// skip past the ")"
|
||||
this.consumeChar();
|
||||
} catch (InvalidSearchFilterException e) {
|
||||
if (debug) {System.out.println("rethrowing e");}
|
||||
throw e; // just rethrow these
|
||||
|
||||
// catch all - any uncaught exception while parsing will end up here
|
||||
} catch (Exception e) {
|
||||
if(debug) {System.out.println(e.getMessage());e.printStackTrace();}
|
||||
throw new InvalidSearchFilterException("Unable to parse " +
|
||||
"character " + pos + " in \""+
|
||||
this.filter + "\"");
|
||||
}
|
||||
|
||||
return filter;
|
||||
}
|
||||
|
||||
protected char getCurrentChar() {
|
||||
return filter.charAt(pos);
|
||||
}
|
||||
|
||||
protected char relCharAt(int i) {
|
||||
return filter.charAt(pos + i);
|
||||
}
|
||||
|
||||
protected void consumeChar() {
|
||||
pos++;
|
||||
}
|
||||
|
||||
protected void consumeChars(int i) {
|
||||
pos += i;
|
||||
}
|
||||
|
||||
protected int relIndexOf(int ch) {
|
||||
return filter.indexOf(ch, pos) - pos;
|
||||
}
|
||||
|
||||
protected String relSubstring(int beginIndex, int endIndex){
|
||||
if(debug){System.out.println("relSubString: " + beginIndex +
|
||||
" " + endIndex);}
|
||||
return filter.substring(beginIndex+pos, endIndex+pos);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A class for dealing with compound filters ("and" & "or" filters).
|
||||
*/
|
||||
final class CompoundFilter implements StringFilter {
|
||||
private Vector<StringFilter> subFilters;
|
||||
private boolean polarity;
|
||||
|
||||
CompoundFilter(boolean polarity) {
|
||||
subFilters = new Vector<>();
|
||||
this.polarity = polarity;
|
||||
}
|
||||
|
||||
public void parse() throws InvalidSearchFilterException {
|
||||
SearchFilter.this.consumeChar(); // consume the "&"
|
||||
while(SearchFilter.this.getCurrentChar() != END_FILTER_TOKEN) {
|
||||
if (debug) {System.out.println("CompoundFilter: adding");}
|
||||
StringFilter filter = SearchFilter.this.createNextFilter();
|
||||
subFilters.addElement(filter);
|
||||
skipWhiteSpace();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean check(Attributes targetAttrs) throws NamingException {
|
||||
for(int i = 0; i<subFilters.size(); i++) {
|
||||
StringFilter filter = subFilters.elementAt(i);
|
||||
if(filter.check(targetAttrs) != this.polarity) {
|
||||
return !polarity;
|
||||
}
|
||||
}
|
||||
return polarity;
|
||||
}
|
||||
} /* CompoundFilter */
|
||||
|
||||
/**
|
||||
* A class for dealing with NOT filters
|
||||
*/
|
||||
final class NotFilter implements StringFilter {
|
||||
private StringFilter filter;
|
||||
|
||||
public void parse() throws InvalidSearchFilterException {
|
||||
SearchFilter.this.consumeChar(); // consume the "!"
|
||||
filter = SearchFilter.this.createNextFilter();
|
||||
}
|
||||
|
||||
public boolean check(Attributes targetAttrs) throws NamingException {
|
||||
return !filter.check(targetAttrs);
|
||||
}
|
||||
} /* notFilter */
|
||||
|
||||
// note: declared here since member classes can't have static variables
|
||||
static final int EQUAL_MATCH = 1;
|
||||
static final int APPROX_MATCH = 2;
|
||||
static final int GREATER_MATCH = 3;
|
||||
static final int LESS_MATCH = 4;
|
||||
|
||||
/**
|
||||
* A class for dealing wtih atomic filters
|
||||
*/
|
||||
final class AtomicFilter implements StringFilter {
|
||||
private String attrID;
|
||||
private String value;
|
||||
private int matchType;
|
||||
|
||||
public void parse() throws InvalidSearchFilterException {
|
||||
|
||||
skipWhiteSpace();
|
||||
|
||||
try {
|
||||
// find the end
|
||||
int endPos = SearchFilter.this.relIndexOf(END_FILTER_TOKEN);
|
||||
|
||||
//determine the match type
|
||||
int i = SearchFilter.this.relIndexOf(EQUAL_TOKEN);
|
||||
if(debug) {System.out.println("AtomicFilter: = at " + i);}
|
||||
int qualifier = SearchFilter.this.relCharAt(i-1);
|
||||
switch(qualifier) {
|
||||
case APPROX_TOKEN:
|
||||
if (debug) {System.out.println("Atomic: APPROX found");}
|
||||
matchType = APPROX_MATCH;
|
||||
attrID = SearchFilter.this.relSubstring(0, i-1);
|
||||
value = SearchFilter.this.relSubstring(i+1, endPos);
|
||||
break;
|
||||
|
||||
case GREATER_TOKEN:
|
||||
if (debug) {System.out.println("Atomic: GREATER found");}
|
||||
matchType = GREATER_MATCH;
|
||||
attrID = SearchFilter.this.relSubstring(0, i-1);
|
||||
value = SearchFilter.this.relSubstring(i+1, endPos);
|
||||
break;
|
||||
|
||||
case LESS_TOKEN:
|
||||
if (debug) {System.out.println("Atomic: LESS found");}
|
||||
matchType = LESS_MATCH;
|
||||
attrID = SearchFilter.this.relSubstring(0, i-1);
|
||||
value = SearchFilter.this.relSubstring(i+1, endPos);
|
||||
break;
|
||||
|
||||
case EXTEND_TOKEN:
|
||||
if(debug) {System.out.println("Atomic: EXTEND found");}
|
||||
throw new OperationNotSupportedException("Extensible match not supported");
|
||||
|
||||
default:
|
||||
if (debug) {System.out.println("Atomic: EQUAL found");}
|
||||
matchType = EQUAL_MATCH;
|
||||
attrID = SearchFilter.this.relSubstring(0,i);
|
||||
value = SearchFilter.this.relSubstring(i+1, endPos);
|
||||
break;
|
||||
}
|
||||
|
||||
attrID = attrID.trim();
|
||||
value = value.trim();
|
||||
|
||||
//update our position
|
||||
SearchFilter.this.consumeChars(endPos);
|
||||
|
||||
} catch (Exception e) {
|
||||
if (debug) {System.out.println(e.getMessage());
|
||||
e.printStackTrace();}
|
||||
InvalidSearchFilterException sfe =
|
||||
new InvalidSearchFilterException("Unable to parse " +
|
||||
"character " + SearchFilter.this.pos + " in \""+
|
||||
SearchFilter.this.filter + "\"");
|
||||
sfe.setRootCause(e);
|
||||
throw(sfe);
|
||||
}
|
||||
|
||||
if(debug) {System.out.println("AtomicFilter: " + attrID + "=" +
|
||||
value);}
|
||||
}
|
||||
|
||||
public boolean check(Attributes targetAttrs) {
|
||||
Enumeration<?> candidates;
|
||||
|
||||
try {
|
||||
Attribute attr = targetAttrs.get(attrID);
|
||||
if(attr == null) {
|
||||
return false;
|
||||
}
|
||||
candidates = attr.getAll();
|
||||
} catch (NamingException ne) {
|
||||
if (debug) {System.out.println("AtomicFilter: should never " +
|
||||
"here");}
|
||||
return false;
|
||||
}
|
||||
|
||||
while(candidates.hasMoreElements()) {
|
||||
String val = candidates.nextElement().toString();
|
||||
if (debug) {System.out.println("Atomic: comparing: " + val);}
|
||||
switch(matchType) {
|
||||
case APPROX_MATCH:
|
||||
case EQUAL_MATCH:
|
||||
if(substringMatch(this.value, val)) {
|
||||
if (debug) {System.out.println("Atomic: EQUAL match");}
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case GREATER_MATCH:
|
||||
if (debug) {System.out.println("Atomic: GREATER match");}
|
||||
if(val.compareTo(this.value) >= 0) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case LESS_MATCH:
|
||||
if (debug) {System.out.println("Atomic: LESS match");}
|
||||
if(val.compareTo(this.value) <= 0) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (debug) {System.out.println("AtomicFilter: unkown " +
|
||||
"matchType");}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// used for substring comparisons (where proto has "*" wildcards
|
||||
private boolean substringMatch(String proto, String value) {
|
||||
// simple case 1: "*" means attribute presence is being tested
|
||||
if(proto.equals(new Character(WILDCARD_TOKEN).toString())) {
|
||||
if(debug) {System.out.println("simple presence assertion");}
|
||||
return true;
|
||||
}
|
||||
|
||||
// simple case 2: if there are no wildcards, call String.equals()
|
||||
if(proto.indexOf(WILDCARD_TOKEN) == -1) {
|
||||
return proto.equalsIgnoreCase(value);
|
||||
}
|
||||
|
||||
if(debug) {System.out.println("doing substring comparison");}
|
||||
// do the work: make sure all the substrings are present
|
||||
int currentPos = 0;
|
||||
StringTokenizer subStrs = new StringTokenizer(proto, "*", false);
|
||||
|
||||
// do we need to begin with the first token?
|
||||
if(proto.charAt(0) != WILDCARD_TOKEN &&
|
||||
!value.toLowerCase(Locale.ENGLISH).startsWith(
|
||||
subStrs.nextToken().toLowerCase(Locale.ENGLISH))) {
|
||||
if(debug) {
|
||||
System.out.println("faild initial test");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
while(subStrs.hasMoreTokens()) {
|
||||
String currentStr = subStrs.nextToken();
|
||||
if (debug) {System.out.println("looking for \"" +
|
||||
currentStr +"\"");}
|
||||
currentPos = value.toLowerCase(Locale.ENGLISH).indexOf(
|
||||
currentStr.toLowerCase(Locale.ENGLISH), currentPos);
|
||||
|
||||
if(currentPos == -1) {
|
||||
return false;
|
||||
}
|
||||
currentPos += currentStr.length();
|
||||
}
|
||||
|
||||
// do we need to end with the last token?
|
||||
if(proto.charAt(proto.length() - 1) != WILDCARD_TOKEN &&
|
||||
currentPos != value.length() ) {
|
||||
if(debug) {System.out.println("faild final test");}
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} /* AtomicFilter */
|
||||
|
||||
// ----- static methods for producing string filters given attribute set
|
||||
// ----- or object array
|
||||
|
||||
|
||||
/**
|
||||
* Creates an LDAP filter as a conjuction of the attributes supplied.
|
||||
*/
|
||||
public static String format(Attributes attrs) throws NamingException {
|
||||
if (attrs == null || attrs.size() == 0) {
|
||||
return "objectClass=*";
|
||||
}
|
||||
|
||||
String answer;
|
||||
answer = "(& ";
|
||||
Attribute attr;
|
||||
for (NamingEnumeration<? extends Attribute> e = attrs.getAll();
|
||||
e.hasMore(); ) {
|
||||
attr = e.next();
|
||||
if (attr.size() == 0 || (attr.size() == 1 && attr.get() == null)) {
|
||||
// only checking presence of attribute
|
||||
answer += "(" + attr.getID() + "=" + "*)";
|
||||
} else {
|
||||
for (NamingEnumeration<?> ve = attr.getAll();
|
||||
ve.hasMore(); ) {
|
||||
String val = getEncodedStringRep(ve.next());
|
||||
if (val != null) {
|
||||
answer += "(" + attr.getID() + "=" + val + ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
answer += ")";
|
||||
//System.out.println("filter: " + answer);
|
||||
return answer;
|
||||
}
|
||||
|
||||
// Writes the hex representation of a byte to a StringBuffer.
|
||||
private static void hexDigit(StringBuffer buf, byte x) {
|
||||
char c;
|
||||
|
||||
c = (char) ((x >> 4) & 0xf);
|
||||
if (c > 9)
|
||||
c = (char) ((c-10) + 'A');
|
||||
else
|
||||
c = (char)(c + '0');
|
||||
|
||||
buf.append(c);
|
||||
c = (char) (x & 0xf);
|
||||
if (c > 9)
|
||||
c = (char)((c-10) + 'A');
|
||||
else
|
||||
c = (char)(c + '0');
|
||||
buf.append(c);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the string representation of an object (such as an attr value).
|
||||
* If obj is a byte array, encode each item as \xx, where xx is hex encoding
|
||||
* of the byte value.
|
||||
* Else, if obj is not a String, use its string representation (toString()).
|
||||
* Special characters in obj (or its string representation) are then
|
||||
* encoded appropriately according to RFC 2254.
|
||||
* * \2a
|
||||
* ( \28
|
||||
* ) \29
|
||||
* \ \5c
|
||||
* NUL \00
|
||||
*/
|
||||
private static String getEncodedStringRep(Object obj) throws NamingException {
|
||||
String str;
|
||||
if (obj == null)
|
||||
return null;
|
||||
|
||||
if (obj instanceof byte[]) {
|
||||
// binary data must be encoded as \hh where hh is a hex char
|
||||
byte[] bytes = (byte[])obj;
|
||||
StringBuffer b1 = new StringBuffer(bytes.length*3);
|
||||
for (int i = 0; i < bytes.length; i++) {
|
||||
b1.append('\\');
|
||||
hexDigit(b1, bytes[i]);
|
||||
}
|
||||
return b1.toString();
|
||||
}
|
||||
if (!(obj instanceof String)) {
|
||||
str = obj.toString();
|
||||
} else {
|
||||
str = (String)obj;
|
||||
}
|
||||
int len = str.length();
|
||||
StringBuffer buf = new StringBuffer(len);
|
||||
char ch;
|
||||
for (int i = 0; i < len; i++) {
|
||||
switch (ch=str.charAt(i)) {
|
||||
case '*':
|
||||
buf.append("\\2a");
|
||||
break;
|
||||
case '(':
|
||||
buf.append("\\28");
|
||||
break;
|
||||
case ')':
|
||||
buf.append("\\29");
|
||||
break;
|
||||
case '\\':
|
||||
buf.append("\\5c");
|
||||
break;
|
||||
case 0:
|
||||
buf.append("\\00");
|
||||
break;
|
||||
default:
|
||||
buf.append(ch);
|
||||
}
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Finds the first occurrence of <tt>ch</tt> in <tt>val</tt> starting
|
||||
* from position <tt>start</tt>. It doesn't count if <tt>ch</tt>
|
||||
* has been escaped by a backslash (\)
|
||||
*/
|
||||
public static int findUnescaped(char ch, String val, int start) {
|
||||
int len = val.length();
|
||||
|
||||
while (start < len) {
|
||||
int where = val.indexOf(ch, start);
|
||||
// if at start of string, or not there at all, or if not escaped
|
||||
if (where == start || where == -1 || val.charAt(where-1) != '\\')
|
||||
return where;
|
||||
|
||||
// start search after escaped star
|
||||
start = where + 1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the expression <tt>expr</tt> using arguments from the array
|
||||
* <tt>args</tt>.
|
||||
*
|
||||
* <code>{i}</code> specifies the <code>i</code>'th element from
|
||||
* the array <code>args</code> is to be substituted for the
|
||||
* string "<code>{i}</code>".
|
||||
*
|
||||
* To escape '{' or '}' (or any other character), use '\'.
|
||||
*
|
||||
* Uses getEncodedStringRep() to do encoding.
|
||||
*/
|
||||
|
||||
public static String format(String expr, Object[] args)
|
||||
throws NamingException {
|
||||
|
||||
int param;
|
||||
int where = 0, start = 0;
|
||||
StringBuffer answer = new StringBuffer(expr.length());
|
||||
|
||||
while ((where = findUnescaped('{', expr, start)) >= 0) {
|
||||
int pstart = where + 1; // skip '{'
|
||||
int pend = expr.indexOf('}', pstart);
|
||||
|
||||
if (pend < 0) {
|
||||
throw new InvalidSearchFilterException("unbalanced {: " + expr);
|
||||
}
|
||||
|
||||
// at this point, pend should be pointing at '}'
|
||||
try {
|
||||
param = Integer.parseInt(expr.substring(pstart, pend));
|
||||
} catch (NumberFormatException e) {
|
||||
throw new InvalidSearchFilterException(
|
||||
"integer expected inside {}: " + expr);
|
||||
}
|
||||
|
||||
if (param >= args.length) {
|
||||
throw new InvalidSearchFilterException(
|
||||
"number exceeds argument list: " + param);
|
||||
}
|
||||
|
||||
answer.append(expr.substring(start, where)).append(getEncodedStringRep(args[param]));
|
||||
start = pend + 1; // skip '}'
|
||||
}
|
||||
|
||||
if (start < expr.length())
|
||||
answer.append(expr.substring(start));
|
||||
|
||||
return answer.toString();
|
||||
}
|
||||
|
||||
/*
|
||||
* returns an Attributes instance containing only attributeIDs given in
|
||||
* "attributeIDs" whose values come from the given DSContext.
|
||||
*/
|
||||
public static Attributes selectAttributes(Attributes originals,
|
||||
String[] attrIDs) throws NamingException {
|
||||
|
||||
if (attrIDs == null)
|
||||
return originals;
|
||||
|
||||
Attributes result = new BasicAttributes();
|
||||
|
||||
for(int i=0; i<attrIDs.length; i++) {
|
||||
Attribute attr = originals.get(attrIDs[i]);
|
||||
if(attr != null) {
|
||||
result.put(attr);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* For testing filter
|
||||
public static void main(String[] args) {
|
||||
|
||||
Attributes attrs = new BasicAttributes(LdapClient.caseIgnore);
|
||||
attrs.put("cn", "Rosanna Lee");
|
||||
attrs.put("sn", "Lee");
|
||||
attrs.put("fn", "Rosanna");
|
||||
attrs.put("id", "10414");
|
||||
attrs.put("machine", "jurassic");
|
||||
|
||||
|
||||
try {
|
||||
System.out.println(format(attrs));
|
||||
|
||||
String expr = "(&(Age = {0})(Account Balance <= {1}))";
|
||||
Object[] fargs = new Object[2];
|
||||
// fill in the parameters
|
||||
fargs[0] = new Integer(65);
|
||||
fargs[1] = new Float(5000);
|
||||
|
||||
System.out.println(format(expr, fargs));
|
||||
|
||||
|
||||
System.out.println(format("bin={0}",
|
||||
new Object[] {new byte[] {0, 1, 2, 3, 4, 5}}));
|
||||
|
||||
System.out.println(format("bin=\\{anything}", null));
|
||||
|
||||
} catch (NamingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
546
jdkSrc/jdk8/com/sun/jndi/toolkit/url/GenericURLContext.java
Normal file
546
jdkSrc/jdk8/com/sun/jndi/toolkit/url/GenericURLContext.java
Normal file
@@ -0,0 +1,546 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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 General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.jndi.toolkit.url;
|
||||
|
||||
import javax.naming.*;
|
||||
import javax.naming.spi.ResolveResult;
|
||||
import javax.naming.spi.NamingManager;
|
||||
|
||||
import java.util.Hashtable;
|
||||
import java.net.MalformedURLException;
|
||||
|
||||
import com.sun.jndi.toolkit.url.Uri.ParseMode;
|
||||
|
||||
/**
|
||||
* This abstract class is a generic URL context that accepts as the
|
||||
* name argument either a string URL or a Name whose first component
|
||||
* is a URL. It resolves the URL to a target context and then continues
|
||||
* the operation using the remaining name in the target context as if
|
||||
* the first component names a junction.
|
||||
*
|
||||
* A subclass must define getRootURLContext()
|
||||
* to process the URL into head/tail pieces. If it wants to control how
|
||||
* URL strings are parsed and compared for the rename() operation, then
|
||||
* it should override getNonRootURLSuffixes() and urlEquals().
|
||||
*
|
||||
* @author Scott Seligman
|
||||
* @author Rosanna Lee
|
||||
*/
|
||||
abstract public class GenericURLContext implements Context {
|
||||
|
||||
protected Hashtable<String, Object> myEnv = null;
|
||||
|
||||
@SuppressWarnings("unchecked") // Expect Hashtable<String, Object>
|
||||
public GenericURLContext(Hashtable<?,?> env) {
|
||||
// context that is not tied to any specific URL
|
||||
myEnv =
|
||||
(Hashtable<String, Object>)(env == null ? null : env.clone());
|
||||
}
|
||||
|
||||
public void close() throws NamingException {
|
||||
myEnv = null;
|
||||
}
|
||||
|
||||
public String getNameInNamespace() throws NamingException {
|
||||
return ""; // %%% check this out: A URL context's name is ""
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves 'name' into a target context with remaining name.
|
||||
* For example, with a JNDI URL "jndi://dnsname/rest_name",
|
||||
* this method resolves "jndi://dnsname/" to a target context,
|
||||
* and returns the target context with "rest_name".
|
||||
* The definition of "root URL" and how much of the URL to
|
||||
* consume is implementation specific.
|
||||
* If rename() is supported for a particular URL scheme,
|
||||
* getRootURLContext(), getURLPrefix(), and getURLSuffix()
|
||||
* must be in sync wrt how URLs are parsed and returned.
|
||||
*/
|
||||
abstract protected ResolveResult getRootURLContext(String url,
|
||||
Hashtable<?,?> env) throws NamingException;
|
||||
|
||||
/**
|
||||
* Returns the suffix of the url. The result should be identical to
|
||||
* that of calling getRootURLContext().getRemainingName(), but
|
||||
* without the overhead of doing anything with the prefix like
|
||||
* creating a context.
|
||||
*<p>
|
||||
* This method returns a Name instead of a String because to give
|
||||
* the provider an opportunity to return a Name (for example,
|
||||
* for weakly separated naming systems like COS naming).
|
||||
*<p>
|
||||
* The default implementation uses skips 'prefix', calls
|
||||
* UrlUtil.decode() on it, and returns the result as a single component
|
||||
* CompositeName.
|
||||
* Subclass should override if this is not appropriate.
|
||||
* This method is used only by rename().
|
||||
* If rename() is supported for a particular URL scheme,
|
||||
* getRootURLContext(), getURLPrefix(), and getURLSuffix()
|
||||
* must be in sync wrt how URLs are parsed and returned.
|
||||
*<p>
|
||||
* For many URL schemes, this method is very similar to URL.getFile(),
|
||||
* except getFile() will return a leading slash in the
|
||||
* 2nd, 3rd, and 4th cases. For schemes like "ldap" and "iiop",
|
||||
* the leading slash must be skipped before the name is an acceptable
|
||||
* format for operation by the Context methods. For schemes that treat the
|
||||
* leading slash as significant (such as "file"),
|
||||
* the subclass must override getURLSuffix() to get the correct behavior.
|
||||
* Remember, the behavior must match getRootURLContext().
|
||||
*
|
||||
* URL Suffix
|
||||
* foo://host:port <empty string>
|
||||
* foo://host:port/rest/of/name rest/of/name
|
||||
* foo:///rest/of/name rest/of/name
|
||||
* foo:/rest/of/name rest/of/name
|
||||
* foo:rest/of/name rest/of/name
|
||||
*/
|
||||
protected Name getURLSuffix(String prefix, String url) throws NamingException {
|
||||
String suffix = url.substring(prefix.length());
|
||||
if (suffix.length() == 0) {
|
||||
return new CompositeName();
|
||||
}
|
||||
|
||||
if (suffix.charAt(0) == '/') {
|
||||
suffix = suffix.substring(1); // skip leading slash
|
||||
}
|
||||
|
||||
try {
|
||||
return new CompositeName().add(UrlUtil.decode(suffix));
|
||||
} catch (MalformedURLException e) {
|
||||
throw new InvalidNameException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the prefix of a URL.
|
||||
* Default implementation looks for slashes and then extracts
|
||||
* prefixes using String.substring().
|
||||
* Subclass should override if this is not appropriate.
|
||||
* This method is used only by rename().
|
||||
* If rename() is supported for a particular URL scheme,
|
||||
* getRootURLContext(), getURLPrefix(), and getURLSuffix()
|
||||
* must be in sync wrt how URLs are parsed and returned.
|
||||
*<p>
|
||||
* URL Prefix
|
||||
* foo://host:port foo://host:port
|
||||
* foo://host:port/rest/of/name foo://host:port
|
||||
* foo:///rest/of/name foo://
|
||||
* foo:/rest/of/name foo:
|
||||
* foo:rest/of/name foo:
|
||||
*/
|
||||
protected String getURLPrefix(String url) throws NamingException {
|
||||
int start = url.indexOf(":");
|
||||
|
||||
if (start < 0) {
|
||||
throw new OperationNotSupportedException("Invalid URL: " + url);
|
||||
}
|
||||
++start; // skip ':'
|
||||
|
||||
if (url.startsWith("//", start)) {
|
||||
start += 2; // skip double slash
|
||||
|
||||
// find where the authority component ends
|
||||
// and the rest of the URL starts
|
||||
int slash = url.indexOf('/', start);
|
||||
int qmark = url.indexOf('?', start);
|
||||
int fmark = url.indexOf('#', start);
|
||||
if (fmark > -1 && qmark > fmark) qmark = -1;
|
||||
if (fmark > -1 && slash > fmark) slash = -1;
|
||||
if (qmark > -1 && slash > qmark) slash = -1;
|
||||
int posn = slash > -1 ? slash
|
||||
: (qmark > -1 ? qmark
|
||||
: (fmark > -1 ? fmark
|
||||
: url.length()));
|
||||
if (posn >= 0) {
|
||||
start = posn;
|
||||
} else {
|
||||
start = url.length(); // rest of URL
|
||||
}
|
||||
}
|
||||
|
||||
// else 0 or 1 iniitial slashes; start is unchanged
|
||||
return url.substring(0, start);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether two URLs are the same.
|
||||
* Default implementation uses String.equals().
|
||||
* Subclass should override if this is not appropriate.
|
||||
* This method is used by rename().
|
||||
*/
|
||||
protected boolean urlEquals(String url1, String url2) {
|
||||
return url1.equals(url2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the context in which to continue the operation. This method
|
||||
* is called when this context is asked to process a multicomponent
|
||||
* Name in which the first component is a URL.
|
||||
* Treat the first component like a junction: resolve it and then use
|
||||
* NamingManager.getContinuationContext() to get the target context in
|
||||
* which to operate on the remainder of the name (n.getSuffix(1)).
|
||||
*/
|
||||
protected Context getContinuationContext(Name n) throws NamingException {
|
||||
Object obj = lookup(n.get(0));
|
||||
CannotProceedException cpe = new CannotProceedException();
|
||||
cpe.setResolvedObj(obj);
|
||||
cpe.setEnvironment(myEnv);
|
||||
return NamingManager.getContinuationContext(cpe);
|
||||
}
|
||||
|
||||
public Object lookup(String name) throws NamingException {
|
||||
ResolveResult res = getRootURLContext(name, myEnv);
|
||||
Context ctx = (Context)res.getResolvedObj();
|
||||
try {
|
||||
return ctx.lookup(res.getRemainingName());
|
||||
} finally {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
|
||||
public Object lookup(Name name) throws NamingException {
|
||||
if (name.size() == 1) {
|
||||
return lookup(name.get(0));
|
||||
} else {
|
||||
Context ctx = getContinuationContext(name);
|
||||
try {
|
||||
return ctx.lookup(name.getSuffix(1));
|
||||
} finally {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void bind(String name, Object obj) throws NamingException {
|
||||
ResolveResult res = getRootURLContext(name, myEnv);
|
||||
Context ctx = (Context)res.getResolvedObj();
|
||||
try {
|
||||
ctx.bind(res.getRemainingName(), obj);
|
||||
} finally {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
|
||||
public void bind(Name name, Object obj) throws NamingException {
|
||||
if (name.size() == 1) {
|
||||
bind(name.get(0), obj);
|
||||
} else {
|
||||
Context ctx = getContinuationContext(name);
|
||||
try {
|
||||
ctx.bind(name.getSuffix(1), obj);
|
||||
} finally {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void rebind(String name, Object obj) throws NamingException {
|
||||
ResolveResult res = getRootURLContext(name, myEnv);
|
||||
Context ctx = (Context)res.getResolvedObj();
|
||||
try {
|
||||
ctx.rebind(res.getRemainingName(), obj);
|
||||
} finally {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
|
||||
public void rebind(Name name, Object obj) throws NamingException {
|
||||
if (name.size() == 1) {
|
||||
rebind(name.get(0), obj);
|
||||
} else {
|
||||
Context ctx = getContinuationContext(name);
|
||||
try {
|
||||
ctx.rebind(name.getSuffix(1), obj);
|
||||
} finally {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void unbind(String name) throws NamingException {
|
||||
ResolveResult res = getRootURLContext(name, myEnv);
|
||||
Context ctx = (Context)res.getResolvedObj();
|
||||
try {
|
||||
ctx.unbind(res.getRemainingName());
|
||||
} finally {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
|
||||
public void unbind(Name name) throws NamingException {
|
||||
if (name.size() == 1) {
|
||||
unbind(name.get(0));
|
||||
} else {
|
||||
Context ctx = getContinuationContext(name);
|
||||
try {
|
||||
ctx.unbind(name.getSuffix(1));
|
||||
} finally {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void rename(String oldName, String newName) throws NamingException {
|
||||
String oldPrefix = getURLPrefix(oldName);
|
||||
String newPrefix = getURLPrefix(newName);
|
||||
if (!urlEquals(oldPrefix, newPrefix)) {
|
||||
throw new OperationNotSupportedException(
|
||||
"Renaming using different URL prefixes not supported : " +
|
||||
oldName + " " + newName);
|
||||
}
|
||||
|
||||
ResolveResult res = getRootURLContext(oldName, myEnv);
|
||||
Context ctx = (Context)res.getResolvedObj();
|
||||
try {
|
||||
ctx.rename(res.getRemainingName(), getURLSuffix(newPrefix, newName));
|
||||
} finally {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
|
||||
public void rename(Name name, Name newName) throws NamingException {
|
||||
if (name.size() == 1) {
|
||||
if (newName.size() != 1) {
|
||||
throw new OperationNotSupportedException(
|
||||
"Renaming to a Name with more components not supported: " + newName);
|
||||
}
|
||||
rename(name.get(0), newName.get(0));
|
||||
} else {
|
||||
// > 1 component with 1st one being URL
|
||||
// URLs must be identical; cannot deal with diff URLs
|
||||
if (!urlEquals(name.get(0), newName.get(0))) {
|
||||
throw new OperationNotSupportedException(
|
||||
"Renaming using different URLs as first components not supported: " +
|
||||
name + " " + newName);
|
||||
}
|
||||
|
||||
Context ctx = getContinuationContext(name);
|
||||
try {
|
||||
ctx.rename(name.getSuffix(1), newName.getSuffix(1));
|
||||
} finally {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public NamingEnumeration<NameClassPair> list(String name) throws NamingException {
|
||||
ResolveResult res = getRootURLContext(name, myEnv);
|
||||
Context ctx = (Context)res.getResolvedObj();
|
||||
try {
|
||||
return ctx.list(res.getRemainingName());
|
||||
} finally {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
|
||||
public NamingEnumeration<NameClassPair> list(Name name) throws NamingException {
|
||||
if (name.size() == 1) {
|
||||
return list(name.get(0));
|
||||
} else {
|
||||
Context ctx = getContinuationContext(name);
|
||||
try {
|
||||
return ctx.list(name.getSuffix(1));
|
||||
} finally {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public NamingEnumeration<Binding> listBindings(String name)
|
||||
throws NamingException {
|
||||
ResolveResult res = getRootURLContext(name, myEnv);
|
||||
Context ctx = (Context)res.getResolvedObj();
|
||||
try {
|
||||
return ctx.listBindings(res.getRemainingName());
|
||||
} finally {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
|
||||
public NamingEnumeration<Binding> listBindings(Name name) throws NamingException {
|
||||
if (name.size() == 1) {
|
||||
return listBindings(name.get(0));
|
||||
} else {
|
||||
Context ctx = getContinuationContext(name);
|
||||
try {
|
||||
return ctx.listBindings(name.getSuffix(1));
|
||||
} finally {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void destroySubcontext(String name) throws NamingException {
|
||||
ResolveResult res = getRootURLContext(name, myEnv);
|
||||
Context ctx = (Context)res.getResolvedObj();
|
||||
try {
|
||||
ctx.destroySubcontext(res.getRemainingName());
|
||||
} finally {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
|
||||
public void destroySubcontext(Name name) throws NamingException {
|
||||
if (name.size() == 1) {
|
||||
destroySubcontext(name.get(0));
|
||||
} else {
|
||||
Context ctx = getContinuationContext(name);
|
||||
try {
|
||||
ctx.destroySubcontext(name.getSuffix(1));
|
||||
} finally {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Context createSubcontext(String name) throws NamingException {
|
||||
ResolveResult res = getRootURLContext(name, myEnv);
|
||||
Context ctx = (Context)res.getResolvedObj();
|
||||
try {
|
||||
return ctx.createSubcontext(res.getRemainingName());
|
||||
} finally {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
|
||||
public Context createSubcontext(Name name) throws NamingException {
|
||||
if (name.size() == 1) {
|
||||
return createSubcontext(name.get(0));
|
||||
} else {
|
||||
Context ctx = getContinuationContext(name);
|
||||
try {
|
||||
return ctx.createSubcontext(name.getSuffix(1));
|
||||
} finally {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Object lookupLink(String name) throws NamingException {
|
||||
ResolveResult res = getRootURLContext(name, myEnv);
|
||||
Context ctx = (Context)res.getResolvedObj();
|
||||
try {
|
||||
return ctx.lookupLink(res.getRemainingName());
|
||||
} finally {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
|
||||
public Object lookupLink(Name name) throws NamingException {
|
||||
if (name.size() == 1) {
|
||||
return lookupLink(name.get(0));
|
||||
} else {
|
||||
Context ctx = getContinuationContext(name);
|
||||
try {
|
||||
return ctx.lookupLink(name.getSuffix(1));
|
||||
} finally {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public NameParser getNameParser(String name) throws NamingException {
|
||||
ResolveResult res = getRootURLContext(name, myEnv);
|
||||
Context ctx = (Context)res.getResolvedObj();
|
||||
try {
|
||||
return ctx.getNameParser(res.getRemainingName());
|
||||
} finally {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
|
||||
public NameParser getNameParser(Name name) throws NamingException {
|
||||
if (name.size() == 1) {
|
||||
return getNameParser(name.get(0));
|
||||
} else {
|
||||
Context ctx = getContinuationContext(name);
|
||||
try {
|
||||
return ctx.getNameParser(name.getSuffix(1));
|
||||
} finally {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String composeName(String name, String prefix)
|
||||
throws NamingException {
|
||||
if (prefix.equals("")) {
|
||||
return name;
|
||||
} else if (name.equals("")) {
|
||||
return prefix;
|
||||
} else {
|
||||
return (prefix + "/" + name);
|
||||
}
|
||||
}
|
||||
|
||||
public Name composeName(Name name, Name prefix) throws NamingException {
|
||||
Name result = (Name)prefix.clone();
|
||||
result.addAll(name);
|
||||
return result;
|
||||
}
|
||||
|
||||
public Object removeFromEnvironment(String propName)
|
||||
throws NamingException {
|
||||
if (myEnv == null) {
|
||||
return null;
|
||||
}
|
||||
return myEnv.remove(propName);
|
||||
}
|
||||
|
||||
public Object addToEnvironment(String propName, Object propVal)
|
||||
throws NamingException {
|
||||
if (myEnv == null) {
|
||||
myEnv = new Hashtable<String, Object>(11, 0.75f);
|
||||
}
|
||||
return myEnv.put(propName, propVal);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked") // clone()
|
||||
public Hashtable<String, Object> getEnvironment() throws NamingException {
|
||||
if (myEnv == null) {
|
||||
return new Hashtable<>(5, 0.75f);
|
||||
} else {
|
||||
return (Hashtable<String, Object>)myEnv.clone();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// To test, declare getURLPrefix and getURLSuffix static.
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
String[] tests = {"file://host:port",
|
||||
"file:///rest/of/name",
|
||||
"file://host:port/rest/of/name",
|
||||
"file:/rest/of/name",
|
||||
"file:rest/of/name"};
|
||||
for (int i = 0; i < tests.length; i++) {
|
||||
String pre = getURLPrefix(tests[i]);
|
||||
System.out.println(pre);
|
||||
System.out.println(getURLSuffix(pre, tests[i]));
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
411
jdkSrc/jdk8/com/sun/jndi/toolkit/url/GenericURLDirContext.java
Normal file
411
jdkSrc/jdk8/com/sun/jndi/toolkit/url/GenericURLDirContext.java
Normal file
@@ -0,0 +1,411 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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 General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package com.sun.jndi.toolkit.url;
|
||||
|
||||
import javax.naming.*;
|
||||
import javax.naming.directory.*;
|
||||
import javax.naming.spi.ResolveResult;
|
||||
import javax.naming.spi.DirectoryManager;
|
||||
|
||||
import java.util.Hashtable;
|
||||
|
||||
/**
|
||||
* This abstract class is a generic URL DirContext that accepts as the
|
||||
* name argument either a string URL or a Name whose first component
|
||||
* is a URL. It resolves the URL to a target context and then continues
|
||||
* the operation using the remaining name in the target context as if
|
||||
* the first component names a junction.
|
||||
*
|
||||
* A subclass must define getRootURLContext()
|
||||
* to process the URL into head/tail pieces. If it wants to control how
|
||||
* URL strings are parsed and compared for the rename() operation, then
|
||||
* it should override getNonRootURLSuffixes() and urlEquals().
|
||||
*
|
||||
* @author Scott Seligman
|
||||
* @author Rosanna Lee
|
||||
*/
|
||||
|
||||
abstract public class GenericURLDirContext extends GenericURLContext
|
||||
implements DirContext {
|
||||
|
||||
protected GenericURLDirContext(Hashtable<?,?> env) {
|
||||
super(env);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the context in which to continue the operation. This method
|
||||
* is called when this context is asked to process a multicomponent
|
||||
* Name in which the first component is a URL.
|
||||
* Treat the first component like a junction: resolve it and then use
|
||||
* DirectoryManager.getContinuationDirContext() to get the target context in
|
||||
* which to operate on the remainder of the name (n.getSuffix(1)).
|
||||
* Do this in case intermediate contexts are not DirContext.
|
||||
*/
|
||||
protected DirContext getContinuationDirContext(Name n) throws NamingException {
|
||||
Object obj = lookup(n.get(0));
|
||||
CannotProceedException cpe = new CannotProceedException();
|
||||
cpe.setResolvedObj(obj);
|
||||
cpe.setEnvironment(myEnv);
|
||||
return DirectoryManager.getContinuationDirContext(cpe);
|
||||
}
|
||||
|
||||
|
||||
public Attributes getAttributes(String name) throws NamingException {
|
||||
ResolveResult res = getRootURLContext(name, myEnv);
|
||||
DirContext ctx = (DirContext)res.getResolvedObj();
|
||||
try {
|
||||
return ctx.getAttributes(res.getRemainingName());
|
||||
} finally {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
|
||||
public Attributes getAttributes(Name name) throws NamingException {
|
||||
if (name.size() == 1) {
|
||||
return getAttributes(name.get(0));
|
||||
} else {
|
||||
DirContext ctx = getContinuationDirContext(name);
|
||||
try {
|
||||
return ctx.getAttributes(name.getSuffix(1));
|
||||
} finally {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Attributes getAttributes(String name, String[] attrIds)
|
||||
throws NamingException {
|
||||
ResolveResult res = getRootURLContext(name, myEnv);
|
||||
DirContext ctx = (DirContext)res.getResolvedObj();
|
||||
try {
|
||||
return ctx.getAttributes(res.getRemainingName(), attrIds);
|
||||
} finally {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
|
||||
public Attributes getAttributes(Name name, String[] attrIds)
|
||||
throws NamingException {
|
||||
if (name.size() == 1) {
|
||||
return getAttributes(name.get(0), attrIds);
|
||||
} else {
|
||||
DirContext ctx = getContinuationDirContext(name);
|
||||
try {
|
||||
return ctx.getAttributes(name.getSuffix(1), attrIds);
|
||||
} finally {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void modifyAttributes(String name, int mod_op, Attributes attrs)
|
||||
throws NamingException {
|
||||
ResolveResult res = getRootURLContext(name, myEnv);
|
||||
DirContext ctx = (DirContext)res.getResolvedObj();
|
||||
try {
|
||||
ctx.modifyAttributes(res.getRemainingName(), mod_op, attrs);
|
||||
} finally {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
|
||||
public void modifyAttributes(Name name, int mod_op, Attributes attrs)
|
||||
throws NamingException {
|
||||
if (name.size() == 1) {
|
||||
modifyAttributes(name.get(0), mod_op, attrs);
|
||||
} else {
|
||||
DirContext ctx = getContinuationDirContext(name);
|
||||
try {
|
||||
ctx.modifyAttributes(name.getSuffix(1), mod_op, attrs);
|
||||
} finally {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void modifyAttributes(String name, ModificationItem[] mods)
|
||||
throws NamingException {
|
||||
ResolveResult res = getRootURLContext(name, myEnv);
|
||||
DirContext ctx = (DirContext)res.getResolvedObj();
|
||||
try {
|
||||
ctx.modifyAttributes(res.getRemainingName(), mods);
|
||||
} finally {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
|
||||
public void modifyAttributes(Name name, ModificationItem[] mods)
|
||||
throws NamingException {
|
||||
if (name.size() == 1) {
|
||||
modifyAttributes(name.get(0), mods);
|
||||
} else {
|
||||
DirContext ctx = getContinuationDirContext(name);
|
||||
try {
|
||||
ctx.modifyAttributes(name.getSuffix(1), mods);
|
||||
} finally {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void bind(String name, Object obj, Attributes attrs)
|
||||
throws NamingException {
|
||||
ResolveResult res = getRootURLContext(name, myEnv);
|
||||
DirContext ctx = (DirContext)res.getResolvedObj();
|
||||
try {
|
||||
ctx.bind(res.getRemainingName(), obj, attrs);
|
||||
} finally {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
|
||||
public void bind(Name name, Object obj, Attributes attrs)
|
||||
throws NamingException {
|
||||
if (name.size() == 1) {
|
||||
bind(name.get(0), obj, attrs);
|
||||
} else {
|
||||
DirContext ctx = getContinuationDirContext(name);
|
||||
try {
|
||||
ctx.bind(name.getSuffix(1), obj, attrs);
|
||||
} finally {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void rebind(String name, Object obj, Attributes attrs)
|
||||
throws NamingException {
|
||||
ResolveResult res = getRootURLContext(name, myEnv);
|
||||
DirContext ctx = (DirContext)res.getResolvedObj();
|
||||
try {
|
||||
ctx.rebind(res.getRemainingName(), obj, attrs);
|
||||
} finally {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
|
||||
public void rebind(Name name, Object obj, Attributes attrs)
|
||||
throws NamingException {
|
||||
if (name.size() == 1) {
|
||||
rebind(name.get(0), obj, attrs);
|
||||
} else {
|
||||
DirContext ctx = getContinuationDirContext(name);
|
||||
try {
|
||||
ctx.rebind(name.getSuffix(1), obj, attrs);
|
||||
} finally {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public DirContext createSubcontext(String name, Attributes attrs)
|
||||
throws NamingException {
|
||||
ResolveResult res = getRootURLContext(name, myEnv);
|
||||
DirContext ctx = (DirContext)res.getResolvedObj();
|
||||
try {
|
||||
return ctx.createSubcontext(res.getRemainingName(), attrs);
|
||||
} finally {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
|
||||
public DirContext createSubcontext(Name name, Attributes attrs)
|
||||
throws NamingException {
|
||||
if (name.size() == 1) {
|
||||
return createSubcontext(name.get(0), attrs);
|
||||
} else {
|
||||
DirContext ctx = getContinuationDirContext(name);
|
||||
try {
|
||||
return ctx.createSubcontext(name.getSuffix(1), attrs);
|
||||
} finally {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public DirContext getSchema(String name) throws NamingException {
|
||||
ResolveResult res = getRootURLContext(name, myEnv);
|
||||
DirContext ctx = (DirContext)res.getResolvedObj();
|
||||
return ctx.getSchema(res.getRemainingName());
|
||||
}
|
||||
|
||||
public DirContext getSchema(Name name) throws NamingException {
|
||||
if (name.size() == 1) {
|
||||
return getSchema(name.get(0));
|
||||
} else {
|
||||
DirContext ctx = getContinuationDirContext(name);
|
||||
try {
|
||||
return ctx.getSchema(name.getSuffix(1));
|
||||
} finally {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public DirContext getSchemaClassDefinition(String name)
|
||||
throws NamingException {
|
||||
ResolveResult res = getRootURLContext(name, myEnv);
|
||||
DirContext ctx = (DirContext)res.getResolvedObj();
|
||||
try {
|
||||
return ctx.getSchemaClassDefinition(res.getRemainingName());
|
||||
} finally {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
|
||||
public DirContext getSchemaClassDefinition(Name name)
|
||||
throws NamingException {
|
||||
if (name.size() == 1) {
|
||||
return getSchemaClassDefinition(name.get(0));
|
||||
} else {
|
||||
DirContext ctx = getContinuationDirContext(name);
|
||||
try {
|
||||
return ctx.getSchemaClassDefinition(name.getSuffix(1));
|
||||
} finally {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public NamingEnumeration<SearchResult> search(String name,
|
||||
Attributes matchingAttributes)
|
||||
throws NamingException {
|
||||
ResolveResult res = getRootURLContext(name, myEnv);
|
||||
DirContext ctx = (DirContext)res.getResolvedObj();
|
||||
try {
|
||||
return ctx.search(res.getRemainingName(), matchingAttributes);
|
||||
} finally {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
|
||||
public NamingEnumeration<SearchResult> search(Name name,
|
||||
Attributes matchingAttributes)
|
||||
throws NamingException {
|
||||
if (name.size() == 1) {
|
||||
return search(name.get(0), matchingAttributes);
|
||||
} else {
|
||||
DirContext ctx = getContinuationDirContext(name);
|
||||
try {
|
||||
return ctx.search(name.getSuffix(1), matchingAttributes);
|
||||
} finally {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public NamingEnumeration<SearchResult> search(String name,
|
||||
Attributes matchingAttributes,
|
||||
String[] attributesToReturn)
|
||||
throws NamingException {
|
||||
ResolveResult res = getRootURLContext(name, myEnv);
|
||||
DirContext ctx = (DirContext)res.getResolvedObj();
|
||||
try {
|
||||
return ctx.search(res.getRemainingName(),
|
||||
matchingAttributes, attributesToReturn);
|
||||
} finally {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
|
||||
public NamingEnumeration<SearchResult> search(Name name,
|
||||
Attributes matchingAttributes,
|
||||
String[] attributesToReturn)
|
||||
throws NamingException {
|
||||
if (name.size() == 1) {
|
||||
return search(name.get(0), matchingAttributes,
|
||||
attributesToReturn);
|
||||
} else {
|
||||
DirContext ctx = getContinuationDirContext(name);
|
||||
try {
|
||||
return ctx.search(name.getSuffix(1),
|
||||
matchingAttributes, attributesToReturn);
|
||||
} finally {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public NamingEnumeration<SearchResult> search(String name,
|
||||
String filter,
|
||||
SearchControls cons)
|
||||
throws NamingException {
|
||||
ResolveResult res = getRootURLContext(name, myEnv);
|
||||
DirContext ctx = (DirContext)res.getResolvedObj();
|
||||
try {
|
||||
return ctx.search(res.getRemainingName(), filter, cons);
|
||||
} finally {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
|
||||
public NamingEnumeration<SearchResult> search(Name name,
|
||||
String filter,
|
||||
SearchControls cons)
|
||||
throws NamingException {
|
||||
if (name.size() == 1) {
|
||||
return search(name.get(0), filter, cons);
|
||||
} else {
|
||||
DirContext ctx = getContinuationDirContext(name);
|
||||
try {
|
||||
return ctx.search(name.getSuffix(1), filter, cons);
|
||||
} finally {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public NamingEnumeration<SearchResult> search(String name,
|
||||
String filterExpr,
|
||||
Object[] filterArgs,
|
||||
SearchControls cons)
|
||||
throws NamingException {
|
||||
ResolveResult res = getRootURLContext(name, myEnv);
|
||||
DirContext ctx = (DirContext)res.getResolvedObj();
|
||||
try {
|
||||
return
|
||||
ctx.search(res.getRemainingName(), filterExpr, filterArgs, cons);
|
||||
} finally {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
|
||||
public NamingEnumeration<SearchResult> search(Name name,
|
||||
String filterExpr,
|
||||
Object[] filterArgs,
|
||||
SearchControls cons)
|
||||
throws NamingException {
|
||||
if (name.size() == 1) {
|
||||
return search(name.get(0), filterExpr, filterArgs, cons);
|
||||
} else {
|
||||
DirContext ctx = getContinuationDirContext(name);
|
||||
try {
|
||||
return ctx.search(name.getSuffix(1), filterExpr, filterArgs, cons);
|
||||
} finally {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
525
jdkSrc/jdk8/com/sun/jndi/toolkit/url/Uri.java
Normal file
525
jdkSrc/jdk8/com/sun/jndi/toolkit/url/Uri.java
Normal file
@@ -0,0 +1,525 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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 General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.jndi.toolkit.url;
|
||||
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
|
||||
/**
|
||||
* A Uri object represents an absolute Uniform Resource Identifier
|
||||
* (URI) as defined by RFC 2396 and updated by RFC 2373 and RFC 2732.
|
||||
* The most commonly used form of URI is the Uniform Resource Locator (URL).
|
||||
*
|
||||
* <p> The java.net.URL class cannot be used to parse URIs since it
|
||||
* requires the installation of URL stream handlers that may not be
|
||||
* available.
|
||||
*
|
||||
* <p> The {@linkplain ParseMode#STRICT strict} parsing mode uses
|
||||
* the java.net.URI class to syntactically validate URI strings.
|
||||
* The {@linkplain ParseMode#COMPAT compat} mode validate the
|
||||
* URI authority and rejects URI fragments, but doesn't perform any
|
||||
* additional validation on path and query, other than that
|
||||
* which may be implemented in the concrete the Uri subclasses.
|
||||
* The {@linkplain ParseMode#LEGACY legacy} mode should not be
|
||||
* used unless the application is capable of validating all URI
|
||||
* strings before any constructors of this class is invoked.
|
||||
*
|
||||
* <p> The format of an absolute URI (see the RFCs mentioned above) is:
|
||||
* <p><blockquote><pre>
|
||||
* absoluteURI = scheme ":" ( hier_part | opaque_part )
|
||||
*
|
||||
* scheme = alpha *( alpha | digit | "+" | "-" | "." )
|
||||
*
|
||||
* hier_part = ( net_path | abs_path ) [ "?" query ]
|
||||
* opaque_part = uric_no_slash *uric
|
||||
*
|
||||
* net_path = "//" authority [ abs_path ]
|
||||
* abs_path = "/" path_segments
|
||||
*
|
||||
* authority = server | reg_name
|
||||
* reg_name = 1*( unreserved | escaped | "$" | "," |
|
||||
* ";" | ":" | "@" | "&" | "=" | "+" )
|
||||
* server = [ [ userinfo "@" ] hostport ]
|
||||
* userinfo = *( unreserved | escaped |
|
||||
* ";" | ":" | "&" | "=" | "+" | "$" | "," )
|
||||
*
|
||||
* hostport = host [ ":" port ]
|
||||
* host = hostname | IPv4address | IPv6reference
|
||||
* port = *digit
|
||||
*
|
||||
* IPv6reference = "[" IPv6address "]"
|
||||
* IPv6address = hexpart [ ":" IPv4address ]
|
||||
* IPv4address = 1*3digit "." 1*3digit "." 1*3digit "." 1*3digit
|
||||
* hexpart = hexseq | hexseq "::" [ hexseq ] | "::" [ hexseq ]
|
||||
* hexseq = hex4 *( ":" hex4)
|
||||
* hex4 = 1*4hex
|
||||
*
|
||||
* path = [ abs_path | opaque_part ]
|
||||
* path_segments = segment *( "/" segment )
|
||||
* segment = *pchar *( ";" param )
|
||||
* param = *pchar
|
||||
* pchar = unreserved | escaped |
|
||||
* ":" | "@" | "&" | "=" | "+" | "$" | ","
|
||||
*
|
||||
* query = *uric
|
||||
*
|
||||
* uric = reserved | unreserved | escaped
|
||||
* uric_no_slash = unreserved | escaped | ";" | "?" | ":" | "@" |
|
||||
* "&" | "=" | "+" | "$" | ","
|
||||
* reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" |
|
||||
* "$" | "," | "[" | "]"
|
||||
* unreserved = alphanum | mark
|
||||
* mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")"
|
||||
* escaped = "%" hex hex
|
||||
* unwise = "{" | "}" | "|" | "\" | "^" | "`"
|
||||
* </pre></blockquote>
|
||||
*
|
||||
* <p> Currently URIs containing <tt>userinfo</tt> or <tt>reg_name</tt>
|
||||
* are not supported.
|
||||
* The <tt>opaque_part</tt> of a non-hierarchical URI is treated as if
|
||||
* if were a <tt>path</tt> without a leading slash.
|
||||
*/
|
||||
|
||||
|
||||
public class Uri {
|
||||
|
||||
// three parsing modes
|
||||
public enum ParseMode {
|
||||
/**
|
||||
* Strict validation mode.
|
||||
* Validate the URI syntactically using {@link java.net.URI}.
|
||||
* Rejects URI fragments unless explicitly supported by the
|
||||
* subclass.
|
||||
*/
|
||||
STRICT,
|
||||
/**
|
||||
* Compatibility mode. The URI authority is syntactically validated.
|
||||
* Rejects URI fragments unless explicitly supported by the
|
||||
* subclass.
|
||||
* This is the default.
|
||||
*/
|
||||
COMPAT,
|
||||
/**
|
||||
* Legacy mode. In this mode, no validation is performed.
|
||||
*/
|
||||
LEGACY
|
||||
}
|
||||
|
||||
protected String uri;
|
||||
protected String scheme;
|
||||
protected String host = null;
|
||||
protected int port = -1;
|
||||
protected boolean hasAuthority;
|
||||
protected String path;
|
||||
protected String query = null;
|
||||
protected String fragment;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a Uri object given a URI string.
|
||||
*/
|
||||
public Uri(String uri) throws MalformedURLException {
|
||||
init(uri);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an uninitialized Uri object. The init() method must
|
||||
* be called before any other Uri methods.
|
||||
*/
|
||||
protected Uri() {
|
||||
}
|
||||
|
||||
/**
|
||||
* The parse mode for parsing this URI.
|
||||
* The default is {@link ParseMode#COMPAT}.
|
||||
* @return the parse mode for parsing this URI.
|
||||
*/
|
||||
protected ParseMode parseMode() {
|
||||
return ParseMode.COMPAT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes a Uri object given a URI string.
|
||||
* This method must be called exactly once, and before any other Uri
|
||||
* methods.
|
||||
*/
|
||||
protected void init(String uri) throws MalformedURLException {
|
||||
this.uri = uri;
|
||||
parse(uri, parseMode());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URI's scheme.
|
||||
*/
|
||||
public String getScheme() {
|
||||
return scheme;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the host from the URI's authority part, or null
|
||||
* if no host is provided. If the host is an IPv6 literal, the
|
||||
* delimiting brackets are part of the returned value (see
|
||||
* {@link java.net.URI#getHost}).
|
||||
*/
|
||||
public String getHost() {
|
||||
return host;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the port from the URI's authority part, or -1 if
|
||||
* no port is provided.
|
||||
*/
|
||||
public int getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URI's path. The path is never null. Note that a
|
||||
* slash following the authority part (or the scheme if there is
|
||||
* no authority part) is part of the path. For example, the path
|
||||
* of "http://host/a/b" is "/a/b".
|
||||
*/
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URI's query part, or null if no query is provided.
|
||||
* Note that a query always begins with a leading "?".
|
||||
*/
|
||||
public String getQuery() {
|
||||
return query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URI as a string.
|
||||
*/
|
||||
public String toString() {
|
||||
return uri;
|
||||
}
|
||||
|
||||
private void parse(String uri, ParseMode mode) throws MalformedURLException {
|
||||
switch (mode) {
|
||||
case STRICT:
|
||||
parseStrict(uri);
|
||||
break;
|
||||
case COMPAT:
|
||||
parseCompat(uri);
|
||||
break;
|
||||
case LEGACY:
|
||||
parseLegacy(uri);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Parses a URI string and sets this object's fields accordingly.
|
||||
* Use java.net.URI to validate the uri string syntax
|
||||
*/
|
||||
private void parseStrict(String uri) throws MalformedURLException {
|
||||
try {
|
||||
if (!isSchemeOnly(uri)) {
|
||||
URI u = new URI(uri);
|
||||
scheme = u.getScheme();
|
||||
if (scheme == null) throw new MalformedURLException("Invalid URI: " + uri);
|
||||
String auth = u.getRawAuthority();
|
||||
hasAuthority = auth != null;
|
||||
if (hasAuthority) {
|
||||
String host = u.getHost();
|
||||
int port = u.getPort();
|
||||
if (host != null) this.host = host;
|
||||
if (port != -1) this.port = port;
|
||||
String hostport = (host == null ? "" : host)
|
||||
+ (port == -1 ? "" : (":" + port));
|
||||
if (!hostport.equals(auth)) {
|
||||
// throw if we have user info or regname
|
||||
throw new MalformedURLException("unsupported authority: " + auth);
|
||||
}
|
||||
}
|
||||
path = u.getRawPath();
|
||||
if (u.getRawQuery() != null) {
|
||||
query = "?" + u.getRawQuery();
|
||||
}
|
||||
if (u.getRawFragment() != null) {
|
||||
if (!acceptsFragment()) {
|
||||
throw new MalformedURLException("URI fragments not supported: " + uri);
|
||||
}
|
||||
fragment = "#" + u.getRawFragment();
|
||||
}
|
||||
} else {
|
||||
// scheme-only URIs are not supported by java.net.URI
|
||||
// validate the URI by appending "/" to the uri string.
|
||||
String s = uri.substring(0, uri.indexOf(':'));
|
||||
URI u = new URI(uri + "/");
|
||||
if (!s.equals(u.getScheme())
|
||||
|| !checkSchemeOnly(uri, u.getScheme())) {
|
||||
throw newInvalidURISchemeException(uri);
|
||||
}
|
||||
scheme = s;
|
||||
path = "";
|
||||
}
|
||||
} catch (URISyntaxException e) {
|
||||
MalformedURLException mue = new MalformedURLException(e.getMessage());
|
||||
mue.initCause(e);
|
||||
throw mue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Parses a URI string and sets this object's fields accordingly.
|
||||
* Compatibility mode. Use java.net.URI to validate the syntax of
|
||||
* the uri string authority.
|
||||
*/
|
||||
private void parseCompat(String uri) throws MalformedURLException {
|
||||
int i; // index into URI
|
||||
|
||||
i = uri.indexOf(':'); // parse scheme
|
||||
int slash = uri.indexOf('/');
|
||||
int qmark = uri.indexOf('?');
|
||||
int fmark = uri.indexOf('#');
|
||||
if (i < 0 || slash > 0 && i > slash || qmark > 0 && i > qmark || fmark > 0 && i > fmark) {
|
||||
throw new MalformedURLException("Invalid URI: " + uri);
|
||||
}
|
||||
if (fmark > -1) {
|
||||
if (!acceptsFragment()) {
|
||||
throw new MalformedURLException("URI fragments not supported: " + uri);
|
||||
}
|
||||
}
|
||||
if (i == uri.length() - 1) {
|
||||
if (!isSchemeOnly(uri)) {
|
||||
throw newInvalidURISchemeException(uri);
|
||||
}
|
||||
}
|
||||
scheme = uri.substring(0, i);
|
||||
i++; // skip past ":"
|
||||
|
||||
hasAuthority = uri.startsWith("//", i);
|
||||
if (fmark > -1 && qmark > fmark) qmark = -1;
|
||||
int endp = qmark > -1 ? qmark : fmark > -1 ? fmark : uri.length();
|
||||
if (hasAuthority) { // parse "//host:port"
|
||||
i += 2; // skip past "//"
|
||||
int starta = i;
|
||||
// authority ends at the first appearance of /, ?, or #
|
||||
int enda = uri.indexOf('/', i);
|
||||
if (enda == -1 || qmark > -1 && qmark < enda) enda = qmark;
|
||||
if (enda == -1 || fmark > -1 && fmark < enda) enda = fmark;
|
||||
if (enda < 0) {
|
||||
enda = uri.length();
|
||||
}
|
||||
if (uri.startsWith(":", i)) {
|
||||
// LdapURL supports empty host.
|
||||
i++;
|
||||
host = "";
|
||||
if (enda > i) {
|
||||
port = Integer.parseInt(uri.substring(i, enda));
|
||||
}
|
||||
} else {
|
||||
// Use URI to parse authority
|
||||
try {
|
||||
// URI requires at least one char after authority:
|
||||
// we use "/" and expect that the resulting URI path
|
||||
// will be exactly "/".
|
||||
URI u = new URI(uri.substring(0, enda) + "/");
|
||||
String auth = uri.substring(starta, enda);
|
||||
host = u.getHost();
|
||||
port = u.getPort();
|
||||
String p = u.getRawPath();
|
||||
String q = u.getRawQuery();
|
||||
String f = u.getRawFragment();
|
||||
String ui = u.getRawUserInfo();
|
||||
if (ui != null) {
|
||||
throw new MalformedURLException("user info not supported in authority: " + ui);
|
||||
}
|
||||
if (!"/".equals(p)) {
|
||||
throw new MalformedURLException("invalid authority: " + auth);
|
||||
}
|
||||
if (q != null) {
|
||||
throw new MalformedURLException("invalid trailing characters in authority: ?" + q);
|
||||
}
|
||||
if (f != null) {
|
||||
throw new MalformedURLException("invalid trailing characters in authority: #" + f);
|
||||
}
|
||||
String hostport = (host == null ? "" : host)
|
||||
+ (port == -1?"":(":" + port));
|
||||
if (!auth.equals(hostport)) {
|
||||
// throw if we have user info or regname
|
||||
throw new MalformedURLException("unsupported authority: " + auth);
|
||||
}
|
||||
} catch (URISyntaxException e) {
|
||||
MalformedURLException mue = new MalformedURLException(e.getMessage());
|
||||
mue.initCause(e);
|
||||
throw mue;
|
||||
}
|
||||
}
|
||||
i = enda;
|
||||
}
|
||||
path = uri.substring(i, endp);
|
||||
// look for query
|
||||
if (qmark > -1) {
|
||||
if (fmark > -1) {
|
||||
query = uri.substring(qmark, fmark);
|
||||
} else {
|
||||
query = uri.substring(qmark);
|
||||
}
|
||||
}
|
||||
if (fmark > -1) {
|
||||
fragment = uri.substring(fmark);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A subclass of {@code Uri} that supports scheme only
|
||||
* URIs can override this method and return true in the
|
||||
* case where the URI string is a scheme-only URI that
|
||||
* the subclass supports.
|
||||
* @implSpec
|
||||
* The default implementation of this method returns false,
|
||||
* always.
|
||||
* @param uri An URI string
|
||||
* @return if this is a scheme-only URI supported by the subclass
|
||||
*/
|
||||
protected boolean isSchemeOnly(String uri) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given uri string should be considered
|
||||
* as a scheme-only URI. For some protocols - e.g. DNS, we
|
||||
* might accept "dns://" as a valid URL denoting default DNS.
|
||||
* For others - we might only accept "scheme:".
|
||||
* @implSpec
|
||||
* The default implementation of this method returns true if
|
||||
* the URI is of the form {@code "<scheme>:"} with nothing
|
||||
* after the scheme delimiter.
|
||||
* @param uri the URI
|
||||
* @param scheme the scheme
|
||||
* @return true if the URI should be considered as a scheme-only
|
||||
* URI supported by this URI scheme.
|
||||
*/
|
||||
protected boolean checkSchemeOnly(String uri, String scheme) {
|
||||
return uri.equals(scheme + ":");
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@code MalformedURLException} to be thrown when the
|
||||
* URI scheme is not supported.
|
||||
*
|
||||
* @param uri the URI string
|
||||
* @return a {@link MalformedURLException}
|
||||
*/
|
||||
protected MalformedURLException newInvalidURISchemeException(String uri) {
|
||||
return new MalformedURLException("Invalid URI scheme: " + uri);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether fragments are supported.
|
||||
* @implSpec
|
||||
* The default implementation of this method retturns false, always.
|
||||
* @return true if fragments are supported.
|
||||
*/
|
||||
protected boolean acceptsFragment() {
|
||||
return parseMode() == ParseMode.LEGACY;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parses a URI string and sets this object's fields accordingly.
|
||||
* Legacy parsing mode.
|
||||
*/
|
||||
private void parseLegacy(String uri) throws MalformedURLException {
|
||||
int i; // index into URI
|
||||
|
||||
i = uri.indexOf(':'); // parse scheme
|
||||
if (i < 0) {
|
||||
throw new MalformedURLException("Invalid URI: " + uri);
|
||||
}
|
||||
scheme = uri.substring(0, i);
|
||||
i++; // skip past ":"
|
||||
|
||||
hasAuthority = uri.startsWith("//", i);
|
||||
if (hasAuthority) { // parse "//host:port"
|
||||
i += 2; // skip past "//"
|
||||
int slash = uri.indexOf('/', i);
|
||||
if (slash < 0) {
|
||||
slash = uri.length();
|
||||
}
|
||||
if (uri.startsWith("[", i)) { // at IPv6 literal
|
||||
int brac = uri.indexOf(']', i + 1);
|
||||
if (brac < 0 || brac > slash) {
|
||||
throw new MalformedURLException("Invalid URI: " + uri);
|
||||
}
|
||||
host = uri.substring(i, brac + 1); // include brackets
|
||||
i = brac + 1; // skip past "[...]"
|
||||
} else { // at host name or IPv4
|
||||
int colon = uri.indexOf(':', i);
|
||||
int hostEnd = (colon < 0 || colon > slash)
|
||||
? slash
|
||||
: colon;
|
||||
if (i < hostEnd) {
|
||||
host = uri.substring(i, hostEnd);
|
||||
}
|
||||
i = hostEnd; // skip past host
|
||||
}
|
||||
|
||||
if ((i + 1 < slash) &&
|
||||
uri.startsWith(":", i)) { // parse port
|
||||
i++; // skip past ":"
|
||||
port = Integer.parseInt(uri.substring(i, slash));
|
||||
}
|
||||
i = slash; // skip to path
|
||||
}
|
||||
int qmark = uri.indexOf('?', i); // look for query
|
||||
if (qmark < 0) {
|
||||
path = uri.substring(i);
|
||||
} else {
|
||||
path = uri.substring(i, qmark);
|
||||
query = uri.substring(qmark);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// Debug
|
||||
public static void main(String args[]) throws MalformedURLException {
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
Uri uri = new Uri(args[i]);
|
||||
|
||||
String h = (uri.getHost() != null) ? uri.getHost() : "";
|
||||
String p = (uri.getPort() != -1) ? (":" + uri.getPort()) : "";
|
||||
String a = uri.hasAuthority ? ("//" + h + p) : "";
|
||||
String q = (uri.getQuery() != null) ? uri.getQuery() : "";
|
||||
|
||||
String str = uri.getScheme() + ":" + a + uri.getPath() + q;
|
||||
if (! uri.toString().equals(str)) {
|
||||
System.out.println(str);
|
||||
}
|
||||
System.out.println(h);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
117
jdkSrc/jdk8/com/sun/jndi/toolkit/url/UrlUtil.java
Normal file
117
jdkSrc/jdk8/com/sun/jndi/toolkit/url/UrlUtil.java
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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 General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.jndi.toolkit.url;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
|
||||
/**
|
||||
* Utilities for dealing with URLs.
|
||||
* @author Vincent Ryan
|
||||
*/
|
||||
|
||||
final public class UrlUtil {
|
||||
|
||||
// To prevent creation of this static class
|
||||
private UrlUtil() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a URI string (according to RFC 2396).
|
||||
*/
|
||||
public static final String decode(String s) throws MalformedURLException {
|
||||
try {
|
||||
return decode(s, "8859_1");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
// ISO-Latin-1 should always be available?
|
||||
throw new MalformedURLException("ISO-Latin-1 decoder unavailable");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a URI string (according to RFC 2396).
|
||||
*
|
||||
* Three-character sequences '%xy', where 'xy' is the two-digit
|
||||
* hexadecimal representation of the lower 8-bits of a character,
|
||||
* are decoded into the character itself.
|
||||
*
|
||||
* The string is subsequently converted using the specified encoding
|
||||
*/
|
||||
public static final String decode(String s, String enc)
|
||||
throws MalformedURLException, UnsupportedEncodingException {
|
||||
try {
|
||||
return URLDecoder.decode(s, enc);
|
||||
} catch (IllegalArgumentException iae) {
|
||||
MalformedURLException mue = new MalformedURLException("Invalid URI encoding: " + s);
|
||||
mue.initCause(iae);
|
||||
throw mue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode a string for inclusion in a URI (according to RFC 2396).
|
||||
*
|
||||
* Unsafe characters are escaped by encoding them in three-character
|
||||
* sequences '%xy', where 'xy' is the two-digit hexadecimal representation
|
||||
* of the lower 8-bits of the character.
|
||||
*
|
||||
* The question mark '?' character is also escaped, as required by RFC 2255.
|
||||
*
|
||||
* The string is first converted to the specified encoding.
|
||||
* For LDAP (2255), the encoding must be UTF-8.
|
||||
*/
|
||||
public static final String encode(String s, String enc)
|
||||
throws UnsupportedEncodingException {
|
||||
|
||||
byte[] bytes = s.getBytes(enc);
|
||||
int count = bytes.length;
|
||||
|
||||
/*
|
||||
* From RFC 2396:
|
||||
*
|
||||
* mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")"
|
||||
* reserved = ";" | "/" | ":" | "?" | "@" | "&" | "=" | "+" | "$" | ","
|
||||
*/
|
||||
final String allowed = "=,+;.'-@&/$_()!~*:"; // '?' is omitted
|
||||
char[] buf = new char[3 * count];
|
||||
int j = 0;
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
if ((bytes[i] >= 0x61 && bytes[i] <= 0x7A) || // a..z
|
||||
(bytes[i] >= 0x41 && bytes[i] <= 0x5A) || // A..Z
|
||||
(bytes[i] >= 0x30 && bytes[i] <= 0x39) || // 0..9
|
||||
(allowed.indexOf(bytes[i]) >= 0)) {
|
||||
buf[j++] = (char) bytes[i];
|
||||
} else {
|
||||
buf[j++] = '%';
|
||||
buf[j++] = Character.forDigit(0xF & (bytes[i] >>> 4), 16);
|
||||
buf[j++] = Character.forDigit(0xF & bytes[i], 16);
|
||||
}
|
||||
}
|
||||
return new String(buf, 0, j);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user