1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 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 }