View Javadoc
1   /*
2    * Copyright 2004-2024 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *    https://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package com.ibatis.sqlmap.engine.mapping.statement;
17  
18  import com.ibatis.sqlmap.client.event.RowHandler;
19  import com.ibatis.sqlmap.engine.mapping.result.ResultMap;
20  import com.ibatis.sqlmap.engine.scope.StatementScope;
21  import com.ibatis.sqlmap.engine.type.XmlTypeMarker;
22  
23  import java.io.StringWriter;
24  import java.sql.ResultSet;
25  import java.sql.SQLException;
26  
27  import javax.xml.XMLConstants;
28  import javax.xml.transform.Transformer;
29  import javax.xml.transform.TransformerException;
30  import javax.xml.transform.TransformerFactory;
31  import javax.xml.transform.dom.DOMSource;
32  import javax.xml.transform.stream.StreamResult;
33  
34  import org.w3c.dom.Document;
35  
36  /**
37   * Class to manager row handler access.
38   */
39  public class RowHandlerCallback {
40  
41    /** The row handler. */
42    private RowHandler rowHandler;
43  
44    /** The result map. */
45    private ResultMap resultMap;
46  
47    /** The result object. */
48    private Object resultObject;
49  
50    /**
51     * Constructor.
52     *
53     * @param resultMap
54     *          - the result map
55     * @param resultObject
56     *          - the result object
57     * @param rowHandler
58     *          - the row handler object
59     */
60    public RowHandlerCallback(ResultMap resultMap, Object resultObject, RowHandler rowHandler) {
61      this.rowHandler = rowHandler;
62      this.resultMap = resultMap;
63      this.resultObject = resultObject;
64    }
65  
66    /**
67     * Prepares the row object, and passes it to the row handler.
68     *
69     * @param statementScope
70     *          - the request scope
71     * @param results
72     *          - the result data
73     * @param rs
74     *          the rs
75     *
76     * @throws SQLException
77     *           the SQL exception
78     */
79    public void handleResultObject(StatementScope statementScope, Object[] results, ResultSet rs) throws SQLException {
80      Object object;
81  
82      statementScope.setCurrentNestedKey(null);
83      object = resultMap.resolveSubMap(statementScope, rs).setResultObjectValues(statementScope, resultObject, results);
84  
85      if (object != ResultMap.NO_VALUE) {
86        // XML Only special processing. (converts elements to string for easy insertion).
87        int stackDepth = statementScope.getSession().getRequestStackDepth();
88        if (stackDepth == 1) {
89          Class targetType = statementScope.getResultMap().getResultClass();
90          if (XmlTypeMarker.class.isAssignableFrom(targetType) && object instanceof Document) {
91            object = documentToString((Document) object);
92          }
93        }
94  
95        rowHandler.handleRow(object);
96      }
97    }
98  
99    /**
100    * Document to string.
101    *
102    * @param document
103    *          the document
104    *
105    * @return the string
106    */
107   private String documentToString(Document document) {
108     String s = null;
109 
110     try {
111       TransformerFactory tFactory = TransformerFactory.newInstance();
112       tFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
113       tFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
114       Transformer transformer = tFactory.newTransformer();
115 
116       DOMSource source = new DOMSource(document);
117       StringWriter writer = new StringWriter();
118       StreamResult result = new StreamResult(writer);
119       transformer.transform(source, result);
120       s = writer.getBuffer().toString();
121 
122     } catch (TransformerException e) {
123       throw new RuntimeException("Error occurred.  Cause: " + e, e);
124     }
125 
126     return s;
127   }
128 
129   /**
130    * Gets the row handler.
131    *
132    * @return the row handler
133    */
134   public RowHandler getRowHandler() {
135     return rowHandler;
136   }
137 
138 }