View Javadoc

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