1. /*
  2. * Copyright 2001-2004 The Apache Software Foundation.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package org.apache.commons.beanutils;
  17. import java.sql.ResultSet;
  18. import java.sql.SQLException;
  19. import java.util.Iterator;
  20. import java.util.NoSuchElementException;
  21. /**
  22. * <p>Implementation of <code>java.util.Iterator</code> returned by the
  23. * <code>iterator()</code> method of {@link ResultSetDynaClass}. Each
  24. * object returned by this iterator will be a {@link DynaBean} that
  25. * represents a single row from the result set being wrapped.</p>
  26. *
  27. * @author Craig R. McClanahan
  28. * @version $Revision: 1.5 $ $Date: 2004/02/28 13:18:34 $
  29. */
  30. public class ResultSetIterator implements DynaBean, Iterator {
  31. // ------------------------------------------------------------ Constructor
  32. /**
  33. * <p>Construct an <code>Iterator</code> for the result set being wrapped
  34. * by the specified {@link ResultSetDynaClass}.</p>
  35. *
  36. * @param dynaClass The {@link ResultSetDynaClass} wrapping the
  37. * result set we will iterate over
  38. */
  39. ResultSetIterator(ResultSetDynaClass dynaClass) {
  40. this.dynaClass = dynaClass;
  41. }
  42. // ----------------------------------------------------- Instance Variables
  43. /**
  44. * <p>Flag indicating whether the result set is currently positioned at a
  45. * row for which we have not yet returned an element in the iteration.</p>
  46. */
  47. protected boolean current = false;
  48. /**
  49. * <p>The {@link ResultSetDynaClass} we are associated with.</p>
  50. */
  51. protected ResultSetDynaClass dynaClass = null;
  52. /**
  53. * <p>Flag indicating whether the result set has indicated that there are
  54. * no further rows.</p>
  55. */
  56. protected boolean eof = false;
  57. // ------------------------------------------------------- DynaBean Methods
  58. /**
  59. * Does the specified mapped property contain a value for the specified
  60. * key value?
  61. *
  62. * @param name Name of the property to check
  63. * @param key Name of the key to check
  64. *
  65. * @exception IllegalArgumentException if there is no property
  66. * of the specified name
  67. */
  68. public boolean contains(String name, String key) {
  69. throw new UnsupportedOperationException
  70. ("FIXME - mapped properties not currently supported");
  71. }
  72. /**
  73. * Return the value of a simple property with the specified name.
  74. *
  75. * @param name Name of the property whose value is to be retrieved
  76. *
  77. * @exception IllegalArgumentException if there is no property
  78. * of the specified name
  79. */
  80. public Object get(String name) {
  81. if (dynaClass.getDynaProperty(name) == null) {
  82. throw new IllegalArgumentException(name);
  83. }
  84. try {
  85. return (dynaClass.getResultSet().getObject(name));
  86. } catch (SQLException e) {
  87. throw new RuntimeException
  88. ("get(" + name + "): SQLException: " + e);
  89. }
  90. }
  91. /**
  92. * Return the value of an indexed property with the specified name.
  93. *
  94. * @param name Name of the property whose value is to be retrieved
  95. * @param index Index of the value to be retrieved
  96. *
  97. * @exception IllegalArgumentException if there is no property
  98. * of the specified name
  99. * @exception IllegalArgumentException if the specified property
  100. * exists, but is not indexed
  101. * @exception IndexOutOfBoundsException if the specified index
  102. * is outside the range of the underlying property
  103. * @exception NullPointerException if no array or List has been
  104. * initialized for this property
  105. */
  106. public Object get(String name, int index) {
  107. throw new UnsupportedOperationException
  108. ("FIXME - indexed properties not currently supported");
  109. }
  110. /**
  111. * Return the value of a mapped property with the specified name,
  112. * or <code>null</code> if there is no value for the specified key.
  113. *
  114. * @param name Name of the property whose value is to be retrieved
  115. * @param key Key of the value to be retrieved
  116. *
  117. * @exception IllegalArgumentException if there is no property
  118. * of the specified name
  119. * @exception IllegalArgumentException if the specified property
  120. * exists, but is not mapped
  121. */
  122. public Object get(String name, String key) {
  123. throw new UnsupportedOperationException
  124. ("FIXME - mapped properties not currently supported");
  125. }
  126. /**
  127. * Return the <code>DynaClass</code> instance that describes the set of
  128. * properties available for this DynaBean.
  129. */
  130. public DynaClass getDynaClass() {
  131. return (this.dynaClass);
  132. }
  133. /**
  134. * Remove any existing value for the specified key on the
  135. * specified mapped property.
  136. *
  137. * @param name Name of the property for which a value is to
  138. * be removed
  139. * @param key Key of the value to be removed
  140. *
  141. * @exception IllegalArgumentException if there is no property
  142. * of the specified name
  143. */
  144. public void remove(String name, String key) {
  145. throw new UnsupportedOperationException
  146. ("FIXME - mapped operations not currently supported");
  147. }
  148. /**
  149. * Set the value of a simple property with the specified name.
  150. *
  151. * @param name Name of the property whose value is to be set
  152. * @param value Value to which this property is to be set
  153. *
  154. * @exception ConversionException if the specified value cannot be
  155. * converted to the type required for this property
  156. * @exception IllegalArgumentException if there is no property
  157. * of the specified name
  158. * @exception NullPointerException if an attempt is made to set a
  159. * primitive property to null
  160. */
  161. public void set(String name, Object value) {
  162. if (dynaClass.getDynaProperty(name) == null) {
  163. throw new IllegalArgumentException(name);
  164. }
  165. try {
  166. dynaClass.getResultSet().updateObject(name, value);
  167. } catch (SQLException e) {
  168. throw new RuntimeException
  169. ("set(" + name + "): SQLException: " + e);
  170. }
  171. }
  172. /**
  173. * Set the value of an indexed property with the specified name.
  174. *
  175. * @param name Name of the property whose value is to be set
  176. * @param index Index of the property to be set
  177. * @param value Value to which this property is to be set
  178. *
  179. * @exception ConversionException if the specified value cannot be
  180. * converted to the type required for this property
  181. * @exception IllegalArgumentException if there is no property
  182. * of the specified name
  183. * @exception IllegalArgumentException if the specified property
  184. * exists, but is not indexed
  185. * @exception IndexOutOfBoundsException if the specified index
  186. * is outside the range of the underlying property
  187. */
  188. public void set(String name, int index, Object value) {
  189. throw new UnsupportedOperationException
  190. ("FIXME - indexed properties not currently supported");
  191. }
  192. /**
  193. * Set the value of a mapped property with the specified name.
  194. *
  195. * @param name Name of the property whose value is to be set
  196. * @param key Key of the property to be set
  197. * @param value Value to which this property is to be set
  198. *
  199. * @exception ConversionException if the specified value cannot be
  200. * converted to the type required for this property
  201. * @exception IllegalArgumentException if there is no property
  202. * of the specified name
  203. * @exception IllegalArgumentException if the specified property
  204. * exists, but is not mapped
  205. */
  206. public void set(String name, String key, Object value) {
  207. throw new UnsupportedOperationException
  208. ("FIXME - mapped properties not currently supported");
  209. }
  210. // ------------------------------------------------------- Iterator Methods
  211. /**
  212. * <p>Return <code>true</code> if the iteration has more elements.</p>
  213. */
  214. public boolean hasNext() {
  215. try {
  216. advance();
  217. return (!eof);
  218. } catch (SQLException e) {
  219. throw new RuntimeException("hasNext(): SQLException: " + e);
  220. }
  221. }
  222. /**
  223. * <p>Return the next element in the iteration.</p>
  224. */
  225. public Object next() {
  226. try {
  227. advance();
  228. if (eof) {
  229. throw new NoSuchElementException();
  230. }
  231. current = false;
  232. return (this);
  233. } catch (SQLException e) {
  234. throw new RuntimeException("next(): SQLException: " + e);
  235. }
  236. }
  237. /**
  238. * <p>Remove the current element from the iteration. This method is
  239. * not supported.</p>
  240. */
  241. public void remove() {
  242. throw new UnsupportedOperationException("remove()");
  243. }
  244. // ------------------------------------------------------ Protected Methods
  245. /**
  246. * <p>Advance the result set to the next row, if there is not a current
  247. * row (and if we are not already at eof).</p>
  248. *
  249. * @exception SQLException if the result set throws an exception
  250. */
  251. protected void advance() throws SQLException {
  252. if (!current && !eof) {
  253. if (dynaClass.getResultSet().next()) {
  254. current = true;
  255. eof = false;
  256. } else {
  257. current = false;
  258. eof = true;
  259. }
  260. }
  261. }
  262. }