Home » Mojarra-2.0.1 » javax » faces » model » [javadoc | source]

    1   /*
    2    * $Id: ResultSetDataModel.java,v 1.34 2007/04/27 22:00:09 ofung Exp $
    3    */
    4   
    5   /*
    6    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    7    * 
    8    * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
    9    * 
   10    * The contents of this file are subject to the terms of either the GNU
   11    * General Public License Version 2 only ("GPL") or the Common Development
   12    * and Distribution License("CDDL") (collectively, the "License").  You
   13    * may not use this file except in compliance with the License. You can obtain
   14    * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
   15    * or glassfish/bootstrap/legal/LICENSE.txt.  See the License for the specific
   16    * language governing permissions and limitations under the License.
   17    * 
   18    * When distributing the software, include this License Header Notice in each
   19    * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
   20    * Sun designates this particular file as subject to the "Classpath" exception
   21    * as provided by Sun in the GPL Version 2 section of the License file that
   22    * accompanied this code.  If applicable, add the following below the License
   23    * Header, with the fields enclosed by brackets [] replaced by your own
   24    * identifying information: "Portions Copyrighted [year]
   25    * [name of copyright owner]"
   26    * 
   27    * Contributor(s):
   28    * 
   29    * If you wish your version of this file to be governed by only the CDDL or
   30    * only the GPL Version 2, indicate your decision by adding "[Contributor]
   31    * elects to include this software in this distribution under the [CDDL or GPL
   32    * Version 2] license."  If you don't indicate a single choice of license, a
   33    * recipient has the option to distribute your version of this file under
   34    * either the CDDL, the GPL Version 2 or to extend the choice of license to
   35    * its licensees as provided above.  However, if you add GPL Version 2 code
   36    * and therefore, elected the GPL Version 2 license, then the option applies
   37    * only if the new code is made subject to such option by the copyright
   38    * holder.
   39    */
   40   
   41   package javax.faces.model;
   42   
   43   
   44   import java.sql.ResultSet;
   45   import java.sql.ResultSetMetaData;
   46   import java.sql.SQLException;
   47   import java.util.AbstractCollection;
   48   import java.util.AbstractSet;
   49   import java.util.Collection;
   50   import java.util.Comparator;
   51   import java.util.Iterator;
   52   import java.util.Map;
   53   import java.util.Set;
   54   import java.util.TreeMap;
   55   import java.io.IOException;
   56   import java.io.ObjectInputStream;
   57   import java.io.NotSerializableException;
   58   import java.io.ObjectOutputStream;
   59   
   60   import javax.faces.FacesException;
   61   
   62   
   63   /**
   64    * <p><strong>ResultSetDataModel</strong> is a convenience implementation of
   65    * {@link DataModel} that wraps a <code>ResultSet</code> of Java objects.
   66    * Note that the specified <code>ResultSet</code> <strong>MUST</strong>
   67    * be scrollable.  In addition, if input components (that will be updating
   68    * model values) reference this object in value binding expressions, the
   69    * specified <code>ResultSet</code> <strong>MUST</strong> be updatable.</p>
   70    */
   71   
   72   public class ResultSetDataModel extends DataModel<Map<String,Object>> {
   73   
   74   
   75       // ------------------------------------------------------------ Constructors
   76   
   77   
   78       /**
   79        * <p>Construct a new {@link ResultSetDataModel} with no specified
   80        * wrapped data.</p>
   81        */
   82       public ResultSetDataModel() {
   83   
   84           this(null);
   85   
   86       }
   87   
   88   
   89       /**
   90        * <p>Construct a new {@link ResultSetDataModel} wrapping the specified
   91        * <code>ResultSet</code>.</p>
   92        *
   93        * @param resultSet <code>ResultSet</code> to be wrapped (if any)
   94        */
   95       public ResultSetDataModel(ResultSet resultSet) {
   96   
   97           super();
   98           setWrappedData(resultSet);
   99   
  100       }
  101   
  102   
  103       // ------------------------------------------------------ Instance Variables
  104   
  105   
  106       // The current row index (zero relative)
  107       private int index = -1;
  108   
  109   
  110       // The metadata for the ResultSet we are wrapping (lazily instantiated)
  111       private ResultSetMetaData metadata = null;
  112   
  113   
  114       // The ResultSet we are wrapping
  115       private ResultSet resultSet = null;
  116   
  117   
  118       // Has the row at the current index been updated?
  119       private boolean updated = false;
  120   
  121   
  122       // -------------------------------------------------------------- Properties
  123   
  124   
  125       /**
  126        * <p>Return <code>true</code> if there is <code>wrappedData</code>
  127        * available, and the result of calling <code>absolute()</code> on the
  128        * underlying <code>ResultSet</code>, passing the current value of
  129        * <code>rowIndex</code> plus one (to account for the fact that
  130        * <code>ResultSet</code> uses one-relative indexing), returns
  131        * <code>true</code>.  Otherwise, return <code>false</code>.</p>
  132        *
  133        * @throws FacesException if an error occurs getting the row availability
  134        */ 
  135       public boolean isRowAvailable() {
  136   
  137           if (resultSet == null) {
  138   	    return (false);
  139           } else if (index < 0) {
  140               return (false);
  141           }
  142           try {
  143               if (resultSet.absolute(index + 1)) {
  144                   return (true);
  145               } else {
  146                   return (false);
  147               }
  148           } catch (SQLException e) {
  149               throw new FacesException(e);
  150           }
  151   
  152       }
  153   
  154   
  155       /**
  156        * <p>Return -1, since <code>ResultSet</code> does not provide a
  157        * standard way to determine the number of available rows without
  158        * scrolling through the entire <code>ResultSet</code>, and this can
  159        * be very expensive if the number of rows is large.</p>
  160        *
  161        * @throws FacesException if an error occurs getting the row count
  162        */
  163       public int getRowCount() {
  164   
  165   	return (-1);
  166   
  167       }
  168   
  169   
  170       /**
  171        * <p>If row data is available, return a <code>Map</code> representing
  172        * the values of the columns for the row specified by <code>rowIndex</code>,
  173        * keyed by the corresponding column names.  If no wrapped data is
  174        * available, return <code>null</code>.</p>
  175        *
  176        * <p>If a non-<code>null</code> <code>Map</code> is returned, its behavior
  177        * must correspond to the contract for a mutable <code>Map</code> as
  178        * described in the JavaDocs for <code>AbstractMap</code>, with the
  179        * following exceptions and specialized behavior:</p>
  180        * <ul>
  181   
  182        * <li>The <code>Map</code>, and any supporting objects it returns,
  183        *     must perform all column name comparisons in a
  184        *     case-insensitive manner.  This case-insensitivity must be
  185        *     implemented using a case-insensitive <code>Comparator</code>,
  186        *     such as
  187        *     <code>String.CASE_INSENSITIVE_ORDER</code>.</li>
  188   
  189        * <li>The following methods must throw
  190        *     <code>UnsupportedOperationException</code>:  <code>clear()</code>,
  191        *     <code>remove()</code>.</li>
  192        * <li>The <code>entrySet()</code> method must return a <code>Set</code>
  193        *     that has the following behavior:
  194        *     <ul>
  195        *     <li>Throw <code>UnsupportedOperationException</code> for any attempt
  196        *         to add or remove entries from the <code>Set</code>, either
  197        *         directly or indirectly through an <code>Iterator</code>
  198        *         returned by the <code>Set</code>.</li>
  199        *     <li>Updates to the <code>value</code> of an entry in this
  200        *         <code>set</code> must write through to the corresponding
  201        *         column value in the underlying <code>ResultSet</code>.</li>
  202        *     </ul></li>
  203        * <li>The <code>keySet()</code> method must return a <code>Set</code>
  204        *     that throws <code>UnsupportedOperationException</code> on any
  205        *     attempt to add or remove keys, either directly or through an
  206        *     <code>Iterator</code> returned by the <code>Set</code>.</li>
  207        * <li>The <code>put()</code> method must throw
  208        *     <code>IllegalArgumentException</code> if a key value for which
  209        *     <code>containsKey()</code> returns <code>false</code> is
  210        *     specified.  However, if a key already present in the <code>Map</code>
  211        *     is specified, the specified value must write through to the
  212        *     corresponding column value in the underlying <code>ResultSet</code>.
  213        *     </li>
  214        * <li>The <code>values()</code> method must return a
  215        *     <code>Collection</code> that throws
  216        *     <code>UnsupportedOperationException</code> on any attempt to add
  217        *     or remove values, either directly or through an <code>Iterator</code>
  218        *     returned by the <code>Collection</code>.</li>
  219        * </ul>
  220        *
  221        * @throws FacesException if an error occurs getting the row data
  222        * @throws IllegalArgumentException if now row data is available
  223        *  at the currently specified row index
  224        */ 
  225       public Map<String,Object> getRowData() {
  226   
  227           if (resultSet == null) {
  228   	    return (null);
  229           } else if (!isRowAvailable()) {
  230               throw new NoRowAvailableException();
  231           }
  232           try {
  233               getMetaData();
  234               return (new ResultSetMap(this, String.CASE_INSENSITIVE_ORDER));
  235           } catch (SQLException e) {
  236               throw new FacesException(e);
  237           }
  238   
  239       }
  240   
  241   
  242       /**
  243        * @throws FacesException {@inheritDoc}     
  244        */ 
  245       public int getRowIndex() {
  246   
  247           return (index);
  248   
  249       }
  250   
  251   
  252       /**
  253        * @throws FacesException {@inheritDoc}
  254        * @throws IllegalArgumentException {@inheritDoc}
  255        */ 
  256       public void setRowIndex(int rowIndex) {
  257   
  258           if (rowIndex < -1) {
  259               throw new IllegalArgumentException();
  260           }
  261   
  262           // Tell the ResultSet that the previous row was updated if necessary
  263           if (updated && (resultSet != null)) {
  264               try {
  265   		if (!resultSet.rowDeleted()) {
  266   		    resultSet.updateRow();
  267   		}
  268                   updated = false;
  269               } catch (SQLException e) {
  270                   throw new FacesException(e);
  271               }
  272           }
  273   
  274           int old = index;
  275           index = rowIndex;
  276   	if (resultSet == null) {
  277   	    return;
  278   	}
  279   	DataModelListener [] listeners = getDataModelListeners();
  280           if ((old != index) && (listeners != null)) {
  281               Object rowData = null;
  282               if (isRowAvailable()) {
  283                   rowData = getRowData();
  284               }
  285               DataModelEvent event =
  286                   new DataModelEvent(this, index, rowData);
  287               int n = listeners.length;
  288               for (int i = 0; i < n; i++) {
  289   		if (null != listeners[i]) {
  290   		    listeners[i].rowSelected(event);
  291   		}
  292               }
  293           }
  294   
  295   
  296       }
  297   
  298   
  299       public Object getWrappedData() {
  300   
  301           return (this.resultSet);
  302   
  303       }
  304   
  305   
  306       /**
  307        * @throws ClassCastException {@inheritDoc}
  308        */
  309       public void setWrappedData(Object data) {
  310   
  311           if (data == null) {
  312               metadata = null;
  313               resultSet = null;
  314               setRowIndex(-1);
  315           } else {
  316               metadata = null;
  317               resultSet = (ResultSet) data;
  318               index = -1;
  319               setRowIndex(0);
  320           }
  321       }
  322   
  323   
  324       // --------------------------------------------------------- Private Methods
  325   
  326   
  327       /**
  328        * <p>Return the <code>ResultSetMetaData</code> for the
  329        * <code>ResultSet</code> we are wrapping, caching it the first time
  330        * it is returned.</p>
  331        *
  332        * @throws FacesException if the <code>ResultSetMetaData</code>
  333        *  cannot be acquired
  334        */
  335       private ResultSetMetaData getMetaData() {
  336   
  337           if (metadata == null) {
  338               try {
  339                   metadata = resultSet.getMetaData();
  340               } catch (SQLException e) {
  341                   throw new FacesException(e);
  342               }
  343           }
  344           return (metadata);
  345   
  346       }
  347   
  348   
  349       /**
  350        * <p>Mark the current row as having been updated, so that we will call
  351        * <code>updateRow()</code> before moving elsewhere.</p>
  352        */
  353       private void updated() {
  354   
  355           this.updated = true;
  356   
  357       }
  358   
  359   
  360       // --------------------------------------------------------- Private Classes
  361   
  362   
  363       // Private implementation of Map that delegates column get and put
  364       // operations to the underlying ResultSet, after setting the required
  365       // row index
  366       // NOT SERIALIZABLE
  367       @SuppressWarnings({"serial"})
  368       private static class ResultSetMap extends TreeMap<String,Object> {
  369   
  370           private ResultSetDataModel model;
  371   
  372           public ResultSetMap(ResultSetDataModel model,
  373                               Comparator<String> comparator) throws SQLException {
  374   
  375               super(comparator);
  376               this.model = model;
  377               index = model.index;
  378               model.resultSet.absolute(index + 1);
  379               int n = model.metadata.getColumnCount();
  380               for (int i = 1; i <= n; i++) {
  381                   super.put(model.metadata.getColumnName(i),
  382                             model.metadata.getColumnName(i));
  383               }
  384           }
  385   
  386           // The zero-relative row index of our row
  387           private int index;
  388   
  389           // Removing entries is not allowed
  390           public void clear() {
  391               throw new UnsupportedOperationException();
  392           }
  393   
  394           public boolean containsValue(Object value) {
  395               for (Iterator i = entrySet().iterator(); i .hasNext(); ) {
  396                   Map.Entry entry = (Map.Entry) i.next();
  397                   Object contained = entry.getValue();
  398                    if (value == null) {
  399                       if (contained == null) {
  400                           return (true);
  401                       }
  402                   } else {
  403                       if (value.equals(contained)) {
  404                           return (true);
  405                       }
  406                   }
  407               }
  408               return (false);
  409           }
  410   
  411           public Set<Map.Entry<String,Object>> entrySet() {
  412               return (new ResultSetEntries(this));
  413           }
  414   
  415           public Object get(Object key) {
  416               if (!containsKey(key)) {
  417                   return (null);
  418               }
  419               try {
  420                   model.resultSet.absolute(index + 1);
  421                   return (model.resultSet.getObject((String) realKey(key)));
  422               } catch (SQLException e) {
  423                   throw new FacesException(e);
  424               }
  425           }
  426   
  427           public Set<String> keySet() {
  428               return (new ResultSetKeys(this));
  429           }
  430   
  431           public Object put(String key, Object value) {
  432               if (!containsKey(key)) {
  433                   throw new IllegalArgumentException();
  434               }
  435               
  436               try {
  437                   model.resultSet.absolute(index + 1);
  438                   Object previous = model.resultSet.getObject((String) realKey(key));
  439                   if ((previous == null) && (value == null)) {
  440                       return (previous);
  441                   } else if ((previous != null) && (value != null) &&
  442                              previous.equals(value)) {
  443                       return (previous);
  444                   }
  445                   model.resultSet.updateObject((String) realKey(key), value);
  446                   model.updated();
  447                   return (previous);
  448               } catch (SQLException e) {
  449                   throw new FacesException(e);
  450               }
  451           }
  452   
  453           public void putAll(Map<? extends String, ? extends Object> map) {
  454               for (Map.Entry<? extends String, ? extends Object> entry : map.entrySet()) {
  455                   put(entry.getKey(), entry.getValue());
  456               }
  457           }
  458   
  459           // Removing entries is not allowed
  460           public Object remove(Object key) {
  461               throw new UnsupportedOperationException();
  462           }
  463   
  464           public Collection<Object> values() {
  465               return (new ResultSetValues(this));
  466           }
  467   
  468           Object realKey(Object key) {
  469               return (super.get(key));
  470           }
  471   
  472           Iterator<String> realKeys() {
  473               return (super.keySet().iterator());
  474           }
  475   
  476           private void writeObject(ObjectOutputStream out) throws IOException {
  477               throw new NotSerializableException();
  478           }
  479   
  480           private void readObject(ObjectInputStream in) throws IOException {
  481               throw new NotSerializableException();
  482           }
  483   
  484       }
  485   
  486   
  487       // Private implementation of Set that implements the entrySet() behavior
  488       // for ResultSetMap
  489       private static class ResultSetEntries extends AbstractSet<Map.Entry<String,Object>> {
  490   
  491           public ResultSetEntries(ResultSetMap map) {
  492               this.map = map;
  493           }
  494   
  495           private ResultSetMap map;
  496   
  497           // Adding entries is not allowed
  498           public boolean add(Map.Entry<String,Object> o) {
  499               throw new UnsupportedOperationException();
  500           }
  501   
  502           // Adding entries is not allowed
  503           public boolean addAll(Collection c) {
  504               throw new UnsupportedOperationException();
  505           }
  506   
  507           // Removing entries is not allowed
  508           public void clear() {
  509               throw new UnsupportedOperationException();
  510           }
  511   
  512           public boolean contains(Object o) {
  513               if (o == null) {
  514                   throw new NullPointerException();
  515               }
  516               if (!(o instanceof Map.Entry)) {
  517                   return (false);
  518               }
  519               Map.Entry e = (Map.Entry) o;
  520               Object k = e.getKey();
  521               Object v = e.getValue();
  522               if (!map.containsKey(k)) {
  523                   return (false);
  524               }
  525               if (v == null) {
  526                   return (map.get(k) == null);
  527               } else {
  528                   return (v.equals(map.get(k)));
  529               }
  530           }
  531   
  532           public boolean isEmpty() {
  533               return (map.isEmpty());
  534           }
  535   
  536           public Iterator<Map.Entry<String,Object>> iterator() {
  537               return (new ResultSetEntriesIterator(map));
  538           }
  539   
  540           // Removing entries is not allowed
  541           public boolean remove(Object o) {
  542               throw new UnsupportedOperationException();
  543           }
  544   
  545           // Removing entries is not allowed
  546           public boolean removeAll(Collection c) {
  547               throw new UnsupportedOperationException();
  548           }
  549   
  550           // Removing entries is not allowed
  551           public boolean retainAll(Collection c) {
  552               throw new UnsupportedOperationException();
  553           }
  554   
  555           public int size() {
  556               return (map.size());
  557           }
  558   
  559       }
  560   
  561   
  562       // Private implementation of Iterator that implements the iterator()
  563       // behavior for the Set returned by entrySet() from ResultSetMap
  564       private static class ResultSetEntriesIterator implements Iterator<Map.Entry<String,Object>> {
  565   
  566           public ResultSetEntriesIterator(ResultSetMap map) {
  567               this.map = map;
  568               this.keys = map.keySet().iterator();
  569           }
  570   
  571           private ResultSetMap map = null;
  572           private Iterator<String> keys = null;
  573   
  574           public boolean hasNext() {
  575               return (keys.hasNext());
  576           }
  577   
  578           public Map.Entry<String,Object> next() {
  579               String key = keys.next();
  580               return (new ResultSetEntry(map, key));
  581           }
  582   
  583           // Removing entries is not allowed
  584           public void remove() {
  585               throw new UnsupportedOperationException();
  586           }
  587   
  588       }
  589   
  590   
  591       // Private implementation of Map.Entry that implements the behavior for
  592       // a single entry from the Set returned by entrySet() from ResultSetMap
  593       private static class ResultSetEntry implements Map.Entry<String,Object> {
  594   
  595           public ResultSetEntry(ResultSetMap map, String key) {
  596               this.map = map;
  597               this.key = key;
  598           }
  599   
  600           private ResultSetMap map;
  601           private String key;
  602   
  603           public boolean equals(Object o) {
  604               if (o == null) {
  605                   return (false);
  606               }
  607               if (!(o instanceof Map.Entry)) {
  608                   return (false);
  609               }
  610               Map.Entry e = (Map.Entry) o;
  611               if (key == null) {
  612                   if (e.getKey() != null) {
  613                       return (false);
  614                   }
  615               } else {
  616                   if (!key.equals(e.getKey())) {
  617                       return (false);
  618                   }
  619               }
  620               Object v = map.get(key);
  621               if (v == null) {
  622                   if (e.getValue() != null) {
  623                       return (false);
  624                   }
  625               } else {
  626                   if (!v.equals(e.getValue())) {
  627                       return (false);
  628                   }
  629               }
  630               return (true);
  631           }
  632   
  633           public String getKey() {
  634               return (key);
  635           }
  636   
  637           public Object getValue() {
  638               return (map.get(key));
  639           }
  640   
  641           public int hashCode() {
  642               Object value = map.get(key);
  643               return (((key == null) ? 0 : key.hashCode()) ^
  644                       ((value == null) ? 0 : value.hashCode()));
  645           }
  646   
  647           public Object setValue(Object value) {
  648               Object previous = map.get(key);
  649               map.put(key, value);
  650               return (previous);
  651           }
  652   
  653       }
  654   
  655   
  656       // Private implementation of Set that implements the keySet() behavior
  657       // for ResultSetMap
  658       private static class ResultSetKeys extends AbstractSet<String> {
  659   
  660           public ResultSetKeys(ResultSetMap map) {
  661               this.map = map;
  662           }
  663   
  664           private ResultSetMap map;
  665   
  666           // Adding keys is not allowed
  667           public boolean add(String o) {
  668               throw new UnsupportedOperationException();
  669           }
  670   
  671           // Adding keys is not allowed
  672           public boolean addAll(Collection c) {
  673               throw new UnsupportedOperationException();
  674           }
  675   
  676           // Removing keys is not allowed
  677           public void clear() {
  678               throw new UnsupportedOperationException();
  679           }
  680   
  681           public boolean contains(Object o) {
  682               return (map.containsKey(o));
  683           }
  684   
  685           public boolean isEmpty() {
  686               return (map.isEmpty());
  687           }
  688   
  689           public Iterator<String> iterator() {
  690               return (new ResultSetKeysIterator(map));
  691           }
  692   
  693           // Removing keys is not allowed
  694           public boolean remove(Object o) {
  695               throw new UnsupportedOperationException();
  696           }
  697   
  698           // Removing keys is not allowed
  699           public boolean removeAll(Collection c) {
  700               throw new UnsupportedOperationException();
  701           }
  702   
  703           // Removing keys is not allowed
  704           public boolean retainAll(Collection c) {
  705               throw new UnsupportedOperationException();
  706           }
  707   
  708           public int size() {
  709               return (map.size());
  710           }
  711   
  712       }
  713   
  714   
  715       // Private implementation of Iterator that implements the iterator()
  716       // behavior for the Set returned by keySet() from ResultSetMap
  717       private static class ResultSetKeysIterator implements Iterator<String> {
  718   
  719           public ResultSetKeysIterator(ResultSetMap map) {
  720               this.keys = map.realKeys();
  721           }
  722   
  723           private Iterator<String> keys = null;
  724   
  725           public boolean hasNext() {
  726               return (keys.hasNext());
  727           }
  728   
  729           public String next() {
  730               return (keys.next());
  731           }
  732   
  733           // Removing keys is not allowed
  734           public void remove() {
  735               throw new UnsupportedOperationException();
  736           }
  737   
  738       }
  739   
  740   
  741       // Private implementation of Collection that implements the behavior
  742       // for the Collection returned by values() from ResultSetMap
  743       private static class ResultSetValues extends AbstractCollection<Object> {
  744   
  745           public ResultSetValues(ResultSetMap map) {
  746               this.map = map;
  747           }
  748   
  749           private ResultSetMap map;
  750   
  751           public boolean add(Object o) {
  752               throw new UnsupportedOperationException();
  753           }
  754   
  755           public boolean addAll(Collection c) {
  756               throw new UnsupportedOperationException();
  757           }
  758   
  759           public void clear() {
  760               throw new UnsupportedOperationException();
  761           }
  762   
  763           public boolean contains(Object value) {
  764               return (map.containsValue(value));
  765           }
  766   
  767           public Iterator<Object> iterator() {
  768               return (new ResultSetValuesIterator(map));
  769           }
  770   
  771           public boolean remove(Object o) {
  772               throw new UnsupportedOperationException();
  773           }
  774   
  775           public boolean removeAll(Collection c) {
  776               throw new UnsupportedOperationException();
  777           }
  778   
  779           public boolean retainAll(Collection c) {
  780               throw new UnsupportedOperationException();
  781           }
  782   
  783           public int size() {
  784               return (map.size());
  785           }
  786   
  787       }
  788   
  789   
  790       // Private implementation of Iterator that implements the behavior
  791       // for the Iterator returned by values().iterator() from ResultSetMap
  792       private static class ResultSetValuesIterator implements Iterator<Object> {
  793   
  794           public ResultSetValuesIterator(ResultSetMap map) {
  795               this.map = map;
  796               this.keys = map.keySet().iterator();
  797           }
  798   
  799           private ResultSetMap map;
  800           private Iterator<String> keys;
  801   
  802           public boolean hasNext() {
  803               return (keys.hasNext());
  804           }
  805   
  806           public Object next() {
  807               return (map.get(keys.next()));
  808           }
  809   
  810           public void remove() {
  811               throw new UnsupportedOperationException();
  812           }
  813   
  814       }
  815   
  816   
  817   }

Home » Mojarra-2.0.1 » javax » faces » model » [javadoc | source]