View Javadoc

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 }