package org.fireflow.service.jdbc; import java.io.IOException; import java.io.InputStream; import java.math.BigDecimal; import java.sql.Blob; import java.sql.Clob; import java.sql.Connection; import java.sql.ParameterMetaData; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Timestamp; import java.text.SimpleDateFormat; import java.util.List; import javax.annotation.PostConstruct; import javax.sql.DataSource; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.apache.commons.codec.binary.Base64; import org.apache.commons.lang.StringUtils; import org.apache.ws.commons.schema.XmlSchemaCollection; import org.fireflow.engine.exception.ServiceInvocationException; import org.fireflow.model.servicedef.impl.AbstractServiceDef; import org.firesoa.common.schema.SQLSchemaGenerator; import org.gibello.zql.ParseException; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.w3c.dom.Text; public abstract class AbstractDBService extends AbstractServiceDef { protected static final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory .newInstance(); /** * 查询SQL语句 select * from t_abc where id=:id */ protected String sql = null; /** * 数据源 */ protected DataSource dataSource = null; public DataSource getDataSource() { return dataSource; } public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; } public String getSQL() { return sql; } public void setSQL(String theSQL) { if (!theSQL.trim().endsWith(";")) { this.sql = theSQL + ";"; } else { this.sql = theSQL; } } @PostConstruct public void afterPropertiesSet() throws Exception { generateSchema();// } protected void generateSchema() throws ParseException, SQLException { Connection conn = this.getDataSource().getConnection(); try { XmlSchemaCollection xmlSchemaCollection = SQLSchemaGenerator .generateXmlSchemaCollectionForSQL(this.getSQL(), this.getTargetNamespaceUri(), conn); this.setXmlSchemaCollection(xmlSchemaCollection); } finally { if (conn != null) { try { conn.close(); } catch (Exception e) { } } } } /** * 填充PreparedStatement * * @param pstmt * @param parameterElements * @return 返回下次填充的起始位置 * @throws SQLException * @throws ServiceInvocationException */ public static int fulfillPreparedStatement(PreparedStatement pstmt, List<Element> parameterElements, int startIndex) throws SQLException, ServiceInvocationException { ParameterMetaData parameterMetaData = pstmt.getParameterMetaData(); int preparedParamCount = parameterMetaData.getParameterCount(); int paramCount = parameterElements.size(); int currentParamIndex = 0; if (preparedParamCount > 0) { for (int i = 0; i < paramCount; i++) { currentParamIndex = i + startIndex; int type = parameterMetaData .getParameterType(currentParamIndex); Element element = parameterElements.get(i); String strValue = null; NodeList nodeList = element.getChildNodes(); for (int k=0;k<nodeList.getLength();k++){ Node node = nodeList.item(k); if (node.getNodeType()==Node.TEXT_NODE){ strValue = ((Text)node).getNodeValue(); } } switch (type) { case java.sql.Types.CHAR: case java.sql.Types.VARCHAR: case java.sql.Types.LONGVARCHAR: //case java.sql.Types.NCHAR: //case java.sql.Types.NVARCHAR: //case java.sql.Types.LONGNVARCHAR: pstmt.setString(currentParamIndex, strValue); break; case java.sql.Types.NUMERIC: case java.sql.Types.DECIMAL: if (StringUtils.isEmpty(strValue)) { pstmt.setNull(currentParamIndex, type); } else { if (strValue.indexOf(".") == -1) { Long theLong = Long.valueOf(strValue); pstmt.setBigDecimal(currentParamIndex, BigDecimal.valueOf(theLong)); } else { Double d = Double.valueOf(strValue); pstmt.setBigDecimal(currentParamIndex, BigDecimal.valueOf(d)); } } break; case java.sql.Types.BOOLEAN: case java.sql.Types.BIT: if (StringUtils.isEmpty(strValue)) { pstmt.setNull(currentParamIndex, type); } else { pstmt.setBoolean(currentParamIndex, Boolean.valueOf(strValue)); } break; case java.sql.Types.TINYINT: case java.sql.Types.SMALLINT: case java.sql.Types.INTEGER: if (StringUtils.isEmpty(strValue)) { pstmt.setNull(currentParamIndex, type); } else { pstmt.setInt(currentParamIndex, Integer.valueOf(strValue)); } break; case java.sql.Types.BIGINT: if (StringUtils.isEmpty(strValue)) { pstmt.setNull(currentParamIndex, type); } else { pstmt.setLong(currentParamIndex, Long.valueOf(strValue)); } break; case java.sql.Types.REAL: if (StringUtils.isEmpty(strValue)) { pstmt.setNull(currentParamIndex, type); } else { pstmt.setFloat(currentParamIndex, Float.valueOf(strValue)); } break; case java.sql.Types.FLOAT: case java.sql.Types.DOUBLE: if (StringUtils.isEmpty(strValue)) { pstmt.setNull(currentParamIndex, type); } else { pstmt.setDouble(currentParamIndex, Double.valueOf(strValue)); } break; case java.sql.Types.BINARY: case java.sql.Types.VARBINARY: case java.sql.Types.LONGVARBINARY: case java.sql.Types.BLOB: case java.sql.Types.CLOB: if (StringUtils.isEmpty(strValue)) { pstmt.setNull(currentParamIndex, type); } else { byte[] content = null; try { content = Base64.decodeBase64(strValue .getBytes("UTF-8")); } catch (Exception e) { e.printStackTrace(); } if (content == null) { pstmt.setNull(currentParamIndex, type); } else { pstmt.setBytes(currentParamIndex, content); } } break; case java.sql.Types.DATE: if (StringUtils.isEmpty(strValue)) { pstmt.setNull(currentParamIndex, type); } else { java.sql.Date sqlDate = java.sql.Date.valueOf(strValue); pstmt.setDate(currentParamIndex, sqlDate); } break; case java.sql.Types.TIME: if (StringUtils.isEmpty(strValue)) { pstmt.setNull(currentParamIndex, type); } else { java.sql.Time t = java.sql.Time.valueOf(strValue); pstmt.setTime(currentParamIndex, t); } break; case java.sql.Types.TIMESTAMP: if (StringUtils.isEmpty(strValue)) { pstmt.setNull(currentParamIndex, type); } else { String dt = strValue; if (dt.indexOf("T") >= 0) {// 如果是“YYYY-MM-DDThh:mm:ss”这种格式,则将T替换成空格 dt = dt.replace("T", " "); } java.sql.Timestamp ts = Timestamp.valueOf(dt); pstmt.setTimestamp(currentParamIndex, ts); } break; } } } return currentParamIndex + 1; } public static Document createDataSet(ResultSet rs, ResultSetMetaData metaData, String targetNamespace) throws SQLException, IOException { DocumentBuilder builder = null; try { builder = documentBuilderFactory.newDocumentBuilder(); } catch (ParserConfigurationException e) { // TODO Auto-generated catch block e.printStackTrace(); } Document doc = builder.newDocument(); Element rootElement = doc.createElementNS(targetNamespace, SQLSchemaGenerator.DATA_SET_ELEMENT); doc.appendChild(rootElement); while (rs.next()) { createRow(rs, metaData, rootElement); } return doc; } protected static Element createRow(ResultSet rs, ResultSetMetaData metaData, Element rootElement) throws SQLException, IOException { Document doc = rootElement.getOwnerDocument(); Element rowElement = doc.createElement(SQLSchemaGenerator.ROW_ELEMENT); rootElement.appendChild(rowElement); int columnCount = metaData.getColumnCount(); for (int i = 1; i <= columnCount; i++) { int type = metaData.getColumnType(i); String columnName = metaData.getColumnName(i); if (columnName==null)columnName=""; Element colElement = doc.createElement(columnName.toLowerCase()); rowElement.appendChild(colElement); switch (type) { case java.sql.Types.CHAR: case java.sql.Types.VARCHAR: case java.sql.Types.LONGVARCHAR: //case java.sql.Types.NCHAR: //case java.sql.Types.NVARCHAR: //case java.sql.Types.LONGNVARCHAR: String content = rs.getString(i); colElement.appendChild(doc.createTextNode(content == null ? "" : content)); break; case java.sql.Types.NUMERIC: case java.sql.Types.DECIMAL: int scale = metaData.getScale(i); if (scale <= 0) {// 按照整数处理 Long l = rs.getLong(i); colElement.appendChild(doc.createTextNode(l == null ? "" : l.toString())); } else {// 按照double处理 Double d = rs.getDouble(i); colElement.appendChild(doc.createTextNode(d == null ? "" : d.toString())); } break; case java.sql.Types.BOOLEAN: case java.sql.Types.BIT: Boolean b = rs.getBoolean(i); colElement.appendChild(doc.createTextNode(b == null ? "" : b.toString())); break; case java.sql.Types.TINYINT: case java.sql.Types.SMALLINT: case java.sql.Types.INTEGER: Integer theInt = rs.getInt(i); colElement.appendChild(doc.createTextNode(theInt == null ? "" : theInt.toString())); break; case java.sql.Types.BIGINT: Long theLong = rs.getLong(i); colElement.appendChild(doc.createTextNode(theLong == null ? "" : theLong.toString())); break; case java.sql.Types.REAL: Float f = rs.getFloat(i); colElement.appendChild(doc.createTextNode((f == null ? "" : f.toString()))); break; case java.sql.Types.FLOAT: case java.sql.Types.DOUBLE: Double db = rs.getDouble(i); colElement.appendChild(doc.createTextNode(db == null ? "" : db.toString())); break; case java.sql.Types.BINARY: case java.sql.Types.VARBINARY: case java.sql.Types.LONGVARBINARY: byte[] bytes = rs.getBytes(i); if (bytes != null) { String base64 = new String(Base64.encodeBase64(bytes),"UTF-8"); colElement.appendChild(doc.createCDATASection(base64)); } case java.sql.Types.BLOB: Blob blob = rs.getBlob(i); if (blob != null) { InputStream in = blob.getBinaryStream(); if (in != null) { byte[] tyeBytes = new byte[in.available()]; int offset = 0; int numRead = 0; while (offset < tyeBytes.length && (numRead = in.read(tyeBytes, offset, tyeBytes.length - offset)) >= 0) { offset += numRead; } String base64_2 = new String(Base64.encodeBase64(tyeBytes),"UTF-8"); colElement.appendChild(doc.createCDATASection(base64_2)); } } break; case java.sql.Types.CLOB: Clob clob = rs.getClob(i); if (clob != null) { InputStream clobIn = clob.getAsciiStream(); if (clobIn != null) { byte[] clobBytes = new byte[clobIn.available()]; int clob_offset = 0; int clob_numRead = 0; while (clob_offset < clobBytes.length && (clob_numRead = clobIn.read(clobBytes, clob_offset, clobBytes.length - clob_offset)) >= 0) { clob_offset += clob_numRead; } String base64_3 = new String(Base64.encodeBase64(clobBytes),"UTF-8"); colElement.appendChild(doc.createCDATASection(base64_3)); } } break; case java.sql.Types.DATE: java.sql.Date sqlDate = rs.getDate(i); colElement.appendChild(doc.createTextNode(sqlDate == null ? "" : sqlDate.toString())); break; case java.sql.Types.TIME: java.sql.Time t = rs.getTime(i); colElement.appendChild(doc.createTextNode(t == null ? "" : t.toString())); break; case java.sql.Types.TIMESTAMP: java.sql.Timestamp ts = rs.getTimestamp(i); SimpleDateFormat df = new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ss"); colElement.appendChild(doc.createTextNode(ts == null ? "" : df.format(ts))); break; } } return rowElement; } }