2 // ========================================================================
3 // Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
4 // ------------------------------------------------------------------------
5 // All rights reserved. This program and the accompanying materials
6 // are made available under the terms of the Eclipse Public License v1.0
7 // and Apache License v2.0 which accompanies this distribution.
9 // The Eclipse Public License is available at
10 // http://www.eclipse.org/legal/epl-v10.html
12 // The Apache License v2.0 is available at
13 // http://www.opensource.org/licenses/apache2.0.php
15 // You may elect to redistribute this code under either of these licenses.
16 // ========================================================================
19 package org.eclipse.jetty.util.resource;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.net.MalformedURLException;
26 import java.net.URLConnection;
27 import java.nio.channels.ReadableByteChannel;
28 import java.security.Permission;
30 import org.eclipse.jetty.util.URIUtil;
31 import org.eclipse.jetty.util.log.Log;
32 import org.eclipse.jetty.util.log.Logger;
34 /* ------------------------------------------------------------ */
35 /** Abstract resource class.
37 public class URLResource extends Resource
39 private static final Logger LOG = Log.getLogger(URLResource.class);
40 protected final URL _url;
41 protected final String _urlString;
43 protected URLConnection _connection;
44 protected InputStream _in=null;
45 transient boolean _useCaches = Resource.__defaultUseCaches;
47 /* ------------------------------------------------------------ */
48 protected URLResource(URL url, URLConnection connection)
51 _urlString=_url.toExternalForm();
52 _connection=connection;
55 /* ------------------------------------------------------------ */
56 protected URLResource (URL url, URLConnection connection, boolean useCaches)
58 this (url, connection);
59 _useCaches = useCaches;
62 /* ------------------------------------------------------------ */
63 protected synchronized boolean checkConnection()
65 if (_connection==null)
68 _connection=_url.openConnection();
69 _connection.setUseCaches(_useCaches);
76 return _connection!=null;
79 /* ------------------------------------------------------------ */
80 /** Release any resources held by the resource.
83 public synchronized void close()
87 try{_in.close();}catch(IOException e){LOG.ignore(e);}
91 if (_connection!=null)
95 /* ------------------------------------------------------------ */
97 * Returns true if the represented resource exists.
100 public boolean exists()
106 if (checkConnection() && _in==null )
107 _in = _connection.getInputStream();
110 catch (IOException e)
117 /* ------------------------------------------------------------ */
119 * Returns true if the represented resource is a container/directory.
120 * If the resource is not a file, resources ending with "/" are
121 * considered directories.
124 public boolean isDirectory()
126 return exists() && _urlString.endsWith("/");
130 /* ------------------------------------------------------------ */
132 * Returns the last modified time
135 public long lastModified()
137 if (checkConnection())
138 return _connection.getLastModified();
143 /* ------------------------------------------------------------ */
145 * Return the length of the resource
150 if (checkConnection())
151 return _connection.getContentLength();
155 /* ------------------------------------------------------------ */
157 * Returns an URL representing the given resource
165 /* ------------------------------------------------------------ */
167 * Returns an File representing the given resource or NULL if this
171 public File getFile()
174 // Try the permission hack
175 if (checkConnection())
177 Permission perm = _connection.getPermission();
178 if (perm instanceof java.io.FilePermission)
179 return new File(perm.getName());
182 // Try the URL file arg
183 try {return new File(_url.getFile());}
184 catch(Exception e) {LOG.ignore(e);}
186 // Don't know the file
190 /* ------------------------------------------------------------ */
192 * Returns the name of the resource
195 public String getName()
197 return _url.toExternalForm();
201 /* ------------------------------------------------------------ */
203 * Returns an input stream to the resource. The underlying
204 * url connection will be nulled out to prevent re-use.
207 public synchronized InputStream getInputStream()
208 throws java.io.IOException
210 return getInputStream (true); //backwards compatibility
215 /* ------------------------------------------------------------ */
217 * Returns an input stream to the resource, optionally nulling
218 * out the underlying url connection. If the connection is not
219 * nulled out, a subsequent call to getInputStream() may return
220 * an existing and already in-use input stream - this depends on
221 * the url protocol. Eg JarURLConnection does not reuse inputstreams.
223 * @param resetConnection if true the connection field is set to null
225 protected synchronized InputStream getInputStream(boolean resetConnection)
226 throws java.io.IOException
228 if (!checkConnection())
229 throw new IOException( "Invalid resource");
235 InputStream in = _in;
239 return _connection.getInputStream();
246 if (LOG.isDebugEnabled()) LOG.debug("Connection nulled");
251 /* ------------------------------------------------------------ */
253 public ReadableByteChannel getReadableByteChannel() throws IOException
258 /* ------------------------------------------------------------ */
260 * Deletes the given resource
263 public boolean delete()
264 throws SecurityException
266 throw new SecurityException( "Delete not supported");
269 /* ------------------------------------------------------------ */
271 * Rename the given resource
274 public boolean renameTo( Resource dest)
275 throws SecurityException
277 throw new SecurityException( "RenameTo not supported");
280 /* ------------------------------------------------------------ */
282 * Returns a list of resource names contained in the given resource
285 public String[] list()
290 /* ------------------------------------------------------------ */
292 * Returns the resource contained inside the current resource with the
296 public Resource addPath(String path)
297 throws IOException,MalformedURLException
302 path = URIUtil.canonicalPath(path);
304 return newResource(URIUtil.addPaths(_url.toExternalForm(),URIUtil.encodePath(path)), _useCaches);
307 /* ------------------------------------------------------------ */
309 public String toString()
314 /* ------------------------------------------------------------ */
316 public int hashCode()
318 return _urlString.hashCode();
321 /* ------------------------------------------------------------ */
323 public boolean equals( Object o)
325 return o instanceof URLResource && _urlString.equals(((URLResource)o)._urlString);
328 /* ------------------------------------------------------------ */
329 public boolean getUseCaches ()
334 /* ------------------------------------------------------------ */
336 public boolean isContainedIn (Resource containingResource) throws MalformedURLException