001    /*
002    $Id: GroovyRowResult.java 3990 2006-08-18 10:25:52Z glaforge $
003    
004    Copyright 2003 (C) James Strachan and Bob Mcwhirter. All Rights Reserved.
005    
006    Redistribution and use of this software and associated documentation
007    ("Software"), with or without modification, are permitted provided
008    that the following conditions are met:
009    
010    1. Redistributions of source code must retain copyright
011       statements and notices.  Redistributions must also contain a
012       copy of this document.
013    
014    2. Redistributions in binary form must reproduce the
015       above copyright notice, this list of conditions and the
016       following disclaimer in the documentation and/or other
017       materials provided with the distribution.
018    
019    3. The name "groovy" must not be used to endorse or promote
020       products derived from this Software without prior written
021       permission of The Codehaus.  For written permission,
022       please contact info@codehaus.org.
023    
024    4. Products derived from this Software may not be called "groovy"
025       nor may "groovy" appear in their names without prior written
026       permission of The Codehaus. "groovy" is a registered
027       trademark of The Codehaus.
028    
029    5. Due credit should be given to The Codehaus -
030       http://groovy.codehaus.org/
031    
032    THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS
033    ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
034    NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
035    FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
036    THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
037    INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
038    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
039    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
040    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
041    STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
042    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
043    OF THE POSSIBILITY OF SUCH DAMAGE.
044    
045    */
046    package groovy.sql;
047    
048    import groovy.lang.GroovyObjectSupport;
049    import groovy.lang.MissingPropertyException;
050    
051    import java.util.*;
052    
053    /**
054     * Represents an extent of objects.
055     * It's used in the oneRow method to be able to access the result
056     * of a SQL query by the name of the column, or by the column number.
057     *
058     * @version $Revision: 3990 $
059     * @Author Jean-Louis Berliet
060     */
061    public class GroovyRowResult extends GroovyObjectSupport implements Map {
062    
063        private LinkedHashMap result;
064    
065        public GroovyRowResult(LinkedHashMap result) {
066            this.result = result;
067        }
068    
069        /**
070         * Retrieve the value of the property by its name    *
071         *
072         * @param property is the name of the property to look at
073         * @return the value of the property
074         */
075        public Object getProperty(String property) {
076            try {
077                Object value = result.get(property);
078                if (value != null)
079                    return value;
080                // if property exists and value is null, return null
081                if (result.containsKey(property))
082                    return null;
083                // with some databases/drivers, the columns names are stored uppercase.
084                String propertyUpper = property.toUpperCase();
085                value = result.get(propertyUpper);
086                if (value != null)
087                    return value;
088                // if property exists and value is null, return null
089                if (result.containsKey(propertyUpper)) 
090                    return null;
091                throw new MissingPropertyException(property, GroovyRowResult.class);
092            }
093            catch (Exception e) {
094                throw new MissingPropertyException(property, GroovyRowResult.class, e);
095            }
096        }
097    
098        /**
099         * Retrieve the value of the property by its index.
100         * A negative index will count backwards from the last column.
101         *
102         * @param index is the number of the column to look at
103         * @return the value of the property
104         */
105        public Object getAt(int index) {
106            try {
107                // a negative index will count backwards from the last column.
108                if (index < 0)
109                    index += result.size();
110                Iterator it = result.values().iterator();
111                int i = 0;
112                Object obj = null;
113                while ((obj == null) && (it.hasNext())) {
114                    if (i == index)
115                        obj = it.next();
116                    else
117                        it.next();
118                    i++;
119                }
120                return (obj);
121            }
122            catch (Exception e) {
123                throw new MissingPropertyException(Integer.toString(index), GroovyRowResult.class, e);
124            }
125        }
126    
127        public String toString() {
128            return (result.toString());
129        }
130    
131        /*
132         * The following methods are needed for implementing the Map interface.
133         * They are just delegating the request to the internal LinkedHashMap
134         */
135         
136        public void clear() {
137            result.clear();
138        }
139    
140        public boolean containsKey(Object key) {
141            return result.containsKey(key);
142        }
143    
144        public boolean containsValue(Object value) {
145            return result.containsValue(value);
146        }
147    
148        public Set entrySet() {
149            return result.entrySet();
150        }
151    
152        public boolean equals(Object o) {
153            return result.equals(o);
154        }
155    
156        public Object get(Object property) {
157            if (property instanceof String)
158                return getProperty((String)property);
159            else
160                return null;
161        }
162    
163        public int hashCode() {
164            return result.hashCode();
165        }
166    
167        public boolean isEmpty() {
168            return result.isEmpty();
169        }
170    
171        public Set keySet() {
172            return result.keySet();
173        }
174    
175        public Object put(Object key, Object value) {
176            return result.put(key, value);
177        }
178    
179        public void putAll(Map t) {
180            result.putAll(t);
181        }
182    
183        public Object remove(Object key) {
184            return result.remove(key);
185        }
186    
187        public int size() {
188            return result.size();
189        }
190    
191        public Collection values() {
192            return result.values();
193        }
194    }