View Javadoc

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  
18  
19  package org.apache.commons.beanutils;
20  
21  
22  import java.sql.SQLException;
23  import java.util.Iterator;
24  import java.util.NoSuchElementException;
25  
26  
27  /***
28   * <p>Implementation of <code>java.util.Iterator</code> returned by the
29   * <code>iterator()</code> method of {@link ResultSetDynaClass}.  Each
30   * object returned by this iterator will be a {@link DynaBean} that
31   * represents a single row from the result set being wrapped.</p>
32   *
33   * @author Craig R. McClanahan
34   * @version $Revision: 556221 $ $Date: 2007-07-14 05:19:21 +0100 (Sat, 14 Jul 2007) $
35   */
36  
37  public class ResultSetIterator implements DynaBean, Iterator {
38  
39  
40      // ------------------------------------------------------------ Constructor
41  
42  
43      /***
44       * <p>Construct an <code>Iterator</code> for the result set being wrapped
45       * by the specified {@link ResultSetDynaClass}.</p>
46       *
47       * @param dynaClass The {@link ResultSetDynaClass} wrapping the
48       *  result set we will iterate over
49       */
50      ResultSetIterator(ResultSetDynaClass dynaClass) {
51  
52          this.dynaClass = dynaClass;
53  
54      }
55  
56  
57      // ----------------------------------------------------- Instance Variables
58  
59  
60  
61      /***
62       * <p>Flag indicating whether the result set is currently positioned at a
63       * row for which we have not yet returned an element in the iteration.</p>
64       */
65      protected boolean current = false;
66  
67  
68      /***
69       * <p>The {@link ResultSetDynaClass} we are associated with.</p>
70       */
71      protected ResultSetDynaClass dynaClass = null;
72  
73  
74      /***
75       * <p>Flag indicating whether the result set has indicated that there are
76       * no further rows.</p>
77       */
78      protected boolean eof = false;
79  
80  
81      // ------------------------------------------------------- DynaBean Methods
82  
83  
84      /***
85       * Does the specified mapped property contain a value for the specified
86       * key value?
87       *
88       * @param name Name of the property to check
89       * @param key Name of the key to check
90       * @return <code>true<code> if the mapped property contains a value for
91       * the specified key, otherwise <code>false</code>
92       *
93       * @exception IllegalArgumentException if there is no property
94       *  of the specified name
95       */
96      public boolean contains(String name, String key) {
97  
98          throw new UnsupportedOperationException
99              ("FIXME - mapped properties not currently supported");
100 
101     }
102 
103 
104     /***
105      * Return the value of a simple property with the specified name.
106      *
107      * @param name Name of the property whose value is to be retrieved
108      * @return The property's value
109      *
110      * @exception IllegalArgumentException if there is no property
111      *  of the specified name
112      */
113     public Object get(String name) {
114 
115         if (dynaClass.getDynaProperty(name) == null) {
116             throw new IllegalArgumentException(name);
117         }
118         try {
119             return dynaClass.getObjectFromResultSet(name);
120         } catch (SQLException e) {
121             throw new RuntimeException
122                 ("get(" + name + "): SQLException: " + e);
123         }
124 
125     }
126 
127 
128     /***
129      * Return the value of an indexed property with the specified name.
130      *
131      * @param name Name of the property whose value is to be retrieved
132      * @param index Index of the value to be retrieved
133      * @return The indexed property's value
134      *
135      * @exception IllegalArgumentException if there is no property
136      *  of the specified name
137      * @exception IllegalArgumentException if the specified property
138      *  exists, but is not indexed
139      * @exception IndexOutOfBoundsException if the specified index
140      *  is outside the range of the underlying property
141      * @exception NullPointerException if no array or List has been
142      *  initialized for this property
143      */
144     public Object get(String name, int index) {
145 
146         throw new UnsupportedOperationException
147             ("FIXME - indexed properties not currently supported");
148 
149     }
150 
151 
152     /***
153      * Return the value of a mapped property with the specified name,
154      * or <code>null</code> if there is no value for the specified key.
155      *
156      * @param name Name of the property whose value is to be retrieved
157      * @param key Key of the value to be retrieved
158      * @return The mapped property's value
159      *
160      * @exception IllegalArgumentException if there is no property
161      *  of the specified name
162      * @exception IllegalArgumentException if the specified property
163      *  exists, but is not mapped
164      */
165     public Object get(String name, String key) {
166 
167         throw new UnsupportedOperationException
168             ("FIXME - mapped properties not currently supported");
169 
170     }
171 
172 
173     /***
174      * Return the <code>DynaClass</code> instance that describes the set of
175      * properties available for this DynaBean.
176      *
177      * @return The associated DynaClass
178      */
179     public DynaClass getDynaClass() {
180 
181         return (this.dynaClass);
182 
183     }
184 
185 
186     /***
187      * Remove any existing value for the specified key on the
188      * specified mapped property.
189      *
190      * @param name Name of the property for which a value is to
191      *  be removed
192      * @param key Key of the value to be removed
193      *
194      * @exception IllegalArgumentException if there is no property
195      *  of the specified name
196      */
197     public void remove(String name, String key) {
198 
199         throw new UnsupportedOperationException
200             ("FIXME - mapped operations not currently supported");
201 
202     }
203 
204 
205     /***
206      * Set the value of a simple property with the specified name.
207      *
208      * @param name Name of the property whose value is to be set
209      * @param value Value to which this property is to be set
210      *
211      * @exception ConversionException if the specified value cannot be
212      *  converted to the type required for this property
213      * @exception IllegalArgumentException if there is no property
214      *  of the specified name
215      * @exception NullPointerException if an attempt is made to set a
216      *  primitive property to null
217      */
218     public void set(String name, Object value) {
219 
220         if (dynaClass.getDynaProperty(name) == null) {
221             throw new IllegalArgumentException(name);
222         }
223         try {
224             dynaClass.getResultSet().updateObject(name, value);
225         } catch (SQLException e) {
226             throw new RuntimeException
227                 ("set(" + name + "): SQLException: " + e);
228         }
229 
230     }
231 
232 
233     /***
234      * Set the value of an indexed property with the specified name.
235      *
236      * @param name Name of the property whose value is to be set
237      * @param index Index of the property to be set
238      * @param value Value to which this property is to be set
239      *
240      * @exception ConversionException if the specified value cannot be
241      *  converted to the type required for this property
242      * @exception IllegalArgumentException if there is no property
243      *  of the specified name
244      * @exception IllegalArgumentException if the specified property
245      *  exists, but is not indexed
246      * @exception IndexOutOfBoundsException if the specified index
247      *  is outside the range of the underlying property
248      */
249     public void set(String name, int index, Object value) {
250 
251         throw new UnsupportedOperationException
252             ("FIXME - indexed properties not currently supported");
253 
254     }
255 
256 
257     /***
258      * Set the value of a mapped property with the specified name.
259      *
260      * @param name Name of the property whose value is to be set
261      * @param key Key of the property to be set
262      * @param value Value to which this property is to be set
263      *
264      * @exception ConversionException if the specified value cannot be
265      *  converted to the type required for this property
266      * @exception IllegalArgumentException if there is no property
267      *  of the specified name
268      * @exception IllegalArgumentException if the specified property
269      *  exists, but is not mapped
270      */
271     public void set(String name, String key, Object value) {
272 
273         throw new UnsupportedOperationException
274             ("FIXME - mapped properties not currently supported");
275 
276     }
277 
278 
279     // ------------------------------------------------------- Iterator Methods
280 
281 
282     /***
283      * <p>Return <code>true</code> if the iteration has more elements.</p>
284      *
285      * @return <code>true</code> if the result set has another
286      * row, otherwise <code>false</code>
287      */
288     public boolean hasNext() {
289 
290         try {
291             advance();
292             return (!eof);
293         } catch (SQLException e) {
294             throw new RuntimeException("hasNext():  SQLException:  " + e);
295         }
296 
297     }
298 
299 
300     /***
301      * <p>Return the next element in the iteration.</p>
302      *
303      * @return advance to the new row and return this
304      */
305     public Object next() {
306 
307         try {
308             advance();
309             if (eof) {
310                 throw new NoSuchElementException();
311             }
312             current = false;
313             return (this);
314         } catch (SQLException e) {
315             throw new RuntimeException("next():  SQLException:  " + e);
316         }
317 
318     }
319 
320 
321     /***
322      * <p>Remove the current element from the iteration.  This method is
323      * not supported.</p>
324      */
325     public void remove() {
326 
327         throw new UnsupportedOperationException("remove()");
328 
329     }
330 
331 
332     // ------------------------------------------------------ Protected Methods
333 
334 
335     /***
336      * <p>Advance the result set to the next row, if there is not a current
337      * row (and if we are not already at eof).</p>
338      *
339      * @exception SQLException if the result set throws an exception
340      */
341     protected void advance() throws SQLException {
342 
343         if (!current && !eof) {
344             if (dynaClass.getResultSet().next()) {
345                 current = true;
346                 eof = false;
347             } else {
348                 current = false;
349                 eof = true;
350             }
351         }
352 
353     }
354 
355 
356 }