From: <st...@us...> - 2007-03-02 18:54:55
|
Revision: 3963 http://svn.sourceforge.net/smartfrog/?rev=3963&view=rev Author: steve_l Date: 2007-03-02 10:53:14 -0800 (Fri, 02 Mar 2007) Log Message: ----------- more db component work, and the release plan Modified Paths: -------------- trunk/core/components/database/src/org/smartfrog/services/database/core/AbstractJdbcOperation.java trunk/core/components/database/src/org/smartfrog/services/database/core/TerminationTransactionImpl.java trunk/core/components/database/src/org/smartfrog/services/database/core/TransactionImpl.java trunk/core/components/database/src/org/smartfrog/services/database/core/components.sf trunk/core/release/doc/release-plan-3.11.mpp trunk/core/smartfrog/docs/sfQuickRef.sxw Added Paths: ----------- trunk/core/components/database/doc/database_readme.sxw trunk/core/components/database/src/org/smartfrog/services/database/core/CounterTransactionImpl.java Added: trunk/core/components/database/doc/database_readme.sxw =================================================================== (Binary files differ) Property changes on: trunk/core/components/database/doc/database_readme.sxw ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Modified: trunk/core/components/database/src/org/smartfrog/services/database/core/AbstractJdbcOperation.java =================================================================== --- trunk/core/components/database/src/org/smartfrog/services/database/core/AbstractJdbcOperation.java 2007-03-02 16:09:37 UTC (rev 3962) +++ trunk/core/components/database/src/org/smartfrog/services/database/core/AbstractJdbcOperation.java 2007-03-02 18:53:14 UTC (rev 3963) @@ -19,13 +19,13 @@ */ package org.smartfrog.services.database.core; -import org.smartfrog.sfcore.prim.PrimImpl; -import org.smartfrog.sfcore.prim.Prim; +import org.smartfrog.sfcore.common.SmartFrogDeploymentException; import org.smartfrog.sfcore.common.SmartFrogException; -import org.smartfrog.sfcore.common.SmartFrogDeploymentException; import org.smartfrog.sfcore.common.SmartFrogResolutionException; +import org.smartfrog.sfcore.logging.Log; import org.smartfrog.sfcore.logging.LogFactory; -import org.smartfrog.sfcore.logging.Log; +import org.smartfrog.sfcore.prim.Prim; +import org.smartfrog.sfcore.prim.PrimImpl; import org.smartfrog.sfcore.utils.ComponentHelper; import java.rmi.RemoteException; @@ -39,7 +39,7 @@ * created 05-Dec-2006 15:10:03 */ -public class AbstractJdbcOperation extends PrimImpl implements JdbcOperation { +public abstract class AbstractJdbcOperation extends PrimImpl implements JdbcOperation { private JdbcBinding database; private boolean autocommit = false; private Log log; @@ -53,8 +53,8 @@ * Can be called to start components. Subclasses should override to provide * functionality Do not block in this call, but spawn off any main loops! * - * @throws org.smartfrog.sfcore.common.SmartFrogException failure while starting - * @throws java.rmi.RemoteException In case of network/rmi error + * @throws SmartFrogException failure while starting + * @throws RemoteException In case of network/rmi error */ public synchronized void sfStart() throws SmartFrogException, RemoteException { @@ -70,9 +70,9 @@ * jdbc options. * * @return a new database connection - * @throws org.smartfrog.sfcore.common.SmartFrogDeploymentException - * @throws org.smartfrog.sfcore.common.SmartFrogResolutionException - * @throws java.rmi.RemoteException + * @throws SmartFrogDeploymentException failure while starting + * @throws SmartFrogResolutionException failure to resolve the attributes + * @throws RemoteException In case of network/rmi error */ protected Connection connect() throws SmartFrogDeploymentException, @@ -135,9 +135,9 @@ * Gets an instance of the required driver. * @param driver the driver classname * @return the driver instance - * @throws org.smartfrog.sfcore.common.SmartFrogDeploymentException to wrap failures to create an instance - * @throws org.smartfrog.sfcore.common.SmartFrogResolutionException if the class would not load - * @throws java.rmi.RemoteException on network problems + * @throws SmartFrogDeploymentException to wrap failures to create an instance + * @throws SmartFrogResolutionException if the class would not load + * @throws RemoteException on network problems */ private Driver loadDriver(String driver) throws SmartFrogDeploymentException, @@ -162,7 +162,7 @@ /** * Commit the operation and close the database * @param connection connection to close - * @throws org.smartfrog.sfcore.common.SmartFrogDeploymentException + * @throws SmartFrogDeploymentException if something went wrong at this point */ public void commitAndClose(Connection connection) throws SmartFrogDeploymentException { @@ -212,7 +212,7 @@ /** * check the connection - * @throws SmartFrogDeploymentException if the connection wont start + * @throws SmartFrogDeploymentException if the connection won't start * @throws SmartFrogResolutionException if there is something wrong with the settings * @throws RemoteException on network problems */ Added: trunk/core/components/database/src/org/smartfrog/services/database/core/CounterTransactionImpl.java =================================================================== --- trunk/core/components/database/src/org/smartfrog/services/database/core/CounterTransactionImpl.java (rev 0) +++ trunk/core/components/database/src/org/smartfrog/services/database/core/CounterTransactionImpl.java 2007-03-02 18:53:14 UTC (rev 3963) @@ -0,0 +1,81 @@ +package org.smartfrog.services.database.core; + +import org.smartfrog.sfcore.common.SmartFrogDeploymentException; +import org.smartfrog.sfcore.common.SmartFrogResolutionException; +import org.smartfrog.sfcore.common.SmartFrogException; +import org.smartfrog.sfcore.prim.TerminationRecord; +import org.smartfrog.sfcore.reference.Reference; + +import java.rmi.RemoteException; +import java.sql.Connection; +import java.sql.SQLException; +import java.util.Vector; +import java.util.Iterator; +import java.util.ArrayList; + +/** + * This component subclasses {@link TransactionImpl} to run the transactions at startup, and the transactions listed in + * counterCommands on termination It can be used as a counterpoint to any components that create tables and the like + * created 28-Nov-2006 14:47:56 + */ + +public class CounterTransactionImpl extends TransactionImpl { + + public static final String ATTR_COUNTERCOMMANDS = "counterCommands"; + + private static final Reference REF_COUNTERCOMMANDS = new Reference(ATTR_COUNTERCOMMANDS); + + /** + * The list of counterCommands, extracted at startup + */ + private ArrayList<String> counterCommands; + + public CounterTransactionImpl() throws RemoteException { + } + + + /** + * The startup operation is to read the commands in then execute them by way of {@link #executeStartupCommands()}. + * Subclasses may change this behaviour + * + * @throws SmartFrogException for smartfrog problems + * @throws RemoteException for network problems. + */ + public synchronized void sfStart() throws SmartFrogException, RemoteException { + super.sfStart(); + Vector cc = null; + cc = sfResolve(REF_COUNTERCOMMANDS, cc, true); + counterCommands = new ArrayList<String>(cc.size()); + for (Object o : cc) { + counterCommands.add(o.toString()); + } + } + + /** + * Override point: termination commands. All exceptions should be caught and printed here. + * + * @throws SmartFrogException SmartFrog problems + * @throws RemoteException network problems + * @throws SQLException SQL problems + */ + protected void runTerminationCommands() throws SmartFrogException, RemoteException, SQLException { + Connection connection = null; + try { + connection = connect(); + executeCommands(connection, counterCommands.iterator()); + performOperation(connection); + commitAndClose(connection); + } finally { + closeQuietly(connection); + } + } + + /** + * Override point: Return true if the component has termination time SQL commands to run + * + * @return true if there are counterCommands. + */ + protected boolean hasTerminationCommands() { + return counterCommands != null && counterCommands.size() > 0; + } +} Modified: trunk/core/components/database/src/org/smartfrog/services/database/core/TerminationTransactionImpl.java =================================================================== --- trunk/core/components/database/src/org/smartfrog/services/database/core/TerminationTransactionImpl.java 2007-03-02 16:09:37 UTC (rev 3962) +++ trunk/core/components/database/src/org/smartfrog/services/database/core/TerminationTransactionImpl.java 2007-03-02 18:53:14 UTC (rev 3963) @@ -22,7 +22,6 @@ import org.smartfrog.sfcore.common.SmartFrogDeploymentException; import org.smartfrog.sfcore.common.SmartFrogResolutionException; import org.smartfrog.sfcore.common.SmartFrogException; -import org.smartfrog.sfcore.prim.TerminationRecord; import java.rmi.RemoteException; import java.sql.Connection; @@ -45,10 +44,8 @@ /** * do not run any commands on startup * - * @throws SmartFrogDeploymentException - * for smartfrog problems - * @throws SmartFrogResolutionException - * for smartfrog problems + * @throws SmartFrogDeploymentException for smartfrog problems + * @throws SmartFrogResolutionException for smartfrog problems * @throws RemoteException for network problems. */ protected void executeStartupCommands() @@ -56,31 +53,32 @@ //do nothing } - /** - * shut down the component by running the operations + * Override point: termination commands. All exceptions should be caught and printed here. * - * @param status termination record + * @throws SmartFrogException SmartFrog problems + * @throws RemoteException network problems + * @throws SQLException SQL problems */ - protected synchronized void sfTerminateWith(TerminationRecord status) { - super.sfTerminateWith(status); - Throwable caught = null; + protected void runTerminationCommands() throws SmartFrogException, RemoteException, SQLException { Connection connection = null; try { connection = connect(); + executeCommands(connection, getCommands().iterator()); performOperation(connection); commitAndClose(connection); - } catch (SQLException e) { - caught = e; - } catch (SmartFrogException e) { - caught = e; - } catch (RemoteException e) { - caught = e; } finally { closeQuietly(connection); } - if(caught!=null) { - sfLog().ignore("Caught while terminating the application",caught); - } } + + /** + * Override point: Return true if the component has termination time SQL commands to run + * + * @return true if we have commmands + */ + protected boolean hasTerminationCommands() { + return getCommands() != null && getCommands().size() > 0; + } + } Modified: trunk/core/components/database/src/org/smartfrog/services/database/core/TransactionImpl.java =================================================================== --- trunk/core/components/database/src/org/smartfrog/services/database/core/TransactionImpl.java 2007-03-02 16:09:37 UTC (rev 3962) +++ trunk/core/components/database/src/org/smartfrog/services/database/core/TransactionImpl.java 2007-03-02 18:53:14 UTC (rev 3963) @@ -45,6 +45,7 @@ import org.smartfrog.sfcore.common.SmartFrogDeploymentException; import org.smartfrog.sfcore.common.SmartFrogException; import org.smartfrog.sfcore.common.SmartFrogResolutionException; +import org.smartfrog.sfcore.prim.TerminationRecord; import java.io.BufferedReader; import java.io.File; @@ -73,7 +74,7 @@ public class TransactionImpl extends AsyncJdbcOperation implements Transaction { public static final String ERROR_NO_COMMANDS = "No commands declared"; public static final String ERROR_TOO_MANY_COMMANDS = "Too many command attributes"; - private List<String> commands; + private List<String> commands=new ArrayList<String>(); private boolean escapeProcessing = false; private String delimiter; private int expectedStatementCount = -1; @@ -87,7 +88,17 @@ public TransactionImpl() throws RemoteException { } + /** + * Get the command list + * @return the list of commands (may be empty) + */ + public List<String> getCommands() { + return commands; + } + + + /** * The startup operation is to read the commands in then execute them by way of {@link #executeStartupCommands()}. * Subclasses may change this behaviour * @throws SmartFrogException for smartfrog problems @@ -110,7 +121,60 @@ executeStartupCommands(); } + /** + * stop the worker thread if it is running. + * + * @param status + */ + protected synchronized void sfTerminateWith(TerminationRecord status) { + super.sfTerminateWith(status); + checkAndRunTerminationCommands(); + } + + /** + * Check for and run the termination commands. Any exceptions raised by {@link #runTerminationCommands()} are logged + * at the warn level but otherwise ignored + */ + protected void checkAndRunTerminationCommands() { + Throwable caught = null; + if (hasTerminationCommands()) { + try { + runTerminationCommands(); + } catch (SQLException e) { + caught = e; + } catch (SmartFrogException e) { + caught = e; + } catch (RemoteException e) { + caught = e; + } + if (caught != null) { + sfLog().warn("Caught while terminating the component", caught); + } + } + } + + /** + * Override point: termination commands. + * All exceptions should be caught and printed here. + * The default implementation does nothing. + * @throws SmartFrogException SmartFrog problems + * @throws RemoteException network problems + * @throws SQLException SQL problems + */ + protected void runTerminationCommands() throws SmartFrogException, RemoteException, SQLException { + + } + + /** + * Override point: Return true if the component has termination time SQL commands to run + * + * @return false + */ + protected boolean hasTerminationCommands() { + return false; + } + /** * Execute any commands to run during {@link #sfStart()}. * This delegates to {@link #startCommandThread()} * @throws SmartFrogDeploymentException for smartfrog problems @@ -205,15 +269,8 @@ e); } } else { - if (commandList != null) { - //the commands are copied to the command list as strings. - commands = new ArrayList<String>(commandList.size()); - for (Object o : commandList) { - commands.add(o.toString()); - } - } else { - //no commands at all. That's not really allowed. - commands = new ArrayList<String>(0); + commands=stringify(commandList); + if (commandList == null) { command = ""; } } @@ -226,13 +283,34 @@ } } + /** + * Turn a vector of commands into a more strongly typed array list + * @param commandList commands; can be null + * @return the equivalent ArrayList. A null command list results an empty list + */ + protected ArrayList<String> stringify(Vector commandList) { + ArrayList<String> result; + if (commandList != null) { + //the commands are copied to the command list as strings. + result = new ArrayList<String>(commandList.size()); + for (Object o : commandList) { + result.add(o.toString()); + } + } else { + //no commands at all. That's not really allowed. + result = new ArrayList<String>(0); + } + return result; + } + + /** * this runs in the other tread. Run the commands one by one * * @param connection the open connection. * - * @throws SQLException - * @throws SmartFrogException + * @throws SQLException SQL execution problems + * @throws SmartFrogException for smartfrog problems */ public void performOperation(Connection connection) throws SQLException, SmartFrogException { @@ -248,7 +326,7 @@ * * @return a (possibly empty) list of commands. * - * @throws IOException + * @throws IOException if the string cannot be read reliably */ public List<String> crackCommands(String sql, String commandDelimiter) throws IOException { @@ -293,8 +371,8 @@ * string, as long as the toString() method of each iterated value returns a * single SQL command (without delimeter) * - * @param connection - * @param commandIterator + * @param connection connection to use + * @param commandIterator iterator over the commands to run * * @throws SmartFrogDeploymentException */ @@ -374,16 +452,22 @@ } } - protected void processNoResults(Statement statement) { + /** + * Override point: action on no results + * @param statement the statement to process + * @throws SQLException if needed + */ + protected void processNoResults(Statement statement) throws SQLException { sfLog().info("--no results--"); } /** * Override point, act on the results * + * @param statement the statement to process * @param results the results of the operation * - * @throws SQLException + * @throws SQLException if needed */ protected void processResults(Statement statement,ResultSet results) throws SQLException { Modified: trunk/core/components/database/src/org/smartfrog/services/database/core/components.sf =================================================================== --- trunk/core/components/database/src/org/smartfrog/services/database/core/components.sf 2007-03-02 16:09:37 UTC (rev 3962) +++ trunk/core/components/database/src/org/smartfrog/services/database/core/components.sf 2007-03-02 18:53:14 UTC (rev 3963) @@ -80,7 +80,6 @@ } } autocommit true; - sfShouldTerminate true; } @@ -130,6 +129,7 @@ } sfClass "org.smartfrog.services.database.core.TransactionImpl"; + sfShouldTerminate true; delimiter ";"; escapeProcessing false; expectedStatementCount -1; @@ -138,12 +138,29 @@ printHeaders true; } +/** + * A CounterTransaction issues a sequence of CounterCommands to + * the database (synchronously) when undeploying. + * Failures of these commands are reported and the sequence halts. + */ +CounterTransaction extends Transaction { + counterTransactionSchema extends Schema { + counterCommands extends Vector { + description "a list of commands to execute when undeploying "; + }; + } + //we do not terminate + sfShouldTerminate false; + counterCommands []; +} /** * This component runs the SQL commands synchronously during termination. * It is where to put shutdown operations like "DROP TABLE table1" */ TerminateTransaction extends Transaction { + //we do not terminate + sfShouldTerminate false; sfClass "org.smartfrog.services.database.core.TerminationTransactionImpl"; } Modified: trunk/core/release/doc/release-plan-3.11.mpp =================================================================== (Binary files differ) Modified: trunk/core/smartfrog/docs/sfQuickRef.sxw =================================================================== (Binary files differ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |