001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package org.apache.naming.resources;
019:
020: import java.io.IOException;
021: import java.net.URL;
022: import java.net.URLConnection;
023: import java.net.URLStreamHandler;
024: import java.util.Hashtable;
025:
026: import javax.naming.directory.DirContext;
027:
028: /**
029: * Stream handler to a JNDI directory context.
030: *
031: * @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
032: * @version $Revision: 467222 $
033: */
034: public class DirContextURLStreamHandler extends URLStreamHandler {
035:
036: // ----------------------------------------------------------- Constructors
037:
038: public DirContextURLStreamHandler() {
039: }
040:
041: public DirContextURLStreamHandler(DirContext context) {
042: this .context = context;
043: }
044:
045: // -------------------------------------------------------------- Variables
046:
047: /**
048: * Bindings class loader - directory context. Keyed by CL id.
049: */
050: private static Hashtable clBindings = new Hashtable();
051:
052: /**
053: * Bindings thread - directory context. Keyed by thread id.
054: */
055: private static Hashtable threadBindings = new Hashtable();
056:
057: // ----------------------------------------------------- Instance Variables
058:
059: /**
060: * Directory context.
061: */
062: protected DirContext context = null;
063:
064: // ------------------------------------------------------------- Properties
065:
066: // ----------------------------------------------- URLStreamHandler Methods
067:
068: /**
069: * Opens a connection to the object referenced by the <code>URL</code>
070: * argument.
071: */
072: protected URLConnection openConnection(URL u) throws IOException {
073: DirContext currentContext = this .context;
074: if (currentContext == null)
075: currentContext = get();
076: return new DirContextURLConnection(currentContext, u);
077: }
078:
079: // ------------------------------------------------------------ URL Methods
080:
081: /**
082: * Override as part of the fix for 36534, to ensure toString is correct.
083: */
084: protected String toExternalForm(URL u) {
085: // pre-compute length of StringBuffer
086: int len = u.getProtocol().length() + 1;
087: if (u.getPath() != null) {
088: len += u.getPath().length();
089: }
090: if (u.getQuery() != null) {
091: len += 1 + u.getQuery().length();
092: }
093: if (u.getRef() != null)
094: len += 1 + u.getRef().length();
095: StringBuffer result = new StringBuffer(len);
096: result.append(u.getProtocol());
097: result.append(":");
098: if (u.getPath() != null) {
099: result.append(u.getPath());
100: }
101: if (u.getQuery() != null) {
102: result.append('?');
103: result.append(u.getQuery());
104: }
105: if (u.getRef() != null) {
106: result.append("#");
107: result.append(u.getRef());
108: }
109: return result.toString();
110: }
111:
112: // --------------------------------------------------------- Public Methods
113:
114: /**
115: * Set the java.protocol.handler.pkgs system property.
116: */
117: public static void setProtocolHandler() {
118: String value = System
119: .getProperty(Constants.PROTOCOL_HANDLER_VARIABLE);
120: if (value == null) {
121: value = Constants.Package;
122: System.setProperty(Constants.PROTOCOL_HANDLER_VARIABLE,
123: value);
124: } else if (value.indexOf(Constants.Package) == -1) {
125: value += "|" + Constants.Package;
126: System.setProperty(Constants.PROTOCOL_HANDLER_VARIABLE,
127: value);
128: }
129: }
130:
131: /**
132: * Returns true if the thread or the context class loader of the current
133: * thread is bound.
134: */
135: public static boolean isBound() {
136: return (clBindings.containsKey(Thread.currentThread()
137: .getContextClassLoader()))
138: || (threadBindings.containsKey(Thread.currentThread()));
139: }
140:
141: /**
142: * Binds a directory context to a class loader.
143: */
144: public static void bind(DirContext dirContext) {
145: ClassLoader currentCL = Thread.currentThread()
146: .getContextClassLoader();
147: if (currentCL != null)
148: clBindings.put(currentCL, dirContext);
149: }
150:
151: /**
152: * Unbinds a directory context to a class loader.
153: */
154: public static void unbind() {
155: ClassLoader currentCL = Thread.currentThread()
156: .getContextClassLoader();
157: if (currentCL != null)
158: clBindings.remove(currentCL);
159: }
160:
161: /**
162: * Binds a directory context to a thread.
163: */
164: public static void bindThread(DirContext dirContext) {
165: threadBindings.put(Thread.currentThread(), dirContext);
166: }
167:
168: /**
169: * Unbinds a directory context to a thread.
170: */
171: public static void unbindThread() {
172: threadBindings.remove(Thread.currentThread());
173: }
174:
175: /**
176: * Get the bound context.
177: */
178: public static DirContext get() {
179:
180: DirContext result = null;
181:
182: Thread currentThread = Thread.currentThread();
183: ClassLoader currentCL = currentThread.getContextClassLoader();
184:
185: // Checking CL binding
186: result = (DirContext) clBindings.get(currentCL);
187: if (result != null)
188: return result;
189:
190: // Checking thread biding
191: result = (DirContext) threadBindings.get(currentThread);
192:
193: // Checking parent CL binding
194: currentCL = currentCL.getParent();
195: while (currentCL != null) {
196: result = (DirContext) clBindings.get(currentCL);
197: if (result != null)
198: return result;
199: currentCL = currentCL.getParent();
200: }
201:
202: if (result == null)
203: throw new IllegalStateException(
204: "Illegal class loader binding");
205:
206: return result;
207:
208: }
209:
210: /**
211: * Binds a directory context to a class loader.
212: */
213: public static void bind(ClassLoader cl, DirContext dirContext) {
214: clBindings.put(cl, dirContext);
215: }
216:
217: /**
218: * Unbinds a directory context to a class loader.
219: */
220: public static void unbind(ClassLoader cl) {
221: clBindings.remove(cl);
222: }
223:
224: /**
225: * Get the bound context.
226: */
227: public static DirContext get(ClassLoader cl) {
228: return (DirContext) clBindings.get(cl);
229: }
230:
231: /**
232: * Get the bound context.
233: */
234: public static DirContext get(Thread thread) {
235: return (DirContext) threadBindings.get(thread);
236: }
237:
238: }
|