001: // ========================================================================
002: // Copyright 1996-2005 Mort Bay Consulting Pty. Ltd.
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: // http://www.apache.org/licenses/LICENSE-2.0
008: // Unless required by applicable law or agreed to in writing, software
009: // distributed under the License is distributed on an "AS IS" BASIS,
010: // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
011: // See the License for the specific language governing permissions and
012: // limitations under the License.
013: // ========================================================================
014: package org.mortbay.resource;
015:
016: import java.io.File;
017: import java.io.IOException;
018: import java.io.InputStream;
019: import java.io.OutputStream;
020: import java.net.MalformedURLException;
021: import java.net.URL;
022: import java.net.URLConnection;
023: import java.security.Permission;
024:
025: import org.mortbay.log.Log;
026: import org.mortbay.util.URIUtil;
027:
028: /* ------------------------------------------------------------ */
029: /** Abstract resource class.
030: *
031: * @author Nuno Pregui�a
032: * @author Greg Wilkins (gregw)
033: */
034: public class URLResource extends Resource {
035:
036: protected URL _url;
037: protected String _urlString;
038: protected transient URLConnection _connection;
039: protected transient InputStream _in = null;
040: transient boolean _useCaches = Resource.__defaultUseCaches;
041:
042: /* ------------------------------------------------------------ */
043: protected URLResource(URL url, URLConnection connection) {
044: _url = url;
045: _urlString = _url.toString();
046: _connection = connection;
047: }
048:
049: protected URLResource(URL url, URLConnection connection,
050: boolean useCaches) {
051: this (url, connection);
052: _useCaches = useCaches;
053: }
054:
055: /* ------------------------------------------------------------ */
056: protected synchronized boolean checkConnection() {
057: if (_connection == null) {
058: try {
059: _connection = _url.openConnection();
060: _connection.setUseCaches(_useCaches);
061: } catch (IOException e) {
062: Log.ignore(e);
063: }
064: }
065: return _connection != null;
066: }
067:
068: /* ------------------------------------------------------------ */
069: /** Release any resources held by the resource.
070: */
071: public synchronized void release() {
072: if (_in != null) {
073: try {
074: _in.close();
075: } catch (IOException e) {
076: Log.ignore(e);
077: }
078: _in = null;
079: }
080:
081: if (_connection != null)
082: _connection = null;
083: }
084:
085: /* ------------------------------------------------------------ */
086: /**
087: * Returns true if the respresened resource exists.
088: */
089: public boolean exists() {
090: try {
091: synchronized (this ) {
092: if (checkConnection() && _in == null)
093: _in = _connection.getInputStream();
094: }
095: } catch (IOException e) {
096: Log.ignore(e);
097: }
098: return _in != null;
099: }
100:
101: /* ------------------------------------------------------------ */
102: /**
103: * Returns true if the respresenetd resource is a container/directory.
104: * If the resource is not a file, resources ending with "/" are
105: * considered directories.
106: */
107: public boolean isDirectory() {
108: return exists() && _url.toString().endsWith("/");
109: }
110:
111: /* ------------------------------------------------------------ */
112: /**
113: * Returns the last modified time
114: */
115: public long lastModified() {
116: if (checkConnection())
117: return _connection.getLastModified();
118: return -1;
119: }
120:
121: /* ------------------------------------------------------------ */
122: /**
123: * Return the length of the resource
124: */
125: public long length() {
126: if (checkConnection())
127: return _connection.getContentLength();
128: return -1;
129: }
130:
131: /* ------------------------------------------------------------ */
132: /**
133: * Returns an URL representing the given resource
134: */
135: public URL getURL() {
136: return _url;
137: }
138:
139: /* ------------------------------------------------------------ */
140: /**
141: * Returns an File representing the given resource or NULL if this
142: * is not possible.
143: */
144: public File getFile() throws IOException {
145: // Try the permission hack
146: if (checkConnection()) {
147: Permission perm = _connection.getPermission();
148: if (perm instanceof java.io.FilePermission)
149: return new File(perm.getName());
150: }
151:
152: // Try the URL file arg
153: try {
154: return new File(_url.getFile());
155: } catch (Exception e) {
156: Log.ignore(e);
157: }
158:
159: // Don't know the file
160: return null;
161: }
162:
163: /* ------------------------------------------------------------ */
164: /**
165: * Returns the name of the resource
166: */
167: public String getName() {
168: return _url.toExternalForm();
169: }
170:
171: /* ------------------------------------------------------------ */
172: /**
173: * Returns an input stream to the resource
174: */
175: public synchronized InputStream getInputStream()
176: throws java.io.IOException {
177: if (!checkConnection())
178: throw new IOException("Invalid resource");
179:
180: try {
181: if (_in != null) {
182: InputStream in = _in;
183: _in = null;
184: return in;
185: }
186: return _connection.getInputStream();
187: } finally {
188: _connection = null;
189: }
190: }
191:
192: /* ------------------------------------------------------------ */
193: /**
194: * Returns an output stream to the resource
195: */
196: public OutputStream getOutputStream() throws java.io.IOException,
197: SecurityException {
198: throw new IOException("Output not supported");
199: }
200:
201: /* ------------------------------------------------------------ */
202: /**
203: * Deletes the given resource
204: */
205: public boolean delete() throws SecurityException {
206: throw new SecurityException("Delete not supported");
207: }
208:
209: /* ------------------------------------------------------------ */
210: /**
211: * Rename the given resource
212: */
213: public boolean renameTo(Resource dest) throws SecurityException {
214: throw new SecurityException("RenameTo not supported");
215: }
216:
217: /* ------------------------------------------------------------ */
218: /**
219: * Returns a list of resource names contained in the given resource
220: */
221: public String[] list() {
222: return null;
223: }
224:
225: /* ------------------------------------------------------------ */
226: /**
227: * Returns the resource contained inside the current resource with the
228: * given name
229: */
230: public Resource addPath(String path) throws IOException,
231: MalformedURLException {
232: if (path == null)
233: return null;
234:
235: path = URIUtil.canonicalPath(path);
236:
237: return newResource(URIUtil
238: .addPaths(_url.toExternalForm(), path));
239: }
240:
241: /* ------------------------------------------------------------ */
242: public String toString() {
243: return _urlString;
244: }
245:
246: /* ------------------------------------------------------------ */
247: public int hashCode() {
248: return _url.hashCode();
249: }
250:
251: /* ------------------------------------------------------------ */
252: public boolean equals(Object o) {
253: return o instanceof URLResource
254: && _url.equals(((URLResource) o)._url);
255: }
256:
257: public boolean getUseCaches() {
258: return _useCaches;
259: }
260: }
|