1
2
3
4
5
6
7
8
9
10
11
12
13
14
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 }