View Javadoc

1   // ========================================================================
2   // Copyright (c) 1996-2009 Mort Bay Consulting Pty. Ltd.
3   // ------------------------------------------------------------------------
4   // All rights reserved. This program and the accompanying materials
5   // are made available under the terms of the Eclipse Public License v1.0
6   // and Apache License v2.0 which accompanies this distribution.
7   // The Eclipse Public License is available at 
8   // http://www.eclipse.org/legal/epl-v10.html
9   // The Apache License v2.0 is available at
10  // http://www.opensource.org/licenses/apache2.0.php
11  // You may elect to redistribute this code under either of these licenses. 
12  // ========================================================================
13  package org.eclipse.jetty.util.resource;
14  
15  import java.io.File;
16  import java.io.IOException;
17  import java.io.InputStream;
18  import java.io.OutputStream;
19  import java.net.MalformedURLException;
20  import java.net.URL;
21  import java.net.URLConnection;
22  import java.security.Permission;
23  
24  import org.eclipse.jetty.util.URIUtil;
25  import org.eclipse.jetty.util.log.Log;
26  import org.eclipse.jetty.util.log.Logger;
27  
28  /* ------------------------------------------------------------ */
29  /** Abstract resource class.
30   */
31  public class URLResource extends Resource
32  {
33      private static final Logger LOG = Log.getLogger(URLResource.class);
34      protected URL _url;
35      protected String _urlString;
36      
37      protected URLConnection _connection;
38      protected InputStream _in=null;
39      transient boolean _useCaches = Resource.__defaultUseCaches;
40      
41      /* ------------------------------------------------------------ */
42      protected URLResource(URL url, URLConnection connection)
43      {
44          _url = url;
45          _urlString=_url.toString();
46          _connection=connection;
47      }
48      
49      /* ------------------------------------------------------------ */
50      protected URLResource (URL url, URLConnection connection, boolean useCaches)
51      {
52          this (url, connection);
53          _useCaches = useCaches;
54      }
55  
56      /* ------------------------------------------------------------ */
57      protected synchronized boolean checkConnection()
58      {
59          if (_connection==null)
60          {
61              try{
62                  _connection=_url.openConnection();
63                  _connection.setUseCaches(_useCaches);
64              }
65              catch(IOException e)
66              {
67                  LOG.ignore(e);
68              }
69          }
70          return _connection!=null;
71      }
72  
73      /* ------------------------------------------------------------ */
74      /** Release any resources held by the resource.
75       */
76      @Override
77      public synchronized void release()
78      {
79          if (_in!=null)
80          {
81              try{_in.close();}catch(IOException e){LOG.ignore(e);}
82              _in=null;
83          }
84  
85          if (_connection!=null)
86              _connection=null;
87      }
88  
89      /* ------------------------------------------------------------ */
90      /**
91       * Returns true if the represented resource exists.
92       */
93      @Override
94      public boolean exists()
95      {
96          try
97          {
98              synchronized(this)
99              {
100                 if (checkConnection() && _in==null )
101                     _in = _connection.getInputStream();
102             }
103         }
104         catch (IOException e)
105         {
106             LOG.ignore(e);
107         }
108         return _in!=null;
109     }
110 
111     /* ------------------------------------------------------------ */
112     /**
113      * Returns true if the respresenetd resource is a container/directory.
114      * If the resource is not a file, resources ending with "/" are
115      * considered directories.
116      */
117     @Override
118     public boolean isDirectory()
119     {
120         return exists() && _url.toString().endsWith("/");
121     }
122 
123 
124     /* ------------------------------------------------------------ */
125     /**
126      * Returns the last modified time
127      */
128     @Override
129     public long lastModified()
130     {
131         if (checkConnection())
132             return _connection.getLastModified();
133         return -1;
134     }
135 
136 
137     /* ------------------------------------------------------------ */
138     /**
139      * Return the length of the resource
140      */
141     @Override
142     public long length()
143     {
144         if (checkConnection())
145             return _connection.getContentLength();
146         return -1;
147     }
148 
149     /* ------------------------------------------------------------ */
150     /**
151      * Returns an URL representing the given resource
152      */
153     @Override
154     public URL getURL()
155     {
156         return _url;
157     }
158 
159     /* ------------------------------------------------------------ */
160     /**
161      * Returns an File representing the given resource or NULL if this
162      * is not possible.
163      */
164     @Override
165     public File getFile()
166         throws IOException
167     {
168         // Try the permission hack
169         if (checkConnection())
170         {
171             Permission perm = _connection.getPermission();
172             if (perm instanceof java.io.FilePermission)
173                 return new File(perm.getName());
174         }
175 
176         // Try the URL file arg
177         try {return new File(_url.getFile());}
178         catch(Exception e) {LOG.ignore(e);}
179 
180         // Don't know the file
181         return null;    
182     }
183 
184     /* ------------------------------------------------------------ */
185     /**
186      * Returns the name of the resource
187      */
188     @Override
189     public String getName()
190     {
191         return _url.toExternalForm();
192     }
193 
194     /* ------------------------------------------------------------ */
195     /**
196      * Returns an input stream to the resource
197      */
198     @Override
199     public synchronized InputStream getInputStream()
200         throws java.io.IOException
201     {
202         if (!checkConnection())
203             throw new IOException( "Invalid resource");
204 
205         try
206         {    
207             if( _in != null)
208             {
209                 InputStream in = _in;
210                 _in=null;
211                 return in;
212             }
213             return _connection.getInputStream();
214         }
215         finally
216         {
217             _connection=null;
218         }
219     }
220 
221 
222     /* ------------------------------------------------------------ */
223     /**
224      * Returns an output stream to the resource
225      */
226     @Override
227     public OutputStream getOutputStream()
228         throws java.io.IOException, SecurityException
229     {
230         throw new IOException( "Output not supported");
231     }
232 
233     /* ------------------------------------------------------------ */
234     /**
235      * Deletes the given resource
236      */
237     @Override
238     public boolean delete()
239         throws SecurityException
240     {
241         throw new SecurityException( "Delete not supported");
242     }
243 
244     /* ------------------------------------------------------------ */
245     /**
246      * Rename the given resource
247      */
248     @Override
249     public boolean renameTo( Resource dest)
250         throws SecurityException
251     {
252         throw new SecurityException( "RenameTo not supported");
253     }
254 
255     /* ------------------------------------------------------------ */
256     /**
257      * Returns a list of resource names contained in the given resource
258      */
259     @Override
260     public String[] list()
261     {
262         return null;
263     }
264 
265     /* ------------------------------------------------------------ */
266     /**
267      * Returns the resource contained inside the current resource with the
268      * given name
269      */
270     @Override
271     public Resource addPath(String path)
272         throws IOException,MalformedURLException
273     {
274         if (path==null)
275             return null;
276 
277         path = URIUtil.canonicalPath(path);
278 
279         return newResource(URIUtil.addPaths(_url.toExternalForm(),path));
280     }
281 
282     /* ------------------------------------------------------------ */
283     @Override
284     public String toString()
285     {
286         return _urlString;
287     }
288 
289     /* ------------------------------------------------------------ */
290     @Override
291     public int hashCode()
292     {
293         return _url.hashCode();
294     }
295     
296     /* ------------------------------------------------------------ */
297     @Override
298     public boolean equals( Object o)
299     {
300         return o instanceof URLResource &&
301             _url.equals(((URLResource)o)._url);
302     }
303 
304     public boolean getUseCaches ()
305     {
306         return _useCaches;
307     }
308     
309     @Override
310     public boolean isContainedIn (Resource containingResource) throws MalformedURLException
311     {
312         return false; //TODO gregw check this!
313     }
314 }