package com.gepower.repair.dao.common;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.apache.log4j.Logger;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.util.StringUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
/**
*
* @author
*
* An Abstract super class for all DAO's.
* Class provide all common method used in the DAO, like loading the sql resources and setting the hibernate template
*
*/
public abstract class AbstaractJDBCTemplate extends JdbcDaoSupport{
protected static final Logger LOG = Logger.getLogger(AbstaractJDBCTemplate.class);
private Map<String, String> sqlMap;
//@Resource(name = "sessionFactory")
// @Autowired
// public void setSuperSessionFactory(SessionFactory sessionFactory) {
// //super.setSessionFactory(sessionFactory);
// }
/** Static block, no changes required for any thread. */
private static XPathExpression expr;
private static DocumentBuilder docBuilder;
static {
expr = null;
docBuilder = null;
try {
LOG.info("BaseDAO static initializer");
LOG.info("\tacquiring document builder...");
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
// dbf.setValidating(true);
docBuilder = dbf.newDocumentBuilder();
LOG.info("\tinstalling XPathExpression...");
XPathFactory xpf = XPathFactory.newInstance();
XPath xpath = xpf.newXPath();
expr = xpath.compile("//sql");
} catch (ParserConfigurationException e) {
LOG.fatal(e);
} catch (XPathExpressionException e) {
LOG.fatal(e);
}
}
/**
* getting the SQL from the xml file
* @return the sql xml file
*/
protected String[] getSqlXml() {
SqlSource sqlXml = getClass().getAnnotation(SqlSource.class);
String[] result = null;
if (sqlXml != null) {
result = sqlXml.value();
}
return result;
}
/**
* load the sql content
*/
private void loadSqls() {
if (sqlMap != null && !sqlMap.isEmpty() ) {
throw new IllegalStateException(
"loadSqls() already be invoked before!");
}
LOG.info("sqlMap ---->" + sqlMap);
sqlMap = new HashMap<String, String>();
String[] sqlXml = getSqlXml();
if (sqlXml == null || sqlXml.length == 0) {
LOG.warn("no sqlXml file specified in this DAO.");
return;
}
for (String location : sqlXml) {
loadSqlFrom(location);
}
dumpLoadedSqls();
}
/**
* get the sql xml file from the path
*
* @param location
* the file path
*/
private final void loadSqlFrom(final String location) {
if (LOG.isDebugEnabled()) {
LOG.debug("try to loading sql from: " + location);
}
final URL xmlURL = AbstaractJDBCTemplate.class.getResource(location);
if (xmlURL == null) {
LOG.error(location + " can not be found in the classpath.");
return;
}
InputStream instream = null;
NodeList sqls = null;
try {
instream = xmlURL.openStream();
synchronized(this){
Document doc = docBuilder.parse(instream);
sqls = (NodeList) expr.evaluate(doc,
XPathConstants.NODESET);
if (sqls == null || sqls.getLength() == 0) {
LOG.warn("no <sql> elements can be found in the xml - "
+ location);
return;
}
}
Element elm = null;
String id = null;
String sql = null;
for (int i = 0; i < sqls.getLength(); i++) {
elm = (Element) sqls.item(i);
sql = elm.getTextContent();
id = elm.getAttribute("id");
if (!StringUtils.hasText(id) || !StringUtils.hasText(sql)) {
LOG.warn("id or sql content is empty, ignore the entry.\nid:"
+ id + "\nsql: " + sql);
continue;
}
sqlMap.put(id.trim(), shrink(sql));
}
} catch (IOException e) {
LOG.fatal("error", e);
} catch (SAXException e) {
LOG.fatal("error", e);
} catch (XPathExpressionException e) {
LOG.fatal("error", e);
} finally {
if (instream != null) {
try {
instream.close();
} catch (IOException e) {
LOG.warn(e);
}
}
}
}
/**
*
* @return return the sqls content
*/
protected String dumpLoadedSqls() {
StringBuilder buf = new StringBuilder();
Map.Entry<String, String> entry = null;
Iterator<Map.Entry<String, String>> iter = null;
for (iter = sqlMap.entrySet().iterator(); iter.hasNext();) {
entry = iter.next();
buf.append(entry.getKey());
buf.append("\t => ");
buf.append(trimToLine(entry.getValue()));
buf.append("\r\n");
}
LOG.debug("Loaded Sqls:\n" + buf.toString());
return buf.toString();
}
/**
*
* @param sqlId
* the sql id
* @return return the related query by the sql id
*/
protected String getSql(String sqlId) {
LOG.info("sqlId -->" + sqlId);
if (!StringUtils.hasText(sqlId)) {
throw new IllegalArgumentException("invalid sqlId: " + sqlId);
}
if (sqlMap == null) {
loadSqls();
}
if(sqlMap.isEmpty()){
LOG.info("===========================----sqlMap is Empty");
loadSqls();
}
String sql =sqlMap.get(sqlId);
LOG.info("SQL : " + sql);
return sql;
}
/**
*
* @return return the query
*/
protected String getSql() {
StackTraceElement stackTrace = null;
try {
boolean flag = true;
if (flag) {
throw new IllegalArgumentException();
}
} catch (IllegalArgumentException e) {
stackTrace = e.getStackTrace()[1];
}
return stackTrace != null ? getSql(stackTrace.getMethodName()) : null;
}
/**
*
* @param str
* the query content
* @return return the query
*/
private static String trimToLine(final String str) {
if (null == str) {
return str;
}
return str.replace("\n", "").replace("\r", "").trim();
}
private static String shrink(String input) {
if (input == null || input.equals("")) {
return input;
}
return input.replaceAll("[\\r\\n\\s]+", " ").trim();
}
}
package com.gepower.repair.dao.common;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Defining an annotation
* @author
*
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface SqlSource {
String[] value() default "/sql.xml";
}
Dao
@SqlSource("/resources/sql/calculatecatalogcost-sql.xml")
sql xml文件
<sqls>
<sql id="findCatalogServices">
</sql>
</sqls>