View Javadoc

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