001package org.kepler.actor.database; 002/* 003 * Copyright (c) 2009-2010 The Regents of the University of California. 004 * All rights reserved. 005 * 006 * '$Author: welker $' 007 * '$Date: 2010-05-05 22:21:26 -0700 (Wed, 05 May 2010) $' 008 * '$Revision: 24234 $' 009 * 010 * Permission is hereby granted, without written agreement and without 011 * license or royalty fees, to use, copy, modify, and distribute this 012 * software and its documentation for any purpose, provided that the above 013 * copyright notice and the following two paragraphs appear in all copies 014 * of this software. 015 * 016 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 017 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 018 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 019 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 020 * SUCH DAMAGE. 021 * 022 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 023 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 024 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 025 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 026 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 027 * ENHANCEMENTS, OR MODIFICATIONS. 028 * 029 */ 030 031 032import java.sql.Connection; 033import java.sql.ResultSet; 034import java.sql.SQLException; 035import java.sql.Statement; 036 037import org.geon.OpenDBConnection; 038 039import ptolemy.actor.TypedIOPort; 040import ptolemy.actor.lib.LimitedFiringSource; 041import ptolemy.actor.parameters.PortParameter; 042import ptolemy.data.BooleanToken; 043import ptolemy.data.RecordToken; 044import ptolemy.data.StringToken; 045import ptolemy.data.type.BaseType; 046import ptolemy.data.type.Type; 047import ptolemy.kernel.CompositeEntity; 048import ptolemy.kernel.util.IllegalActionException; 049import ptolemy.kernel.util.NameDuplicationException; 050 051/** 052 * Create a database table if the table doesn't exist. 053 * 054 * @author Jing Tao 055 */ 056 057public class DatabaseTableCreator extends LimitedFiringSource { 058 059 public DatabaseTableCreator(CompositeEntity container, String name) 060 throws NameDuplicationException, IllegalActionException { 061 super(container, name); 062 tableNameParam = new PortParameter(this, "Table Name"); 063 tableNameParam.setStringMode(true); 064 tableNameParam.setTypeEquals(BaseType.STRING); 065 tableNameParam.getPort().setTypeEquals(BaseType.STRING); 066 067 createTableIfNotExistParam = new PortParameter(this, "Create the table if it doesn't exist"); 068 createTableIfNotExistParam.setStringMode(false); 069 createTableIfNotExistParam.setTypeEquals(BaseType.BOOLEAN); 070 createTableIfNotExistParam.getPort().setTypeEquals(BaseType.BOOLEAN); 071 createTableIfNotExistParam.setExpression("true"); 072 073 sqlScriptParam = new PortParameter(this, "SQL Script"); 074 sqlScriptParam.setStringMode(true); 075 sqlScriptParam.setTypeEquals(BaseType.STRING); 076 sqlScriptParam.getPort().setTypeEquals(BaseType.STRING); 077 078 dbParams = new PortParameter(this, "Database Param"); 079 Type type = OpenDBConnection.getDBParamsType(); 080 dbParams.setTypeEquals(type); 081 dbParams.getPort().setTypeEquals(type); 082 dbParams.setExpression("{driver = \"org.hsqldb.jdbcDriver\", password = \"pass\", url = \"jdbc:hsqldb:hsql://localhost/hsqldb\", user = \"sa\"}"); 083 boolean isInput = false; 084 boolean isOutput = true; 085 statusPort = new TypedIOPort(this, "Status", isInput, isOutput); 086 statusPort.setMultiport(false); 087 statusPort.setTypeEquals(BaseType.BOOLEAN); 088 089 } 090 091 // ///////////////////////////////////////////////////////////////// 092 // // ports and parameters //// 093 094 095 /** Output of this actor. Ture if the table exists or was created successfully, false otherwise*/ 096 public TypedIOPort statusPort; 097 098 /** The name of the table which will be created**/ 099 public PortParameter tableNameParam; 100 101 /** Flag indicates to create the table if the table doesn't exist*/ 102 public PortParameter createTableIfNotExistParam; 103 104 /** A sql script to create the table**/ 105 public PortParameter sqlScriptParam; 106 107 108 /** Parameter to access a database. It includes user name, password, 109 driver name and db url**/ 110 public PortParameter dbParams; 111 112 113 114 // ///////////////////////////////////////////////////////////////// 115 // // public methods //// 116 117 /** Close the connection if open. */ 118 public void initialize() throws IllegalActionException { 119 super.initialize(); 120 _closeConnection(); 121 } 122 123 /** 124 * Reconfigure actor when certain attributes change. 125 * 126 * @param attribute 127 * The changed Attribute. 128 * @throws ptolemy.kernel.util.IllegalActionException 129 * 130 */ 131 public void attributeChanged(ptolemy.kernel.util.Attribute attribute) 132 throws ptolemy.kernel.util.IllegalActionException { 133 134 if (attribute == tableNameParam) { 135 if (tableNameParam != null && tableNameParam.getToken() != null){ 136 tableName = ((StringToken)tableNameParam.getToken()).stringValue(); 137 //System.out.println("get the table name "+tableName+" from attributedChanged method"); 138 } 139 } else if (attribute == createTableIfNotExistParam) { 140 if (createTableIfNotExistParam != null && createTableIfNotExistParam.getToken() != null){ 141 createTableIfNotExisted = ((BooleanToken)createTableIfNotExistParam.getToken()).booleanValue(); 142 //System.out.println("get the flag createTableIfNotExisted "+createTableIfNotExisted+" from attributedChanged method"); 143 } 144 } else if(attribute == sqlScriptParam){ 145 if (sqlScriptParam != null && sqlScriptParam.getToken() != null){ 146 sqlScript = ((StringToken)sqlScriptParam.getToken()).stringValue(); 147 //System.out.println("get the sql "+sqlScript+" from attributedChanged method"); 148 } 149 } else if(attribute == dbParams){ 150 dbParams.update(); 151 } else { 152 super.attributeChanged(attribute); 153 } 154 } 155 156 157 /** If connection is closed, open a new one. */ 158 public void fire() throws IllegalActionException { 159 super.fire(); 160 //System.out.println("the fire in DatabaseTable creator !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); 161 boolean ifTableExist = true; 162 if (tableNameParam != null && tableNameParam.getToken() != null) { 163 tableName = ((StringToken)tableNameParam.getToken()).stringValue(); 164 //System.out.println("get the table name "+tableName+" from fire method"); 165 } 166 if (createTableIfNotExistParam != null && createTableIfNotExistParam.getToken() != null) { 167 createTableIfNotExisted = ((BooleanToken)createTableIfNotExistParam.getToken()).booleanValue(); 168 //System.out.println("get the flag createTableIfNotExisted "+createTableIfNotExisted+" from fire method"); 169 } 170 if (sqlScriptParam != null && sqlScriptParam.getToken() != null) { 171 sqlScript = ((StringToken)sqlScriptParam.getToken()).stringValue(); 172 //System.out.println("get the sql "+sqlScript+" from fire method"); 173 } 174 if (_db == null) { 175 getConnection(); 176 } 177 178 //System.out.println("final table name: "+tableName); 179 String selectionSQL = _createSelectSQL(tableName); 180 181 ResultSet rs; 182 try { 183 Statement st = _db.createStatement(); 184 rs = st.executeQuery(selectionSQL); 185 } catch (SQLException e) { 186 ifTableExist = false; 187 } 188 if(ifTableExist){ 189 //table does exist, sent status "true" to output 190 //System.out.println("The table "+tableName+" does exist"); 191 statusPort.send(0, new BooleanToken(true)); 192 } else{ 193 //System.out.println("the final createTableIfNotExisted is "+createTableIfNotExisted); 194 //System.out.println("the final sql is "+sqlScript); 195 if(!createTableIfNotExisted){ 196 //since we don't need create the table, just send the false status 197 //System.out.println("The table "+tableName+" doesn't exist but we don't need to create it"); 198 statusPort.send(0, new BooleanToken(false)); 199 } else { 200 try { 201 202 Statement st = _db.createStatement(); 203 rs = st.executeQuery(sqlScript); 204 //System.out.println("Successfully created the table "+tableName+" with sql "+sqlScript); 205 statusPort.send(0, new BooleanToken(true)); 206 } catch (SQLException e) { 207 //System.out.println("Failed to create the table "+tableName+" with sql "+sqlScript); 208 ifTableExist = false; 209 } 210 } 211 212 } 213 } 214 215 /** Close the connection if open. */ 216 public void wrapup() throws IllegalActionException { 217 super.wrapup(); 218 _closeConnection(); 219 } 220 221 // ///////////////////////////////////////////////////////////////// 222 // // protected methods //// 223 224 /** Get the database connection. */ 225 protected void getConnection() throws IllegalActionException { 226 dbParams.update(); 227 RecordToken params = (RecordToken) dbParams.getToken(); 228 if (params != null) { 229 _db = OpenDBConnection.getConnection(params); 230 } else { 231 throw new IllegalActionException(this, 232 "Please specify the database parameters. Actor couldn't access the database without those paramters."+ 233 "The parameter looks like: {driver = \"org.hsqldb.jdbcDriver\", password = \"pass\", url = \"jdbc:hsqldb:hsql://localhost/hsqldb\", user = \"sa\"}"); 234 } 235 } 236 237 // ///////////////////////////////////////////////////////////////// 238 // // protected variables //// 239 240 /** A JDBC database connection. */ 241 protected Connection _db = null; 242 protected String tableName = null; 243 protected boolean createTableIfNotExisted= false; 244 protected String sqlScript = null; 245 246 // ///////////////////////////////////////////////////////////////// 247 // // private methods //// 248 249 /** Close the connection if open. */ 250 private void _closeConnection() throws IllegalActionException { 251 try { 252 if (_db != null) { 253 _db.close(); 254 } 255 _db = null; 256 } catch (SQLException e) { 257 throw new IllegalActionException(this, "SQLException: " 258 + e.getMessage()); 259 } 260 } 261 262 /** Create the select sql command with the given table name */ 263 private String _createSelectSQL(String tableName) throws IllegalActionException { 264 String selectionSql = null; 265 if(tableName != null && !tableName.trim().equals("")){ 266 selectionSql = "SELECT * FROM "+tableName; 267 } else { 268 throw new IllegalActionException(this, "Exception: Please specify the table name which you want to create. "); 269 } 270 return selectionSql; 271 } 272}