View Javadoc

1   package org.apache.commons.digester3.plugins.strategies;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import static org.apache.commons.digester3.binder.DigesterLoader.newLoader;
23  
24  import java.io.ByteArrayInputStream;
25  import java.io.ByteArrayOutputStream;
26  import java.io.IOException;
27  import java.io.InputStream;
28  
29  import org.apache.commons.digester3.Digester;
30  import org.apache.commons.digester3.plugins.PluginException;
31  import org.apache.commons.digester3.plugins.RuleLoader;
32  import org.apache.commons.digester3.xmlrules.FromXmlRulesModule;
33  import org.apache.commons.logging.Log;
34  import org.xml.sax.InputSource;
35  
36  /**
37   * A rule-finding algorithm which loads an xmlplugins-format file.
38   * <p>
39   * Note that the "include" feature of xmlrules is not supported.
40   * 
41   * @since 1.6
42   */
43  public class LoaderFromStream
44      extends RuleLoader
45  {
46  
47      private final byte[] input;
48  
49      /**
50       * The contents of the input stream are loaded into memory, and cached for later use.
51       * <p>
52       * The caller is responsible for closing the input stream after this method has returned.
53       *
54       * @param s the input stream has to be loaded into memory
55       * @throws Exception if any error occurs while reading the input stream
56       */
57      public LoaderFromStream( InputStream s )
58          throws Exception
59      {
60          try
61          {
62              ByteArrayOutputStream baos = new ByteArrayOutputStream();
63              byte[] buf = new byte[256];
64              for ( ;; )
65              {
66                  int i = s.read( buf );
67                  if ( i == -1 )
68                  {
69                      break;
70                  }
71                  baos.write( buf, 0, i );
72              }
73              input = baos.toByteArray();
74          }
75          finally
76          {
77              try
78              {
79                  if ( s != null )
80                  {
81                      s.close();
82                  }
83              }
84              catch ( IOException e )
85              {
86                  // close quietly
87              }
88          }
89      }
90  
91      /**
92       * {@inheritDoc}
93       */
94      @Override
95      public void addRules( final Digester d, final String path )
96          throws PluginException
97      {
98          Log log = d.getLogger();
99          boolean debug = log.isDebugEnabled();
100         if ( debug )
101         {
102             log.debug( "LoaderFromStream: loading rules for plugin at path [" + path + "]" );
103         }
104 
105         // Note that this input-source doesn't have any idea of its
106         // system id, so it has no way of resolving relative URLs
107         // such as the "include" feature of xmlrules. This is ok,
108         // because that doesn't work well with our approach of
109         // caching the input data in memory anyway.
110 
111         final InputSource source = new InputSource( new ByteArrayInputStream( input ) );
112         newLoader( new FromXmlRulesModule()
113         {
114 
115             @Override
116             protected void loadRules()
117             {
118                 useRootPath( path );
119                 loadXMLRules( source );
120             }
121 
122         } ).createRuleSet().addRuleInstances( d );
123     }
124 
125 }