📄 sqlmapparser.java
字号:
package com.ibatis.sqlmap.engine.builder.xml;
import com.ibatis.common.logging.Log;
import com.ibatis.common.logging.LogFactory;
import com.ibatis.common.resources.Resources;
import com.ibatis.common.xml.Nodelet;
import com.ibatis.common.xml.NodeletException;
import com.ibatis.common.xml.NodeletParser;
import com.ibatis.common.xml.NodeletUtils;
import com.ibatis.sqlmap.client.extensions.TypeHandlerCallback;
import com.ibatis.sqlmap.engine.cache.CacheModel;
import com.ibatis.sqlmap.engine.mapping.parameter.BasicParameterMap;
import com.ibatis.sqlmap.engine.mapping.parameter.BasicParameterMapping;
import com.ibatis.sqlmap.engine.mapping.result.*;
import com.ibatis.sqlmap.engine.mapping.statement.*;
import com.ibatis.sqlmap.engine.type.CustomTypeHandler;
import com.ibatis.sqlmap.engine.type.TypeHandler;
import org.w3c.dom.Node;
import java.io.InputStream;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.StringTokenizer;
import java.util.Iterator;
public class SqlMapParser extends BaseParser {
private static final Log log = LogFactory.getLog(SqlMapParser.class);
protected final NodeletParser parser = new NodeletParser();
public SqlMapParser(Variables vars) {
super(vars);
parser.setValidation(true);
parser.setEntityResolver(new SqlMapClasspathEntityResolver());
addSqlMapNodelets();
addSqlNodelets();
addTypeAliasNodelets();
addCacheModelNodelets();
addParameterMapNodelets();
addResultMapNodelets();
addStatementNodelets();
}
public void parse(Reader reader) throws NodeletException {
parser.parse(reader);
}
public void parse(InputStream inputStream) throws NodeletException {
parser.parse(inputStream);
}
private void addSqlMapNodelets() {
parser.addNodelet("/sqlMap", new Nodelet() {
public void process(Node node) throws Exception {
Properties attributes = NodeletUtils.parseAttributes(node, vars.properties);
vars.currentNamespace = attributes.getProperty("namespace");
}
});
parser.addNodelet("/sqlMap/end()", new Nodelet() {
public void process(Node node) throws Exception {
Iterator names = vars.delegate.getResultMapNames();
while (names.hasNext()) {
String name = (String)names.next();
ResultMap rm = vars.delegate.getResultMap(name);
Discriminator disc = rm.getDiscriminator();
if (disc != null) {
disc.bindSubMaps();
}
}
}
});
}
private void addSqlNodelets() {
parser.addNodelet("/sqlMap/sql", new Nodelet() {
public void process(Node node) throws Exception {
Properties attributes = NodeletUtils.parseAttributes(node, vars.properties);
String id = attributes.getProperty("id");
if (vars.useStatementNamespaces) {
id = applyNamespace(id);
}
if (vars.sqlIncludes.containsKey(id)) {
// To be upgraded to throwing of a RuntimeException later on
log.warn("Duplicate <sql>-include '" + id + "' found.");
}
else {
vars.sqlIncludes.put(id, node);
}
}
});
}
private void addTypeAliasNodelets() {
parser.addNodelet("/sqlMap/typeAlias", new Nodelet() {
public void process(Node node) throws Exception {
Properties prop = NodeletUtils.parseAttributes(node, vars.properties);
String alias = prop.getProperty("alias");
String type = prop.getProperty("type");
vars.typeHandlerFactory.putTypeAlias(alias, type);
}
});
}
private void addCacheModelNodelets() {
parser.addNodelet("/sqlMap/cacheModel", new Nodelet() {
public void process(Node node) throws Exception {
vars.currentCacheModel = new CacheModel();
vars.currentProperties = new Properties();
}
});
parser.addNodelet("/sqlMap/cacheModel/end()", new Nodelet() {
public void process(Node node) throws Exception {
vars.errorCtx.setActivity("building a cache model");
Properties attributes = NodeletUtils.parseAttributes(node, vars.properties);
String id = applyNamespace(attributes.getProperty("id"));
String type = attributes.getProperty("type");
type = vars.typeHandlerFactory.resolveAlias(type);
String readOnly = attributes.getProperty("readOnly");
if (readOnly != null && readOnly.length() > 0) {
vars.currentCacheModel.setReadOnly("true".equals(readOnly));
} else {
vars.currentCacheModel.setReadOnly(true);
}
String serialize = attributes.getProperty("serialize");
if (serialize != null && serialize.length() > 0) {
vars.currentCacheModel.setSerialize("true".equals(serialize));
} else {
vars.currentCacheModel.setSerialize(false);
}
vars.errorCtx.setObjectId(id + " cache model");
vars.errorCtx.setMoreInfo("Check the cache model type.");
vars.currentCacheModel.setId(id);
vars.currentCacheModel.setResource(vars.errorCtx.getResource());
try {
vars.currentCacheModel.setControllerClassName(type);
} catch (Exception e) {
throw new RuntimeException("Error setting Cache Controller Class. Cause: " + e, e);
}
vars.errorCtx.setMoreInfo("Check the cache model configuration.");
vars.currentCacheModel.configure(vars.currentProperties);
if (vars.client.getDelegate().isCacheModelsEnabled()) {
vars.client.getDelegate().addCacheModel(vars.currentCacheModel);
}
vars.errorCtx.setMoreInfo(null);
vars.errorCtx.setObjectId(null);
vars.currentProperties = null;
vars.currentCacheModel = null;
}
});
parser.addNodelet("/sqlMap/cacheModel/property", new Nodelet() {
public void process(Node node) throws Exception {
vars.errorCtx.setMoreInfo("Check the cache model properties.");
Properties attributes = NodeletUtils.parseAttributes(node, vars.properties);
String name = attributes.getProperty("name");
String value = NodeletUtils.parsePropertyTokens(attributes.getProperty("value"), vars.properties);
vars.currentProperties.put(name, value);
}
});
parser.addNodelet("/sqlMap/cacheModel/flushOnExecute", new Nodelet() {
public void process(Node node) throws Exception {
vars.errorCtx.setMoreInfo("Check the cache model flush on statement elements.");
Properties childAttributes = NodeletUtils.parseAttributes(node, vars.properties);
vars.currentCacheModel.addFlushTriggerStatement(childAttributes.getProperty("statement"));
}
});
parser.addNodelet("/sqlMap/cacheModel/flushInterval", new Nodelet() {
public void process(Node node) throws Exception {
Properties childAttributes = NodeletUtils.parseAttributes(node, vars.properties);
long t = 0;
try {
vars.errorCtx.setMoreInfo("Check the cache model flush interval.");
String milliseconds = childAttributes.getProperty("milliseconds");
String seconds = childAttributes.getProperty("seconds");
String minutes = childAttributes.getProperty("minutes");
String hours = childAttributes.getProperty("hours");
if (milliseconds != null) t += Integer.parseInt(milliseconds);
if (seconds != null) t += Integer.parseInt(seconds) * 1000;
if (minutes != null) t += Integer.parseInt(minutes) * 60 * 1000;
if (hours != null) t += Integer.parseInt(hours) * 60 * 60 * 1000;
if (t < 1) throw new RuntimeException("A flush interval must specify one or more of milliseconds, seconds, minutes or hours.");
vars.currentCacheModel.setFlushInterval(t);
} catch (NumberFormatException e) {
throw new RuntimeException("Error building cache '" + vars.currentCacheModel.getId() + "' in '" + "resourceNAME" + "'. Flush interval milliseconds must be a valid long integer value. Cause: " + e, e);
}
}
});
}
private void addParameterMapNodelets() {
parser.addNodelet("/sqlMap/parameterMap/end()", new Nodelet() {
public void process(Node node) throws Exception {
vars.currentParameterMap.setParameterMappingList(vars.parameterMappingList);
vars.client.getDelegate().addParameterMap(vars.currentParameterMap);
vars.errorCtx.setMoreInfo(null);
vars.errorCtx.setObjectId(null);
}
});
parser.addNodelet("/sqlMap/parameterMap", new Nodelet() {
public void process(Node node) throws Exception {
vars.errorCtx.setActivity("building a parameter map");
vars.currentParameterMap = new BasicParameterMap(vars.client.getDelegate());
Properties attributes = NodeletUtils.parseAttributes(node, vars.properties);
String id = applyNamespace(attributes.getProperty("id"));
String parameterClassName = attributes.getProperty("class");
parameterClassName = vars.typeHandlerFactory.resolveAlias(parameterClassName);
vars.currentParameterMap.setId(id);
vars.currentParameterMap.setResource(vars.errorCtx.getResource());
vars.errorCtx.setObjectId(id + " parameter map");
Class parameterClass = null;
try {
vars.errorCtx.setMoreInfo("Check the parameter class.");
parameterClass = Resources.classForName(parameterClassName);
} catch (Exception e) {
//TODO: Why is this commented out?
//throw new SqlMapException("Error configuring ParameterMap. Could not set ParameterClass. Cause: " + e, e);
}
vars.currentParameterMap.setParameterClass(parameterClass);
vars.parameterMappingList = new ArrayList();
vars.errorCtx.setMoreInfo("Check the parameter mappings.");
}
});
parser.addNodelet("/sqlMap/parameterMap/parameter", new Nodelet() {
public void process(Node node) throws Exception {
Properties childAttributes = NodeletUtils.parseAttributes(node, vars.properties);
String propertyName = childAttributes.getProperty("property");
String jdbcType = childAttributes.getProperty("jdbcType");
String type = childAttributes.getProperty("typeName");
String javaType = childAttributes.getProperty("javaType");
String resultMap = childAttributes.getProperty("resultMap");
String nullValue = childAttributes.getProperty("nullValue");
String mode = childAttributes.getProperty("mode");
String callback = childAttributes.getProperty("typeHandler");
String numericScale = childAttributes.getProperty("numericScale");
callback = vars.typeHandlerFactory.resolveAlias(callback);
javaType = vars.typeHandlerFactory.resolveAlias(javaType);
resultMap = applyNamespace( resultMap );
vars.errorCtx.setObjectId(propertyName + " mapping of the " + vars.currentParameterMap.getId() + " parameter map");
TypeHandler handler = null;
if (callback != null) {
vars.errorCtx.setMoreInfo("Check the parameter mapping typeHandler attribute '" + callback + "' (must be a TypeHandler or TypeHandlerCallback implementation).");
try {
Object impl = Resources.classForName(callback).newInstance();
if (impl instanceof TypeHandlerCallback) {
handler = new CustomTypeHandler((TypeHandlerCallback) impl);
} else if (impl instanceof TypeHandler) {
handler = (TypeHandler) impl;
} else {
throw new RuntimeException ("The class '"+callback+"' is not a valid implementation of TypeHandler or TypeHandlerCallback");
}
} catch (Exception e) {
throw new RuntimeException("Error occurred during custom type handler configuration. Cause: " + e, e);
}
} else {
vars.errorCtx.setMoreInfo("Check the parameter mapping property type or name.");
handler = resolveTypeHandler(vars.client.getDelegate().getTypeHandlerFactory(), vars.currentParameterMap.getParameterClass(), propertyName, javaType, jdbcType);
}
BasicParameterMapping mapping = new BasicParameterMapping();
mapping.setPropertyName(propertyName);
mapping.setJdbcTypeName(jdbcType);
mapping.setTypeName(type);
mapping.setResultMapName( resultMap );
mapping.setNullValue(nullValue);
if (mode != null && mode.length() > 0) {
mapping.setMode(mode);
}
mapping.setTypeHandler(handler);
try {
if (javaType != null && javaType.length() > 0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -