1 //---------------------------------------------------------------------- 2 // 3 // PerfectJPattern: "Design patterns are good but components are better!" 4 // Adapter.java Copyright (c) 2009 Giovanni Azua Garcia 5 // bravegag@hotmail.com 6 // 7 // This program is free software; you can redistribute it and/or 8 // modify it under the terms of the GNU General Public License 9 // as published by the Free Software Foundation; either version 3 10 // of the License, or (at your option) any later version. 11 // 12 // This program is distributed in the hope that it will be useful, 13 // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 // GNU General Public License for more details. 16 // 17 // You should have received a copy of the GNU General Public License 18 // along with this program; if not, see <http://www.gnu.org/licenses/>. 19 // 20 //---------------------------------------------------------------------- 21 package org.perfectjpattern.core.structural.adapter; 22 23 import java.lang.reflect.Method; 24 25 import org.apache.commons.lang.Validate; 26 import org.perfectjpattern.core.api.structural.adapter.IAdapter; 27 import org.perfectjpattern.core.api.structural.adapter.IAdaptingStrategy; 28 import org.perfectjpattern.core.structural.*; 29 30 /** 31 * Concrete implementation of {@link IAdapter} 32 * 33 * @param <T> <code>Target</code> element type 34 * @param <A> <code>Adaptee</code> element type 35 * 36 * @author <a href="mailto:bravegag@hotmail.com">Giovanni Azua</a> 37 * @version $Revision: 1.0 $Date: Jan 28, 2009 1:43:35 PM $ 38 */ 39 public 40 class Adapter<T, A> 41 extends AbstractSurrogate<T, A> 42 implements IAdapter<T, A> 43 { 44 //------------------------------------------------------------------------ 45 // public 46 //------------------------------------------------------------------------ 47 /** 48 * Constructs an {@link Adapter} taking as input the <code>Target</code> 49 * interface type, an <code>Adaptee</code> instance and the 50 * {@link IAdaptingStrategy} for matching those interfaces. 51 * 52 * @param aTargetInterface Target interface class type 53 * @param anAdaptee Adaptee instance 54 * @param anAdaptingStrategy Strategy for matching the Target and Adaptee 55 * interfaces 56 * @throws IllegalArgumentException 'aTargetInterface' must not be null 57 * @throws IllegalArgumentException 'anAdaptee' must not be null 58 * @throws IllegalArgumentException 'anAdaptingStrategy' must not be null 59 */ 60 public 61 Adapter(Class<T> aTargetInterface, A anAdaptee, IAdaptingStrategy 62 anAdaptingStrategy) 63 throws IllegalArgumentException 64 { 65 super(aTargetInterface, anAdaptee); 66 67 setAdaptingStrategy(anAdaptingStrategy); 68 } 69 70 //------------------------------------------------------------------------ 71 /** 72 * Constructs an {@link Adapter} instance having the target interface, the 73 * adaptee instance and assigning the default adapting strategy 74 * 75 * @param aTargetInterface Target interface type 76 * @param anAdaptee Adaptee instance 77 * @throws IllegalArgumentException 'aTargetInterface' must not be null 78 * @throws IllegalArgumentException 'anAdaptee' must not be null 79 */ 80 public 81 Adapter(Class<T> anInterface, A anAdaptee) 82 throws IllegalArgumentException 83 { 84 this(anInterface, anAdaptee, DEFAULT_ADAPTING_STRATEGY); 85 } 86 87 //------------------------------------------------------------------------ 88 /** 89 * {@inheritDoc} 90 */ 91 public A 92 getAdaptee() 93 { 94 return super.getUnderlying(); 95 } 96 97 //------------------------------------------------------------------------ 98 /** 99 * {@inheritDoc} 100 */ 101 public T 102 getTarget() 103 { 104 return super.getComponent(); 105 } 106 107 //------------------------------------------------------------------------ 108 /** 109 * {@inheritDoc} 110 */ 111 @SuppressWarnings("unchecked") 112 public final void 113 setAdaptingStrategy(IAdaptingStrategy anAdaptingStrategy) 114 throws IllegalArgumentException 115 { 116 Validate.notNull(anAdaptingStrategy, 117 "'anAdaptingStrategy' must not be null"); 118 119 theAdaptingStrategy = anAdaptingStrategy; 120 121 Class<T> myTarget = (Class<T>) getComponentClass(); 122 A myAdaptee = getUnderlying(); 123 124 Object myAdapter = this; 125 theAdaptingStrategy.validate(myTarget, myAdaptee, myAdapter); 126 } 127 128 //------------------------------------------------------------------------ 129 // protected 130 //------------------------------------------------------------------------ 131 /** 132 * {@inheritDoc} 133 */ 134 @SuppressWarnings("unchecked") 135 @Override 136 protected Object 137 invokeUnderlying(Method aMethod, Object[] anArguments) 138 throws Throwable 139 { 140 Class<T> myTarget = (Class<T>) getComponentClass(); 141 A myAdaptee = super.getUnderlying(); 142 143 Object myAdapter = this; 144 Method myTargetMethod = theAdaptingStrategy.resolve(myTarget, 145 myAdaptee, myAdapter, aMethod); 146 147 return myTargetMethod.invoke(myAdaptee, anArguments); 148 } 149 150 //------------------------------------------------------------------------ 151 // members 152 //------------------------------------------------------------------------ 153 /** 154 * Reference to {@link IAdaptingStrategy} implementation that defines how 155 * the Adapter should match the Adaptee interface 156 */ 157 private IAdaptingStrategy theAdaptingStrategy; 158 159 /** 160 * Default concrete {@link IAdaptingStrategy} implementation 161 */ 162 private static final IAdaptingStrategy DEFAULT_ADAPTING_STRATEGY = 163 new ExactMatchAdaptingStrategy(); 164 }