001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.kernel.upgrade.dao.orm;
016    
017    import com.liferay.portal.kernel.upgrade.UpgradeException;
018    import com.liferay.portal.kernel.util.GetterUtil;
019    import com.liferay.portal.kernel.util.StringPool;
020    import com.liferay.portal.kernel.util.StringUtil;
021    
022    import java.lang.reflect.InvocationHandler;
023    import java.lang.reflect.Method;
024    
025    import java.sql.ResultSet;
026    import java.sql.ResultSetMetaData;
027    import java.sql.SQLException;
028    import java.sql.Types;
029    
030    import java.util.ArrayList;
031    import java.util.HashMap;
032    import java.util.List;
033    import java.util.Map;
034    
035    /**
036     * @author Minhchau Dang
037     */
038    public class UpgradeOptimizedResultSetHandler implements InvocationHandler {
039    
040            public UpgradeOptimizedResultSetHandler(ResultSet resultSet)
041                    throws SQLException {
042    
043                    _resultSet = resultSet;
044    
045                    _columnNames.add(StringPool.BLANK);
046    
047                    ResultSetMetaData resultSetMetaData = _resultSet.getMetaData();
048    
049                    for (int i = 1; i <= resultSetMetaData.getColumnCount(); i++) {
050                            int columnType = resultSetMetaData.getColumnType(i);
051    
052                            _columnTypes.put(i, columnType);
053    
054                            String columnName = resultSetMetaData.getColumnName(i);
055    
056                            _columnNames.add(columnName);
057    
058                            String lowerCaseColumnName = StringUtil.toLowerCase(columnName);
059    
060                            _columnTypes.put(lowerCaseColumnName, columnType);
061                    }
062            }
063    
064            @Override
065            public Object invoke(Object proxy, Method method, Object[] arguments)
066                    throws Throwable {
067    
068                    String methodName = method.getName();
069    
070                    if (methodName.equals("close")) {
071                            _resultSet.close();
072    
073                            return null;
074                    }
075    
076                    if (methodName.equals("next")) {
077                            if (_resultSet.isBeforeFirst()) {
078                                    _next = _resultSet.next();
079                            }
080    
081                            Object returnValue = _next;
082    
083                            _cacheColumnValues();
084    
085                            if (_next) {
086                                    _next = _resultSet.next();
087                            }
088    
089                            return returnValue;
090                    }
091    
092                    Object column = arguments[0];
093    
094                    if (column instanceof String) {
095                            String columnString = (String)column;
096    
097                            column = StringUtil.toLowerCase(columnString);
098                    }
099    
100                    Object returnValue = _columnValues.get(column);
101    
102                    if (methodName.equals("getBoolean")) {
103                            if ((returnValue == null) || !(returnValue instanceof Number)) {
104                                    return GetterUtil.getBoolean(returnValue);
105                            }
106                            else {
107                                    Number number = (Number)returnValue;
108    
109                                    double doubleValue = number.doubleValue();
110    
111                                    if (doubleValue == 0.0) {
112                                            return false;
113                                    }
114                                    else {
115                                            return true;
116                                    }
117                            }
118                    }
119                    else if (methodName.equals("getDouble")) {
120                            if ((returnValue == null) || !(returnValue instanceof Number)) {
121                                    return GetterUtil.getDouble(returnValue);
122                            }
123                            else {
124                                    Number number = (Number)returnValue;
125    
126                                    return number.doubleValue();
127                            }
128                    }
129                    else if (methodName.equals("getFloat")) {
130                            if ((returnValue == null) || !(returnValue instanceof Number)) {
131                                    return GetterUtil.getFloat(returnValue);
132                            }
133                            else {
134                                    Number number = (Number)returnValue;
135    
136                                    return number.floatValue();
137                            }
138                    }
139                    else if (methodName.equals("getInt")) {
140                            if ((returnValue == null) || !(returnValue instanceof Number)) {
141                                    return GetterUtil.getInteger(returnValue);
142                            }
143                            else {
144                                    Number number = (Number)returnValue;
145    
146                                    return number.intValue();
147                            }
148                    }
149                    else if (methodName.equals("getLong")) {
150                            if ((returnValue == null) || !(returnValue instanceof Number)) {
151                                    return GetterUtil.getLong(returnValue);
152                            }
153                            else {
154                                    Number number = (Number)returnValue;
155    
156                                    return number.longValue();
157                            }
158                    }
159                    else if (methodName.equals("getShort")) {
160                            if ((returnValue == null) || !(returnValue instanceof Number)) {
161                                    return GetterUtil.getShort(returnValue);
162                            }
163                            else {
164                                    Number number = (Number)returnValue;
165    
166                                    return number.shortValue();
167                            }
168                    }
169                    else if (methodName.equals("getString")) {
170                            if ((returnValue == null) || (returnValue instanceof String)) {
171                                    return returnValue;
172                            }
173                            else {
174                                    return String.valueOf(returnValue);
175                            }
176                    }
177    
178                    return returnValue;
179            }
180    
181            private void _cacheColumnValues() throws Exception {
182                    _columnValues.clear();
183    
184                    if (!_next) {
185                            return;
186                    }
187    
188                    for (int i = 1; i < _columnNames.size(); ++i) {
189                            String columnName = _columnNames.get(i);
190    
191                            String lowerCaseColumnName = StringUtil.toLowerCase(columnName);
192    
193                            Integer columnType = _columnTypes.get(lowerCaseColumnName);
194    
195                            Object value = _getValue(columnName, columnType);
196    
197                            _columnValues.put(i, value);
198    
199                            _columnValues.put(lowerCaseColumnName, value);
200                    }
201            }
202    
203            private Object _getValue(String name, Integer type) throws Exception {
204                    Object value = null;
205    
206                    int t = type.intValue();
207    
208                    if (t == Types.BIGINT) {
209                            value = GetterUtil.getLong(_resultSet.getLong(name));
210                    }
211                    else if (t == Types.BINARY) {
212                            value = _resultSet.getBytes(name);
213                    }
214                    else if (t == Types.BIT) {
215                            value = GetterUtil.getBoolean(_resultSet.getBoolean(name));
216                    }
217                    else if (t == Types.BLOB) {
218                            value = _resultSet.getBytes(name);
219                    }
220                    else if (t == Types.BOOLEAN) {
221                            value = GetterUtil.getBoolean(_resultSet.getBoolean(name));
222                    }
223                    else if (t == Types.CHAR) {
224                            value = GetterUtil.getString(_resultSet.getString(name));
225                    }
226                    else if (t == Types.CLOB) {
227                            value = GetterUtil.getString(_resultSet.getString(name));
228                    }
229                    else if (t == Types.DATE) {
230                            value = _resultSet.getDate(name);
231                    }
232                    else if (t == Types.DECIMAL) {
233                            value = _resultSet.getBigDecimal(name);
234                    }
235                    else if (t == Types.DOUBLE) {
236                            value = GetterUtil.getDouble(_resultSet.getDouble(name));
237                    }
238                    else if (t == Types.FLOAT) {
239                            value = GetterUtil.getFloat(_resultSet.getFloat(name));
240                    }
241                    else if (t == Types.INTEGER) {
242                            value = GetterUtil.getInteger(_resultSet.getInt(name));
243                    }
244                    else if (t == Types.LONGNVARCHAR) {
245                            value = GetterUtil.getString(_resultSet.getString(name));
246                    }
247                    else if (t == Types.LONGVARBINARY) {
248                            value = _resultSet.getBytes(name);
249                    }
250                    else if (t == Types.LONGVARCHAR) {
251                            value = GetterUtil.getString(_resultSet.getString(name));
252                    }
253                    else if (t == Types.NCHAR) {
254                            value = GetterUtil.getString(_resultSet.getString(name));
255                    }
256                    else if (t == Types.NCLOB) {
257                            value = GetterUtil.getString(_resultSet.getString(name));
258                    }
259                    else if (t == Types.NUMERIC) {
260                            value = GetterUtil.getLong(_resultSet.getLong(name));
261                    }
262                    else if (t == Types.NVARCHAR) {
263                            value = GetterUtil.getString(_resultSet.getString(name));
264                    }
265                    else if (t == Types.REAL) {
266                            value = GetterUtil.getFloat(_resultSet.getFloat(name));
267                    }
268                    else if (t == Types.ROWID) {
269                            value = GetterUtil.getFloat(_resultSet.getFloat(name));
270                    }
271                    else if (t == Types.SMALLINT) {
272                            value = GetterUtil.getShort(_resultSet.getShort(name));
273                    }
274                    else if (t == Types.SQLXML) {
275                            value = GetterUtil.getString(_resultSet.getString(name));
276                    }
277                    else if (t == Types.TIME) {
278                            value = _resultSet.getTime(name);
279                    }
280                    else if (t == Types.TIMESTAMP) {
281                            value = _resultSet.getTimestamp(name);
282                    }
283                    else if (t == Types.TINYINT) {
284                            value = GetterUtil.getShort(_resultSet.getShort(name));
285                    }
286                    else if (t == Types.VARBINARY) {
287                            value = _resultSet.getBytes(name);
288                    }
289                    else if (t == Types.VARCHAR) {
290                            value = GetterUtil.getString(_resultSet.getString(name));
291                    }
292                    else {
293                            throw new UpgradeException(
294                                    "Upgrade code using unsupported class type " + type);
295                    }
296    
297                    return value;
298            }
299    
300            private List<String> _columnNames = new ArrayList<String>();
301            private Map<Object, Integer> _columnTypes = new HashMap<Object, Integer>();
302            private Map<Object, Object> _columnValues = new HashMap<Object, Object>();
303            private boolean _next;
304            private ResultSet _resultSet;
305    
306    }