1 16 package com.ibatis.sqlmap.engine.mapping.statement; 17 18 import com.ibatis.common.jdbc.exception.NestedSQLException; 19 import com.ibatis.common.io.ReaderInputStream; 20 import com.ibatis.common.exception.NestedRuntimeException; 21 import com.ibatis.sqlmap.client.event.RowHandler; 22 import com.ibatis.sqlmap.engine.execution.SqlExecutor; 23 import com.ibatis.sqlmap.engine.mapping.parameter.ParameterMap; 24 import com.ibatis.sqlmap.engine.mapping.result.ResultMap; 25 import com.ibatis.sqlmap.engine.mapping.sql.Sql; 26 import com.ibatis.sqlmap.engine.scope.ErrorContext; 27 import com.ibatis.sqlmap.engine.scope.RequestScope; 28 import com.ibatis.sqlmap.engine.transaction.Transaction; 29 import com.ibatis.sqlmap.engine.transaction.TransactionException; 30 import com.ibatis.sqlmap.engine.type.*; 31 import org.w3c.dom.Document ; 32 33 import javax.xml.parsers.*; 34 import java.sql.Connection ; 35 import java.sql.SQLException ; 36 import java.util.List ; 37 import java.io.*; 38 39 public class GeneralStatement extends BaseStatement { 40 41 public StatementType getStatementType() { 42 return StatementType.UNKNOWN; 43 } 44 45 public int executeUpdate(RequestScope request, Transaction trans, Object parameterObject) 46 throws SQLException { 47 ErrorContext errorContext = request.getErrorContext(); 48 errorContext.setActivity("preparing the mapped statement for execution"); 49 errorContext.setObjectId(this.getId()); 50 errorContext.setResource(this.getResource()); 51 52 request.getSession().setCommitRequired(true); 53 54 try { 55 parameterObject = validateParameter(parameterObject); 56 57 Sql sql = getSql(); 58 59 errorContext.setMoreInfo("Check the parameter map."); 60 ParameterMap parameterMap = sql.getParameterMap(request, parameterObject); 61 62 errorContext.setMoreInfo("Check the result map."); 63 ResultMap resultMap = sql.getResultMap(request, parameterObject); 64 65 request.setResultMap(resultMap); 66 request.setParameterMap(parameterMap); 67 68 int rows = 0; 69 70 errorContext.setMoreInfo("Check the parameter map."); 71 Object [] parameters = parameterMap.getParameterObjectValues(request, parameterObject); 72 73 errorContext.setMoreInfo("Check the SQL statement."); 74 String sqlString = sql.getSql(request, parameterObject); 75 76 errorContext.setActivity("executing mapped statement"); 77 errorContext.setMoreInfo("Check the statement or the result map."); 78 rows = sqlExecuteUpdate(request, trans.getConnection(), sqlString, parameters); 79 80 errorContext.setMoreInfo("Check the output parameters."); 81 if (parameterObject != null) { 82 postProcessParameterObject(request, parameterObject, parameters); 83 } 84 85 errorContext.reset(); 86 sql.cleanup(request); 87 notifyListeners(); 88 return rows; 89 } catch (SQLException e) { 90 errorContext.setCause(e); 91 throw new NestedSQLException(errorContext.toString(), e.getSQLState(), e.getErrorCode(), e); 92 } catch (Exception e) { 93 errorContext.setCause(e); 94 throw new NestedSQLException(errorContext.toString(), e); 95 } 96 } 97 98 public Object executeQueryForObject(RequestScope request, Transaction trans, Object parameterObject, Object resultObject) 99 throws SQLException { 100 try { 101 Object object = null; 102 103 DefaultRowHandler rowHandler = new DefaultRowHandler(); 104 executeQueryWithCallback(request, trans.getConnection(), parameterObject, resultObject, rowHandler, SqlExecutor.NO_SKIPPED_RESULTS, SqlExecutor.NO_MAXIMUM_RESULTS); 105 List list = rowHandler.getList(); 106 107 if (list.size() > 1) { 108 throw new SQLException("Error: executeQueryForObject returned too many results."); 109 } else if (list.size() > 0) { 110 object = list.get(0); 111 } 112 113 return object; 114 } catch (TransactionException e) { 115 throw new NestedSQLException("Error getting Connection from Transaction. Cause: " + e, e); 116 } 117 } 118 119 public List executeQueryForList(RequestScope request, Transaction trans, Object parameterObject, int skipResults, int maxResults) 120 throws SQLException { 121 try { 122 DefaultRowHandler rowHandler = new DefaultRowHandler(); 123 executeQueryWithCallback(request, trans.getConnection(), parameterObject, null, rowHandler, skipResults, maxResults); 124 return rowHandler.getList(); 125 } catch (TransactionException e) { 126 throw new NestedSQLException("Error getting Connection from Transaction. Cause: " + e, e); 127 } 128 } 129 130 public void executeQueryWithRowHandler(RequestScope request, Transaction trans, Object parameterObject, RowHandler rowHandler) 131 throws SQLException { 132 try { 133 executeQueryWithCallback(request, trans.getConnection(), parameterObject, null, rowHandler, SqlExecutor.NO_SKIPPED_RESULTS, SqlExecutor.NO_MAXIMUM_RESULTS); 134 } catch (TransactionException e) { 135 throw new NestedSQLException("Error getting Connection from Transaction. Cause: " + e, e); 136 } 137 } 138 139 143 protected void executeQueryWithCallback(RequestScope request, Connection conn, Object parameterObject, Object resultObject, RowHandler rowHandler, int skipResults, int maxResults) 144 throws SQLException { 145 ErrorContext errorContext = request.getErrorContext(); 146 errorContext.setActivity("preparing the mapped statement for execution"); 147 errorContext.setObjectId(this.getId()); 148 errorContext.setResource(this.getResource()); 149 150 try { 151 parameterObject = validateParameter(parameterObject); 152 153 Sql sql = getSql(); 154 155 errorContext.setMoreInfo("Check the parameter map."); 156 ParameterMap parameterMap = sql.getParameterMap(request, parameterObject); 157 158 errorContext.setMoreInfo("Check the result map."); 159 ResultMap resultMap = sql.getResultMap(request, parameterObject); 160 161 request.setResultMap(resultMap); 162 request.setParameterMap(parameterMap); 163 164 errorContext.setMoreInfo("Check the parameter map."); 165 Object [] parameters = parameterMap.getParameterObjectValues(request, parameterObject); 166 167 errorContext.setMoreInfo("Check the SQL statement."); 168 String sqlString = sql.getSql(request, parameterObject); 169 170 errorContext.setActivity("executing mapped statement"); 171 errorContext.setMoreInfo("Check the SQL statement or the result map."); 172 RowHandlerCallback callback = new RowHandlerCallback(resultMap, resultObject, rowHandler); 173 sqlExecuteQuery(request, conn, sqlString, parameters, skipResults, maxResults, callback); 174 175 errorContext.setMoreInfo("Check the output parameters."); 176 if (parameterObject != null) { 177 postProcessParameterObject(request, parameterObject, parameters); 178 } 179 180 errorContext.reset(); 181 sql.cleanup(request); 182 notifyListeners(); 183 } catch (SQLException e) { 184 errorContext.setCause(e); 185 throw new NestedSQLException(errorContext.toString(), e.getSQLState(), e.getErrorCode(), e); 186 } catch (Exception e) { 187 errorContext.setCause(e); 188 throw new NestedSQLException(errorContext.toString(), e); 189 } 190 } 191 192 protected void postProcessParameterObject(RequestScope request, Object parameterObject, Object [] parameters) { 193 } 194 195 protected int sqlExecuteUpdate(RequestScope request, Connection conn, String sqlString, Object [] parameters) throws SQLException { 196 if (request.getSession().isInBatch()) { 197 getSqlExecutor().addBatch(request, conn, sqlString, parameters); 198 return 0; 199 } else { 200 return getSqlExecutor().executeUpdate(request, conn, sqlString, parameters); 201 } 202 } 203 204 protected void sqlExecuteQuery(RequestScope request, Connection conn, String sqlString, Object [] parameters, int skipResults, int maxResults, RowHandlerCallback callback) throws SQLException { 205 getSqlExecutor().executeQuery(request, conn, sqlString, parameters, skipResults, maxResults, callback); 206 } 207 208 protected Object validateParameter(Object param) 209 throws SQLException { 210 Object newParam = param; 211 Class parameterClass = getParameterClass(); 212 if (newParam != null && parameterClass != null) { 213 if (DomTypeMarker.class.isAssignableFrom(parameterClass)) { 214 if (XmlTypeMarker.class.isAssignableFrom(parameterClass)) { 215 if (!(newParam instanceof String ) 216 && !(newParam instanceof Document )) { 217 throw new SQLException("Invalid parameter object type. Expected '" + String .class.getName() + "' or '" + Document .class.getName() + "' but found '" + newParam.getClass().getName() + "'."); 218 } 219 if (!(newParam instanceof Document )) { 220 newParam = stringToDocument ((String )newParam); 221 } 222 } else { 223 if (!Document .class.isAssignableFrom(newParam.getClass())) { 224 throw new SQLException("Invalid parameter object type. Expected '" + Document .class.getName() + "' but found '" + newParam.getClass().getName() + "'."); 225 } 226 } 227 } else { 228 if (!parameterClass.isAssignableFrom(newParam.getClass())) { 229 throw new SQLException("Invalid parameter object type. Expected '" + parameterClass.getName() + "' but found '" + newParam.getClass().getName() + "'."); 230 } 231 } 232 } 233 return newParam; 234 } 235 236 private Document stringToDocument (String s) { 237 try { 238 DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); 239 DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); 240 return documentBuilder.parse(new ReaderInputStream(new StringReader(s))); 241 } catch (Exception e) { 242 throw new NestedRuntimeException("Error occurred. Cause: " + e, e); 243 } 244 } 245 } 246 | Popular Tags |