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