001/* $Id: FinderFromFile.java 992060 2010-09-02 19:09:47Z simonetripodi $
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 */
018package org.apache.commons.digester.plugins.strategies;
019
020import java.util.Properties;
021import java.io.InputStream;
022import java.io.FileInputStream;
023import java.io.IOException;
024
025import org.apache.commons.digester.Digester;
026import org.apache.commons.digester.plugins.RuleFinder;
027import org.apache.commons.digester.plugins.RuleLoader;
028import org.apache.commons.digester.plugins.PluginException;
029
030/**
031 * A rule-finding algorithm which expects the user to specify an absolute
032 * or relative path in the plugin declaration.
033 * <p>
034 * The file is expected to contain Digester rules in xmlrules format.
035 *
036 * @since 1.6
037 */
038
039public class FinderFromFile extends RuleFinder {
040    /**
041     * Xml attribute that needs to be present on a plugin declaration
042     * in order to specify the file to load rules from.
043     */
044    public static String DFLT_FILENAME_ATTR = "file";
045    
046    /** See {@link #findLoader}. */
047    private String filenameAttr;
048    
049    /** See {@link #findLoader}. */
050    public FinderFromFile() {
051        this(DFLT_FILENAME_ATTR);
052    }
053
054    /** See {@link #findLoader}. */
055    public FinderFromFile(String filenameAttr) { 
056        this.filenameAttr = filenameAttr;
057    }
058    
059    /**
060     * If there exists a property with the name specified in the constructor,
061     * then load that file, run it through the xmlrules module and return an 
062     * object encapsulating those rules.
063     * <p>
064     * If there is no matching property provided, then just return null.
065     * <p>
066     * The returned object (when non-null) will add the selected rules to
067     * the digester whenever its addRules method is invoked.
068     */
069    @Override
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