001: /*
002: * Copyright 1999,2004 The Apache Software Foundation.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.apache.naming.resources;
018:
019: import java.net.URL;
020: import java.net.URLConnection;
021: import java.io.IOException;
022: import java.io.InputStream;
023: import java.io.FileNotFoundException;
024: import java.security.Permission;
025: import java.util.Date;
026: import java.util.Enumeration;
027: import java.util.Vector;
028: import javax.naming.NamingException;
029: import javax.naming.NamingEnumeration;
030: import javax.naming.NameClassPair;
031: import javax.naming.directory.DirContext;
032: import javax.naming.directory.Attribute;
033: import javax.naming.directory.Attributes;
034: import org.apache.naming.JndiPermission;
035: import org.apache.naming.resources.Resource;
036: import org.apache.naming.resources.ResourceAttributes;
037:
038: /**
039: * Connection to a JNDI directory context.
040: * <p/>
041: * Note: All the object attribute names are the WebDAV names, not the HTTP
042: * names, so this class overrides some methods from URLConnection to do the
043: * queries using the right names. Content handler is also not used; the
044: * content is directly returned.
045: *
046: * @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
047: * @version $Revision: 1.2 $
048: */
049: public class DirContextURLConnection extends URLConnection {
050:
051: // ----------------------------------------------------------- Constructors
052:
053: public DirContextURLConnection(DirContext context, URL url) {
054: super (url);
055: if (context == null)
056: throw new IllegalArgumentException(
057: "Directory context can't be null");
058: if (System.getSecurityManager() != null) {
059: this .permission = new JndiPermission(url.toString());
060: }
061: this .context = context;
062: }
063:
064: // ----------------------------------------------------- Instance Variables
065:
066: /**
067: * Directory context.
068: */
069: protected DirContext context;
070:
071: /**
072: * Associated resource.
073: */
074: protected Resource resource;
075:
076: /**
077: * Associated DirContext.
078: */
079: protected DirContext collection;
080:
081: /**
082: * Other unknown object.
083: */
084: protected Object object;
085:
086: /**
087: * Attributes.
088: */
089: protected Attributes attributes;
090:
091: /**
092: * Date.
093: */
094: protected long date;
095:
096: /**
097: * Permission
098: */
099: protected Permission permission;
100:
101: // ------------------------------------------------------------- Properties
102:
103: /**
104: * Connect to the DirContext, and retrive the bound object, as well as
105: * its attributes. If no object is bound with the name specified in the
106: * URL, then an IOException is thrown.
107: *
108: * @throws IOException Object not found
109: */
110: public void connect() throws IOException {
111:
112: if (!connected) {
113:
114: try {
115: date = System.currentTimeMillis();
116: String path = getURL().getFile();
117: if (context instanceof ProxyDirContext) {
118: ProxyDirContext proxyDirContext = (ProxyDirContext) context;
119: String hostName = proxyDirContext.getHostName();
120: String contextName = proxyDirContext
121: .getContextName();
122: if (hostName != null) {
123: if (!path.startsWith("/" + hostName + "/"))
124: return;
125: path = path.substring(hostName.length() + 1);
126: }
127: if (contextName != null) {
128: if (!path.startsWith(contextName + "/")) {
129: return;
130: } else {
131: path = path.substring(contextName.length());
132: }
133: }
134: }
135: object = context.lookup(path);
136: attributes = context.getAttributes(path);
137: if (object instanceof Resource)
138: resource = (Resource) object;
139: if (object instanceof DirContext)
140: collection = (DirContext) object;
141: } catch (NamingException e) {
142: // Object not found
143: }
144:
145: connected = true;
146:
147: }
148:
149: }
150:
151: /**
152: * Return the content length value.
153: */
154: public int getContentLength() {
155: return getHeaderFieldInt(ResourceAttributes.CONTENT_LENGTH, -1);
156: }
157:
158: /**
159: * Return the content type value.
160: */
161: public String getContentType() {
162: return getHeaderField(ResourceAttributes.CONTENT_TYPE);
163: }
164:
165: /**
166: * Return the last modified date.
167: */
168: public long getDate() {
169: return date;
170: }
171:
172: /**
173: * Return the last modified date.
174: */
175: public long getLastModified() {
176:
177: if (!connected) {
178: // Try to connect (silently)
179: try {
180: connect();
181: } catch (IOException e) {
182: }
183: }
184:
185: if (attributes == null)
186: return 0;
187:
188: Attribute lastModified = attributes
189: .get(ResourceAttributes.LAST_MODIFIED);
190: if (lastModified != null) {
191: try {
192: Date lmDate = (Date) lastModified.get();
193: return lmDate.getTime();
194: } catch (Exception e) {
195: }
196: }
197:
198: return 0;
199: }
200:
201: /**
202: * Returns the name of the specified header field.
203: */
204: public String getHeaderField(String name) {
205:
206: if (!connected) {
207: // Try to connect (silently)
208: try {
209: connect();
210: } catch (IOException e) {
211: }
212: }
213:
214: if (attributes == null)
215: return (null);
216:
217: Attribute attribute = attributes.get(name);
218: try {
219: return attribute.get().toString();
220: } catch (Exception e) {
221: // Shouldn't happen, unless the attribute has no value
222: }
223:
224: return (null);
225:
226: }
227:
228: /**
229: * Get object content.
230: */
231: public Object getContent() throws IOException {
232:
233: if (!connected)
234: connect();
235:
236: if (resource != null)
237: return getInputStream();
238: if (collection != null)
239: return collection;
240: if (object != null)
241: return object;
242:
243: throw new FileNotFoundException();
244:
245: }
246:
247: /**
248: * Get object content.
249: */
250: public Object getContent(Class[] classes) throws IOException {
251:
252: Object object = getContent();
253:
254: for (int i = 0; i < classes.length; i++) {
255: if (classes[i].isInstance(object))
256: return object;
257: }
258:
259: return null;
260:
261: }
262:
263: /**
264: * Get input stream.
265: */
266: public InputStream getInputStream() throws IOException {
267:
268: if (!connected)
269: connect();
270:
271: if (resource == null) {
272: throw new FileNotFoundException();
273: } else {
274: // Reopen resource
275: try {
276: resource = (Resource) context
277: .lookup(getURL().getFile());
278: } catch (NamingException e) {
279: }
280: }
281:
282: return (resource.streamContent());
283:
284: }
285:
286: /**
287: * Get the Permission for this URL
288: */
289: public Permission getPermission() {
290:
291: return permission;
292: }
293:
294: // --------------------------------------------------------- Public Methods
295:
296: /**
297: * List children of this collection. The names given are relative to this
298: * URI's path. The full uri of the children is then : path + "/" + name.
299: */
300: public Enumeration list()
301: throws IOException {
302:
303: if (!connected) {
304: connect();
305: }
306:
307: if ((resource == null) && (collection == null)) {
308: throw new FileNotFoundException();
309: }
310:
311: Vector result = new Vector();
312:
313: if (collection != null) {
314: try {
315: NamingEnumeration enum = context.list(getURL().getFile());
316: while (enum.hasMoreElements()) {
317: NameClassPair ncp = (NameClassPair) enum.nextElement();
318: result.addElement(ncp.getName());
319: }
320: } catch (NamingException e) {
321: // Unexpected exception
322: throw new FileNotFoundException();
323: }
324: }
325:
326: return result.elements();
327:
328: }
329:
330: }
|