1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package com.ibatis.sqlmap.engine.builder.xml;
17
18 import com.ibatis.common.resources.Resources;
19 import com.ibatis.common.xml.NodeletUtils;
20 import com.ibatis.sqlmap.client.SqlMapException;
21 import com.ibatis.sqlmap.engine.config.MappedStatementConfig;
22 import com.ibatis.sqlmap.engine.mapping.statement.MappedStatement;
23
24 import java.util.Properties;
25
26 import org.w3c.dom.CharacterData;
27 import org.w3c.dom.Node;
28 import org.w3c.dom.NodeList;
29
30
31
32
33 public class SqlStatementParser {
34
35
36 private XmlParserState state;
37
38
39
40
41
42
43
44 public SqlStatementParser(XmlParserState config) {
45 this.state = config;
46 }
47
48
49
50
51
52
53
54
55
56 public void parseGeneralStatement(Node node, MappedStatement statement) {
57
58
59 Properties attributes = NodeletUtils.parseAttributes(node, state.getGlobalProps());
60 String id = attributes.getProperty("id");
61 String parameterMapName = state.applyNamespace(attributes.getProperty("parameterMap"));
62 String parameterClassName = attributes.getProperty("parameterClass");
63 String resultMapName = attributes.getProperty("resultMap");
64 String resultClassName = attributes.getProperty("resultClass");
65 String cacheModelName = state.applyNamespace(attributes.getProperty("cacheModel"));
66 String xmlResultName = attributes.getProperty("xmlResultName");
67 String resultSetType = attributes.getProperty("resultSetType");
68 String fetchSize = attributes.getProperty("fetchSize");
69 String allowRemapping = attributes.getProperty("remapResults");
70 String timeout = attributes.getProperty("timeout");
71
72 if (state.isUseStatementNamespaces()) {
73 id = state.applyNamespace(id);
74 }
75 String[] additionalResultMapNames = null;
76 if (resultMapName != null) {
77 additionalResultMapNames = state.getAllButFirstToken(resultMapName);
78 resultMapName = state.getFirstToken(resultMapName);
79 resultMapName = state.applyNamespace(resultMapName);
80 for (int i = 0; i < additionalResultMapNames.length; i++) {
81 additionalResultMapNames[i] = state.applyNamespace(additionalResultMapNames[i]);
82 }
83 }
84
85 String[] additionalResultClassNames = null;
86 if (resultClassName != null) {
87 additionalResultClassNames = state.getAllButFirstToken(resultClassName);
88 resultClassName = state.getFirstToken(resultClassName);
89 }
90 Class[] additionalResultClasses = null;
91 if (additionalResultClassNames != null) {
92 additionalResultClasses = new Class[additionalResultClassNames.length];
93 for (int i = 0; i < additionalResultClassNames.length; i++) {
94 additionalResultClasses[i] = resolveClass(additionalResultClassNames[i]);
95 }
96 }
97
98 state.getConfig().getErrorContext().setMoreInfo("Check the parameter class.");
99 Class parameterClass = resolveClass(parameterClassName);
100
101 state.getConfig().getErrorContext().setMoreInfo("Check the result class.");
102 Class resultClass = resolveClass(resultClassName);
103
104 Integer timeoutInt = timeout == null ? null : Integer.valueOf(timeout);
105 Integer fetchSizeInt = fetchSize == null ? null : Integer.valueOf(fetchSize);
106 boolean allowRemappingBool = "true".equals(allowRemapping);
107
108 MappedStatementConfig statementConf = state.getConfig().newMappedStatementConfig(id, statement,
109 new XMLSqlSource(state, node), parameterMapName, parameterClass, resultMapName, additionalResultMapNames,
110 resultClass, additionalResultClasses, resultSetType, fetchSizeInt, allowRemappingBool, timeoutInt,
111 cacheModelName, xmlResultName);
112
113 findAndParseSelectKey(node, statementConf);
114 }
115
116
117
118
119
120
121
122
123
124 private Class resolveClass(String resultClassName) {
125 try {
126 if (resultClassName != null) {
127 return Resources.classForName(state.getConfig().getTypeHandlerFactory().resolveAlias(resultClassName));
128 } else {
129 return null;
130 }
131 } catch (ClassNotFoundException e) {
132 throw new SqlMapException("Error. Could not initialize class. Cause: " + e, e);
133 }
134 }
135
136
137
138
139
140
141
142
143
144 private void findAndParseSelectKey(Node node, MappedStatementConfig config) {
145 state.getConfig().getErrorContext().setActivity("parsing select key tags");
146 boolean foundSQLFirst = false;
147 NodeList children = node.getChildNodes();
148 for (int i = 0; i < children.getLength(); i++) {
149 Node child = children.item(i);
150 if (child.getNodeType() == Node.CDATA_SECTION_NODE || child.getNodeType() == Node.TEXT_NODE) {
151 String data = ((CharacterData) child).getData();
152 if (data.trim().length() > 0) {
153 foundSQLFirst = true;
154 }
155 } else if (child.getNodeType() == Node.ELEMENT_NODE && "selectKey".equals(child.getNodeName())) {
156 Properties attributes = NodeletUtils.parseAttributes(child, state.getGlobalProps());
157 String keyPropName = attributes.getProperty("keyProperty");
158 String resultClassName = attributes.getProperty("resultClass");
159 String type = attributes.getProperty("type");
160 config.setSelectKeyStatement(new XMLSqlSource(state, child), resultClassName, keyPropName, foundSQLFirst, type);
161 break;
162 }
163 }
164 state.getConfig().getErrorContext().setMoreInfo(null);
165
166 }
167
168 }