001/* $Id: FinderFromFile.java 471661 2006-11-06 08:09:25Z skitching $
002 *
003 * Licensed to the Apache Software Foundation (ASF) under one or more
004 * contributor license agreements.  See the NOTICE file distributed with
005 * this work for additional information regarding copyright ownership.
006 * The ASF licenses this file to You under the Apache License, Version 2.0
007 * (the "License"); you may not use this file except in compliance with
008 * the License.  You may obtain a copy of the License at
009 * 
010 *      http://www.apache.org/licenses/LICENSE-2.0
011 * 
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */ 
018 
019package org.apache.commons.digester.plugins.strategies;
020
021import java.util.Properties;
022import java.io.InputStream;
023import java.io.FileInputStream;
024import java.io.IOException;
025
026import org.apache.commons.digester.Digester;
027import org.apache.commons.digester.plugins.RuleFinder;
028import org.apache.commons.digester.plugins.RuleLoader;
029import org.apache.commons.digester.plugins.PluginException;
030
031/**
032 * A rule-finding algorithm which expects the user to specify an absolute
033 * or relative path in the plugin declaration.
034 * <p>
035 * The file is expected to contain Digester rules in xmlrules format.
036 *
037 * @since 1.6
038 */
039
040public class FinderFromFile extends RuleFinder {
041    /**
042     * Xml attribute that needs to be present on a plugin declaration
043     * in order to specify the file to load rules from.
044     */
045    public static String DFLT_FILENAME_ATTR = "file";
046    
047    /** See {@link #findLoader}. */
048    private String filenameAttr;
049    
050    /** See {@link #findLoader}. */
051    public FinderFromFile() {
052        this(DFLT_FILENAME_ATTR);
053    }
054
055    /** See {@link #findLoader}. */
056    public FinderFromFile(String filenameAttr) { 
057        this.filenameAttr = filenameAttr;
058    }
059    
060    /**
061     * If there exists a property with the name specified in the constructor,
062     * then load that file, run it through the xmlrules module and return an 
063     * object encapsulating those rules.
064     * <p>
065     * If there is no matching property provided, then just return null.
066     * <p>
067     * The returned object (when non-null) will add the selected rules to
068     * the digester whenever its addRules method is invoked.
069     */
070    public RuleLoader findLoader(Digester d, Class pluginClass, Properties p)
071                        throws PluginException {
072
073        String rulesFileName = p.getProperty(filenameAttr);
074        if (rulesFileName == null) {
075            // nope, user hasn't requested dynamic rules to be loaded
076            // from a specific file.
077            return null;
078        }
079        
080        InputStream is = null;
081        try {
082            is = new FileInputStream(rulesFileName);
083        } catch(IOException ioe) {
084            throw new PluginException(
085                "Unable to process file [" + rulesFileName + "]", ioe);
086        }
087        
088        try {
089            RuleLoader loader = new LoaderFromStream(is);
090            return loader;
091        } catch(Exception e) {
092            throw new PluginException(
093                "Unable to load xmlrules from file [" + 
094                rulesFileName + "]", e);
095        } finally {
096            try {
097                is.close();
098            } catch(java.io.IOException ioe) {
099                throw new PluginException(
100                    "Unable to close stream for file [" + 
101                    rulesFileName + "]", ioe);
102            }
103        }
104    }
105}
106