/* * BEGIN_HEADER - DO NOT EDIT * * The contents of this file are subject to the terms * of the Common Development and Distribution License * (the "License"). You may not use this file except * in compliance with the License. * * You can obtain a copy of the license at * https://open-jbi-components.dev.java.net/public/CDDLv1.0.html. * See the License for the specific language governing * permissions and limitations under the License. * * When distributing Covered Code, include this CDDL * HEADER in each file and include the License file at * https://open-jbi-components.dev.java.net/public/CDDLv1.0.html. * If applicable add the following below this CDDL HEADER, * with the fields enclosed by brackets "[]" replaced with * your own identifying information: Portions Copyright * [year] [name of copyright owner] */ /* * @(#)JDBCDenormalizer.java * * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved. * * END_HEADER - DO NOT EDIT */ package org.glassfish.openesb.databasebc; import java.io.StringWriter; import java.sql.CallableStatement; import java.sql.DatabaseMetaData; import java.sql.ParameterMetaData; import java.sql.PreparedStatement; import java.sql.ResultSet; import org.glassfish.openesb.databasebc.model.metadata.DBMetaData; import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.StringTokenizer; import java.util.logging.Level; import java.util.logging.Logger; import javax.jbi.messaging.MessagingException; import javax.jbi.messaging.NormalizedMessage; import javax.wsdl.Input; import javax.wsdl.Message; import javax.wsdl.Operation; import javax.wsdl.Part; import javax.xml.namespace.QName; import javax.xml.transform.Source; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMResult; import javax.xml.transform.stream.StreamResult; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import com.ibm.wsdl.util.xml.DOMUtils; import com.sun.jbi.internationalization.Messages; import org.glassfish.openesb.databasebc.extensions.JDBCOperationInput; import com.sun.jbi.nms.wsdl11wrapper.HelperFactory; import com.sun.jbi.nms.wsdl11wrapper.WrapperParser; import java.io.InputStream; import java.io.Reader; import java.util.Scanner; import javax.xml.transform.stream.StreamSource; import org.glassfish.openesb.databasebc.extensions.SPOperationInput; import org.glassfish.openesb.databasebc.util.CachedQueryParameter; import org.glassfish.openesb.databasebc.util.ParamMetadataCache; /** * * JDBCDenormalizer * */ public class JDBCDenormalizer { private static final Messages mMessages = Messages.getMessages( JDBCDenormalizer.class); private static final Logger mLogger = Messages.getLogger( JDBCDenormalizer.class); private String dbName = null; private String catalog = null; private ArrayList outParamIndex = new ArrayList(); private HashMap outParamTypes = new HashMap(); private HashMap outParamNames = new HashMap(); private HashMap mColNamesTypes = new HashMap(); private String mRecordPrefix = null; //113494 private String driverName_; /** * * @param normalizedMessage * @param opMetaData * @param ps * @throws MessagingException */ protected void denormalizeOutbound(final NormalizedMessage normalizedMessage, String dbName, final OperationMetaData opMetaData, final PreparedStatement ps) throws MessagingException { if (opMetaData != null) { final JDBCOperationInput mJdbcOperationInput = opMetaData. getJDBCOperationInput(); final String operationType = mJdbcOperationInput.getOperationType(); mColNamesTypes = mJdbcOperationInput.getColNamesTypes(); //if (JDBCUtil.opList.contains(operationType)) { try { Element element = transformMessage(normalizedMessage, opMetaData); if (element != null) populatePreparedStatement(element, dbName, opMetaData, ps); } catch (final SQLException ex) { final String msg = JDBCDenormalizer.mMessages.getString( "DBBC_E00709.JDBCDN_FailedPopulate_PS") + "Reason: " + ex.getLocalizedMessage() + " SQLState: " + ex. getSQLState() + " ErrorCode:" + ex.getErrorCode(); throw new MessagingException(msg, ex); } catch (final Exception ex) { final String msg = JDBCDenormalizer.mMessages.getString( "DBBC_E00709.JDBCDN_FailedPopulate_PS") + "Reason: " + ex.getLocalizedMessage(); throw new MessagingException(msg, ex); } //} } } /** * * @param normalizedMessage * @param opMetaData * @param dbmeta * @param cs * @throws MessagingException */ protected void denormalizeOutboundProc(final NormalizedMessage normalizedMessage, final OperationMetaData opMetaData, final DatabaseMetaData dbmeta, final CallableStatement cs) throws MessagingException { if (opMetaData != null) { final SPOperationInput mJdbcOperationInput = opMetaData. getJDBCSPOperationInput(); final String operationType = mJdbcOperationInput.getOperationType(); try { Element element = transformMessage(normalizedMessage, opMetaData); if (element != null) populateProcedure(element, opMetaData, dbmeta, cs); } catch (final SQLException ex) { final String msg = JDBCDenormalizer.mMessages.getString( "DBBC_E00711.DN_FailedPopulate_Proc") + "Reason: " + ex.getLocalizedMessage() + " SQLState: " + ex. getSQLState() + " ErrorCode:" + ex.getErrorCode(); throw new MessagingException(msg, ex); } catch (final Throwable th) { final String msg = JDBCDenormalizer.mMessages.getString( "DBBC_E00712.DN_Failed_Proc") + "Reason: " + th. getLocalizedMessage(); throw new MessagingException(msg, th); } } } /** * * @param tableElem * @param opMetaData * @param cs * @throws SQLException * @throws MessagingException * @throws Exception */ @SuppressWarnings("empty-statement") private void populateProcedure(final Element tableElem, final OperationMetaData opMetaData, final DatabaseMetaData dbmeta, CallableStatement cs) throws SQLException, MessagingException, Exception { final SPOperationInput jdbcSql = opMetaData.getJDBCSPOperationInput(); driverName_ = dbmeta.getDriverName(); String sqltext = jdbcSql.getExecutionString(); String procName = getProcName(sqltext); /* * Modified by Logicoy for [ task #20 ] DB BC - Insert statement should return primary key auto-increment value inserted */ String pcatalog = null; String pschema = null; if (dbName != null) pschema = dbName; if (catalog != null) pcatalog = catalog; ResultSet rs = null; if (mLogger.isLoggable(Level.INFO)) mLogger.log(Level.INFO, JDBCDenormalizer.mMessages.getString( "DBBC_R00716.JDBCDN_StartPopulateProc")); if (jdbcSql != null) { final String dbURL = dbmeta.getURL(); ParamMetadataCache paramsCache = ParamMetadataCache.instance(); ArrayList params = paramsCache.getMetadata( dbURL, opMetaData); if (params == null) { try { final String dbms = dbmeta.getDatabaseProductName(). toLowerCase(); final String colNamePattern = ((dbms.contains("sql server") || dbms.contains( "adaptive server")) && sqltext.contains("=")) ? null : "%"; rs = dbmeta.getProcedureColumns(pcatalog, pschema, procName, colNamePattern); } catch (final SQLException ex) { if (mLogger.isLoggable(Level.FINE)) mLogger.log(Level.SEVERE, JDBCDenormalizer.mMessages.getString( "DBBC_R00721.JDBCDN_UnableToProcessMedataData"), ex); else if (mLogger.isLoggable(Level.INFO)) mLogger.log(Level.SEVERE, JDBCDenormalizer.mMessages.getString( "DBBC_R00721.JDBCDN_UnableToProcessMedataData")); } if (rs != null) params = cacheQueryParameters(rs); else { final String msg = JDBCDenormalizer.mMessages.getString( "DBBC_R00721.JDBCDN_UnableToProcessMedataData"); MessagingException me = new MessagingException(msg); mLogger.log(Level.SEVERE, msg); throw me; } try { rs.close(); } catch (SQLException e) { mLogger.log(Level.WARNING, JDBCDenormalizer.mMessages.getString( "DBBC_R00727.JDBCDN_CursorLeak") + procName); } paramsCache.storeMetadata(dbURL, opMetaData, params); } for (int i = 0; i < params.size(); ++i) { if (mLogger.isLoggable(Level.FINE)) mLogger.log(Level.FINE, JDBCDenormalizer.mMessages.getString( "DBBC_R00719.JDBCDN_ProcessColumn")); CachedQueryParameter param = params.get(i); String columnName = param.getName(); // strip off "@" in front of columnName // In case if it is function, for RETURN parameter coulumnName will be null. if (columnName != null && columnName.charAt(0) == '@') columnName = columnName.substring(1); int targetSqlType = param.getType(); int colType = param.getDirection(); String type_Name = param.getTypeName(); short numericScale = param.getPrecision(); final int columnNumber = i + 1; if (colType == DatabaseMetaData.procedureColumnIn) { if ((targetSqlType == 1111) && (type_Name.equals( "PL/SQL TABLE"))) targetSqlType = -14; if ((targetSqlType == 1111) && (type_Name.equals( "PL/SQL RECORD"))) targetSqlType = -14; if ((targetSqlType == 1111) && (type_Name.equals("CLOB"))) targetSqlType = 2005; if ((targetSqlType == 1111) && (type_Name.equals("NVARCHAR2"))) targetSqlType = 12; final Element columnElem = findMatchingColumnElement( columnName, tableElem, mRecordPrefix); //113494 if (columnElem != null) { final String value = DOMUtils.getChildCharacterData( columnElem); String isNull = ""; try { isNull = columnElem.getAttribute("isNull"); } catch (Exception e) { mLogger.log(Level.FINE, JDBCDenormalizer.mMessages.getString( "DBBC_R00722.JDBCDN_IsNullNotSet")); } if (((value != null) && !value.trim().equals("")) || (!isNull. equalsIgnoreCase("true"))) if (dbmeta.getDriverName().toLowerCase().contains( "oracle") && targetSqlType == java.sql.Types.BLOB) cs.setBinaryStream(columnNumber, (java.io.ByteArrayInputStream) JDBCUtil.convert(value, targetSqlType, cs.getConnection()), value.length()); else if (dbmeta.getDriverName().toLowerCase(). contains("oracle") && targetSqlType == java.sql.Types.CLOB) cs.setCharacterStream(columnNumber, (java.io.StringReader) JDBCUtil.convert( value, targetSqlType, cs.getConnection()), value.length()); else cs.setObject(columnNumber, JDBCUtil.convert(value, targetSqlType, cs.getConnection()), targetSqlType); else cs.setNull(columnNumber, targetSqlType); }//end of if }//end of if if (colType == DatabaseMetaData.procedureColumnInOut || colType == DatabaseMetaData.procedureColumnOut) try { // if the parameter is a cursor type, add its index to the arraylist if ((targetSqlType == 1111) && (type_Name.equals( "REF CURSOR"))) { targetSqlType = -10; cs.registerOutParameter(columnNumber, targetSqlType); } else if ((targetSqlType == 1111) && (type_Name.equals("CLOB"))) { targetSqlType = 2005; cs.registerOutParameter(columnNumber, targetSqlType, type_Name); } else if (dbmeta.getDatabaseProductName(). toLowerCase().contains("oracle")) cs.registerOutParameter(columnNumber, targetSqlType); else cs.registerOutParameter(columnNumber, targetSqlType, type_Name); outParamIndex.add(Integer.valueOf(Double.valueOf( columnNumber).intValue())); outParamTypes.put(columnNumber, type_Name); outParamNames.put(columnNumber, columnName); } catch (SQLException e) { if (mLogger.isLoggable(Level.FINE)) mLogger.log(Level.WARNING, e.getLocalizedMessage(), e); else if (mLogger.isLoggable(Level.INFO)) mLogger.log(Level.WARNING, e.getLocalizedMessage()); throw e; } // check if the parameter is RETURN type (i.e. it is a function) if (colType == DatabaseMetaData.procedureColumnReturn) try { // if the parameter is a cursor type, add its index to the arraylist if ((targetSqlType == 1111) && (type_Name.equals( "REF CURSOR"))) { targetSqlType = -10; cs.registerOutParameter(columnNumber, targetSqlType); } else if ((dbmeta.getDatabaseProductName(). toLowerCase().contains("sql server") || dbmeta.getDatabaseProductName(). toLowerCase().contains("adaptive server")) && columnName.equals("RETURN_VALUE")) cs.registerOutParameter(columnNumber, targetSqlType, type_Name); else cs.registerOutParameter(columnNumber, targetSqlType, numericScale); outParamIndex.add(Integer.valueOf(Double.valueOf( columnNumber).intValue())); outParamTypes.put(columnNumber, type_Name); //columnName will be null for RETURN type. However DB BC wizard puts it as param1. //So hardcoding it so that normalizes return value. if (columnName == null) columnName = "param1"; outParamNames.put(columnNumber, columnName); } catch (SQLException e) { if (mLogger.isLoggable(Level.FINE)) mLogger.log(Level.WARNING, e.getLocalizedMessage(), e); else if (mLogger.isLoggable(Level.INFO)) mLogger.log(Level.WARNING, e.getLocalizedMessage()); throw e; } //i++; if (mLogger.isLoggable(Level.FINEST)) { mLogger.log(Level.FINEST, JDBCDenormalizer.mMessages.getString( "DBBC_R00717.JDBCDN_ColumnName") + " == " + columnName); mLogger.log(Level.FINEST, JDBCDenormalizer.mMessages.getString( "DBBC_R00718.JDBCDN_ColumnType") + " == " + type_Name); } }//end of While } } /** * * @param tableElem * @param opMetaData * @param ps * @throws SQLException * @throws MessagingException * @throws Exception */ private void populatePreparedStatement(final Element tableElem, String dbName, final OperationMetaData opMetaData, final PreparedStatement ps) throws SQLException, MessagingException, Exception { /* * Modified by Logicoy for [ task #20 ] DB BC - Insert statement should return primary key auto-increment value inserted */ DatabaseMetaData dbMeta = ps.getConnection().getMetaData(); final JDBCOperationInput jdbcSql = opMetaData.getJDBCSql(); /** /* * Modified by Logicoy for [ task #20 ] DB BC - Insert statement should return primary key auto-increment value inserted * * When generatedKey is specified, parameterMetaData's count includes the generatedKey's parameter also. * So we need to reduce the param count value by 1 so that it matches the number of columns specified in paramOrder. * This is applicable only for Oracle. */ String generatedKey = jdbcSql.getGeneratedKey(); boolean isOracle = dbMeta.getDriverName().toLowerCase().contains( "oracle"); boolean reduceParamCountFromParamMetaData = false; if (generatedKey != null && !generatedKey.equals("") && isOracle) reduceParamCountFromParamMetaData = true; /* Logicoy - changes ends here */ if (mLogger.isLoggable(Level.FINE)) mLogger.log(Level.FINE, JDBCDenormalizer.mMessages.getString( "DBBC_R00720.JDBCDN_StartPopulatePS")); if (jdbcSql != null) { //113494 start mRecordPrefix = opMetaData.getJDBCSql().getTableName(); // see if the table name is null (SQL SE) // then take the query name as the prefix if (mRecordPrefix == null) { mRecordPrefix = opMetaData.getJDBCOperationOutput().getName(); mRecordPrefix = mRecordPrefix.substring(0, mRecordPrefix.indexOf("Response")); } //113494 end ArrayList paramsList = ParamMetadataCache.instance().getMetadata(dbMeta.getURL(), opMetaData); if (paramsList == null) { ParameterMetaData paramMetaData = null; try { paramMetaData = ps.getParameterMetaData(); } catch (final SQLException ex) { mLogger.log(Level.WARNING, ex.getLocalizedMessage()); } if (paramMetaData != null) { /* * Modified by Logicoy for [ task #20 ] DB BC - Insert statement should return primary key auto-increment value inserted */ /** * Modified by Logicoy. * When generatedKey is specified, parameterMetaData's count includes the generatedKey's parameter also. * So we need to reduce the param count value by 1 so that it matches the number of columns specified in paramOrder. * This is applicable only for Oracle. */ int parameters = paramMetaData.getParameterCount(); if (reduceParamCountFromParamMetaData) parameters = parameters - 1; if (parameters > 0) {// If there are no parameter we do not need to set anything /* Logicoy - changes ends here */ // on Prepared statement String paramOrder = jdbcSql.getParamOrder(); // changed for SQLSE since the user cannot enter param // ordering in sqlprojects. // we should generate a default param ordering. if (paramOrder == null || paramOrder.trim().equals("")) paramOrder = getDefaultParameterOrderString( parameters); final List columns = extractColumns(paramOrder); if (mLogger.isLoggable(Level.FINE)) mLogger.log(Level.FINE, JDBCDenormalizer.mMessages.getString( "DBBC_R00722.JDBCDN_TotalColumns") + columns.size()); paramsList = cacheQueryParameters(columns, paramMetaData, reduceParamCountFromParamMetaData); } else paramsList = cacheEmptyQueryParams(); ParamMetadataCache.instance().storeMetadata(dbMeta.getURL(), opMetaData, paramsList); } } if (paramsList != null) for (int i = 0; i < paramsList.size(); i++) { if (mLogger.isLoggable(Level.FINE)) mLogger.log(Level.FINE, JDBCDenormalizer.mMessages.getString( "DBBC_R00724.JDBCDN_ProcessParam")); CachedQueryParameter param = paramsList.get(i); final String columnName = param.getName(); final int columnNumber = i + 1; final Element columnElement = findMatchingColumnElement( columnName, tableElem, mRecordPrefix); //113494 Issue if (columnElement != null) { final String value = DOMUtils.getChildCharacterData( columnElement); String isNull = ""; String isDefaultColumn = ""; try { isNull = columnElement.getAttribute("isNull"); } catch (Exception e) { mLogger.log(Level.FINE, JDBCDenormalizer.mMessages.getString( "DBBC_R00722.JDBCDN_IsNullNotSet")); } try { isDefaultColumn = columnElement.getAttribute( "isDefaultColumn"); } catch (Exception e) { mLogger.log(Level.FINE, JDBCDenormalizer.mMessages.getString( "DBBC_R00723.JDBCDN_IsDefaultNotSet")); } /* * Modified by Logicoy Inc., * Open ESB Bug No: 107 - Throws error during insert when any of the parameter has empty value * The below condition checks if value is not empty, not isNull and not isDefault. Changed the OR condition (BUG) to AND condition * */ if ((((value != null) && !value.trim().equals("")) && (!isNull.equalsIgnoreCase("true"))) && (((value != null) && !value.trim().equals("")) && (!isDefaultColumn.equalsIgnoreCase("true")))) { /* * Logiocy Inc., * Bug 107 - changes ends here */ int columnType = param.getType(); if (ps.getConnection().getMetaData().getDriverName(). toLowerCase().contains("oracle") && columnType == java.sql.Types.BLOB) ps.setBinaryStream(columnNumber, (java.io.ByteArrayInputStream) JDBCUtil.convert(value, columnType, ps.getConnection()), value.length()); else if (ps.getConnection().getMetaData(). getDriverName().toLowerCase().contains( "oracle") && columnType == java.sql.Types.CLOB) ps.setCharacterStream(columnNumber, (java.io.StringReader) JDBCUtil.convert( value, columnType, ps.getConnection()), value.length()); else ps.setObject(columnNumber, JDBCUtil.convert( value, columnType, ps.getConnection()), columnType); if (mLogger.isLoggable(Level.FINEST)) { mLogger.log(Level.FINEST, mMessages.getString( "DBBC_R00717.JDBCDN_ColumnName") + " == " + columnName); mLogger.log(Level.FINEST, mMessages.getString( "DBBC_R00726.JDBCDN_ColumnType") + " == " + columnType); } } else { int columnType = param.getType(); if ((!isNull.equalsIgnoreCase("true")) && (isDefaultColumn != null && isDefaultColumn. equalsIgnoreCase("true"))) { if (!param.defaultSet()) { ResultSet rs = ps.getConnection(). getMetaData().getColumns(null, null, jdbcSql.getTableName(), "%"); while (rs.next()) if (columnName.equalsIgnoreCase(rs.getString("COLUMN_NAME")) && rs. getString("COLUMN_DEF") != null) //ps.setObject(columnNumber, JDBCUtil.convert(rs.getString("COLUMN_DEF"), columnType, ps.getConnection()), columnType); param.setDefault(rs.getString( "COLUMN_DEF")); param.setDefault(null); } if (param.hasDefault()) ps.setObject(columnNumber, JDBCUtil.convert( param.getDefault(), columnType, ps.getConnection()), columnType); else ps.setNull(columnNumber, columnType); } else ps.setNull(columnNumber, columnType); } } } else { final String msg = mMessages.getString( "DBBC_E00714.JDBCDN_Failed_PS_Param"); throw new MessagingException(msg); } } } /** * * @param dbColumnName * @param tableElem * @return */ private Element findMatchingColumnElement(final String dbColumnName, final Element tableElem, String recordPrefix) { // 113494 Issue Element columnElem = null; NodeList childNodes = tableElem.getChildNodes(); for (int i = 0; i < childNodes.getLength(); i++) { final Node child = childNodes.item(i); if ((child instanceof Element) && child.getLocalName().equalsIgnoreCase( recordPrefix + "_Record")) { // 113494 Issue if (mLogger.isLoggable(Level.FINEST)) mLogger.log(Level.FINEST, recordPrefix + "_Record"); columnElem = (Element) child; childNodes = columnElem.getChildNodes(); } } for (int i = 0; i < childNodes.getLength(); i++) { final Node child = childNodes.item(i); if ((child instanceof Element) && child.getLocalName().equalsIgnoreCase(dbColumnName)) { columnElem = (Element) child; break; } } if (null == columnElem) { //throw new MessagingException(String.format(JDBCDenormalizer.mMessages.getString("DBBC_E00727.JDBCDN_FailedFindColumnElem"), dbColumnName)); columnElem = tableElem.getOwnerDocument().createElement(dbColumnName); columnElem.setAttribute("isNull", "true"); } return columnElem; } /** * * @param paramOrder * @return */ private List extractColumns(final String paramOrder) { final List columnList = new ArrayList(); if (paramOrder != null) { final Scanner tok = new Scanner(paramOrder).useDelimiter( "\\s*" + "," + "\\s*"); while (tok.hasNext()) { final String column = tok.next(); columnList.add(column.trim()); } } return columnList; } /** * * @param parent * @param msgQName * @return */ private Element findChildElement(final Element parent, final QName msgQName) { final String ns = msgQName.getNamespaceURI(); final String localName = msgQName.getLocalPart(); NodeList nl = null; if ((ns != null) && !ns.trim().equals("")) nl = parent.getElementsByTagNameNS(ns, localName); else nl = parent.getElementsByTagName(localName); if ((nl != null) && (nl.getLength() > 0)) { if (JDBCDenormalizer.mLogger.isLoggable(Level.INFO)) JDBCDenormalizer.mLogger.log(Level.INFO, "found element"); if (JDBCDenormalizer.mLogger.isLoggable(Level.FINEST)) JDBCDenormalizer.mLogger.log(Level.FINEST, "found element with name, " + localName); final Element e2 = (Element) nl.item(0); return e2; } return null; } /** * * @param root * @param elemName * @return */ private Element findPart(final Element root, final String elemName) { // parts wrappers never have namespace final NodeList nl = root.getElementsByTagName(elemName); if ((nl != null) && (nl.getLength() > 0)) { if (JDBCDenormalizer.mLogger.isLoggable(Level.INFO)) JDBCDenormalizer.mLogger.log(Level.INFO, "found element with name, " + elemName); final Element e2 = (Element) nl.item(0); return e2; } return null; } /** ** Used by SQLSE to get the default parameter ordering. * @param pmeta * @return */ /* * Modified by Logicoy for [ task #20 ] DB BC - Insert statement should return primary key auto-increment value inserted */ /** * Modified by Logicoy * Refactored this method to pass the parameterMetaData's count instead of passing the ParameterMetaDataObject itself * since we only need the count value. */ private String getDefaultParameterOrderString(int numParams) { String parameterOrderString = null; //int numParams = 0; //if (pmeta != null) { /*try { numParams = pmeta.getParameterCount(); } catch (final SQLException sqle) { JDBCDenormalizer.mLogger.log(Level.WARNING, JDBCDenormalizer.mMessages.getString("JDBCDN_Failed_ParamCount")); return null; }*/ if (numParams > 0) for (int i = 1; i <= numParams; i++) { final String paramname = "param" + String.valueOf(i); parameterOrderString = (parameterOrderString == null) ? paramname : (parameterOrderString + "," + paramname); } //} return parameterOrderString; } //register out parameters private void registerOutParameters(CallableStatement cstmt, final DatabaseMetaData dbmeta) throws SQLException, NullPointerException { String errMsg = ""; int colCount = 0; boolean isFunction = false; boolean hasParameters = true; // indicates if the procedure is within a package or standalone boolean isPackaged = true; ArrayList paramIndices = new ArrayList(); ArrayList result = new ArrayList(); int paramIndex = 0; try { ParameterMetaData pmeta = cstmt.getParameterMetaData(); if (pmeta != null) { int numParams = pmeta.getParameterCount(); if (numParams > 0) // get info for each parameter for (int i = 1; i <= numParams; i++) { // try to get the sql type info - default to VARCHAR String sqlType = "VARCHAR"; try { sqlType = DBMetaData.getSQLTypeDescription(pmeta.getParameterType( i)); } catch (SQLException e) { mLogger.log(Level.WARNING, "Could not get SQL Type Description from DBMetadata", e.getLocalizedMessage()); } // try to get the java type info - default to String /** * Changing it to not use metadata class name and instead use the HashMap SQLTOJAVATYPES. * Without the change the parameter datatypes java.lang.Double and WSDLGenerator look up list * exepects native type double, float, short etc. **/ String javaType = "java.lang.String"; javaType = DBMetaData.getJavaFromSQLTypeDescription(sqlType); // added abey for Procedure ResultSet try { if ((pmeta.getParameterType(i) == java.sql.Types.OTHER) && (pmeta. getParameterTypeName(i).equalsIgnoreCase( "REF CURSOR"))) { sqlType = "RESULTSET"; javaType = "java.sql.ResultSet"; } } catch (SQLException e) { mLogger.log(Level.WARNING, "Could not get Java type information from DBMetadata", e.getLocalizedMessage()); } // try to get the param type, default to IN // always default it since getParameterMode() in data direct 3.3 throws exception // and 3.4 return UNKNOWN type String paramType = "IN"; try { paramType = DBMetaData.getPrepStmtParamTypeDescription(pmeta. getParameterMode((i))); } catch (SQLException e) { mLogger.log(Level.WARNING, "Could not get PreparedStatement Parameter Description", e.getLocalizedMessage()); } // set defalut type int sqlTypeCode = java.sql.Types.VARCHAR; if (paramType.equalsIgnoreCase("INOUT") || paramType. equalsIgnoreCase("OUT")) try { // if the parameter is a cursor type, add its index to the arraylist if ((pmeta.getParameterType(i) == 1111) && (paramType.equals( "OTHER"))) sqlTypeCode = java.sql.Types.OTHER; } catch (SQLException e) { mLogger.log(Level.WARNING, "Driver Does not support getting the Datatypes", e.getLocalizedMessage()); } if (paramType.equals("RETURN")) try { // if the parameter is a cursor type, add its index to the arraylist if ((pmeta.getParameterType(i) == 1111) && (paramType.equals( "OTHER"))) { //sqlTypeCode = java.sql.Types.OTHER; } } catch (SQLException e) { mLogger.log(Level.WARNING, "Driver Does not support getting the Datatypes", e.getLocalizedMessage()); } cstmt.registerOutParameter(paramIndex, sqlTypeCode); outParamIndex.add(Integer.valueOf(Double.valueOf( paramIndex).intValue())); } } } catch (SQLException e) { mLogger.log(Level.WARNING, "Could not get Parameter MetaData", e); } } /* private String getProcName(String sqlText) { String proc_name = ""; String schema = ""; final Scanner tok = new Scanner(sqlText).useDelimiter("\\s*" + " " + "\\s*"); while (tok.hasNext()) { String column = tok.next(); int cnt = 0; column=column.toLowerCase(); if(column.endsWith("call")){ cnt++; proc_name=tok.next(); if(proc_name.contains(".")){ final Scanner tok1 = new Scanner(proc_name).useDelimiter("\\s*" + "." + "\\s*"); schema=tok1.next(); proc_name=tok1.next(); } if(proc_name.contains("(")){ int i = proc_name.indexOf("("); proc_name=proc_name.substring(0, i); } if(proc_name.contains("}")){ int i = proc_name.indexOf("}"); proc_name=proc_name.substring(0, i); } } if(cnt>0) break; } return proc_name; } */ public String getProcName( String sqlText) { String proc_name = ""; String schema = ""; final StringTokenizer tok = new StringTokenizer(sqlText, " "); while (tok.hasMoreElements()) { String column = (String) tok.nextElement(); int cnt = 0; column = column.toLowerCase(); if (column.endsWith("call")) { cnt++; proc_name = (String) tok.nextElement(); if (proc_name.contains(".")) { //final StringTokenizer tok1 = new StringTokenizer(proc_name, "."); //catalog = tok1.nextToken(); //final String beforeDot1 = tok1.nextToken(); //proc_name = tok1.nextToken(); String[] procData = proc_name.split("\\."); final int len = procData.length; proc_name = procData[len - 1]; String catName = null; String schemaName = null; if (len == 3) { catName = procData[0]; schemaName = procData[1]; } else schemaName = procData[0]; if (driverName_.toLowerCase().contains("oracle")) { catalog = schemaName; dbName = catName; } else { catalog = catName; dbName = schemaName; } } if (proc_name.contains("(")) { int i = proc_name.indexOf("("); proc_name = proc_name.substring(0, i); } if (proc_name.contains("}")) { int i = proc_name.indexOf("}"); proc_name = proc_name.substring(0, i); } } if (cnt > 0) break; } return proc_name; } private final Element transformMessage(final NormalizedMessage normalizedMessage, final OperationMetaData opMetaData) throws MessagingException { Element element = null; try { final TransformerFactory tFactory = TransformerFactory.newInstance(); final Transformer trans = tFactory.newTransformer(); final Source source = normalizedMessage.getContent(); final DOMResult result = new DOMResult(); trans.transform(source, result); if (source instanceof StreamSource) { StreamSource stream = (StreamSource) source; InputStream inputStream = stream.getInputStream(); if (inputStream != null) inputStream.reset(); Reader reader = stream.getReader(); if (reader != null) reader.reset(); } final Node node = result.getNode(); final StringWriter strWriter = new StringWriter(); final StreamResult sResult = new StreamResult(strWriter); trans.transform(source, sResult); if (source instanceof StreamSource) { StreamSource stream = (StreamSource) source; InputStream inputStream = stream.getInputStream(); if (inputStream != null) inputStream.reset(); Reader reader = stream.getReader(); if (reader != null) reader.reset(); } if (node != null) { Document normalDoc = null; if (node instanceof Document) normalDoc = (Document) node; else normalDoc = ((Element) node).getOwnerDocument(); final Element normalRoot = normalDoc.getDocumentElement(); //final BindingOperation bindingOperation = opMetaData.getBindingOperation(); final Operation operation = opMetaData.getOperation(); final Input input = operation.getInput(); final Message inputMessage = input.getMessage(); if (HelperFactory.WRAPPER_ENABLED) { final WrapperParser wrapperParser = HelperFactory.createParser(); wrapperParser.parse(normalDoc, inputMessage); final Map parts = inputMessage.getParts(); final Iterator it = parts.values().iterator(); while (it.hasNext()) { final Part part = (Part) it.next(); if (wrapperParser.hasPart(part.getName())) { final QName elementQName = part.getElementName(); if (elementQName == null) { final String msgEx = JDBCDenormalizer.mMessages.getString( "DBBC_E00706.DN_Failed_Denormalize") + part.getName() + "should have element attribute defined."; throw new MessagingException(msgEx); } //Element element = null; final NodeList unwrappedList = wrapperParser.getPartNodes(part. getName()); for (int j = 0; j < unwrappedList.getLength(); j++) { final Node unwrapped = unwrappedList.item(j); if ((unwrapped.getNodeType() == Node.ELEMENT_NODE) && (unwrapped.getLocalName() != null) && unwrapped.getLocalName().equals(elementQName. getLocalPart())) { element = (Element) unwrapped; break; } } /*if (element != null) { populateProcedure(element, opMetaData, dbmeta,cs); //registerOutParameters(cs); } else { final String msgEx = JDBCDenormalizer.mMessages.getString( "JDBCDN_Failed_Finding_Node") + elementQName.getLocalPart() + ", in the part wrapper"; JDBCDenormalizer.mLogger.log(Level.WARNING, msgEx); throw new MessagingException(msgEx); }*/ } } } else { final Element messageElement = normalRoot; if (messageElement != null) { final Map parts = inputMessage.getParts(); final Iterator it = parts.values().iterator(); while (it.hasNext()) { final Part part = (Part) it.next(); final Element partElement = findPart(messageElement, part.getName()); if (partElement != null) { final QName elementQName = part.getElementName(); if (elementQName != null) element = findChildElement(partElement, elementQName); } } } } } } catch (final TransformerConfigurationException ex) { final String msg = JDBCDenormalizer.mMessages.getString( "DBBC_E00708.DN_Failed_Convert_NM"); throw new MessagingException(msg, ex); } catch (final TransformerException ex) { final String msg = JDBCDenormalizer.mMessages.getString( "DBBC_E00708.DN_Failed_Convert_NM"); throw new MessagingException(msg, ex); } catch (final Throwable th) { final String msg = JDBCDenormalizer.mMessages.getString( "DBBC_E00712.DN_Failed_Proc"); throw new MessagingException(msg, th); } return element; } protected void setDatabaseName(String databaseName) { dbName = databaseName; } protected ArrayList getOutParamIndex() { return outParamIndex; } protected HashMap getOutParamTypes() { return outParamTypes; } protected HashMap getOutParamNames() { return outParamNames; } /* * Modified by Logicoy for [ task #20 ] DB BC - Insert statement should return primary key auto-increment value inserted */ /* * Modified by Logicoy * Added reduceParamCountFromParamMetaData */ protected ArrayList cacheQueryParameters(List paramNames, ParameterMetaData paramMeta, boolean reduceParamCountFromParamMetaData) throws SQLException { int size = paramNames.size(); int paramCount = paramMeta.getParameterCount(); if (reduceParamCountFromParamMetaData) paramCount = paramCount - 1; if (size != paramCount) return null; ArrayList params = new ArrayList(size); for (int i = 0; i < size; ++i) { final int metaIdx = i + 1; String name = paramNames.get(i); int type = -1; try { //Oracle doesn't support this feature. Shame on them! type = paramMeta.getParameterType(metaIdx); } catch (SQLException e) { type = (int) JDBCUtil.builtInTypes.get(mColNamesTypes.get(name)); } /*String typeName = null; try{ // ... and this typeName = paramMeta.getParameterTypeName(metaIdx); } catch(SQLException e){ } int direction = paramMeta.getParameterMode(metaIdx); short precision = (short) paramMeta.getPrecision(metaIdx);*/ CachedQueryParameter cp = new CachedQueryParameter(name, type); params.add(cp); } return params; } protected ArrayList cacheEmptyQueryParams() { return new ArrayList(0); } protected ArrayList cacheQueryParameters(ResultSet paramsInfo) throws SQLException { if (paramsInfo == null) return null; ArrayList params = new ArrayList(); while (paramsInfo.next()) { String name = paramsInfo.getString("COLUMN_NAME"); int type = (int) java.sql.Types.VARCHAR; try { type = paramsInfo.getInt("DATA_TYPE"); } catch (final SQLException e) { type = (int) JDBCUtil.builtInTypes.get(mColNamesTypes.get(name)); if (mLogger.isLoggable(Level.FINEST)) mLogger.log(Level.WARNING, "DBBC_R00723.JDBCDN_DriverNoSupportForMetaData", e); else if (mLogger.isLoggable(Level.INFO)) mLogger.log(Level.WARNING, "DBBC_R00723.JDBCDN_DriverNoSupportForMetaData", e. getLocalizedMessage()); } String typeName = "VARCHAR"; try { typeName = paramsInfo.getString("TYPE_NAME"); } catch (final SQLException e) { //typeName = JDBCUtil.builtInTypes.get(mColNamesTypes.get(name)); if (mLogger.isLoggable(Level.FINEST)) mLogger.log(Level.WARNING, "DBBC_R00723.JDBCDN_DriverNoSupportForMetaData", e); else if (mLogger.isLoggable(Level.INFO)) mLogger.log(Level.WARNING, "DBBC_R00723.JDBCDN_DriverNoSupportForMetaData", e. getLocalizedMessage()); } int direction = Integer.valueOf(ParameterMetaData.parameterModeIn); try { direction = paramsInfo.getInt("COLUMN_TYPE"); } catch (final SQLException e) { if (mLogger.isLoggable(Level.FINEST)) mLogger.log(Level.WARNING, "DBBC_R00723.JDBCDN_DriverNoSupportForMetaData", e); else if (mLogger.isLoggable(Level.INFO)) mLogger.log(Level.WARNING, "DBBC_R00723.JDBCDN_DriverNoSupportForMetaData", e. getLocalizedMessage()); } short precision = 0; try { precision = paramsInfo.getShort("SCALE"); } catch (final SQLException e) { if (mLogger.isLoggable(Level.FINEST)) mLogger.log(Level.WARNING, "DBBC_R00723.JDBCDN_DriverNoSupportForMetaData", e); else if (mLogger.isLoggable(Level.INFO)) mLogger.log(Level.WARNING, "DBBC_R00723.JDBCDN_DriverNoSupportForMetaData", e. getLocalizedMessage()); } CachedQueryParameter cp = new CachedQueryParameter(name, type, typeName, direction, precision); params.add(cp); } return params; } }