001: /*
002: * Copyright 2004 Clinton Begin
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package com.ibatis.sqlmap.engine.mapping.result;
017:
018: import com.ibatis.common.beans.ClassInfo;
019: import com.ibatis.common.beans.Probe;
020: import com.ibatis.common.beans.ProbeFactory;
021:
022: import com.ibatis.sqlmap.client.SqlMapException;
023: import com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate;
024: import com.ibatis.sqlmap.engine.scope.RequestScope;
025: import com.ibatis.sqlmap.engine.type.DomTypeMarker;
026:
027: import java.sql.ResultSet;
028: import java.sql.ResultSetMetaData;
029: import java.sql.SQLException;
030: import java.util.ArrayList;
031: import java.util.HashMap;
032: import java.util.List;
033: import java.util.Map;
034:
035: /**
036: * An automatic result map for simple stuff
037: */
038: public class AutoResultMap extends BasicResultMap {
039:
040: /**
041: * Constructor to pass in the SqlMapExecutorDelegate
042: *
043: * @param delegate - the delegate
044: */
045: public AutoResultMap(SqlMapExecutorDelegate delegate,
046: boolean allowRemapping) {
047: super (delegate);
048: this .allowRemapping = allowRemapping;
049: }
050:
051: public synchronized Object[] getResults(RequestScope request,
052: ResultSet rs) throws SQLException {
053: if (allowRemapping || getResultMappings() == null) {
054: initialize(rs);
055: }
056: return super .getResults(request, rs);
057: }
058:
059: private void initialize(ResultSet rs) {
060: if (getResultClass() == null) {
061: throw new SqlMapException("The automatic ResultMap named "
062: + this .getId()
063: + " had a null result class (not allowed).");
064: } else if (Map.class.isAssignableFrom(getResultClass())) {
065: initializeMapResults(rs);
066: } else if (getDelegate().getTypeHandlerFactory()
067: .getTypeHandler(getResultClass()) != null) {
068: initializePrimitiveResults(rs);
069: } else if (DomTypeMarker.class
070: .isAssignableFrom(getResultClass())) {
071: initializeXmlResults(rs);
072: } else {
073: initializeBeanResults(rs);
074: }
075: }
076:
077: private void initializeBeanResults(ResultSet rs) {
078: try {
079: ClassInfo classInfo = ClassInfo
080: .getInstance(getResultClass());
081: String[] propertyNames = classInfo
082: .getWriteablePropertyNames();
083:
084: Map propertyMap = new HashMap();
085: for (int i = 0; i < propertyNames.length; i++) {
086: propertyMap.put(propertyNames[i]
087: .toUpperCase(java.util.Locale.ENGLISH),
088: propertyNames[i]);
089: }
090:
091: List resultMappingList = new ArrayList();
092: ResultSetMetaData rsmd = rs.getMetaData();
093: for (int i = 0, n = rsmd.getColumnCount(); i < n; i++) {
094: String columnName = rsmd.getColumnLabel(i + 1);
095: String upperColumnName = columnName
096: .toUpperCase(java.util.Locale.ENGLISH);
097: String matchedProp = (String) propertyMap
098: .get(upperColumnName);
099: Class type = null;
100: if (matchedProp == null) {
101: Probe p = ProbeFactory.getProbe(this
102: .getResultClass());
103: try {
104: type = p.getPropertyTypeForSetter(this
105: .getResultClass(), columnName);
106: } catch (Exception e) {
107: //TODO - add logging to this class?
108: }
109: } else {
110: type = classInfo.getSetterType(matchedProp);
111: }
112: if (type != null || matchedProp != null) {
113: BasicResultMapping resultMapping = new BasicResultMapping();
114: resultMapping
115: .setPropertyName((matchedProp != null ? matchedProp
116: : columnName));
117: resultMapping.setColumnName(columnName);
118: resultMapping.setColumnIndex(i + 1);
119: resultMapping.setTypeHandler(getDelegate()
120: .getTypeHandlerFactory().getTypeHandler(
121: type)); //map SQL to JDBC type
122: resultMappingList.add(resultMapping);
123: }
124: }
125: setResultMappingList(resultMappingList);
126:
127: } catch (SQLException e) {
128: throw new RuntimeException(
129: "Error automapping columns. Cause: " + e);
130: }
131:
132: }
133:
134: private void initializeXmlResults(ResultSet rs) {
135: try {
136: List resultMappingList = new ArrayList();
137: ResultSetMetaData rsmd = rs.getMetaData();
138: for (int i = 0, n = rsmd.getColumnCount(); i < n; i++) {
139: String columnName = rsmd.getColumnLabel(i + 1);
140: BasicResultMapping resultMapping = new BasicResultMapping();
141: resultMapping.setPropertyName(columnName);
142: resultMapping.setColumnName(columnName);
143: resultMapping.setColumnIndex(i + 1);
144: resultMapping.setTypeHandler(getDelegate()
145: .getTypeHandlerFactory().getTypeHandler(
146: String.class));
147: resultMappingList.add(resultMapping);
148: }
149: setResultMappingList(resultMappingList);
150: } catch (SQLException e) {
151: throw new RuntimeException(
152: "Error automapping columns. Cause: " + e);
153: }
154: }
155:
156: private void initializeMapResults(ResultSet rs) {
157: try {
158: List resultMappingList = new ArrayList();
159: ResultSetMetaData rsmd = rs.getMetaData();
160: for (int i = 0, n = rsmd.getColumnCount(); i < n; i++) {
161: String columnName = rsmd.getColumnLabel(i + 1);
162: BasicResultMapping resultMapping = new BasicResultMapping();
163: resultMapping.setPropertyName(columnName);
164: resultMapping.setColumnName(columnName);
165: resultMapping.setColumnIndex(i + 1);
166: resultMapping.setTypeHandler(getDelegate()
167: .getTypeHandlerFactory().getTypeHandler(
168: Object.class));
169: resultMappingList.add(resultMapping);
170: }
171:
172: setResultMappingList(resultMappingList);
173:
174: } catch (SQLException e) {
175: throw new RuntimeException(
176: "Error automapping columns. Cause: " + e);
177: }
178: }
179:
180: private void initializePrimitiveResults(ResultSet rs) {
181: try {
182: ResultSetMetaData rsmd = rs.getMetaData();
183: String columnName = rsmd.getColumnLabel(1);
184: BasicResultMapping resultMapping = new BasicResultMapping();
185: resultMapping.setPropertyName(columnName);
186: resultMapping.setColumnName(columnName);
187: resultMapping.setColumnIndex(1);
188: resultMapping.setTypeHandler(getDelegate()
189: .getTypeHandlerFactory().getTypeHandler(
190: getResultClass()));
191:
192: List resultMappingList = new ArrayList();
193: resultMappingList.add(resultMapping);
194:
195: setResultMappingList(resultMappingList);
196:
197: } catch (SQLException e) {
198: throw new RuntimeException(
199: "Error automapping columns. Cause: " + e);
200: }
201: }
202:
203: }
|