    001    /*
    002     * Licensed to the Apache Software Foundation (ASF) under one or more
    003     * contributor license agreements.  See the NOTICE file distributed with
    004     * this work for additional information regarding copyright ownership.
    005     * The ASF licenses this file to You under the Apache License, Version 2.0
    006     * (the "License"); you may not use this file except in compliance with
    007     * the License.  You may obtain a copy of the License at
    008     *
    009     *      http://www.apache.org/licenses/LICENSE-2.0
    010     *
    011     * Unless required by applicable law or agreed to in writing, software
    012     * distributed under the License is distributed on an "AS IS" BASIS,
    013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014     * See the License for the specific language governing permissions and
    015     * limitations under the License.
    016     */
    017
    018
    019    package org.apache.commons.beanutils;
    020
    021
    022    import java.sql.SQLException;
    023    import java.util.Iterator;
    024    import java.util.NoSuchElementException;
    025
    026
    027    /**
    028     * <p>Implementation of <code>java.util.Iterator</code> returned by the
    029     * <code>iterator()</code> method of {@link ResultSetDynaClass}.  Each
    030     * object returned by this iterator will be a {@link DynaBean} that
    031     * represents a single row from the result set being wrapped.</p>
    032     *
    033     * @author Craig R. McClanahan
    034     * @version $Revision: 556221 $ $Date: 2007-07-14 05:19:21 +0100 (Sat, 14 Jul 2007) $
    035     */
    036
    037    public class ResultSetIterator implements DynaBean, Iterator {
    038
    039
    040        // ------------------------------------------------------------ Constructor
    041
    042
    043        /**
    044         * <p>Construct an <code>Iterator</code> for the result set being wrapped
    045         * by the specified {@link ResultSetDynaClass}.</p>
    046         *
    047         * @param dynaClass The {@link ResultSetDynaClass} wrapping the
    048         *  result set we will iterate over
    049         */
    050        ResultSetIterator(ResultSetDynaClass dynaClass) {
    051
    052            this.dynaClass = dynaClass;
    053
    054        }
    055
    056
    057        // ----------------------------------------------------- Instance Variables
    058
    059
    060
    061        /**
    062         * <p>Flag indicating whether the result set is currently positioned at a
    063         * row for which we have not yet returned an element in the iteration.</p>
    064         */
    065        protected boolean current = false;
    066
    067
    068        /**
    069         * <p>The {@link ResultSetDynaClass} we are associated with.</p>
    070         */
    071        protected ResultSetDynaClass dynaClass = null;
    072
    073
    074        /**
    075         * <p>Flag indicating whether the result set has indicated that there are
    076         * no further rows.</p>
    077         */
    078        protected boolean eof = false;
    079
    080
    081        // ------------------------------------------------------- DynaBean Methods
    082
    083
    084        /**
    085         * Does the specified mapped property contain a value for the specified
    086         * key value?
    087         *
    088         * @param name Name of the property to check
    089         * @param key Name of the key to check
    090         * @return <code>true<code> if the mapped property contains a value for
    091         * the specified key, otherwise <code>false</code>
    092         *
    093         * @exception IllegalArgumentException if there is no property
    094         *  of the specified name
    095         */
    096        public boolean contains(String name, String key) {
    097
    098            throw new UnsupportedOperationException
    099                ("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    }