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