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