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