View Javadoc

1   // ========================================================================
2   // Copyright (c) 2007-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  
14  package org.eclipse.jetty.util.resource;
15  
16  import java.io.File;
17  import java.io.IOException;
18  import java.io.InputStream;
19  import java.io.OutputStream;
20  import java.net.MalformedURLException;
21  import java.net.URL;
22  import java.util.ArrayList;
23  import java.util.HashSet;
24  import java.util.StringTokenizer;
25  
26  import org.eclipse.jetty.util.URIUtil;
27  
28  /**
29   * A collection of resources (dirs).
30   * Allows webapps to have multiple (static) sources.
31   * The first resource in the collection is the main resource.
32   * If a resource is not found in the main resource, it looks it up in 
33   * the order the resources were constructed.
34   * 
35   * 
36   *
37   */
38  public class ResourceCollection extends Resource
39  {
40      
41      private Resource[] _resources;
42      
43      public ResourceCollection()
44      {
45          
46      }
47      
48      /* ------------------------------------------------------------ */
49      public ResourceCollection(Resource[] resources)
50      {
51          setResources(resources);
52      }
53      
54      /* ------------------------------------------------------------ */
55      public ResourceCollection(String[] resources)
56      {
57          setResources(resources);
58      }
59      
60      /* ------------------------------------------------------------ */
61      public ResourceCollection(String csvResources)
62      {
63          setResources(csvResources);
64      }
65      
66      /* ------------------------------------------------------------ */
67      /**
68       * 
69       * @param resources Resource array
70       */
71      public void setResources(Resource[] resources)
72      {
73          if(_resources!=null)
74              throw new IllegalStateException("*resources* already set.");
75          
76          if(resources==null)
77              throw new IllegalArgumentException("*resources* must not be null.");
78          
79          if(resources.length==0)
80              throw new IllegalArgumentException("arg *resources* must be one or more resources.");
81          
82          _resources = resources;
83          for(Resource r : _resources)
84          {
85              if(!r.exists() || !r.isDirectory())
86                  throw new IllegalArgumentException(r + " is not an existing directory.");
87          }
88      }
89      
90      /* ------------------------------------------------------------ */
91      /**
92       * 
93       * @param resources String array
94       */
95      public void setResources(String[] resources)
96      {
97          if(_resources!=null)
98              throw new IllegalStateException("*resources* already set.");
99          
100         if(resources==null)
101             throw new IllegalArgumentException("*resources* must not be null.");
102         
103         if(resources.length==0)
104             throw new IllegalArgumentException("arg *resources* must be one or more resources.");
105         
106         _resources = new Resource[resources.length];
107         try
108         {
109             for(int i=0; i<resources.length; i++)
110             {
111                 _resources[i] = Resource.newResource(resources[i]);
112                 if(!_resources[i].exists() || !_resources[i].isDirectory())
113                     throw new IllegalArgumentException(_resources[i] + " is not an existing directory.");
114             }
115         }
116         catch(Exception e)
117         {
118             throw new RuntimeException(e);
119         }
120     }
121     
122     /* ------------------------------------------------------------ */
123     /**
124      * 
125      * @param csvResources Comma separated values
126      */
127     public void setResources(String csvResources)
128     {
129         if(_resources!=null)
130             throw new IllegalStateException("*resources* already set.");
131         
132         if(csvResources==null)
133             throw new IllegalArgumentException("*csvResources* must not be null.");
134         
135         StringTokenizer tokenizer = new StringTokenizer(csvResources, ",;");
136         int len = tokenizer.countTokens();
137         if(len==0)
138             throw new IllegalArgumentException("arg *resources* must be one or more resources.");
139         
140         _resources = new Resource[len];
141         try
142         {            
143             for(int i=0; tokenizer.hasMoreTokens(); i++)
144             {
145                 _resources[i] = Resource.newResource(tokenizer.nextToken().trim());
146                 if(!_resources[i].exists() || !_resources[i].isDirectory())
147                     throw new IllegalArgumentException(_resources[i] + " is not an existing directory.");
148             }
149         }
150         catch(Exception e)
151         {
152             throw new RuntimeException(e);
153         }
154     }
155     
156     /* ------------------------------------------------------------ */
157     /**
158      * 
159      * @param csvResources Comma separated values
160      */
161     public void setResourcesAsCSV(String csvResources)
162     {
163         setResources(csvResources);
164     }
165     
166     /* ------------------------------------------------------------ */
167     /**
168      * 
169      * @return the resource array
170      */
171     public Resource[] getResources()
172     {
173         return _resources;
174     }
175     
176     /* ------------------------------------------------------------ */
177     /**
178      * @param path The path segment to add
179      * @return The contained resource (found first) in the collection of resources
180      */
181     public Resource addPath(String path) throws IOException, MalformedURLException
182     {
183         if(_resources==null)
184             throw new IllegalStateException("*resources* not set.");
185         
186         if(path==null)
187             throw new MalformedURLException();
188         
189         if(path.length()==0 || URIUtil.SLASH.equals(path))
190             return this;
191         
192         Resource resource=null;
193         ArrayList<Resource> resources = null;
194         int i=0;
195         for(; i<_resources.length; i++)
196         {
197             resource = _resources[i].addPath(path);  
198             if (resource.exists())
199             {
200                 if (resource.isDirectory())
201                     break;       
202                 return resource;
203             }
204         }  
205 
206         for(i++; i<_resources.length; i++)
207         {
208             Resource r = _resources[i].addPath(path); 
209             if (r.exists() && r.isDirectory())
210             {
211                 if (resource!=null)
212                 {
213                     resources = new ArrayList<Resource>();
214                     resources.add(resource);
215                     resource=null;
216                 }
217                 resources.add(r);
218             }
219         }
220 
221         if (resource!=null)
222             return resource;
223         if (resources!=null)
224             return new ResourceCollection(resources.toArray(new Resource[resources.size()]));
225         return null;
226     }
227     
228     /* ------------------------------------------------------------ */
229     /**
230      * @param path
231      * @return the resource(file) if found, returns a list of resource dirs if its a dir, else null.
232      * @throws IOException
233      * @throws MalformedURLException
234      */
235     protected Object findResource(String path) throws IOException, MalformedURLException
236     {        
237         Resource resource=null;
238         ArrayList<Resource> resources = null;
239         int i=0;
240         for(; i<_resources.length; i++)
241         {
242             resource = _resources[i].addPath(path);  
243             if (resource.exists())
244             {
245                 if (resource.isDirectory())
246                     break;
247                
248                 return resource;
249             }
250         }  
251 
252         for(i++; i<_resources.length; i++)
253         {
254             Resource r = _resources[i].addPath(path); 
255             if (r.exists() && r.isDirectory())
256             {
257                 if (resource!=null)
258                 {
259                     resources = new ArrayList<Resource>();
260                     resources.add(resource);
261                 }
262                 resources.add(r);
263             }
264         }
265         
266         if (resource!=null)
267             return resource;
268         if (resources!=null)
269             return resources;
270         return null;
271     }
272     
273     /* ------------------------------------------------------------ */
274     public boolean delete() throws SecurityException
275     {
276         throw new UnsupportedOperationException();
277     }
278     
279     /* ------------------------------------------------------------ */
280     public boolean exists()
281     {
282         if(_resources==null)
283             throw new IllegalStateException("*resources* not set.");
284         
285         return true;
286     }
287     
288     /* ------------------------------------------------------------ */
289     public File getFile() throws IOException
290     {
291         if(_resources==null)
292             throw new IllegalStateException("*resources* not set.");
293         
294         for(Resource r : _resources)
295         {
296             File f = r.getFile();
297             if(f!=null)
298                 return f;
299         }
300         return null;
301     }
302     
303     /* ------------------------------------------------------------ */
304     public InputStream getInputStream() throws IOException
305     {
306         if(_resources==null)
307             throw new IllegalStateException("*resources* not set.");
308         
309         for(Resource r : _resources)
310         {
311             InputStream is = r.getInputStream();
312             if(is!=null)
313                 return is;
314         }
315         return null;
316     }
317     
318     /* ------------------------------------------------------------ */
319     public String getName()
320     {
321         if(_resources==null)
322             throw new IllegalStateException("*resources* not set.");
323         
324         for(Resource r : _resources)
325         {
326             String name = r.getName();
327             if(name!=null)
328                 return name;
329         }
330         return null;
331     }
332     
333     /* ------------------------------------------------------------ */
334     public OutputStream getOutputStream() throws IOException, SecurityException
335     {
336         if(_resources==null)
337             throw new IllegalStateException("*resources* not set.");
338         
339         for(Resource r : _resources)
340         {
341             OutputStream os = r.getOutputStream();
342             if(os!=null)
343                 return os;
344         }
345         return null;
346     }
347     
348     /* ------------------------------------------------------------ */
349     public URL getURL()
350     {
351         if(_resources==null)
352             throw new IllegalStateException("*resources* not set.");
353         
354         for(Resource r : _resources)
355         {
356             URL url = r.getURL();
357             if(url!=null)
358                 return url;
359         }
360         return null;
361     }
362     
363     /* ------------------------------------------------------------ */
364     public boolean isDirectory()
365     {
366         if(_resources==null)
367             throw new IllegalStateException("*resources* not set.");
368         
369         return true;
370     }
371     
372     /* ------------------------------------------------------------ */
373     public long lastModified()
374     {
375         if(_resources==null)
376             throw new IllegalStateException("*resources* not set.");
377         
378         for(Resource r : _resources)
379         {
380             long lm = r.lastModified();
381             if (lm!=-1)
382                 return lm;
383         }
384         return -1;
385     }
386     
387     /* ------------------------------------------------------------ */
388     public long length()
389     {
390         return -1;
391     }    
392     
393     /* ------------------------------------------------------------ */
394     /**
395      * @return The list of resource names(merged) contained in the collection of resources.
396      */    
397     public String[] list()
398     {
399         if(_resources==null)
400             throw new IllegalStateException("*resources* not set.");
401         
402         HashSet<String> set = new HashSet<String>();
403         for(Resource r : _resources)
404         {
405             for(String s : r.list())
406                 set.add(s);
407         }
408         return set.toArray(new String[set.size()]);
409     }
410     
411     /* ------------------------------------------------------------ */
412     public void release()
413     {
414         if(_resources==null)
415             throw new IllegalStateException("*resources* not set.");
416         
417         for(Resource r : _resources)
418             r.release();
419     }
420     
421     /* ------------------------------------------------------------ */
422     public boolean renameTo(Resource dest) throws SecurityException
423     {
424         throw new UnsupportedOperationException();
425     }
426     
427     /* ------------------------------------------------------------ */
428     /**
429      * @return the list of resources separated by a path separator
430      */
431     public String toString()
432     {
433         if(_resources==null)
434             throw new IllegalStateException("*resources* not set.");
435         
436         StringBuilder buffer = new StringBuilder();
437         for(Resource r : _resources)
438             buffer.append(r.toString()).append(';');
439         return buffer.toString();
440     }
441 
442 
443     public boolean isContainedIn(Resource r) throws MalformedURLException
444     {
445         // TODO could look at implementing the semantic of is this collection a subset of the Resource r?
446         return false;
447     }
448 
449 }