001/* $Id: LoaderFromStream.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.io.InputStream;
022import java.io.ByteArrayInputStream;
023import java.io.ByteArrayOutputStream;
024import java.io.IOException;
025import org.xml.sax.InputSource;
026
027import org.apache.commons.digester.Digester;
028import org.apache.commons.digester.plugins.RuleLoader;
029import org.apache.commons.digester.plugins.PluginException;
030import org.apache.commons.digester.xmlrules.FromXmlRuleSet;
031import org.apache.commons.logging.Log;
032
033/**
034 * A rule-finding algorithm which loads an xmlplugins-format file.
035 * <p>
036 * Note that the "include" feature of xmlrules is not supported.
037 *
038 * @since 1.6
039 */
040
041public class LoaderFromStream extends RuleLoader {
042
043    private byte[] input;
044    private FromXmlRuleSet ruleSet;
045    
046    /** See {@link #load}. */
047    public LoaderFromStream(InputStream s) throws Exception {
048        load(s);
049    }
050
051    /**
052     * The contents of the input stream are loaded into memory, and
053     * cached for later use.
054     * <p>
055     * The caller is responsible for closing the input stream after this
056     * method has returned.
057     */
058    private void load(InputStream s) throws IOException {
059        ByteArrayOutputStream baos = new ByteArrayOutputStream();
060        byte[] buf = new byte[256];
061        for(;;) {
062            int i = s.read(buf);
063            if (i == -1)
064                break;
065            baos.write(buf, 0, i);
066        }
067        input = baos.toByteArray();
068    }
069    
070    /**
071     * Add the rules previously loaded from the input stream into the
072     * specified digester.
073     */
074    public void addRules(Digester d, String path) throws PluginException {
075        Log log = d.getLogger();
076        boolean debug = log.isDebugEnabled();
077        if (debug) {
078            log.debug(
079                "LoaderFromStream: loading rules for plugin at path [" 
080                + path + "]");
081        }
082
083        // Note that this input-source doesn't have any idea of its
084        // system id, so it has no way of resolving relative URLs
085        // such as the "include" feature of xmlrules. This is ok,
086        // because that doesn't work well with our approach of
087        // caching the input data in memory anyway.
088
089        InputSource source = new InputSource(new ByteArrayInputStream(input));
090        FromXmlRuleSet ruleSet = new FromXmlRuleSet(source);
091        ruleSet.addRuleInstances(d, path);
092    }
093}
094