156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson/* 256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * Copyright (C) 2010 Google Inc. 356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * 456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * Licensed under the Apache License, Version 2.0 (the "License"); 556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * you may not use this file except in compliance with the License. 656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * You may obtain a copy of the License at 756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * 856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * http://www.apache.org/licenses/LICENSE-2.0 956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * 1056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * Unless required by applicable law or agreed to in writing, software 1156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * distributed under the License is distributed on an "AS IS" BASIS, 1256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * See the License for the specific language governing permissions and 1456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * limitations under the License. 1556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson */ 1656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 1756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodsonpackage com.google.clearsilver.jsilver.resourceloader; 1856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 1956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodsonimport com.google.clearsilver.jsilver.exceptions.JSilverTemplateNotFoundException; 2056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 2156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodsonimport java.io.FilterReader; 2256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodsonimport java.io.IOException; 2356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodsonimport java.io.Reader; 2456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodsonimport java.util.ArrayList; 2556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodsonimport java.util.List; 2656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 2756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson/** 2856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * ResourceLoader composed of other ResourceLoaders. When a resource is loaded, it will search 2956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * through each ResourceLoader until it finds something. 3056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * 3156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * @see ResourceLoader 3256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson */ 3356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodsonpublic class CompositeResourceLoader implements ResourceLoader { 3456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 3556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson private final List<ResourceLoader> loaders = new ArrayList<ResourceLoader>(); 3656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 3756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public CompositeResourceLoader(Iterable<ResourceLoader> loaders) { 3856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson for (ResourceLoader loader : loaders) { 3956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson add(loader); 4056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 4156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 4256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 4356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public CompositeResourceLoader(ResourceLoader... loaders) { 4456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson for (ResourceLoader loader : loaders) { 4556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson add(loader); 4656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 4756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 4856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 4956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public void add(ResourceLoader loader) { 5056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson loaders.add(loader); 5156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 5256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 5356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public Reader open(String name) throws IOException { 5456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson for (ResourceLoader loader : loaders) { 5556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson Reader reader = loader.open(name); 5656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson if (reader != null) { 5756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson return new ReaderTracer(reader, loader); 5856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 5956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 6056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson return null; 6156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 6256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 6356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson @Override 6456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public Reader openOrFail(String name) throws JSilverTemplateNotFoundException, IOException { 6556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson Reader reader = open(name); 6656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson if (reader == null) { 6756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson throw new JSilverTemplateNotFoundException(name); 6856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } else { 6956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson return reader; 7056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 7156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 7256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 7356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public void close(Reader reader) throws IOException { 7456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson if (!(reader instanceof ReaderTracer)) { 7556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson throw new IllegalArgumentException("I can't close a reader I didn't open."); 7656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 7756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson reader.close(); 7856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 7956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 8056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson /** 8156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * We return the filename as the key of uniqueness as we assume that if this 8256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * CompositeResourceLoader is in use, then there won't be another ResourceLoader that we are 8356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * competing against. If we did need to worry about it we would want to prepend the key from 8456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * above. 8556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson */ 8656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson @Override 8756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public Object getKey(String filename) { 8856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson return filename; 8956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 9056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 9156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson /** 9256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * Return the first non-null version identifier found among the ResourceLoaders, using the same 9356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * search order as {@link #open(String)}. 9456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson */ 9556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson @Override 9656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public Object getResourceVersionId(String filename) { 9756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson for (ResourceLoader loader : loaders) { 9856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson Object currentKey = loader.getResourceVersionId(filename); 9956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson if (currentKey != null) { 10056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson return currentKey; 10156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 10256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 10356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson return null; 10456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 10556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 10656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson /** 10756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * Wraps a reader, associating it with the original ResourceLoader - this is necessary so when 10856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * close() is called, we delegate back to original ResourceLoader. 10956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson */ 11056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson private static class ReaderTracer extends FilterReader { 11156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 11256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson private final ResourceLoader originalLoader; 11356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 11456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public ReaderTracer(Reader in, ResourceLoader originalLoader) { 11556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson super(in); 11656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson this.originalLoader = originalLoader; 11756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 11856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 11956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public void close() throws IOException { 12056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson originalLoader.close(in); 12156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 12256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 12356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 12456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson} 125