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 java.io.IOException;
23  import java.io.InputStream;
24  import java.util.Properties;
25  
26  import org.apache.commons.digester3.Digester;
27  import org.apache.commons.digester3.plugins.PluginException;
28  import org.apache.commons.digester3.plugins.RuleFinder;
29  import org.apache.commons.digester3.plugins.RuleLoader;
30  
31  /**
32   * A rule-finding algorithm which expects the user to specify a resource name (ie a file in the classpath). The file is
33   * expected to contain Digester rules in xmlrules format.
34   * 
35   * @since 1.6
36   */
37  public class FinderFromResource
38      extends RuleFinder
39  {
40  
41      /**
42       * Default name of xml attribute on the plugin declaration which is used to configure rule-loading
43       * for that declaration.
44       */
45      private static final String DFLT_RESOURCE_ATTR = "resource";
46  
47      /** See {@link #findLoader}. */
48      private final String resourceAttr;
49  
50      /** Constructor. */
51      public FinderFromResource()
52      {
53          this( DFLT_RESOURCE_ATTR );
54      }
55  
56      /**
57       * See {@link #findLoader}.
58       *
59       * @param resourceAttr Name of xml attribute on the plugin declaration which is used to configure rule-loading
60       *        for that declaration
61       */
62      public FinderFromResource( String resourceAttr )
63      {
64          this.resourceAttr = resourceAttr;
65      }
66  
67      /**
68       * If there exists a property with the name matching constructor param resourceAttr, then load that file, run it
69       * through the xmlrules module and return an object encapsulating those rules.
70       * <p>
71       * If there is no matching property provided, then just return null.
72       * <p>
73       * The returned object (when non-null) will add the selected rules to the digester whenever its addRules method is
74       * invoked.
75       *
76       * @param d The digester instance where locating plugin classes
77       * @param pluginClass The plugin Java class
78       * @param p The properties object that holds any xml attributes the user may have specified on the plugin
79       *          declaration in order to indicate how to locate the plugin rules.
80       * @return a source of digester rules for the specified plugin class.
81       * @throws PluginException if the algorithm finds a source of rules, but there is something invalid
82       *         about that source.
83       */
84      @Override
85      public RuleLoader findLoader( Digester d, Class<?> pluginClass, Properties p )
86          throws PluginException
87      {
88          String resourceName = p.getProperty( resourceAttr );
89          if ( resourceName == null )
90          {
91              // nope, user hasn't requested dynamic rules to be loaded
92              // from a specific file.
93              return null;
94          }
95  
96          InputStream is = pluginClass.getClassLoader().getResourceAsStream( resourceName );
97  
98          if ( is == null )
99          {
100             throw new PluginException( "Resource " + resourceName + " not found." );
101         }
102 
103         return loadRules( d, pluginClass, is, resourceName );
104     }
105 
106     /**
107      * Open the specified resource file (ie a file in the classpath, including being within a jar in the classpath), run
108      * it through the xmlrules module and return an object encapsulating those rules.
109      * 
110      * @param d is the digester into which rules will eventually be loaded.
111      * @param pluginClass is the class whose xml params the rules are parsing.
112      * @param is is where the xmlrules will be read from, and must be non-null.
113      * @param resourceName is a string describing the source of the xmlrules, for use in generating error messages.
114      * @return a source of digester rules for the specified plugin class.
115      * @throws PluginException if any error occurs
116      */
117     public static RuleLoader loadRules( Digester d, Class<?> pluginClass, InputStream is, String resourceName )
118         throws PluginException
119     {
120         try
121         {
122             RuleLoader loader = new LoaderFromStream( is );
123             return loader;
124         }
125         catch ( Exception e )
126         {
127             throw new PluginException( "Unable to load xmlrules from resource [" + resourceName + "]", e );
128         }
129         finally
130         {
131             try
132             {
133                 is.close();
134             }
135             catch ( IOException ioe )
136             {
137                 throw new PluginException( "Unable to close stream for resource [" + resourceName + "]", ioe );
138             }
139         }
140     }
141 
142 }