"Geir Magnusson Jr." <[EMAIL PROTECTED]> writes: > Re Dan's, I was uncomfortable with the classpath loader acquiring 'memory' - > once it found something, it stuck it there for good until a restart, which I > didn't think supported the usual expectations of a classpath-ish loader - > although I saw that he had a valid need.
As you noticed, the "memory" is used to keep the resource lookups quick. FileResourceLoader currently uses this same technique. > So here is what I cooked up - adapters for any resource loader. > > The idea is that you make one of these, which extends ResourceLoader, and as > part of it's configuration, you supply the class and properties for a 'real' > loader, like File- or Classpath-. > > So then you make an adapter for whatever purpose you want - I tried to make > one copying from Dan's proposed modifications so he can test it to see if it > works. > > I'm not sure this is the best approach in terms of structure. Certainly if > this approach seems useful, we should refactor the resource system to make > this a formal thing - that the concept of a 'ResourceAdapter' is a first > class citizen, rather than this sneaky approach. So the adapter wraps the resource loader. Formalizing the concept of an adaptive loader is it good idea. It draws on the existing Velocity configuraiton vocabulary and extends it, which is much better than introducing an entirely new entity (the new addition won't be as foreign to developers). I've gone ahead and checked in the code as two classes, LoaderAdapter and PathMapAdapter, which are two halves of the code seen below. I'm thinking that LoaderAdapter might be better named either ResourceLoaderAdapter or AdaptiveResourceLoader. Thoughts? > package org.apache.velocity.runtime.resource.loader.adapter; > > /* > * The Apache Software License, Version 1.1 > * > * Copyright (c) 2002 The Apache Software Foundation. All rights > * reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions > * are met: > * > * 1. Redistributions of source code must retain the above copyright > * notice, this list of conditions and the following disclaimer. > * > * 2. Redistributions in binary form must reproduce the above copyright > * notice, this list of conditions and the following disclaimer in > * the documentation and/or other materials provided with the > * distribution. > * > * 3. The end-user documentation included with the redistribution, if > * any, must include the following acknowlegement: > * "This product includes software developed by the > * Apache Software Foundation (http://www.apache.org/)." > * Alternately, this acknowlegement may appear in the software itself, > * if and wherever such third-party acknowlegements normally appear. > * > * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software > * Foundation" must not be used to endorse or promote products derived > * from this software without prior written permission. For written > * permission, please contact [EMAIL PROTECTED] > * > * 5. Products derived from this software may not be called "Apache" > * nor may "Apache" appear in their names without prior written > * permission of the Apache Group. > * > * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED > * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES > * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE > * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR > * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, > * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT > * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF > * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND > * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, > * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT > * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF > * SUCH DAMAGE. > * ==================================================================== > * > * This software consists of voluntary contributions made by many > * individuals on behalf of the Apache Software Foundation. For more > * information on the Apache Software Foundation, please see > * <http://www.apache.org/>. > */ > > import org.apache.velocity.runtime.resource.loader.ResourceLoader; > import org.apache.velocity.runtime.resource.loader.ResourceLoaderFactory; > import org.apache.velocity.runtime.resource.Resource; > import org.apache.velocity.exception.ResourceNotFoundException; > > import java.util.Hashtable; > import java.util.Map; > import java.util.List; > import java.io.InputStream; > > import org.apache.commons.collections.ExtendedProperties; > > > /** > * Simple ResourceLoader adapter derived from Dan Rall's proposed > * changes to the ClasspathResourceLoader > * > * @author <a href="[EMAIL PROTECTED]">Geir Magnusson Jr.</a> > * @author <a href="mailto:[EMAIL PROTECTED]">Daniel Rall</a> > * @version $Id:$ > */ > public class PathMapAdapter extends ResourceLoader > { > /** > * The paths to search for templates. > */ > protected List paths = null; > > /** > * Template to path mappings > */ > protected Map templatePaths = new Hashtable(); > > /** > * Resource loader we are going to use. We need to have > * one specified? > */ > protected ResourceLoader resourceLoader = null; > > /** > * This is abstract in the base class, so we need it > */ > public void init( ExtendedProperties configuration) > { > rsvc.info("PathMapAdapter : initialization starting."); > > /* > * the most important thing is that we are are given > * a ResourceLoader to use > */ > > String loaderClass = configuration.getString( "loader" ); > > try > { > ExtendedProperties loaderConfiguration = > configuration.subset("loader"); > > resourceLoader = ResourceLoaderFactory.getLoader( rsvc, loaderClass); > resourceLoader.commonInit( rsvc, loaderConfiguration); > resourceLoader.init( loaderConfiguration); > > rsvc.info("PathMapAdapter : using loader : " + loaderClass ); > } > catch( Exception e ) > { > rsvc.error("PathMapAdapter : problem instantiating loader : " + e ); > } > > /* > * now get the paths > */ > paths = configuration.getVector("path"); > > int size = paths.size(); > > for (int i = 0; i < size; i++) > { > rsvc.info("PathMapAdapter : adding path '" + > paths.get(i) + "'"); > } > rsvc.info("PathMapAdapter : initialization complete."); > } > > > /** > * Get an InputStream so that the Runtime can build a > * template with it. > * > * @param name name of template to get > * @return InputStream containing the template > * @throws ResourceNotFoundException if template not found > * in classpath. > */ > public synchronized InputStream getResourceStream(String name) > throws ResourceNotFoundException > { > if (name == null || name.length() == 0) > { > throw new ResourceNotFoundException("No template name provided"); > } > > InputStream result = null; > String path = (String) templatePaths.get(name); > > if (path != null) > { > try > { > result = openStream( path, name); > } > catch (Exception e) > { > throw new ResourceNotFoundException("Couldn't find resource: " + > e.getMessage()); > } > } > else > { > int size = paths.size(); > for (int i = 0; i < size; i++) > { > path = (String) paths.get(i); > try > { > rsvc.debug("Looking for " + name + " in path " + path); > path = normalizePath(path); > rsvc.debug("Normalized path to " + path); > result = openStream( path, name); > if (result != null) > { > templatePaths.put(name, path); > break; > } > } > catch (Exception ignored) > { > // Expected to happen for resources not found in > // this path. > } > } > } > > if ( result == null) > { > throw new ResourceNotFoundException("PathMapAdapter : " + name + " not >found"); > } > > return result; > } > > /** > * Uses the configured loader to return the stream > */ > private InputStream openStream( String path, String name) > throws Exception > { > return resourceLoader.getResourceStream( > path.length() > 0 ? path + "/" + name : name ); > } > > /** > * Normalizes a path for use with a <code>ClassLoader</code>. > */ > private String normalizePath(String path) > { > if (path.startsWith("/")) > { > path = path.substring(1); > } > else if (path.startsWith("./")) > { > path = path.substring(2); > } > else if (path.equals(".")) > { > path = ""; > } > return path; > } > > public boolean isSourceModified(Resource resource) > { > return resourceLoader.isSourceModified( resource ); > } > > public long getLastModified(Resource resource) > { > return resourceLoader.getLastModified( resource ); > } > } > > > > > resource.loader = adapter > adapter.resource.loader.class = >org.apache.velocity.runtime.resource.loader.adapter.PathMapAdapter > adapter.resource.loader.loader = >org.apache.velocity.runtime.resource.loader.FileResourceLoader > adapter.resource.loader.loader.path = . > adapter.resource.loader.path = foo, bar -- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>
