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 */
018package org.apache.commons.digester.plugins.strategies;
019
020import java.io.InputStream;
021import java.io.ByteArrayInputStream;
022import java.io.ByteArrayOutputStream;
023import java.io.IOException;
024import org.xml.sax.InputSource;
025
026import org.apache.commons.digester.Digester;
027import org.apache.commons.digester.plugins.RuleLoader;
028import org.apache.commons.digester.plugins.PluginException;
029import org.apache.commons.digester.xmlrules.FromXmlRuleSet;
030import 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
040public 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