CompositeResourceLoader.java revision 56ed4167b942ec265f9cee70ac4d71d10b3835ce
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/* 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright (C) 2010 Google Inc. 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Licensed under the Apache License, Version 2.0 (the "License"); 5b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) * you may not use this file except in compliance with the License. 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * You may obtain a copy of the License at 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * http://www.apache.org/licenses/LICENSE-2.0 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Unless required by applicable law or agreed to in writing, software 11a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch * distributed under the License is distributed on an "AS IS" BASIS, 12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * See the License for the specific language governing permissions and 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * limitations under the License. 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochpackage com.google.clearsilver.jsilver.resourceloader; 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import com.google.clearsilver.jsilver.exceptions.JSilverTemplateNotFoundException; 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import java.io.FilterReader; 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import java.io.IOException; 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import java.io.Reader; 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import java.util.ArrayList; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import java.util.List; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ResourceLoader composed of other ResourceLoaders. When a resource is loaded, it will search 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * through each ResourceLoader until it finds something. 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @see ResourceLoader 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)public class CompositeResourceLoader implements ResourceLoader { 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private final List<ResourceLoader> loaders = new ArrayList<ResourceLoader>(); 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public CompositeResourceLoader(Iterable<ResourceLoader> loaders) { 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (ResourceLoader loader : loaders) { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) add(loader); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public CompositeResourceLoader(ResourceLoader... loaders) { 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (ResourceLoader loader : loaders) { 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) add(loader); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public void add(ResourceLoader loader) { 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loaders.add(loader); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public Reader open(String name) throws IOException { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (ResourceLoader loader : loaders) { 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Reader reader = loader.open(name); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (reader != null) { 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new ReaderTracer(reader, loader); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return null; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) @Override 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public Reader openOrFail(String name) throws JSilverTemplateNotFoundException, IOException { 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Reader reader = open(name); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (reader == null) { 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) throw new JSilverTemplateNotFoundException(name); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return reader; 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public void close(Reader reader) throws IOException { 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(reader instanceof ReaderTracer)) { 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) throw new IllegalArgumentException("I can't close a reader I didn't open."); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reader.close(); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /** 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * We return the filename as the key of uniqueness as we assume that if this 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * CompositeResourceLoader is in use, then there won't be another ResourceLoader that we are 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * competing against. If we did need to worry about it we would want to prepend the key from 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * above. 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) @Override 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public Object getKey(String filename) { 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return filename; 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Return the first non-null version identifier found among the ResourceLoaders, using the same 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * search order as {@link #open(String)}. 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) @Override 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public Object getResourceVersionId(String filename) { 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (ResourceLoader loader : loaders) { 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Object currentKey = loader.getResourceVersionId(filename); 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (currentKey != null) { 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return currentKey; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return null; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Wraps a reader, associating it with the original ResourceLoader - this is necessary so when 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * close() is called, we delegate back to original ResourceLoader. 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private static class ReaderTracer extends FilterReader { 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private final ResourceLoader originalLoader; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public ReaderTracer(Reader in, ResourceLoader originalLoader) { 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) super(in); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.originalLoader = originalLoader; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public void close() throws IOException { 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) originalLoader.close(in); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)