001: /*
002: * <copyright>
003: *
004: * Copyright 1997-2004 BBNT Solutions, LLC
005: * under sponsorship of the Defense Advanced Research Projects
006: * Agency (DARPA).
007: *
008: * You can redistribute this software and/or modify it under the
009: * terms of the Cougaar Open Source License as published on the
010: * Cougaar Open Source Website (www.cougaar.org).
011: *
012: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
013: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
014: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
015: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
016: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
017: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
018: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
019: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
020: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
021: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
022: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
023: *
024: * </copyright>
025: */
026:
027: package org.cougaar.planning.ldm;
028:
029: import java.io.IOException;
030: import java.sql.Connection;
031: import java.sql.ResultSet;
032: import java.sql.SQLException;
033: import java.sql.Statement;
034: import java.util.HashMap;
035: import java.util.Map;
036:
037: import org.cougaar.core.node.DBInitializerService;
038: import org.cougaar.util.DBConnectionPool;
039: import org.cougaar.util.DBProperties;
040: import org.cougaar.util.Parameters;
041: import org.cougaar.util.log.Logger;
042: import org.cougaar.util.log.Logging;
043: import org.cougaar.util.log.NullLogger;
044:
045: /**
046: * Database initializer implementation that strictly allows initializing
047: * assets using the non-CSMART / reference database structure.
048: * @see AssetInitializerServiceComponent
049: * @see DBAssetInitializerServiceProvider
050: **/
051: public class NonCSMARTDBInitializerServiceImpl implements
052: DBInitializerService {
053:
054: /** Query file located in planning/data/common **/
055: public static final String QUERY_FILE = "NonCSMARTDBAssetInitializer.q";
056:
057: private final Logger logger;
058: private final DBProperties dbp;
059: private final String database;
060: private final String username;
061: private final String password;
062:
063: /**
064: * Constructor creates a DBInitializer from the DBInitializer.q
065: * query control file and sets up variables for referencing the database.
066: * <p>
067: */
068: public NonCSMARTDBInitializerServiceImpl() throws SQLException,
069: IOException {
070: Logger l = Logging.getLogger(getClass());
071: logger = ((l == null) ? NullLogger.getLogger() : l);
072:
073: dbp = DBProperties.readQueryFile(QUERY_FILE, "planning");
074: database = dbp.getProperty("database");
075: username = dbp.getProperty("username");
076: password = dbp.getProperty("password");
077: if (logger.isInfoEnabled()) {
078: logger.info("Will initialize assets from non-CSMART DB "
079: + database);
080: }
081:
082: try {
083: String dbtype = dbp.getDBType();
084: ensureDriverClass(dbtype);
085: } catch (ClassNotFoundException e) {
086: throw new SQLException("Driver not found for " + database);
087: }
088: }
089:
090: public Map createSubstitutions() {
091: Map m = new HashMap(7);
092: return m;
093: }
094:
095: public String getNonNullString(ResultSet rs, int ix, String query)
096: throws SQLException {
097: String result = rs.getString(ix);
098: if (result == null)
099: throw new RuntimeException("Null in DB ix=" + ix
100: + " query=" + query);
101: return result;
102: }
103:
104: public String getQuery(String queryName, Map substitutions) {
105: return dbp.getQuery(queryName, substitutions);
106: }
107:
108: public Connection getConnection() throws SQLException {
109: return DBConnectionPool.getConnection(database, username,
110: password);
111: }
112:
113: public ResultSet executeQuery(Statement stmt, String query)
114: throws SQLException {
115: try {
116: boolean shouldLog = logger.isDebugEnabled();
117: long startTime = (shouldLog ? 0L : System
118: .currentTimeMillis());
119: ResultSet rs = stmt.executeQuery(query);
120: if (shouldLog) {
121: long endTime = System.currentTimeMillis();
122: logger.debug((endTime - startTime) + " " + query);
123: }
124: return rs;
125: } catch (SQLException sqle) {
126: if (logger.isErrorEnabled()) {
127: logger.error("Query failed: " + query, sqle);
128: }
129: throw sqle;
130: }
131: }
132:
133: /**
134: * Translate the value of a "query" attribute type. The "key"
135: * should be one or more query substitutions. Each substitution is
136: * an equals separated key and value. Multiple substitutions are
137: * separated by semi-colon. Backslash can quote a character. The
138: * query may be in a different database. If so, then the dbp
139: * should contain properties named by concatenating the query
140: * name with .database, .username, .password describing the
141: * database to connect to.
142: * @param type is the "data type" of the attribute value and
143: * names a query that should be done to obtain the actual
144: * value.
145: * @return a two-element array of attribute type and value.
146: **/
147: public Object[] translateAttributeValue(String type, String key)
148: throws SQLException {
149: Map substitutions = createSubstitutions();
150: substitutions.put(":key:", key);
151: String db = dbp.getProperty(type + ".database", database);
152: String un = dbp.getProperty(type + ".username", username);
153: String pw = dbp.getProperty(type + ".password", password);
154: try {
155: ensureDriverClass(dbp.getDBType(db));
156: } catch (ClassNotFoundException cnfe) {
157: throw new SQLException("Driver not found for " + db);
158: }
159: Connection conn = DBConnectionPool.getConnection(db, un, pw);
160: try {
161: Statement stmt = conn.createStatement();
162: String query = dbp.getQueryForDatabase(type, substitutions,
163: type + ".database");
164: ResultSet rs = executeQuery(stmt, query);
165: Object[] result = new Object[2];
166: if (rs.next()) {
167: result[0] = rs.getString(1);
168: result[1] = rs.getString(2);
169: } else {
170: // It would be nice to not die if the GEOLOC or whatever
171: // is not found. I'm just not certain
172: // how the caller (ie AssetDataDBReader) will react
173: // if the result is an empty String.
174: // result[0] = type;
175: // result[1] = "";
176: throw new SQLException(
177: "No row returned for attribute value query "
178: + type + "(" + key + ")");
179: }
180: rs.close();
181: stmt.close();
182: return result;
183: } finally {
184: conn.close();
185: }
186: }
187:
188: private void ensureDriverClass(String dbtype) throws SQLException,
189: ClassNotFoundException {
190: String driverParam = "driver." + dbtype;
191: String driverClass = Parameters.findParameter(driverParam);
192: if (driverClass == null) {
193: // this is likely a "cougaar.rc" problem.
194: // Parameters should be modified to help generate this exception:
195: throw new SQLException("Unable to find driver class for \""
196: + driverParam + "\" -- check your \"cougaar.rc\"");
197: }
198: Class.forName(driverClass);
199: }
200:
201: }
|