View Javadoc

1   package org.apache.commons.digester3;
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.util.ArrayList;
23  import java.util.List;
24  
25  import org.xml.sax.Attributes;
26  
27  /**
28   * <p>
29   * <code>Rules</code> <em>Decorator</em> that returns default rules when no matches are returned by the wrapped
30   * implementation.
31   * </p>
32   * <p>
33   * This allows default <code>Rule</code> instances to be added to any existing <code>Rules</code> implementation. These
34   * default <code>Rule</code> instances will be returned for any match for which the wrapped implementation does not
35   * return any matches.
36   * </p>
37   * <p>
38   * For example,
39   * 
40   * <pre>
41   *   Rule alpha;
42   *   ...
43   *   WithDefaultsRulesWrapper rules = new WithDefaultsRulesWrapper(new BaseRules());
44   *   rules.addDefault(alpha);
45   *   ...
46   *   digester.setRules(rules);
47   *   ...
48   * </pre>
49   * 
50   * when a pattern does not match any other rule, then rule alpha will be called.
51   * </p>
52   * <p>
53   * <code>WithDefaultsRulesWrapper</code> follows the <em>Decorator</em> pattern.
54   * </p>
55   * 
56   * @since 1.6
57   */
58  public class WithDefaultsRulesWrapper
59      implements Rules
60  {
61  
62      // --------------------------------------------------------- Fields
63  
64      /** The Rules implementation that this class wraps. */
65      private Rules wrappedRules;
66  
67      /** Rules to be fired when the wrapped implementations returns none. */
68      private List<Rule> defaultRules = new ArrayList<Rule>();
69  
70      /** All rules (preserves order in which they were originally added) */
71      private List<Rule> allRules = new ArrayList<Rule>();
72  
73      // --------------------------------------------------------- Constructor
74  
75      /**
76       * Base constructor.
77       *
78       * @param wrappedRules the wrapped <code>Rules</code> implementation, not null
79       */
80      public WithDefaultsRulesWrapper( Rules wrappedRules )
81      {
82          if ( wrappedRules == null )
83          {
84              throw new IllegalArgumentException( "Wrapped rules must not be null" );
85          }
86          this.wrappedRules = wrappedRules;
87      }
88  
89      // --------------------------------------------------------- Properties
90  
91      /**
92       * {@inheritDoc}
93       */
94      public Digester getDigester()
95      {
96          return wrappedRules.getDigester();
97      }
98  
99      /**
100      * {@inheritDoc}
101      */
102     public void setDigester( Digester digester )
103     {
104         wrappedRules.setDigester( digester );
105         for ( Rule rule : defaultRules )
106         {
107             rule.setDigester( digester );
108         }
109     }
110 
111     /**
112      * {@inheritDoc}
113      */
114     public String getNamespaceURI()
115     {
116         return wrappedRules.getNamespaceURI();
117     }
118 
119     /**
120      * {@inheritDoc}
121      */
122     public void setNamespaceURI( String namespaceURI )
123     {
124         wrappedRules.setNamespaceURI( namespaceURI );
125     }
126 
127     /**
128      * Gets Rule's which will be fired when the wrapped implementation returns no matches
129      *
130      * @return Rule's which will be fired when the wrapped implementation returns no matches
131      **/
132     public List<Rule> getDefaults()
133     {
134         return defaultRules;
135     }
136 
137     // --------------------------------------------------------- Public Methods
138 
139     /**
140      * {@inheritDoc}
141      */
142     public List<Rule> match( String namespaceURI, String pattern, String name, Attributes attributes )
143     {
144         List<Rule> matches = wrappedRules.match( namespaceURI, pattern, name, attributes );
145         if ( matches == null || matches.isEmpty() )
146         {
147             // a little bit of defensive programming
148             return new ArrayList<Rule>( defaultRules );
149         }
150         // otherwise
151         return matches;
152     }
153 
154     /**
155      * Adds a rule to be fired when wrapped implementation returns no matches
156      *
157      * @param rule a Rule to be fired when wrapped implementation returns no matches
158      **/
159     public void addDefault( Rule rule )
160     {
161         // set up rule
162         if ( wrappedRules.getDigester() != null )
163         {
164             rule.setDigester( wrappedRules.getDigester() );
165         }
166 
167         if ( wrappedRules.getNamespaceURI() != null )
168         {
169             rule.setNamespaceURI( wrappedRules.getNamespaceURI() );
170         }
171 
172         defaultRules.add( rule );
173         allRules.add( rule );
174     }
175 
176     /**
177      * {@inheritDoc}
178      */
179     public List<Rule> rules()
180     {
181         return allRules;
182     }
183 
184     /**
185      * {@inheritDoc}
186      */
187     public void clear()
188     {
189         wrappedRules.clear();
190         allRules.clear();
191         defaultRules.clear();
192     }
193 
194     /**
195      * {@inheritDoc}
196      */
197     public void add( String pattern, Rule rule )
198     {
199         wrappedRules.add( pattern, rule );
200         allRules.add( rule );
201     }
202 
203 }