View Javadoc

1   /*
2    * Copyright 2001-2004 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */ 
16  package org.apache.commons.betwixt.strategy;
17  
18  import java.util.ArrayList;
19  import java.util.Iterator;
20  
21  /*** 
22   * <p>ClassNormalizer that uses a list of substitutions.</p>
23   * <p>
24   * This <code>ClassNormalizer</code> checks a list (in order) to find a matching
25   * Class. 
26   * This match can be performed either strictly (using equality) or taking into account
27   * inheritance and implementation.
28   * If a match is found then the first substituted class is returned as the normalization.
29   * </p>
30   * @author Robert Burrell Donkin
31   * @since 0.5
32   */
33  public class ListedClassNormalizer extends ClassNormalizer {
34  
35      /*** Entries to be normalized */
36      private ArrayList normalizations = new ArrayList();
37      /*** Should the equality (rather than isAssignabledFrom) be used to check */
38      private boolean strickCheck = false;
39  
40      /***
41        * Is strict checking of substitutions on?
42        * @return true is equality is used to compare classes when considering substition,
43        * otherwise isAssignableFrom will be used so that super classes and super interfaces 
44        * will be matched.
45        */
46      public boolean isStrickCheck() {
47          return strickCheck;
48      }
49  
50      /***
51        * Sets strict checking of substitutions?
52        * @param strickCheck if true then equality will be used to compare classes 
53        * when considering substition,
54        * otherwise isAssignableFrom will be used so that super classes and super interfaces 
55        * will be matched.
56        */
57      public void setStrickCheck(boolean strickCheck) {
58          this.strickCheck = strickCheck;
59      }
60  
61      /***
62        * Adds this given substitution to the list.
63        * No warning is given if the match has already been added to the list.
64        * @param match if any classes matching this then the normal class will be substituted
65        * @param substitute the normalized Class if the primary class is matched
66        */
67      public void addSubstitution( Class match, Class substitute ) {
68          normalizations.add( new ListEntry( match, substitute ));
69      }
70      
71      /***
72        * Adds the given substitute to the list.
73        * This is a convenience method useful when {@link #isStrickCheck} is false.
74        * In this case, any subclasses (if this is a class) or implementating classes
75        * if this is an interface) will be subsituted with this value.
76        * @param substitute sustitude this Class
77        */
78      public void addSubstitution( Class substitute ) {
79          addSubstitution( substitute, substitute );
80      }
81  
82      /***
83        * Normalize given class.
84        * The normalized Class is the Class that Betwixt should 
85        * introspect. 
86        * This strategy class allows the introspected Class to be 
87        * varied.
88        *
89        * @param clazz the class to normalize, not null
90        * @return this implementation check it's list of substitutations in order
91        * and returns the first that matchs. If {@link #isStrickCheck} then equality 
92        * is used otherwise isAssignableFrom is used (so that super class and interfaces are matched).
93        */
94      public Class normalize( Class clazz ) {
95          Iterator it = normalizations.iterator();
96          while ( it.hasNext() ) {
97              ListEntry entry = (ListEntry) it.next();
98              if ( strickCheck ) {
99                  if ( entry.match.equals( clazz ) ) {
100                     return entry.substitute;
101                 }
102             } else {
103                 if ( entry.match.isAssignableFrom( clazz )) {
104                     return entry.substitute;
105                 }
106             }
107         }
108         
109         return clazz;
110     }
111     
112     /*** Holds list entries */
113     private class ListEntry {        
114         /*** Class to be check */
115         Class match;
116         /*** Substituted to be returned */
117         Class substitute;
118         
119         /*** 
120           * Base constructor 
121           * @param match match this Class
122           * @param subsistute substitute matches with this Class
123           */
124         ListEntry( Class match, Class substitute ) {
125             this.match = match;
126             this.substitute = substitute;
127         }
128     }
129 }