//======================================================================== //Copyright 2007 Mort Bay Consulting Pty. Ltd. //------------------------------------------------------------------------ //Licensed under the Apache License, Version 2.0 (the "License"); //you may not use this file except in compliance with the License. //You may obtain a copy of the License at //http://www.apache.org/licenses/LICENSE-2.0 //Unless required by applicable law or agreed to in writing, software //distributed under the License is distributed on an "AS IS" BASIS, //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //See the License for the specific language governing permissions and //limitations under the License. //======================================================================== package org.mortbay.resource; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.HashSet; import java.util.StringTokenizer; import org.mortbay.util.URIUtil; /** * A collection of resources (dirs). * Allows webapps to have multiple (static) sources. * The first resource in the collection is the main resource. * If a resource is not found in the main resource, it looks it up in * the order the resources were constructed. * * @author dyu * */ public class ResourceCollection extends Resource { private Resource[] _resources; public ResourceCollection() { } /* ------------------------------------------------------------ */ public ResourceCollection(Resource[] resources) { setResources(resources); } /* ------------------------------------------------------------ */ public ResourceCollection(String[] resources) { setResources(resources); } /* ------------------------------------------------------------ */ public ResourceCollection(String csvResources) { setResources(csvResources); } /* ------------------------------------------------------------ */ /** * * @param resources Resource array */ public void setResources(Resource[] resources) { if(_resources!=null) throw new IllegalStateException("*resources* already set."); if(resources==null) throw new IllegalArgumentException("*resources* must not be null."); if(resources.length==0) throw new IllegalArgumentException("arg *resources* must be one or more resources."); _resources = resources; for(int i=0; i<_resources.length; i++) { Resource r = _resources[i]; if(!r.exists() || !r.isDirectory()) throw new IllegalArgumentException(r + " is not an existing directory."); } } /* ------------------------------------------------------------ */ /** * * @param resources String array */ public void setResources(String[] resources) { if(_resources!=null) throw new IllegalStateException("*resources* already set."); if(resources==null) throw new IllegalArgumentException("*resources* must not be null."); if(resources.length==0) throw new IllegalArgumentException("arg *resources* must be one or more resources."); _resources = new Resource[resources.length]; try { for(int i=0; i<resources.length; i++) { _resources[i] = Resource.newResource(resources[i]); if(!_resources[i].exists() || !_resources[i].isDirectory()) throw new IllegalArgumentException(_resources[i] + " is not an existing directory."); } } catch(Exception e) { throw new RuntimeException(e); } } /* ------------------------------------------------------------ */ /** * * @param csvResources Comma separated values */ public void setResources(String csvResources) { if(_resources!=null) throw new IllegalStateException("*resources* already set."); if(csvResources==null) throw new IllegalArgumentException("*csvResources* must not be null."); StringTokenizer tokenizer = new StringTokenizer(csvResources, ",;"); int len = tokenizer.countTokens(); if(len==0) throw new IllegalArgumentException("arg *resources* must be one or more resources."); _resources = new Resource[len]; try { for(int i=0; tokenizer.hasMoreTokens(); i++) { _resources[i] = Resource.newResource(tokenizer.nextToken().trim()); if(!_resources[i].exists() || !_resources[i].isDirectory()) throw new IllegalArgumentException(_resources[i] + " is not an existing directory."); } } catch(Exception e) { throw new RuntimeException(e); } } /* ------------------------------------------------------------ */ /** * * @param csvResources Comma separated values */ public void setResourcesAsCSV(String csvResources) { setResources(csvResources); } /* ------------------------------------------------------------ */ /** * * @return the resource array */ public Resource[] getResources() { return _resources; } /* ------------------------------------------------------------ */ /** * @param path The path segment to add * @return The contained resource (found first) in the collection of resources */ public Resource addPath(String path) throws IOException, MalformedURLException { if(_resources==null) throw new IllegalStateException("*resources* not set."); if(path==null) throw new MalformedURLException(); if(path.length()==0 || URIUtil.SLASH.equals(path)) return this; Resource resource=null; ArrayList resources = null; int i=0; for(; i<_resources.length; i++) { resource = _resources[i].addPath(path); if (resource.exists()) { if (resource.isDirectory()) break; return resource; } } for(i++; i<_resources.length; i++) { Resource r = _resources[i].addPath(path); if (r.exists() && r.isDirectory()) { if (resource!=null) { resources = new ArrayList(); resources.add(resource); resource=null; } resources.add(r); } } if (resource!=null) return resource; if (resources!=null) return new ResourceCollection((Resource[])resources.toArray(new Resource[resources.size()])); return null; } /* ------------------------------------------------------------ */ /** * @param path * @return the resource(file) if found, returns a list of resource dirs if its a dir, else null. * @throws IOException * @throws MalformedURLException */ protected Object findResource(String path) throws IOException, MalformedURLException { Resource resource=null; ArrayList resources = null; int i=0; for(; i<_resources.length; i++) { resource = _resources[i].addPath(path); if (resource.exists()) { if (resource.isDirectory()) break; return resource; } } for(i++; i<_resources.length; i++) { Resource r = _resources[i].addPath(path); if (r.exists() && r.isDirectory()) { if (resource!=null) { resources = new ArrayList(); resources.add(resource); } resources.add(r); } } if (resource!=null) return resource; if (resources!=null) return resources; return null; } /* ------------------------------------------------------------ */ public boolean delete() throws SecurityException { throw new UnsupportedOperationException(); } /* ------------------------------------------------------------ */ public boolean exists() { if(_resources==null) throw new IllegalStateException("*resources* not set."); return true; } /* ------------------------------------------------------------ */ public File getFile() throws IOException { if(_resources==null) throw new IllegalStateException("*resources* not set."); for(int i=0; i<_resources.length; i++) { File f = _resources[i].getFile(); if(f!=null) return f; } return null; } /* ------------------------------------------------------------ */ public InputStream getInputStream() throws IOException { if(_resources==null) throw new IllegalStateException("*resources* not set."); for(int i=0; i<_resources.length; i++) { InputStream is = _resources[i].getInputStream(); if(is!=null) return is; } return null; } /* ------------------------------------------------------------ */ public String getName() { if(_resources==null) throw new IllegalStateException("*resources* not set."); for(int i=0; i<_resources.length; i++) { String name = _resources[i].getName(); if(name!=null) return name; } return null; } /* ------------------------------------------------------------ */ public OutputStream getOutputStream() throws IOException, SecurityException { if(_resources==null) throw new IllegalStateException("*resources* not set."); for(int i=0; i<_resources.length; i++) { OutputStream os = _resources[i].getOutputStream(); if(os!=null) return os; } return null; } /* ------------------------------------------------------------ */ public URL getURL() { if(_resources==null) throw new IllegalStateException("*resources* not set."); for(int i=0; i<_resources.length; i++) { URL url = _resources[i].getURL(); if(url!=null) return url; } return null; } /* ------------------------------------------------------------ */ public boolean isDirectory() { if(_resources==null) throw new IllegalStateException("*resources* not set."); return true; } /* ------------------------------------------------------------ */ public long lastModified() { if(_resources==null) throw new IllegalStateException("*resources* not set."); for(int i=0; i<_resources.length; i++) { long lm = _resources[i].lastModified(); if (lm!=-1) return lm; } return -1; } /* ------------------------------------------------------------ */ public long length() { return -1; } /* ------------------------------------------------------------ */ /** * @return The list of resource names(merged) contained in the collection of resources. */ public String[] list() { if(_resources==null) throw new IllegalStateException("*resources* not set."); HashSet set = new HashSet(); for(int i=0; i<_resources.length; i++) { String[] list = _resources[i].list(); for(int j=0; j<list.length; j++) set.add(list[j]); } return (String[])set.toArray(new String[set.size()]); } /* ------------------------------------------------------------ */ public void release() { if(_resources==null) throw new IllegalStateException("*resources* not set."); for(int i=0; i<_resources.length; i++) _resources[i].release(); } /* ------------------------------------------------------------ */ public boolean renameTo(Resource dest) throws SecurityException { throw new UnsupportedOperationException(); } /* ------------------------------------------------------------ */ /** * @return the list of resources separated by a path separator */ public String toString() { if(_resources==null) return ""; StringBuffer buffer = new StringBuffer(); for(int i=0; i<_resources.length; i++) buffer.append(_resources[i].toString()).append(';'); return buffer.toString(); } }