001/* 002 * Copyright (c) 2009-2010 The Regents of the University of California. 003 * All rights reserved. 004 * 005 * '$Author: crawl $' 006 * '$Date: 2016-09-14 19:10:43 +0000 (Wed, 14 Sep 2016) $' 007 * '$Revision: 34528 $' 008 * 009 * Permission is hereby granted, without written agreement and without 010 * license or royalty fees, to use, copy, modify, and distribute this 011 * software and its documentation for any purpose, provided that the above 012 * copyright notice and the following two paragraphs appear in all copies 013 * of this software. 014 * 015 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 016 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 017 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 018 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 019 * SUCH DAMAGE. 020 * 021 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 022 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 023 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 024 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 025 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 026 * ENHANCEMENTS, OR MODIFICATIONS. 027 * 028 */ 029 030package org.geon; 031 032import java.sql.Connection; 033import java.sql.PreparedStatement; 034import java.sql.SQLException; 035 036import ptolemy.actor.TypedAtomicActor; 037import ptolemy.actor.TypedIOPort; 038import ptolemy.actor.parameters.PortParameter; 039import ptolemy.data.BooleanToken; 040import ptolemy.data.DoubleToken; 041import ptolemy.data.IntToken; 042import ptolemy.data.LongToken; 043import ptolemy.data.RecordToken; 044import ptolemy.data.StringToken; 045import ptolemy.data.Token; 046import ptolemy.data.expr.Parameter; 047import ptolemy.data.type.BaseType; 048import ptolemy.data.type.Type; 049import ptolemy.kernel.CompositeEntity; 050import ptolemy.kernel.util.IllegalActionException; 051import ptolemy.kernel.util.NameDuplicationException; 052 053/** 054 * A base class for actors that access JDBC databases. 055 * 056 * @author Daniel Crawl 057 * @version $Id: DatabaseAccessor.java 34528 2016-09-14 19:10:43Z crawl $ 058 */ 059 060public class DatabaseAccessor extends TypedAtomicActor { 061 public DatabaseAccessor(CompositeEntity container, String name) 062 throws NameDuplicationException, IllegalActionException { 063 super(container, name); 064 065 dbParams = new PortParameter(this, "dbParams"); 066 Type type = OpenDBConnection.getDBParamsType(); 067 dbParams.setTypeEquals(type); 068 dbParams.getPort().setTypeEquals(type); 069 070 dbcon = new TypedIOPort(this, "dbcon", true, false); 071 dbcon.setTypeEquals(DBConnectionToken.DBCONNECTION); 072 073 dbconTokenConsumptionRate = new Parameter(dbcon, 074 "tokenConsumptionRate", IntToken.ONE); 075 } 076 077 // ///////////////////////////////////////////////////////////////// 078 // // ports and parameters //// 079 080 /** A record token containing parameters to create a database connection. */ 081 public PortParameter dbParams; 082 083 /** A reference to the database connection. */ 084 public TypedIOPort dbcon; 085 086 /** Parameter to change token consumption rate on dbcon. */ 087 public Parameter dbconTokenConsumptionRate; 088 089 // ///////////////////////////////////////////////////////////////// 090 // // public methods //// 091 092 /** Close the connection if open. */ 093 @Override 094 public void initialize() throws IllegalActionException { 095 super.initialize(); 096 _closeConnection(); 097 } 098 099 /** If connection is closed, open a new one. */ 100 @Override 101 public void fire() throws IllegalActionException { 102 dbParams.update(); 103 if (_db == null) { 104 getConnection(); 105 } 106 } 107 108 /** Close the connection if open. */ 109 @Override 110 public void wrapup() throws IllegalActionException { 111 super.wrapup(); 112 _closeConnection(); 113 } 114 115 // ///////////////////////////////////////////////////////////////// 116 // // protected methods //// 117 118 /** Get the database connection. */ 119 protected void getConnection() throws IllegalActionException { 120 // first check dbParams 121 RecordToken params = (RecordToken) dbParams.getToken(); 122 if (params != null) { 123 _db = OpenDBConnection.getConnection(params); 124 } else if(_db == null && dbcon.getWidth() > 0) { 125 DBConnectionToken dbToken = (DBConnectionToken) dbcon.get(0); 126 try { 127 _db = dbToken.getValue(); 128 } catch (Exception e) { 129 throw new IllegalActionException(this, e, "CONNECTION FAILURE"); 130 } 131 } 132 133 if(_db == null) { 134 throw new IllegalActionException(this, "Must provide either" + 135 " database connection parameters in dbParams or database" + 136 " connection in dbcon."); 137 } 138 139 // we no longer need to read from dbcon 140 dbconTokenConsumptionRate.setToken(IntToken.ZERO); 141 } 142 143 /** Set a parameter value in a prepared statement. 144 * @param st The prepared statement 145 * @param index The index to set in the prepared statement 146 * @param token The token containing the value to set. 147 */ 148 protected void _setPreparedStatementValue(PreparedStatement st, int index, Token token) 149 throws IllegalActionException, SQLException { 150 Type type = token.getType(); 151 if(type == BaseType.STRING) { 152 st.setString(index, ((StringToken)token).stringValue()); 153 } else if(type == BaseType.INT) { 154 st.setInt(index, ((IntToken)token).intValue()); 155 } else if(type == BaseType.LONG) { 156 st.setLong(index, ((LongToken)token).longValue()); 157 } else if(type == BaseType.DOUBLE) { 158 st.setDouble(index, ((DoubleToken)token).doubleValue()); 159 } else if(type == BaseType.BOOLEAN) { 160 st.setBoolean(index, ((BooleanToken)token).booleanValue()); 161 } else { 162 st.setString(index, token.toString()); 163 } 164 } 165 166 167 // ///////////////////////////////////////////////////////////////// 168 // // protected variables //// 169 170 /** A JDBC database connection. */ 171 protected Connection _db = null; 172 173 // ///////////////////////////////////////////////////////////////// 174 // // private methods //// 175 176 /** Close the connection if open. */ 177 private void _closeConnection() throws IllegalActionException { 178 try { 179 if (_db != null) { 180 _db.close(); 181 } 182 _db = null; 183 184 // reset the token consumption rate on dbcon 185 dbconTokenConsumptionRate.setToken(IntToken.ONE); 186 } catch (SQLException e) { 187 throw new IllegalActionException(this, "SQLException: " 188 + e.getMessage()); 189 } 190 } 191}