Home » synapse-1.2-src » org.apache.synapse.mediators.db » [javadoc | source]

    1   /*
    2    *  Licensed to the Apache Software Foundation (ASF) under one
    3    *  or more contributor license agreements.  See the NOTICE file
    4    *  distributed with this work for additional information
    5    *  regarding copyright ownership.  The ASF licenses this file
    6    *  to you under the Apache License, Version 2.0 (the
    7    *  "License"); you may not use this file except in compliance
    8    *  with the License.  You may obtain a copy of the License at
    9    *
   10    *   http://www.apache.org/licenses/LICENSE-2.0
   11    *
   12    *  Unless required by applicable law or agreed to in writing,
   13    *  software distributed under the License is distributed on an
   14    *   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   15    *  KIND, either express or implied.  See the License for the
   16    *  specific language governing permissions and limitations
   17    *  under the License.
   18    */
   19   
   20   package org.apache.synapse.mediators.db;
   21   
   22   import org.apache.commons.dbcp.BasicDataSource;
   23   import org.apache.commons.dbcp.datasources.PerUserPoolDataSource;
   24   import org.apache.commons.logging.Log;
   25   import org.apache.synapse.ManagedLifecycle;
   26   import org.apache.synapse.MessageContext;
   27   import org.apache.synapse.config.xml.AbstractDBMediatorFactory;
   28   import org.apache.synapse.core.SynapseEnvironment;
   29   import org.apache.synapse.mediators.AbstractMediator;
   30   
   31   import javax.sql.DataSource;
   32   import javax.xml.namespace.QName;
   33   import java.math.BigDecimal;
   34   import java.sql;
   35   import java.sql.Date;
   36   import java.util;
   37   
   38   /**
   39    * This abstract DB mediator will perform common DB connection pooling etc. for all DB mediators
   40    */
   41   public abstract class AbstractDBMediator extends AbstractMediator implements ManagedLifecycle {
   42   
   43       /** Hold JDBC properties */
   44       protected Map dataSourceProps = new HashMap();
   45       /** The DataSource to get DB connections */
   46       private DataSource dataSource = null;
   47       /** Statements */
   48       List statementList = new ArrayList();
   49   
   50       /**
   51        * Initializes the mediator. Does nothing right now. If DataSource lookup is supported, could
   52        * do the IC lookup here
   53        * @param se the Synapse environment reference
   54        */
   55       public void init(SynapseEnvironment se) {
   56           // do nothing
   57       }
   58   
   59       /**
   60        * Destroys the mediator. If we are using our custom DataSource, then shut down the connections
   61        */
   62       public void destroy() {
   63           if (this.dataSource instanceof BasicDataSource) {
   64               try {
   65                   ((BasicDataSource) this.dataSource).close();
   66                   log.info("Successfully shut down DB connection pool for URL : " + getDSName());
   67               } catch (SQLException e) {
   68                   log.warn("Error shutting down DB connection pool for URL : " + getDSName());
   69               }
   70           } else if (this.dataSource instanceof PerUserPoolDataSource) {
   71               ((PerUserPoolDataSource) this.dataSource).close();
   72               log.info("Successfully shut down DB connection pool for URL : " + getDSName());
   73           }
   74       }
   75   
   76       /**
   77        * Process each SQL statement against the current message
   78        * @param synCtx the current message
   79        * @return true, always
   80        */
   81       public boolean mediate(MessageContext synCtx) {
   82   
   83           String name = (this instanceof DBLookupMediator ? "DBLookup" : "DBReport");
   84           boolean traceOn = isTraceOn(synCtx);
   85           boolean traceOrDebugOn = isTraceOrDebugOn(traceOn);
   86   
   87           if (traceOrDebugOn) {
   88               traceOrDebug(traceOn, "Start : " + name + " mediator");
   89   
   90               if (traceOn && trace.isTraceEnabled()) {
   91                   trace.trace("Message : " + synCtx.getEnvelope());
   92               }
   93           }
   94   
   95           for (Iterator iter = statementList.iterator(); iter.hasNext(); ) {
   96               processStatement((Statement) iter.next(), synCtx);
   97           }
   98   
   99           if (traceOrDebugOn) {
  100               traceOrDebug(traceOn, "End : " + name + " mediator");
  101           }
  102           return true;
  103       }
  104   
  105       /**
  106        * Subclasses must specify how each SQL statement is processed
  107        * @param query the SQL statement
  108        * @param msgCtx current message
  109        */
  110       abstract protected void processStatement(Statement query, MessageContext msgCtx);
  111   
  112       /**
  113        * Return the name or (hopefully) unique connection URL specific to the DataSource being used
  114        * This is used for logging purposes only
  115        * @return a unique name or URL to refer to the DataSource being used
  116        */
  117       protected String getDSName() {
  118           return (String) dataSourceProps.get(AbstractDBMediatorFactory.URL_Q);
  119       }
  120   
  121       public DataSource getDataSource() {
  122           return dataSource;
  123       }
  124   
  125       public void setDataSource(DataSource dataSource) {
  126           this.dataSource = dataSource;
  127       }
  128   
  129       public void addDataSourceProperty(QName name, String value) {
  130           dataSourceProps.put(name, value);
  131       }
  132   
  133       public void addDataSourceProperty(String name, String value) {
  134           dataSourceProps.put(name, value);
  135       }
  136   
  137       public Map getDataSourceProps() {
  138           return dataSourceProps;
  139       }
  140   
  141       public void addStatement(Statement stmnt) {
  142           statementList.add(stmnt);
  143       }
  144   
  145       public List getStatementList() {
  146           return statementList;
  147       }
  148   
  149       /**
  150        * Return a Prepared statement for the given Statement object, which is ready to be executed
  151        * @param stmnt
  152        * @param msgCtx
  153        * @return
  154        * @throws SQLException
  155        */
  156       protected PreparedStatement getPreparedStatement(Statement stmnt, MessageContext msgCtx) throws SQLException {
  157   
  158           boolean traceOn = isTraceOn(msgCtx);
  159           boolean traceOrDebugOn = isTraceOrDebugOn(traceOn);
  160   
  161           Log serviceLog = msgCtx.getServiceLog();
  162   
  163           if (traceOrDebugOn) {
  164               traceOrDebug(traceOn, "Getting a connection from DataSource " + getDSName() +
  165                   " and preparing statement : " + stmnt.getRawStatement());
  166           }
  167           Connection con = getDataSource().getConnection();
  168           PreparedStatement ps = con.prepareStatement(stmnt.getRawStatement());
  169   
  170           // set parameters if any
  171           List params = stmnt.getParameters();
  172           int column = 1;
  173   
  174           for (Iterator pi = params.iterator(); pi.hasNext(); ) {
  175   
  176               Statement.Parameter param = (Statement.Parameter) pi.next();
  177               String value = (param.getPropertyName() != null ?
  178                   param.getPropertyName() : param.getXpath().stringValueOf(msgCtx));
  179   
  180               if (traceOrDebugOn) {
  181                   traceOrDebug(traceOn, "Setting as parameter : " + column + " value : " + value +
  182                       " as JDBC Type : " + param.getType() + "(see java.sql.Types for valid types)");
  183               }
  184   
  185               switch (param.getType()) {
  186                   // according to J2SE 1.5 /docs/guide/jdbc/getstart/mapping.html
  187                   case Types.CHAR:
  188                   case Types.VARCHAR:
  189                   case Types.LONGVARCHAR: {
  190                       ps.setString(column++, value);
  191                       break;
  192                   }
  193                   case Types.NUMERIC:
  194                   case Types.DECIMAL: {
  195                       ps.setBigDecimal(column++, new BigDecimal(value));
  196                       break;
  197                   }
  198                   case Types.BIT: {
  199                       ps.setBoolean(column++, Boolean.parseBoolean(value));
  200                       break;
  201                   }
  202                   case Types.TINYINT: {
  203                       ps.setByte(column++, Byte.parseByte(value));
  204                       break;
  205                   }
  206                   case Types.SMALLINT: {
  207                       ps.setShort(column++, Short.parseShort(value));
  208                       break;
  209                   }
  210                   case Types.INTEGER: {
  211                       ps.setInt(column++, Integer.parseInt(value));
  212                       break;
  213                   }
  214                   case Types.BIGINT: {
  215                       ps.setLong(column++, Long.parseLong(value));
  216                       break;
  217                   }
  218                   case Types.REAL: {
  219                       ps.setFloat(column++, Float.parseFloat(value));
  220                       break;
  221                   }
  222                   case Types.FLOAT: {
  223                       ps.setDouble(column++, Double.parseDouble(value));
  224                       break;
  225                   }
  226                   case Types.DOUBLE: {
  227                       ps.setDouble(column++, Double.parseDouble(value));
  228                       break;
  229                   }
  230                   // skip BINARY, VARBINARY and LONGVARBINARY
  231                   case Types.DATE: {
  232                       ps.setDate(column++, Date.valueOf(value));
  233                       break;
  234                   }
  235                   case Types.TIME: {
  236                       ps.setTime(column++, Time.valueOf(value));
  237                       break;
  238                   }
  239                   case Types.TIMESTAMP: {
  240                       ps.setTimestamp(column++, Timestamp.valueOf(value));
  241                       break;
  242                   }
  243                   // skip CLOB, BLOB, ARRAY, DISTINCT, STRUCT, REF, JAVA_OBJECT
  244                   default: {
  245                       String msg = "Trying to set an un-supported JDBC Type : " + param.getType() +
  246                           " against column : " + column + " and statement : " + stmnt.getRawStatement() +
  247                           " used by a DB mediator against DataSource : " + getDSName() +
  248                           " (see java.sql.Types for valid type values)";
  249                       handleException(msg, msgCtx);
  250                   }
  251               }
  252           }
  253   
  254           if (traceOrDebugOn) {
  255               traceOrDebug(traceOn, "Successfully prepared statement : " + stmnt.getRawStatement() +
  256                   " against DataSource : " + getDSName());
  257           }
  258           return ps;
  259       }
  260   }

Home » synapse-1.2-src » org.apache.synapse.mediators.db » [javadoc | source]