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 }