View Javadoc

1   //----------------------------------------------------------------------
2   // 
3   // PerfectJPattern: "Design patterns are good but components are better!" 
4   // List2QueueAdapter.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.util.*;
24  
25  import org.perfectjpattern.core.api.structural.adapter.*;
26  
27  /**
28   * Adapter that provides a {@link Queue} based on a {@link List} implementation.
29   * That is, it adapts the {@link List} to behave and look like a {@link Queue}. 
30   * Please note that this is not an exhaustive implementation of {@link Queue} 
31   * nor it replaces the proper JDK {@link Queue} implementations. The purpose 
32   * of this Adapter is only to demonstrate:
33   * <ul>
34   * <li>How to use PerfectJPattern's {@link Adapter} implementation to adapt an 
35   * implementation to a given target interface</li>
36   * <li>How the componentized Adapter facilitates adapting types by means of:
37   * <ul>
38   * <li>Automatically delegating to the adapter implementation calls made to 
39   * the target interface in this case e.g. {@link #remove()}, {@link #poll()} 
40   * {@link #element()} {@link #peek()}</li>
41   * <li>Otherwise automatically delegating to the Adaptee implementation using 
42   * a specified {@link IAdaptingStrategy} in this case 
43   * {@link NameMatchAdaptingStrategy} where it maps e.g. {@link Queue#
44   * offer(Object)} to {@link ArrayList#add(Object)}</li>
45   * </ul>
46   * </li>
47   * </ul>
48   * Noteworthy is how this implementation did NOT have to provide a full blown
49   * implementation of all of the Target {@link Queue} interface methods e.g. 
50   * {@link Collection#addAll(Collection)} or {@link Collection#toArray()} as 
51   * the call forwarding is automatically handled by PerfectJPattern's 
52   * {@link Adapter} 
53   * <br/><br/>
54   * 
55   * @param <E> Type of the {@link Queue} elements
56   * 
57   * @author <a href="mailto:bravegag@hotmail.com">Giovanni Azua</a>
58   * @version $Revision: 1.0 $Date: Feb 5, 2009 8:55:42 PM $
59   */
60  public 
61  class List2QueueAdapter<E>
62  extends Adapter<Queue<E>, List<E>>
63  {
64      //------------------------------------------------------------------------
65      // public
66      //------------------------------------------------------------------------
67      /**
68       * Constructs a {@link List2QueueAdapter} from the underlying Adaptee 
69       * {@link List} implementation.
70       * 
71       * @param anAdaptee The Adaptee {@link List} implementation to adapt
72       * @throws IllegalArgumentException 'anAdaptee' must not be null
73       */
74      @SuppressWarnings("unchecked")
75      public 
76      List2QueueAdapter(List<E> anAdaptee)
77      throws IllegalArgumentException
78      {
79          super((Class<Queue<E>>) ((Class<?>) Queue.class), anAdaptee, 
80              new NameMatchAdaptingStrategy(METHODS_MAPPING));
81      }    
82  
83      //------------------------------------------------------------------------
84      /**
85       * Retrieves and removes the head of this queue.  This method differs
86       * from {@link #poll poll} only in that it throws an exception if this
87       * queue is empty.
88       *
89       * @return the head of this queue
90       * @throws NoSuchElementException if this queue is empty
91       */
92      public E 
93      remove()
94      throws NoSuchElementException
95      {
96          List<E> myList = getUnderlying(); 
97  
98          if (myList.isEmpty())
99          {
100             throw new NoSuchElementException("The Queue is empty");
101         }
102         
103         E myElement = myList.get(0);
104         myList.remove(0);
105             
106         return myElement;                    
107     }    
108 
109     //------------------------------------------------------------------------
110     /**
111      * Retrieves and removes the head of this queue,
112      * or returns <tt>null</tt> if this queue is empty.
113      *
114      * @return the head of this queue, or <tt>null</tt> if this queue is empty
115      */
116     public E 
117     poll()
118     {
119         E myElement = null;
120         try
121         {
122             myElement = remove();
123         }
124         catch (NoSuchElementException anException)
125         {
126             // nothing to do
127         }
128             
129         return myElement;                            
130     }
131 
132     //------------------------------------------------------------------------
133     /**
134      * Retrieves, but does not remove, the head of this queue.  This method
135      * differs from {@link #peek peek} only in that it throws an exception
136      * if this queue is empty.
137      *
138      * @return the head of this queue
139      * @throws NoSuchElementException if this queue is empty
140      */
141     public E 
142     element()
143     {
144         List<E> myList = getUnderlying(); 
145 
146         if (myList.isEmpty())
147         {
148             throw new NoSuchElementException("The Queue is empty");
149         }
150         
151         E myElement = myList.get(0);
152             
153         return myElement;                            
154     }
155 
156     //------------------------------------------------------------------------
157     /**
158      * Retrieves, but does not remove, the head of this queue,
159      * or returns <tt>null</tt> if this queue is empty.
160      *
161      * @return the head of this queue, or <tt>null</tt> if this queue is empty
162      */
163     public E 
164     peek()
165     {
166         E myElement = null;
167         try
168         {
169             myElement = element();
170         }
171         catch (NoSuchElementException anException)
172         {
173             // nothing to do
174         }
175             
176         return myElement;                                    
177     }    
178     
179     //------------------------------------------------------------------------
180     // members
181     //------------------------------------------------------------------------
182     private static final Map<String, String> METHODS_MAPPING = 
183         new HashMap<String, String>();    
184     static
185     {
186         METHODS_MAPPING.put("add", "add");
187         METHODS_MAPPING.put("offer", "add");        
188     }
189 }