001: /*
002: * $Header: /export/home/cvsroot/MyPersonalizerRepository/MyPersonalizer/Subsystems/Kernel/Sources/es/udc/mypersonalizer/kernel/model/repository/sql/storers/AbstractSQLMetaPropertyVisitor.java,v 1.1.1.1 2004/03/25 12:08:36 fbellas Exp $
003: * $Revision: 1.1.1.1 $
004: * $Date: 2004/03/25 12:08:36 $
005: *
006: * =============================================================================
007: *
008: * Copyright (c) 2003, The MyPersonalizer Development Group
009: * (http://www.tic.udc.es/~fbellas/mypersonalizer/index.html) at
010: * University Of A Coruna
011: * All rights reserved.
012: *
013: * Redistribution and use in source and binary forms, with or without
014: * modification, are permitted provided that the following conditions are met:
015: *
016: * - Redistributions of source code must retain the above copyright notice,
017: * this list of conditions and the following disclaimer.
018: *
019: * - Redistributions in binary form must reproduce the above copyright notice,
020: * this list of conditions and the following disclaimer in the documentation
021: * and/or other materials provided with the distribution.
022: *
023: * - Neither the name of the University Of A Coruna nor the names of its
024: * contributors may be used to endorse or promote products derived from
025: * this software without specific prior written permission.
026: *
027: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
028: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
029: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
030: * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
031: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
032: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
033: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
034: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
035: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
036: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
037: * POSSIBILITY OF SUCH DAMAGE.
038: *
039: */
040:
041: package es.udc.mypersonalizer.kernel.model.repository.sql.storers;
042:
043: import java.sql.Connection;
044: import java.sql.PreparedStatement;
045: import java.sql.ResultSet;
046: import java.sql.SQLException;
047: import java.util.Iterator;
048: import java.util.Map;
049:
050: import es.udc.mypersonalizer.kernel.model.annotators.sql.SQLPersistenceTypeAnnotationHelper;
051: import es.udc.mypersonalizer.kernel.model.metainfo.MetaProperty;
052: import es.udc.mypersonalizer.kernel.util.exceptions.VisitorException;
053:
054: /**
055: * Common class for all MetaPropertyVisitors that access the data through
056: * SQL and JDBC, offering some utility methods.
057: *
058: * @author Abel Muinho
059: * @since 1.0
060: */
061: public abstract class AbstractSQLMetaPropertyVisitor implements
062: MetaProperty.Visitor {
063:
064: /**
065: * The <code>Connection</code> for this visitor.
066: */
067: private Connection connection;
068:
069: /**
070: * The key for this visitor as a <code>Map</code>.
071: */
072: private Map key;
073:
074: /**
075: * The constructor for an SQL visitor.
076: * @param connection a connection to the database
077: * @param key the map that contains pairs of key fields and their
078: * corresponding values.
079: */
080: protected AbstractSQLMetaPropertyVisitor(Connection connection,
081: Map key) {
082: this .connection = connection;
083: this .key = key;
084: }
085:
086: /**
087: * Returns the connection to de database.
088: * @return The stablished connection to the database engine.
089: */
090: protected Connection getConnection() {
091: return connection;
092: }
093:
094: /**
095: * Returns the key of the property being accessed.
096: * @return A Map representing the pairs <code>attribute = value</code> of
097: * the database key for the property.
098: */
099: protected Map getKey() {
100: return key;
101: }
102:
103: /**
104: * Returns the name of the table where properties of the given MetaProperty
105: * "type" will be stored.
106: * @param metaProperty MetaProperty describing the information to be stored.
107: * @return the name of the table where instances of this MetaProperty are
108: * stored.
109: */
110: protected String getTableName(MetaProperty metaProperty) {
111: return SQLPersistenceTypeAnnotationHelper
112: .getTableNameAnnotation(metaProperty);
113: }
114:
115: /**
116: * Returns pairs of assigned key/value separated with "AND".
117: * This is a utility function, as it performs the same task as
118: * <code>allAndKeys(getKey())</code>.
119: *
120: * @return a <code>String</code> with the pairs of keys as comparissions
121: * separated with " AND ".
122: */
123: protected String allAndKeys() {
124: return allAndKeys(key);
125: }
126:
127: /**
128: * Returns a <code>String</code> in a format suitable for use with
129: * {@link java.sql.Connection#prepareStatement(String)} where all the key
130: * columns equal a parameter (i.e. "column = ?").
131: *
132: * @param map The map which will converted to a String representing
133: * a SQL contition.
134: * @return a <code>String</code> The formatted <code>String</code>.
135: */
136: protected String allAndKeys(Map map) {
137: Iterator iterator;
138: Object theKey;
139: String theString;
140:
141: iterator = map.keySet().iterator();
142: theKey = iterator.next();
143: theString = theKey + " = ?";
144: while (iterator.hasNext()) {
145: theKey = iterator.next();
146: theString += " AND " + theKey + " = ?";
147: }
148: return theString;
149: }
150:
151: /**
152: * Creates a statement and adds a descriptive error message to
153: * the exception thrown in case of error.
154: * @param query The parametrized SQL query to prepare.
155: * @throws VisitorException if the statement can't be created.
156: * @return the created statement.
157: */
158: protected PreparedStatement createStatement(String query)
159: throws VisitorException {
160: PreparedStatement statement;
161: try {
162: statement = getConnection().prepareStatement(query);
163: } catch (SQLException e) {
164: throw new VisitorException(
165: "FATAL ERROR: cannot create statement.", e);
166: }
167: return statement;
168: }
169:
170: /**
171: * Closes a statement and adds a descriptive error message to
172: * the exception thrown in case of error.
173: * @param statement The statement to be closed.
174: * @throws VisitorException if the statement can't be closed.
175: */
176: protected void closeStatement(PreparedStatement statement)
177: throws VisitorException {
178: if (statement != null) {
179: try {
180: statement.close();
181: } catch (SQLException e) {
182: throw new VisitorException(
183: "FATAL ERROR: cannot close statement.", e);
184: }
185: }
186: }
187:
188: /**
189: * Executes an update operation on the Database and adds a descriptive
190: * error message to the exception thrown in case of error.
191: * @param statement The <code>PreparedStatement</code> object wich will
192: * execute the SQL update.
193: * @throws VisitorException if the query can't be executed.
194: */
195: protected void executeUpdate(PreparedStatement statement)
196: throws VisitorException {
197:
198: try {
199: statement.executeUpdate();
200: } catch (SQLException e) {
201: throw new VisitorException(
202: "FATAL ERROR: executing an update." + statement, e);
203: }
204: }
205:
206: /**
207: * Executes an update operation on the Database and adds a descriptive error message to
208: * the exception thrown in case of error.
209: * @param statement The <code>Statement</code> object wich will execute the
210: * SQL query.
211: * @return the result of the query as a <code>ResultSet</code> object.
212: * @throws VisitorException if the query can't be executed.
213: */
214: protected ResultSet executeQuery(PreparedStatement statement)
215: throws VisitorException {
216:
217: try {
218: return statement.executeQuery();
219: } catch (SQLException e) {
220: throw new VisitorException(
221: "FATAL ERROR: executing a query.", e);
222: }
223: }
224:
225: /**
226: * Adds the key values to the <code>PreparedStatement</code> starting at
227: * argument <code>paramNumber</code>.
228: * @param statement <code>Statement</code> whose parameters are to be
229: * assigned a value.
230: * @param paramNumber First paramenter to be assigned a value.
231: * @throws VisitorException if the parameters can't be assigned a value.
232: */
233: protected void fillKeyValues(PreparedStatement statement,
234: int paramNumber) throws VisitorException {
235:
236: try {
237: // let the JDBC driver handle key-field types.
238: Iterator keyValuesIterator = getKey().values().iterator();
239: while (keyValuesIterator.hasNext()) {
240: statement.setObject(paramNumber++, keyValuesIterator
241: .next());
242: }
243: } catch (SQLException e) {
244: throw new VisitorException(
245: "ERROR: Can't fill in the values for the key in the PreparedStatement: "
246: + e.getMessage(), e);
247: }
248: }
249:
250: }
|