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