cocoon-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From h...@apache.org
Subject cvs commit: xml-cocoon2/src/java/org/apache/cocoon/acting/modular DatabaseAction.java DatabaseAddAction.java DatabaseDeleteAction.java DatabaseSelectAction.java DatabaseUpdateAction.java TestAction.java
Date Tue, 28 May 2002 13:42:51 GMT
haul        02/05/28 06:42:50

  Modified:    src/java/org/apache/cocoon/acting/modular
                        DatabaseAction.java DatabaseAddAction.java
                        DatabaseDeleteAction.java DatabaseSelectAction.java
                        DatabaseUpdateAction.java TestAction.java
  Log:
  Changed modules from using the request object to using objectModel instead. This
  entails some larger modifications to the modular database actions as they used
  to inherit the setColumn method which doesn't work anymore. Some code has been put
  to a utility class and the modular datbase action are now no subclass of the
  original ones anymore.
  
  Revision  Changes    Path
  1.4       +299 -337  xml-cocoon2/src/java/org/apache/cocoon/acting/modular/DatabaseAction.java
  
  Index: DatabaseAction.java
  ===================================================================
  RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/acting/modular/DatabaseAction.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- DatabaseAction.java	2 May 2002 12:52:58 -0000	1.3
  +++ DatabaseAction.java	28 May 2002 13:42:50 -0000	1.4
  @@ -77,6 +77,7 @@
   import org.apache.avalon.framework.activity.Disposable;
   import org.apache.avalon.framework.component.Component;
   import org.apache.avalon.framework.component.ComponentException;
  +import org.apache.avalon.framework.component.ComponentManager;
   import org.apache.avalon.framework.component.ComponentSelector;
   import org.apache.avalon.framework.configuration.Configurable;
   import org.apache.avalon.framework.configuration.Configuration;
  @@ -92,19 +93,19 @@
   import org.apache.avalon.excalibur.component.DefaultRoleManager;
   import org.apache.avalon.excalibur.datasource.DataSourceComponent;
   
  +
   import org.apache.cocoon.Constants;
   import org.apache.cocoon.ProcessingException;
   import org.apache.cocoon.components.classloader.RepositoryClassLoader;
  -import org.apache.cocoon.environment.ObjectModelHelper;
  -import org.apache.cocoon.environment.Request;
   import org.apache.cocoon.environment.Redirector;
   import org.apache.cocoon.environment.SourceResolver;
   import org.apache.cocoon.generation.ImageDirectoryGenerator;
   import org.apache.cocoon.util.ClassUtils;
   import org.apache.cocoon.util.HashMap;
  +import org.apache.cocoon.util.JDBCTypeConversions;
   import org.apache.cocoon.selection.Selector;
   
  -import org.apache.cocoon.acting.AbstractDatabaseAction;
  +import org.apache.cocoon.acting.AbstractComplementaryConfigurableAction;
   import org.apache.cocoon.components.modules.database.AutoIncrementModule;
   import org.apache.cocoon.components.modules.input.InputModule;
   import org.apache.cocoon.components.modules.output.OutputModule;
  @@ -116,8 +117,7 @@
    * and writing parameters. In addition the descriptor format has
    * changed to accomodate the new features.
    *
  - * <p>This action is heavily based upon the original DatabaseAddAction
  - * and relies on the AbstractDatabaseAction.</p>
  + * <p>This action is heavily based upon the original DatabaseAddActions.</p>
    *
    * <p>Modes have to be configured in cocoon.xconf. Mode names from
    * descriptor.xml file are looked up in the component service. Default
  @@ -141,13 +141,12 @@
    * </table>
    *
    * @author <a href="mailto:haul@apache.org">Christian Haul</a>
  - * @version CVS $Id: DatabaseAction.java,v 1.3 2002/05/02 12:52:58 cziegeler Exp $
  + * @version CVS $Id: DatabaseAction.java,v 1.4 2002/05/28 13:42:50 haul Exp $
    * @see org.apache.cocoon.modules.input
    * @see org.apache.cocoon.modules.output
    * @see org.apache.cocoon.modules.database
    */
  -public abstract class DatabaseAction extends AbstractDatabaseAction {
  -
  +public abstract class DatabaseAction  extends AbstractComplementaryConfigurableAction implements Configurable, Disposable {
   
       // ========================================================================
       // constants
  @@ -173,7 +172,8 @@
       // instance vars
       // ========================================================================
   
  -    protected HashMap defaultModeNames = new HashMap( 3 );
  +    protected ComponentSelector dbselector;
  +    protected Map defaultModeNames = new HashMap( 3 );
       protected final HashMap cachedQueryData = new HashMap();
   
   
  @@ -260,20 +260,41 @@
       }
   
       // ========================================================================
  +    // Avalon methods
  +    // ========================================================================
  +
  +    /**
  +     * Compose the Actions so that we can select our databases.
  +     */
  +    public void compose(ComponentManager manager) throws ComponentException {
  +        this.dbselector = (ComponentSelector) manager.lookup(DataSourceComponent.ROLE + "Selector");
  +
  +        super.compose(manager);
  +    }
  +
  +
  +    /**
  +     *  dispose
  +     */
  +    public void dispose() {
  +        this.manager.release(dbselector);
  +    }
  +
  +
  +    // ========================================================================
       // protected utility methods
       // ========================================================================
   
       /**
  -     * override super's method since we prefer to get the datasource
  -     * from defaults first or from sitemap parameters rather than from
  -     * descriptor file.
  +     * Get the Datasource we need.
        */
       protected DataSourceComponent getDataSource( Configuration conf, Parameters parameters )
           throws ComponentException {
   
           String sourceName = parameters.getParameter( "connection", (String) settings.get( "connection" ) );
           if ( sourceName == null ) {
  -            return getDataSource( conf );
  +            Configuration dsn = conf.getChild("connection");
  +            return (DataSourceComponent) this.dbselector.select(dsn.getValue(""));
           } else {
               if (getLogger().isDebugEnabled())
                   getLogger().debug("Using datasource: "+sourceName);
  @@ -281,25 +302,31 @@
           }
       }
   
  +    /**
  +     * Return whether a type is a Large Object (BLOB/CLOB).
  +     */
  +    protected final boolean isLargeObject (String type) {
  +        if ("ascii".equals(type)) return true;
  +        if ("binary".equals(type)) return true;
  +        if ("image".equals(type)) return true;
  +
  +        return false;
  +    }
   
       /**
  -     * Store a key/value pair in the request attributes. We prefix the key
  +     * Store a key/value pair in the output attributes. We prefix the key
        * with the name of this class to prevent potential name collisions.
  -     * This method overrides super class' method to allow an OutputModule
  -     * to take care of what to do with the values.
        */
  -    protected void setRequestAttribute(Request request, String key, Object value) {
  +    protected void setOutputAttribute(Map objectModel, String outputMode, String key, Object value) {
   
           ComponentSelector outputSelector = null;
           OutputModule output = null;
  -        String outputMode = null;
           try {
               outputSelector=(ComponentSelector) this.manager.lookup(OUTPUT_MODULE_SELECTOR);
  -            outputMode = (String) request.getAttribute(ATTRIBUTE_KEY);
               if (outputMode != null && outputSelector != null && outputSelector.hasComponent(outputMode)){
                   output = (OutputModule) outputSelector.select(outputMode);
               }
  -            output.setAttribute( null, request, key, value );
  +            output.setAttribute( null, objectModel, key, value );
           } catch (Exception e) {
                   if (getLogger().isWarnEnabled())
                       getLogger()
  @@ -316,238 +343,6 @@
       }
   
   
  -    /**
  -     * Retrieve a value from the request attributes.
  -     * This method overrides super class' method to allow an OutputModule
  -     * to take care of where to get the values.
  -     */
  -    // FIXME: OutputModule doesn't provide getAttribute anymore
  -    protected Object getRequestAttribute(Request request, String key) {
  -
  -        if (getLogger().isErrorEnabled())
  -            getLogger()
  -                .error("getRequestAttribute not supported");
  -        return null;
  -    }
  -
  -
  -    // ========================================================================
  -    // main method
  -    // ========================================================================
  -
  -
  -    /**
  -     * Add a record to the database.  This action assumes that
  -     * the file referenced by the "descriptor" parameter conforms
  -     * to the AbstractDatabaseAction specifications.
  -     */
  -    public Map act( Redirector redirector, SourceResolver resolver, Map objectModel,
  -                    String source, Parameters param ) throws Exception {
  -
  -        DataSourceComponent datasource = null;
  -        Connection conn = null;
  -        Map results = new HashMap();
  -        int rows = 0;
  -
  -        // read global parameter settings
  -        boolean reloadable = Constants.DESCRIPTOR_RELOADABLE_DEFAULT;
  -        Request request = ObjectModelHelper.getRequest(objectModel);
  -
  -        // call specific default modes apart from output mode are not supported
  -        // set request attribute
  -        String outputMode = param.getParameter("output", (String) defaultModeNames.get(MODE_OUTPUT));
  -        request.setAttribute(ATTRIBUTE_KEY, outputMode);
  -
  -        if (this.settings.containsKey("reloadable"))
  -            reloadable = Boolean.getBoolean((String) this.settings.get("reloadable"));
  -
  -        // read local parameter settings
  -        try {
  -            Configuration conf =
  -                this.getConfiguration(param.getParameter("descriptor", (String) this.settings.get("descriptor")),
  -                                      resolver,
  -                                      param.getParameterAsBoolean("reloadable",reloadable));
  -
  -            // get database connection and try to turn off autocommit
  -            datasource = this.getDataSource(conf, param);
  -            conn = datasource.getConnection();
  -            if (conn.getAutoCommit() == true) {
  -                try {
  -                    conn.setAutoCommit(false);
  -                } catch (Exception ex) {
  -                    String tmp = param.getParameter("use-transactions",(String) this.settings.get("use-transactions",null));
  -                    if (tmp != null &&  (tmp.equalsIgnoreCase("no") || tmp.equalsIgnoreCase("false") || tmp.equalsIgnoreCase("0"))) {
  -                        if (getLogger().isErrorEnabled())
  -                            getLogger().error("This DB connection does not support transactions. If you want to risk your data's integrity by continuing nonetheless set parameter \"use-transactions\" to \"no\".");
  -                        throw ex;
  -                    }
  -                }
  -            }
  -
  -            // find tables to work with
  -            Configuration[] tables = conf.getChildren("table");
  -            String tablesetname = param.getParameter("table-set", (String) this.settings.get("table-set"));
  -            Map set_tables = null; // default to old behaviour
  -
  -            HashMap modeTypes = null;
  -
  -            if (tablesetname != null) {
  -                // new set based behaviour
  -                Configuration[] tablesets = conf.getChildren("table-set");
  -                String setname = null;
  -                boolean found = false;
  -
  -                // find tables contained in tableset
  -                int j = 0;
  -                for (j=0; j<tablesets.length; j++) {
  -                    setname = tablesets[j].getAttribute ("name", "");
  -                    if (tablesetname.trim().equals (setname.trim ())) {
  -                        found = true;
  -                        break;
  -                    }
  -                }
  -                if (!found) {
  -                    throw new IOException(" given set " + tablesetname + " does not exists in a description file.");
  -                }
  -
  -                Configuration[] set = tablesets[j].getChildren("table");
  -
  -                // construct a Map that contains the names of the tables
  -                // contained in the requested tableset
  -                set_tables = new HashMap(set.length);
  -                for (int i=0; i<set.length; i++) {
  -                    // look for alternative mode types
  -                    modeTypes = new HashMap(2);
  -                    modeTypes.put( MODE_AUTOINCR, set[i].getAttribute( "autoincr-mode", "autoincr" ) );
  -                    modeTypes.put( MODE_OTHERS, set[i].getAttribute( "others-mode",   "others" ) );
  -                    set_tables.put(set[i].getAttribute("name",""), modeTypes);
  -                }
  -            } else {
  -                modeTypes = new HashMap(2);
  -                modeTypes.put( MODE_AUTOINCR, "autoincr" );
  -                modeTypes.put( MODE_OTHERS, "others" );
  -            };
  -
  -            for (int i=0; i<tables.length; i++) {
  -                if (set_tables == null ||
  -                     set_tables.containsKey( tables[i].getAttribute( "name" ) ) ||
  -                     ( tables[i].getAttribute( "alias", null ) != null && set_tables.containsKey( tables[i].getAttribute( "alias" ) ) )
  -                     ) {
  -                    if (tablesetname != null) {
  -                        if (tables[i].getAttribute("alias", null) != null && set_tables.containsKey(tables[i].getAttribute("alias"))){
  -                            modeTypes = (HashMap) set_tables.get(tables[i].getAttribute("alias"));
  -                            set_tables.remove(tables[i].getAttribute("alias"));
  -                        } else {
  -                            modeTypes = (HashMap) set_tables.get(tables[i].getAttribute("name"));
  -                            set_tables.remove(tables[i].getAttribute("name"));
  -                        }
  -                    }
  -                    rows += processTable( tables[i], conn, request, results, modeTypes );
  -                }
  -            }
  -
  -            if (conn.getAutoCommit()==false)
  -                conn.commit();
  -
  -            // obtain output mode module and rollback output
  -            ComponentSelector outputSelector = null;
  -            OutputModule output = null;
  -            try {
  -                outputSelector=(ComponentSelector) this.manager.lookup(OUTPUT_MODULE_SELECTOR);
  -                if (outputMode != null && outputSelector != null && outputSelector.hasComponent(outputMode)){
  -                    output = (OutputModule) outputSelector.select(outputMode);
  -                }
  -                output.commit( null, request );
  -            } catch (Exception e) {
  -                if (getLogger().isWarnEnabled())
  -                    getLogger()
  -                        .warn( "Could not select output mode "
  -                               + (String) outputMode
  -                               + ":" + e.getMessage() );
  -            } finally {
  -                if (outputSelector != null) {
  -                    if (output != null)
  -                        outputSelector.release(output);
  -                    this.manager.release(outputSelector);
  -                }
  -            }
  -
  -        } catch (Exception e) {
  -            if ( conn != null ) {
  -                try {
  -                    if (getLogger().isDebugEnabled())
  -                        getLogger().debug( "Rolling back transaction. Caused by " + e.getMessage() );
  -                    conn.rollback();
  -                    results = null;
  -
  -                    // obtain output mode module and commit output
  -                    ComponentSelector outputSelector = null;
  -                    OutputModule output = null;
  -                    try {
  -                        outputSelector=(ComponentSelector) this.manager.lookup(OUTPUT_MODULE_SELECTOR);
  -                        if (outputMode != null && outputSelector != null && outputSelector.hasComponent(outputMode)){
  -                            output = (OutputModule) outputSelector.select(outputMode);
  -                        }
  -                        output.rollback( null, request, e);
  -                    } catch (Exception e2) {
  -                        if (getLogger().isWarnEnabled())
  -                            getLogger()
  -                                .warn( "Could not select output mode "
  -                                       + (String) outputMode
  -                                       + ":" + e2.getMessage() );
  -                    } finally {
  -                        if (outputSelector != null) {
  -                            if (output != null)
  -                                outputSelector.release(output);
  -                            this.manager.release(outputSelector);
  -                        }
  -                    }
  -
  -                } catch (SQLException se) {
  -                    if (getLogger().isDebugEnabled())
  -                        getLogger().debug("There was an error rolling back the transaction", se);
  -                }
  -            }
  -
  -            //throw new ProcessingException("Could not add record :position = " + currentIndex, e);
  -
  -            // don't throw an exception, an error has been signalled, that should suffice
  -
  -            String throwException = (String) this.settings.get( "throw-exception",
  -                                                                param.getParameter( "throw-exception", null ) );
  -            if ( throwException != null &&
  -                 ( throwException.equalsIgnoreCase( "true" ) || throwException.equalsIgnoreCase( "yes" ) ) ) {
  -                throw new ProcessingException("Could not add record",e);
  -            }
  -        } finally {
  -            if (conn != null) {
  -                try {
  -                    conn.close();
  -                } catch (SQLException sqe) {
  -                    getLogger().warn("There was an error closing the datasource", sqe);
  -                }
  -            }
  -
  -            if (datasource != null)
  -                this.dbselector.release(datasource);
  -        }
  -        if (results != null) {
  -            if (rows>0) {
  -                results.put("row-count",new Integer(rows));
  -            } else {
  -                results = null;
  -            }
  -        } else {
  -            if (rows>0) {
  -                results = new HashMap(1);
  -                results.put("row-count",new Integer(rows));
  -            }
  -        }
  -
  -        return (results == null? results : Collections.unmodifiableMap(results));
  -    }
  -
  -
   
       /**
        * Inserts a row or a set of rows into the given table based on the
  @@ -555,10 +350,10 @@
        *
        * @param table the table's configuration
        * @param conn the database connection
  -     * @param request the request
  +     * @param objectModel the objectModel
        */
  -    protected int processTable( Configuration table, Connection conn, Request request,
  -                                 Map results, HashMap modeTypes )
  +    protected int processTable( Configuration table, Connection conn, Map objectModel,
  +                                 Map results, Map modeTypes )
           throws SQLException, ConfigurationException, Exception {
   
           PreparedStatement statement = null;
  @@ -567,7 +362,8 @@
               LookUpKey luk = new LookUpKey(table, modeTypes);
               CacheHelper queryData = null;
   
  -            getLogger().debug("modeTypes : "+ modeTypes);
  +            if (getLogger().isDebugEnabled())
  +                getLogger().debug("modeTypes : "+ modeTypes);
   
               // get cached data
               // synchronize complete block since we don't want 100s of threads
  @@ -585,7 +381,7 @@
                   getLogger().debug("query: "+queryData.queryString);
               statement = conn.prepareStatement(queryData.queryString);
   
  -            Object[][] columnValues = this.getColumnValues( table, queryData, request );
  +            Object[][] columnValues = this.getColumnValues( table, queryData, objectModel );
   
               int setLength = 1;
               if ( queryData.isSet ) {
  @@ -599,7 +395,7 @@
               for ( int rowIndex = 0; rowIndex < setLength; rowIndex++ ) {
                   if (getLogger().isDebugEnabled())
                       getLogger().debug( "====> row no. " + rowIndex );
  -                rows += processRow( request, conn, statement, table, queryData, columnValues, rowIndex, results );
  +                rows += processRow( objectModel, conn, statement, (String) modeTypes.get(MODE_OUTPUT), table, queryData, columnValues, rowIndex, results );
               }
   
           } finally {
  @@ -646,8 +442,7 @@
       /**
        * compose name for output a long the lines of "table.column"
        */
  -    protected String getOutputName ( Configuration tableConf, Configuration columnConf )
  -        throws ConfigurationException {
  +    protected String getOutputName ( Configuration tableConf, Configuration columnConf ) {
   
           return getOutputName( tableConf, columnConf, -1 );
       }
  @@ -657,11 +452,10 @@
        * compose name for output a long the lines of "table.column[row]" or
        * "table.column" if rowIndex is -1.
        */
  -    protected String getOutputName ( Configuration tableConf, Configuration columnConf, int rowIndex )
  -        throws ConfigurationException {
  +    protected String getOutputName ( Configuration tableConf, Configuration columnConf, int rowIndex ) {
   
  -        return ( tableConf.getAttribute("alias", tableConf.getAttribute("name") )
  -                 + "." + columnConf.getAttribute("name")
  +        return ( tableConf.getAttribute("alias", tableConf.getAttribute("name", null) )
  +                 + "." + columnConf.getAttribute("name",null)
                    + ( rowIndex == -1 ? "" : "[" + rowIndex + "]" ) );
       }
   
  @@ -675,7 +469,7 @@
        * a set.
        *
        */
  -    protected Object[] getColumnValue( Configuration tableConf, Column column, Request request )
  +    protected Object[] getColumnValue( Configuration tableConf, Column column, Map objectModel )
           throws ConfigurationException, ComponentException {
   
           if ( column.isAutoIncrement ) {
  @@ -696,12 +490,12 @@
                   if ( column.isSet ){
                       if (getLogger().isDebugEnabled())
                           getLogger().debug( "Trying to set column " + cname +" using getAttributeValues method");
  -                    values = input.getAttributeValues( cname, column.modeConf, request );
  +                    values = input.getAttributeValues( cname, column.modeConf, objectModel );
                   } else {
                       if (getLogger().isDebugEnabled())
                           getLogger().debug( "Trying to set column " + cname +" using getAttribute method");
                       values = new Object[1];
  -                    values[0] = input.getAttribute( cname, column.modeConf, request );
  +                    values[0] = input.getAttribute( cname, column.modeConf, objectModel );
                   }
   
                   if ( values != null ) {
  @@ -727,8 +521,8 @@
       /**
        * Setup parsed attribute configuration object
        */
  -    protected void fillModes ( Configuration[] conf, boolean isKey, HashMap defaultModeNames,
  -                               HashMap modeTypes, CacheHelper set )
  +    protected void fillModes ( Configuration[] conf, boolean isKey, Map defaultModeNames,
  +                               Map modeTypes, CacheHelper set )
           throws ConfigurationException {
   
           String setMode = null;
  @@ -772,98 +566,266 @@
           }
       }
   
  +    /**
  +     * create a unique name using the getOutputName method and write
  +     * the value to the output module and the results map if present.
  +     *
  +     */
  +    protected void setOutput( Map objectModel, String outputMode, Map results,
  +                         Configuration table, Configuration column, int rowIndex, Object value ) {
   
  +        String param = this.getOutputName( table, column, rowIndex );
  +        if (getLogger().isDebugEnabled())
  +            getLogger().debug( "Setting column " + param + " to " + value );
  +        this.setOutputAttribute(objectModel, outputMode, param, value);
  +        if (results != null)
  +            results.put( param, String.valueOf( value ) );
  +    }
   
       /**
  -     * Put key values into request attributes.
  +     * set a column in a statement using the appropriate JDBC setXXX method.
  +     *
        */
  -    protected void storeKeyValue( Configuration tableConf, Column key, int rowIndex, Connection conn,
  -                                  Statement statement, Request request, Map results )
  -        throws SQLException, ConfigurationException, ComponentException {
  +    protected void setColumn ( PreparedStatement statement, int position, Configuration entry, Object value ) throws Exception {
   
  -        ComponentSelector autoincrSelector = null;
  -        AutoIncrementModule autoincr = null;
  -        try {
  -            autoincrSelector=(ComponentSelector) this.manager.lookup(DATABASE_MODULE_SELECTOR);
  -            if (key.mode != null && autoincrSelector != null && autoincrSelector.hasComponent(key.mode)){
  -                autoincr = (AutoIncrementModule) autoincrSelector.select(key.mode);
  -            }
  +        JDBCTypeConversions.setColumn(statement, position, value, (Integer) JDBCTypeConversions.typeConstants.get(entry.getAttribute("type")));
  +    }
   
  -            if (!autoincr.includeAsValue()) {
  -                String keyname = getOutputName( tableConf, key.columnConf, rowIndex );
  -                Object value = autoincr.getPostValue( tableConf, key.columnConf, key.modeConf, conn, statement, request );
  -                if (getLogger().isDebugEnabled())
  -                    getLogger().debug( "Retrieving autoincrement for " + keyname + "as " + value );
  -                setRequestAttribute( request, keyname, value );
  -                results.put( keyname, String.valueOf( value ) );
  -            }
   
  -        } finally {
  -            if (autoincrSelector != null) {
  -                if (autoincr != null)
  -                    autoincrSelector.release(autoincr);
  -                this.manager.release(autoincrSelector);
  -            }
  -         }
  +    /**
  +     * set a column in a statement using the appropriate JDBC setXXX
  +     * method and propagate the value to the output module and results
  +     * map if present. Effectively combines calls to setColumn and
  +     * setOutput.
  +     *
  +     */
  +    protected void setColumn ( Map objectModel, String outputMode, Map results,
  +                               Configuration table, Configuration column, int rowIndex, 
  +                               Object value, PreparedStatement statement, int position ) throws Exception {
   
  +        this.setOutput( objectModel, outputMode, results, table, column, rowIndex, value );
  +        this.setColumn( statement, position, column, value );
       }
   
   
  +    // ========================================================================
  +    // main method
  +    // ========================================================================
  +
  +
       /**
  -     * Sets the key value on the prepared statement for an autoincrement type.
  -     *
  -     * @param table the table's configuration object
  -     * @param column the key's configuration object
  -     * @param currentIndex the position of the key column
  -     * @param rowIndex the position in the current row set
  -     * @param conn the database connection
  -     * @param statement the insert statement
  -     * @param request the request object
  -     * @param result sitemap result object
  -     * @return the number of columns by which to increment the currentIndex
  +     * Add a record to the database.  This action assumes that
  +     * the file referenced by the "descriptor" parameter conforms
  +     * to the AbstractDatabaseAction specifications.
        */
  -    protected int setKeyAuto ( Configuration table, Column column, int currentIndex, int rowIndex,
  -                               Connection conn, PreparedStatement statement, Request request, Map results )
  -        throws ConfigurationException, SQLException, ComponentException, Exception {
  +    public Map act( Redirector redirector, SourceResolver resolver, Map objectModel,
  +                    String source, Parameters param ) throws Exception {
  +
  +        DataSourceComponent datasource = null;
  +        Connection conn = null;
  +        Map results = new HashMap();
  +        int rows = 0;
   
  -        int columnCount = 0;
  +        // read global parameter settings
  +        boolean reloadable = Constants.DESCRIPTOR_RELOADABLE_DEFAULT;
  +
  +        // call specific default modes apart from output mode are not supported
  +        // set request attribute
  +        String outputMode = param.getParameter("output", (String) defaultModeNames.get(MODE_OUTPUT));
   
  +        if (this.settings.containsKey("reloadable"))
  +            reloadable = Boolean.getBoolean((String) this.settings.get("reloadable"));
   
  -        ComponentSelector autoincrSelector = null;
  -        AutoIncrementModule autoincr = null;
  +        // read local parameter settings
           try {
  -            autoincrSelector=(ComponentSelector) this.manager.lookup(DATABASE_MODULE_SELECTOR);
  -            if (column.mode != null && autoincrSelector != null && autoincrSelector.hasComponent(column.mode)){
  -                autoincr = (AutoIncrementModule) autoincrSelector.select(column.mode);
  +            Configuration conf =
  +                this.getConfiguration(param.getParameter("descriptor", (String) this.settings.get("descriptor")),
  +                                      resolver,
  +                                      param.getParameterAsBoolean("reloadable",reloadable));
  +
  +            // get database connection and try to turn off autocommit
  +            datasource = this.getDataSource(conf, param);
  +            conn = datasource.getConnection();
  +            if (conn.getAutoCommit() == true) {
  +                try {
  +                    conn.setAutoCommit(false);
  +                } catch (Exception ex) {
  +                    String tmp = param.getParameter("use-transactions",(String) this.settings.get("use-transactions",null));
  +                    if (tmp != null &&  (tmp.equalsIgnoreCase("no") || tmp.equalsIgnoreCase("false") || tmp.equalsIgnoreCase("0"))) {
  +                        if (getLogger().isErrorEnabled())
  +                            getLogger().error("This DB connection does not support transactions. If you want to risk your data's integrity by continuing nonetheless set parameter \"use-transactions\" to \"no\".");
  +                        throw ex;
  +                    }
  +                }
               }
   
  -            if ( autoincr.includeInQuery() ) {
  -                if ( autoincr.includeAsValue() ) {
  -                    Object value = autoincr.getPreValue( table, column.columnConf, column.modeConf, conn, request );
  -                    String keyname = this.getOutputName( table, column.columnConf, rowIndex );
  -                    if (getLogger().isDebugEnabled())
  -                        getLogger().debug( "Setting key " + keyname + " to " + value );
  -                    statement.setObject( currentIndex, value );
  -                    setRequestAttribute( request, keyname, value );
  -                    results.put( keyname, String.valueOf( value ) );
  -                    columnCount = 1;
  +            // find tables to work with
  +            Configuration[] tables = conf.getChildren("table");
  +            String tablesetname = param.getParameter("table-set", (String) this.settings.get("table-set"));
  +            Map set_tables = null; // default to old behaviour
  +
  +            Map modeTypes = null;
  +
  +            if (tablesetname != null) {
  +                // new set based behaviour
  +                Configuration[] tablesets = conf.getChildren("table-set");
  +                String setname = null;
  +                boolean found = false;
  +
  +                // find tables contained in tableset
  +                int j = 0;
  +                for (j=0; j<tablesets.length; j++) {
  +                    setname = tablesets[j].getAttribute ("name", "");
  +                    if (tablesetname.trim().equals (setname.trim ())) {
  +                        found = true;
  +                        break;
  +                    }
  +                }
  +                if (!found) {
  +                    throw new IOException(" given set " + tablesetname + " does not exists in a description file.");
  +                }
  +
  +                Configuration[] set = tablesets[j].getChildren("table");
  +
  +                // construct a Map that contains the names of the tables
  +                // contained in the requested tableset
  +                set_tables = new HashMap(set.length);
  +                for (int i=0; i<set.length; i++) {
  +                    // look for alternative mode types
  +                    modeTypes = new HashMap(6);
  +                    modeTypes.put( MODE_AUTOINCR, set[i].getAttribute( "autoincr-mode", "autoincr" ) );
  +                    modeTypes.put( MODE_OTHERS, set[i].getAttribute( "others-mode",   "others" ) );
  +                    modeTypes.put( MODE_OUTPUT, outputMode );
  +                    set_tables.put(set[i].getAttribute("name",""), modeTypes);
                   }
               } else {
  -                if (getLogger().isDebugEnabled())
  -                    getLogger().debug( "Automatically setting key" );
  +                modeTypes = new HashMap(6);
  +                modeTypes.put( MODE_AUTOINCR, "autoincr" );
  +                modeTypes.put( MODE_OTHERS, "others" );
  +                modeTypes.put( MODE_OUTPUT, outputMode );
  +            };
  +
  +            for (int i=0; i<tables.length; i++) {
  +                if (set_tables == null ||
  +                     set_tables.containsKey( tables[i].getAttribute( "name" ) ) ||
  +                     ( tables[i].getAttribute( "alias", null ) != null && set_tables.containsKey( tables[i].getAttribute( "alias" ) ) )
  +                     ) {
  +                    if (tablesetname != null) {
  +                        if (tables[i].getAttribute("alias", null) != null && set_tables.containsKey(tables[i].getAttribute("alias"))){
  +                            modeTypes = (Map) set_tables.get(tables[i].getAttribute("alias"));
  +                            set_tables.remove(tables[i].getAttribute("alias"));
  +                        } else {
  +                            modeTypes = (Map) set_tables.get(tables[i].getAttribute("name"));
  +                            set_tables.remove(tables[i].getAttribute("name"));
  +                        }
  +                    }
  +                    rows += processTable( tables[i], conn, objectModel, results, modeTypes );
  +                }
  +            }
  +
  +            if (conn.getAutoCommit()==false)
  +                conn.commit();
  +
  +            // obtain output mode module and rollback output
  +            ComponentSelector outputSelector = null;
  +            OutputModule output = null;
  +            try {
  +                outputSelector=(ComponentSelector) this.manager.lookup(OUTPUT_MODULE_SELECTOR);
  +                if (outputMode != null && outputSelector != null && outputSelector.hasComponent(outputMode)){
  +                    output = (OutputModule) outputSelector.select(outputMode);
  +                }
  +                output.commit( null, objectModel );
  +            } catch (Exception e) {
  +                if (getLogger().isWarnEnabled())
  +                    getLogger()
  +                        .warn( "Could not select output mode "
  +                               + (String) outputMode
  +                               + ":" + e.getMessage() );
  +            } finally {
  +                if (outputSelector != null) {
  +                    if (output != null)
  +                        outputSelector.release(output);
  +                    this.manager.release(outputSelector);
  +                }
               }
   
  +        } catch (Exception e) {
  +            if ( conn != null ) {
  +                try {
  +                    if (getLogger().isDebugEnabled())
  +                        getLogger().debug( "Rolling back transaction. Caused by " + e.getMessage() );
  +                    conn.rollback();
  +                    results = null;
  +
  +                    // obtain output mode module and commit output
  +                    ComponentSelector outputSelector = null;
  +                    OutputModule output = null;
  +                    try {
  +                        outputSelector=(ComponentSelector) this.manager.lookup(OUTPUT_MODULE_SELECTOR);
  +                        if (outputMode != null && outputSelector != null && outputSelector.hasComponent(outputMode)){
  +                            output = (OutputModule) outputSelector.select(outputMode);
  +                        }
  +                        output.rollback( null, objectModel, e);
  +                    } catch (Exception e2) {
  +                        if (getLogger().isWarnEnabled())
  +                            getLogger()
  +                                .warn( "Could not select output mode "
  +                                       + (String) outputMode
  +                                       + ":" + e2.getMessage() );
  +                    } finally {
  +                        if (outputSelector != null) {
  +                            if (output != null)
  +                                outputSelector.release(output);
  +                            this.manager.release(outputSelector);
  +                        }
  +                    }
  +
  +                } catch (SQLException se) {
  +                    if (getLogger().isDebugEnabled())
  +                        getLogger().debug("There was an error rolling back the transaction", se);
  +                }
  +            }
  +
  +            //throw new ProcessingException("Could not add record :position = " + currentIndex, e);
  +
  +            // don't throw an exception, an error has been signalled, that should suffice
  +
  +            String throwException = (String) this.settings.get( "throw-exception",
  +                                                                param.getParameter( "throw-exception", null ) );
  +            if ( throwException != null &&
  +                 ( throwException.equalsIgnoreCase( "true" ) || throwException.equalsIgnoreCase( "yes" ) ) ) {
  +                throw new ProcessingException("Could not add record",e);
  +            }
           } finally {
  -            if (autoincrSelector != null) {
  -                if (autoincr != null)
  -                    autoincrSelector.release(autoincr);
  -                this.manager.release(autoincrSelector);
  +            if (conn != null) {
  +                try {
  +                    conn.close();
  +                } catch (SQLException sqe) {
  +                    getLogger().warn("There was an error closing the datasource", sqe);
  +                }
               }
  -         }
   
  -        return columnCount;
  +            if (datasource != null)
  +                this.dbselector.release(datasource);
  +        }
  +        if (results != null) {
  +            if (rows>0) {
  +                results.put("row-count",new Integer(rows));
  +            } else {
  +                results = null;
  +            }
  +        } else {
  +            if (rows>0) {
  +                results = new HashMap(1);
  +                results.put("row-count",new Integer(rows));
  +            }
  +        }
  +
  +        return (results == null? results : Collections.unmodifiableMap(results));
       }
   
  +
  +
       // ========================================================================
       // abstract methods
       // ========================================================================
  @@ -876,7 +838,7 @@
        * This method is intended to be overridden by classes that
        * implement other operations e.g. delete
        */
  -    protected abstract int processRow( Request request, Connection conn, PreparedStatement statement,
  +    protected abstract int processRow( Map objectModel, Connection conn, PreparedStatement statement, String outputMode,
                                          Configuration table, CacheHelper queryData, Object[][] columnValues,
                                          int rowIndex, Map results )
           throws SQLException, ConfigurationException, Exception;
  @@ -887,7 +849,7 @@
        * This method is intended to be overridden by classes that
        * implement other operations e.g. delete
        */
  -    protected abstract String selectMode( boolean isAutoIncrement, HashMap modes );
  +    protected abstract String selectMode( boolean isAutoIncrement, Map modes );
   
   
       /**
  @@ -907,7 +869,7 @@
        * This method is intended to be overridden by classes that
        * implement other operations e.g. delete
        */
  -    abstract Object[][] getColumnValues( Configuration tableConf, CacheHelper queryData, Request request )
  +    abstract Object[][] getColumnValues( Configuration tableConf, CacheHelper queryData, Map objectModel )
           throws ConfigurationException, ComponentException;
   
       /**
  @@ -921,7 +883,7 @@
        * @param table the table's configuration object
        * @return the insert query as a string
        */
  -    protected abstract CacheHelper getQuery( Configuration table, HashMap modeTypes, HashMap defaultModeNames )
  +    protected abstract CacheHelper getQuery( Configuration table, Map modeTypes, Map defaultModeNames )
           throws ConfigurationException, ComponentException;
   
   }
  
  
  
  1.3       +97 -14    xml-cocoon2/src/java/org/apache/cocoon/acting/modular/DatabaseAddAction.java
  
  Index: DatabaseAddAction.java
  ===================================================================
  RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/acting/modular/DatabaseAddAction.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- DatabaseAddAction.java	28 Apr 2002 20:02:22 -0000	1.2
  +++ DatabaseAddAction.java	28 May 2002 13:42:50 -0000	1.3
  @@ -53,6 +53,7 @@
   
   import java.util.Map;
   import java.sql.Connection;
  +import java.sql.Statement;
   import java.sql.PreparedStatement;
   import java.sql.SQLException;
   import org.apache.cocoon.util.HashMap;
  @@ -62,8 +63,6 @@
   import org.apache.avalon.framework.configuration.Configuration;
   import org.apache.avalon.framework.configuration.ConfigurationException;
   
  -import org.apache.cocoon.environment.Request;
  -
   import org.apache.cocoon.components.modules.database.AutoIncrementModule;
   
   /**
  @@ -72,7 +71,7 @@
    * {@see DatabaseAction} for details.
    *
    * @author <a href="mailto:haul@apache.org">Christian Haul</a>
  - * @version CVS $Id: DatabaseAddAction.java,v 1.2 2002/04/28 20:02:22 haul Exp $
  + * @version CVS $Id: DatabaseAddAction.java,v 1.3 2002/05/28 13:42:50 haul Exp $
    */
   public class DatabaseAddAction extends DatabaseAction {
   
  @@ -80,7 +79,7 @@
       /**
        * set all necessary ?s and execute the query
        */
  -    protected int processRow ( Request request, Connection conn, PreparedStatement statement,
  +    protected int processRow ( Map objectModel, Connection conn, PreparedStatement statement, String outputMode,
                                  Configuration table, CacheHelper queryData, Object[][] columnValues,
                                  int rowIndex, Map results )
           throws SQLException, ConfigurationException, Exception {
  @@ -90,12 +89,12 @@
               Column col = queryData.columns[i];
               if ( col.isAutoIncrement && col.isKey ) {
                   currentIndex += setKeyAuto( table, col, currentIndex, rowIndex,
  -                                            conn, statement, request, results );
  +                                            conn, statement, objectModel, outputMode, results );
               } else {
  -                this.setColumn( statement, currentIndex, request, col.columnConf,
  -                                getOutputName( table, col.columnConf, rowIndex ),
  -                                columnValues[ i ][ ( col.isSet ? rowIndex : 0 ) ],
  -                                rowIndex);
  +                this.setOutput( objectModel, outputMode, results, table, col.columnConf, rowIndex,
  +                                columnValues[ i ][ ( col.isSet ? rowIndex : 0 ) ]);
  +                this.setColumn( statement, currentIndex, col.columnConf, 
  +                                columnValues[ i ][ ( col.isSet ? rowIndex : 0 ) ]);
                   currentIndex++;
               }
           }
  @@ -104,7 +103,7 @@
           for (int i = 0; i < queryData.columns.length; i++) {
               if ( queryData.columns[i].isAutoIncrement && queryData.columns[i].isKey ) {
                   storeKeyValue( table, queryData.columns[i], rowIndex,
  -                               conn, statement, request, results );
  +                               conn, statement, objectModel, outputMode, results );
               }
           }
           return rowCount;
  @@ -112,11 +111,95 @@
   
   
       /**
  +     * Sets the key value on the prepared statement for an autoincrement type.
  +     *
  +     * @param table the table's configuration object
  +     * @param column the key's configuration object
  +     * @param currentIndex the position of the key column
  +     * @param rowIndex the position in the current row set
  +     * @param conn the database connection
  +     * @param statement the insert statement
  +     * @param objectModel the objectModel object
  +     * @param outputMode name of the requested output module
  +     * @param result sitemap result object
  +     * @return the number of columns by which to increment the currentIndex
  +     */
  +    protected int setKeyAuto ( Configuration table, Column column, int currentIndex, int rowIndex,
  +                               Connection conn, PreparedStatement statement, Map objectModel, String outputMode, Map results )
  +        throws ConfigurationException, SQLException, ComponentException, Exception {
  +
  +        int columnCount = 0;
  +        ComponentSelector autoincrSelector = null;
  +        AutoIncrementModule autoincr = null;
  +        try {
  +            autoincrSelector=(ComponentSelector) this.manager.lookup(DATABASE_MODULE_SELECTOR);
  +            if (column.mode != null && autoincrSelector != null && autoincrSelector.hasComponent(column.mode)){
  +                autoincr = (AutoIncrementModule) autoincrSelector.select(column.mode);
  +            }
  +
  +            if ( autoincr.includeInQuery() ) {
  +                if ( autoincr.includeAsValue() ) {
  +                    Object value = autoincr.getPreValue( table, column.columnConf, column.modeConf, conn, objectModel );
  +                    this.setColumn(objectModel, outputMode, results, table, column.columnConf, rowIndex, value, statement, currentIndex);
  +                    columnCount = 1;
  +                }
  +            } else {
  +                if (getLogger().isDebugEnabled())
  +                    getLogger().debug( "Automatically setting key" );
  +            }
  +
  +        } finally {
  +            if (autoincrSelector != null) {
  +                if (autoincr != null)
  +                    autoincrSelector.release(autoincr);
  +                this.manager.release(autoincrSelector);
  +            }
  +         }
  +
  +        return columnCount;
  +    }
  +
  +
  +
  +    /**
  +     * Put key values into request attributes. Checks whether the
  +     * value needs to be retrieved from the database module first.
  +     *
  +     */
  +    protected void storeKeyValue( Configuration tableConf, Column key, int rowIndex, Connection conn,
  +                                  Statement statement, Map objectModel, String outputMode, Map results )
  +        throws SQLException, ConfigurationException, ComponentException {
  +
  +        ComponentSelector autoincrSelector = null;
  +        AutoIncrementModule autoincr = null;
  +        try {
  +            autoincrSelector=(ComponentSelector) this.manager.lookup(DATABASE_MODULE_SELECTOR);
  +            if (key.mode != null && autoincrSelector != null && autoincrSelector.hasComponent(key.mode)){
  +                autoincr = (AutoIncrementModule) autoincrSelector.select(key.mode);
  +            }
  +
  +            if (!autoincr.includeAsValue()) {
  +                Object value = autoincr.getPostValue( tableConf, key.columnConf, key.modeConf, conn, statement, objectModel );
  +                this.setOutput(objectModel, outputMode, results, tableConf, key.columnConf, rowIndex, value);
  +            }
  +
  +        } finally {
  +            if (autoincrSelector != null) {
  +                if (autoincr != null)
  +                    autoincrSelector.release(autoincr);
  +                this.manager.release(autoincrSelector);
  +            }
  +         }
  +
  +    }
  +
  +
  +    /**
        * determine which mode to use as default mode
        * here: INSERT
        * highly specific to operation INSERT / UPDATE / DELETE / SELECT
        */
  -    protected String selectMode ( boolean isAutoIncrement, HashMap modes ) {
  +    protected String selectMode ( boolean isAutoIncrement, Map modes ) {
   
           if ( isAutoIncrement )
               return (String) modes.get( MODE_AUTOINCR );
  @@ -137,12 +220,12 @@
        * database operation.
        */
       protected Object[][] getColumnValues( Configuration tableConf, CacheHelper queryData,
  -                                          Request request )
  +                                          Map objectModel )
           throws ConfigurationException, ComponentException {
   
           Object[][] columnValues = new Object[ queryData.columns.length ][];
           for ( int i = 0; i < queryData.columns.length; i++ ){
  -            columnValues[i] = this.getColumnValue( tableConf, queryData.columns[i], request );
  +            columnValues[i] = this.getColumnValue( tableConf, queryData.columns[i], objectModel );
           }
           return columnValues;
       }
  @@ -155,7 +238,7 @@
        * @param table the table's configuration object
        * @return the insert query as a string
        */
  -    protected CacheHelper getQuery( Configuration table, HashMap modeTypes, HashMap defaultModeNames )
  +    protected CacheHelper getQuery( Configuration table, Map modeTypes, Map defaultModeNames )
           throws ConfigurationException, ComponentException {
   
           LookUpKey lookUpKey = new LookUpKey( table, modeTypes );
  
  
  
  1.3       +10 -15    xml-cocoon2/src/java/org/apache/cocoon/acting/modular/DatabaseDeleteAction.java
  
  Index: DatabaseDeleteAction.java
  ===================================================================
  RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/acting/modular/DatabaseDeleteAction.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- DatabaseDeleteAction.java	28 Apr 2002 20:02:22 -0000	1.2
  +++ DatabaseDeleteAction.java	28 May 2002 13:42:50 -0000	1.3
  @@ -61,16 +61,12 @@
   import org.apache.avalon.framework.configuration.Configuration;
   import org.apache.avalon.framework.configuration.ConfigurationException;
   
  -import org.apache.cocoon.environment.Request;
  -
   /**
    * Updates a record in a database. The action can update one or more
  - * tables, and can update more than one row to a table at a time. The
  - * form descriptor semantics for this are still in a bit of a state of
  - * flux.
  + * tables, and can update more than one row to a table at a time. 
    *
    * @author <a href="mailto:haul@apache.org">Christian Haul</a>
  - * @version CVS $Id: DatabaseDeleteAction.java,v 1.2 2002/04/28 20:02:22 haul Exp $
  + * @version CVS $Id: DatabaseDeleteAction.java,v 1.3 2002/05/28 13:42:50 haul Exp $
    */
   public class DatabaseDeleteAction extends DatabaseAction {
   
  @@ -79,7 +75,7 @@
        * here: DELETE
        * highly specific to operation INSERT / UPDATE / DELETE / SELECT
        */
  -    protected String selectMode ( boolean isAutoIncrement, HashMap modes ) {
  +    protected String selectMode ( boolean isAutoIncrement, Map modes ) {
   
           return (String) modes.get( MODE_OTHERS );
       }
  @@ -96,13 +92,13 @@
        * Fetch all values for all key columns that are needed to do the
        * database operation.
        */
  -    protected Object[][] getColumnValues( Configuration tableConf, CacheHelper queryData, Request request )
  +    protected Object[][] getColumnValues( Configuration tableConf, CacheHelper queryData, Map objectModel )
           throws ConfigurationException, ComponentException {
   
           Object[][] columnValues = new Object[ queryData.columns.length ][];
           for ( int i = 0; i < queryData.columns.length; i++ ){
               if ( queryData.columns[i].isKey ) {
  -                columnValues[i] = this.getColumnValue( tableConf, queryData.columns[i], request );
  +                columnValues[i] = this.getColumnValue( tableConf, queryData.columns[i], objectModel );
               } else {
                   // columnValues[i] = new Object[1]; // this should not be needed
               }
  @@ -120,7 +116,7 @@
        * @param table the table's configuration object
        * @return the insert query as a string
        */
  -    protected CacheHelper getQuery( Configuration table, HashMap modeTypes, HashMap defaultModeNames )
  +    protected CacheHelper getQuery( Configuration table, Map modeTypes, Map defaultModeNames )
           throws ConfigurationException, ComponentException {
   
           LookUpKey lookUpKey = new LookUpKey( table, modeTypes );
  @@ -158,7 +154,7 @@
       /**
        * set all necessary ?s and execute the query
        */
  -    protected int processRow ( Request request, Connection conn, PreparedStatement statement,
  +    protected int processRow ( Map objectModel, Connection conn, PreparedStatement statement, String outputMode,
                                  Configuration table, CacheHelper queryData, Object[][] columnValues,
                                  int rowIndex, Map results )
           throws SQLException, ConfigurationException, Exception {
  @@ -169,10 +165,9 @@
           for (int i = 0; i < queryData.columns.length; i++) {
               Column col = queryData.columns[i];
               if ( col.isKey ) {
  -                this.setColumn( statement, currentIndex, request, col.columnConf,
  -                                getOutputName( table, col.columnConf, rowIndex ),
  -                                columnValues[ i ][ ( col.isSet ? rowIndex : 0 ) ],
  -                                rowIndex);
  +                this.setColumn( objectModel, outputMode, results, table, col.columnConf, rowIndex,
  +                                columnValues[ i ][ ( col.isSet ? rowIndex : 0 ) ], 
  +                                statement, currentIndex );
                   currentIndex++;
               }
           }
  
  
  
  1.3       +14 -100   xml-cocoon2/src/java/org/apache/cocoon/acting/modular/DatabaseSelectAction.java
  
  Index: DatabaseSelectAction.java
  ===================================================================
  RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/acting/modular/DatabaseSelectAction.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- DatabaseSelectAction.java	28 Apr 2002 20:02:22 -0000	1.2
  +++ DatabaseSelectAction.java	28 May 2002 13:42:50 -0000	1.3
  @@ -69,18 +69,15 @@
   import org.apache.avalon.framework.configuration.Configuration;
   import org.apache.avalon.framework.configuration.ConfigurationException;
   
  -import org.apache.cocoon.environment.Request;
  -
  -import org.apache.cocoon.acting.AbstractDatabaseAction;
  +import org.apache.cocoon.util.JDBCTypeConversions;
   
   /**
    * Selects a record from a database. The action can select one or more
    * tables, and can select from more than one row of a table at a
  - * time. The form descriptor semantics for this are still in a bit of
  - * a state of flux.
  + * time.
    *
    * @author <a href="mailto:haul@apache.org">Christian Haul</a>
  - * @version CVS $Id: DatabaseSelectAction.java,v 1.2 2002/04/28 20:02:22 haul Exp $
  + * @version CVS $Id: DatabaseSelectAction.java,v 1.3 2002/05/28 13:42:50 haul Exp $
    */
   public class DatabaseSelectAction extends DatabaseAction {
   
  @@ -89,7 +86,7 @@
        * here: SELECT
        * highly specific to operation INSERT / UPDATE / DELETE / SELECT
        */
  -    protected String selectMode ( boolean isAutoIncrement, HashMap modes ) {
  +    protected String selectMode ( boolean isAutoIncrement, Map modes ) {
           
           return (String) modes.get( MODE_OTHERS );
       }
  @@ -110,7 +107,7 @@
        * @param table the table's configuration object
        * @return the insert query as a string
        */
  -    protected CacheHelper getQuery( Configuration table, HashMap modeTypes, HashMap defaultModeNames )
  +    protected CacheHelper getQuery( Configuration table, Map modeTypes, Map defaultModeNames )
           throws ConfigurationException, ComponentException {
   
           LookUpKey lookUpKey = new LookUpKey( table, modeTypes );
  @@ -168,13 +165,13 @@
        * Fetch all values for all key columns that are needed to do the
        * database operation.
        */
  -    protected Object[][] getColumnValues( Configuration tableConf, CacheHelper queryData, Request request )
  +    protected Object[][] getColumnValues( Configuration tableConf, CacheHelper queryData, Map objectModel )
           throws ConfigurationException, ComponentException {
   
           Object[][] columnValues = new Object[ queryData.columns.length ][];
           for ( int i = 0; i < queryData.columns.length; i++ ){
               if ( queryData.columns[i].isKey ) {
  -                columnValues[i] = this.getColumnValue( tableConf, queryData.columns[i], request );
  +                columnValues[i] = this.getColumnValue( tableConf, queryData.columns[i], objectModel );
               } else {
                   // columnValues[i] = new Object[1]; // this should not be needed
               }
  @@ -186,8 +183,9 @@
       /**
        * set all necessary ?s and execute the query
        */
  -    protected int processRow ( Request request, Connection conn, PreparedStatement statement, Configuration table,
  -                               CacheHelper queryData, Object[][] columnValues, int rowIndex, Map results )
  +    protected int processRow ( Map objectModel, Connection conn, PreparedStatement statement, String outputMode,
  +                               Configuration table, CacheHelper queryData, Object[][] columnValues, 
  +                               int rowIndex, Map results )
           throws SQLException, ConfigurationException, Exception {
   
           int currentIndex = 1;
  @@ -196,10 +194,8 @@
           for (int i = 0; i < queryData.columns.length; i++) {
               Column col = queryData.columns[i];
               if ( col.isKey ) {
  -                this.setColumn( statement, currentIndex, request, col.columnConf,
  -                                getOutputName( table, col.columnConf, rowIndex ),
  -                                columnValues[ i ][ ( col.isSet ? rowIndex : 0 ) ],
  -                                rowIndex);
  +                this.setColumn(objectModel, outputMode, results, table, col.columnConf, rowIndex,
  +                               columnValues[ i ][ ( col.isSet ? rowIndex : 0 ) ], statement, currentIndex );
                   currentIndex++;
               }
           }
  @@ -213,94 +209,12 @@
               //}
               for (int i = 0; i < queryData.columns.length; i++) {
                   if ( !queryData.columns[i].isKey ) {
  -                    Object value = this.getColumn( resultset, queryData.columns[i].columnConf );
  -                    String param = getOutputName( table, queryData.columns[i].columnConf, rowIndex );
  -                    this.setRequestAttribute( request, param, value );
  -                    results.put(param,value);
  +                    Object value = JDBCTypeConversions.getColumn( resultset, queryData.columns[i].columnConf );
  +                    this.setOutput(objectModel, outputMode, results, table, queryData.columns[i].columnConf, rowIndex, value);
                   }
               }
           }
           return rowIndex;
  -    }
  -
  -
  -    /**
  -     * Get the Statement column so that the results are mapped correctly.
  -     * (this has been copied from AbstractDatabaseAction and modified slightly)
  -     */
  -    protected Object getColumn(ResultSet set, Configuration column ) throws Exception {
  -
  -        Integer type = (Integer) AbstractDatabaseAction.typeConstants.get(column.getAttribute("type"));
  -        String dbcol = column.getAttribute("name");
  -        Object value = null;
  -
  -        switch (type.intValue()) {
  -        case Types.CLOB:
  -            Clob dbClob = set.getClob(dbcol);
  -            int length = (int) dbClob.length();
  -            InputStream asciiStream = new BufferedInputStream(dbClob.getAsciiStream());
  -            byte[] buffer = new byte[length];
  -            asciiStream.read(buffer);
  -            String str = new String(buffer);
  -            asciiStream.close();
  -            value = str;
  -            break;
  -        case Types.BIGINT:
  -            value = set.getBigDecimal(dbcol);
  -            break;
  -        case Types.TINYINT:
  -            value = new Byte(set.getByte(dbcol));
  -            break;
  -        case Types.VARCHAR:
  -            value  = set.getString(dbcol);
  -            break;
  -        case Types.DATE:
  -            value = set.getDate(dbcol);
  -            break;
  -        case Types.DOUBLE:
  -            value = new Double(set.getDouble(dbcol));
  -            break;
  -        case Types.FLOAT:
  -            value = new Float(set.getFloat(dbcol));
  -            break;
  -        case Types.INTEGER:
  -            value = new Integer(set.getInt(dbcol));
  -            break;
  -        case Types.NUMERIC:
  -            value = new Long(set.getLong(dbcol));
  -            break;
  -        case Types.SMALLINT:
  -            value = new Short(set.getShort(dbcol));
  -            break;
  -        case Types.TIME:
  -            value = set.getTime(dbcol);
  -            break;
  -        case Types.TIMESTAMP:
  -            value = set.getTimestamp(dbcol);
  -            break;
  -        case Types.ARRAY:
  -            value = set.getArray(dbcol); // new Integer(set.getInt(dbcol));
  -            break;
  -        case Types.BIT:
  -            value = new Integer(set.getInt(dbcol));
  -            break;
  -        case Types.CHAR:
  -            value = new Integer(set.getInt(dbcol));
  -            break;
  -        case Types.STRUCT:
  -            value = (Struct) set.getObject(dbcol);
  -            break;
  -        case Types.OTHER:
  -            value = set.getObject(dbcol);
  -            break;
  -
  -        default:
  -            // The blob types have to be requested separately, via a Reader.
  -            value = "";
  -            break;
  -        }
  -
  -        return value;
       }
   
   
  
  
  
  1.3       +15 -22    xml-cocoon2/src/java/org/apache/cocoon/acting/modular/DatabaseUpdateAction.java
  
  Index: DatabaseUpdateAction.java
  ===================================================================
  RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/acting/modular/DatabaseUpdateAction.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- DatabaseUpdateAction.java	28 Apr 2002 20:02:22 -0000	1.2
  +++ DatabaseUpdateAction.java	28 May 2002 13:42:50 -0000	1.3
  @@ -61,16 +61,12 @@
   import org.apache.avalon.framework.configuration.Configuration;
   import org.apache.avalon.framework.configuration.ConfigurationException;
   
  -import org.apache.cocoon.environment.Request;
  -
   /**
    * Updates a record in a database. The action can update one or more
  - * tables, and can update more than one row to a table at a time. The
  - * form descriptor semantics for this are still in a bit of a state of
  - * flux.
  + * tables, and can update more than one row to a table at a time.
    *
    * @author <a href="mailto:haul@apache.org">Christian Haul</a>
  - * @version CVS $Id: DatabaseUpdateAction.java,v 1.2 2002/04/28 20:02:22 haul Exp $
  + * @version CVS $Id: DatabaseUpdateAction.java,v 1.3 2002/05/28 13:42:50 haul Exp $
    */
   public class DatabaseUpdateAction extends DatabaseAction {
   
  @@ -79,7 +75,7 @@
        * here: UPDATE
        * highly specific to operation INSERT / UPDATE / DELETE / SELECT
        */
  -    protected String selectMode ( boolean isAutoIncrement, HashMap modes ) {
  +    protected String selectMode ( boolean isAutoIncrement, Map modes ) {
   
           return (String) modes.get( MODE_OTHERS );
       }
  @@ -96,12 +92,12 @@
        * Fetch all values for all columns that are needed to do the
        * database operation.
        */
  -    protected Object[][] getColumnValues( Configuration tableConf, CacheHelper queryData, Request request )
  +    protected Object[][] getColumnValues( Configuration tableConf, CacheHelper queryData, Map objectModel )
           throws ConfigurationException, ComponentException {
   
           Object[][] columnValues = new Object[ queryData.columns.length ][];
           for ( int i = 0; i < queryData.columns.length; i++ ){
  -            columnValues[i] = this.getColumnValue( tableConf, queryData.columns[i], request );
  +            columnValues[i] = this.getColumnValue( tableConf, queryData.columns[i], objectModel );
           }
           return columnValues;
       }
  @@ -115,7 +111,7 @@
        * @param table the table's configuration object
        * @return the insert query as a string
        */
  -    protected CacheHelper getQuery( Configuration table, HashMap modeTypes, HashMap defaultModeNames )
  +    protected CacheHelper getQuery( Configuration table, Map modeTypes, Map defaultModeNames )
           throws ConfigurationException, ComponentException {
   
           LookUpKey lookUpKey = new LookUpKey( table, modeTypes );
  @@ -171,8 +167,9 @@
       /**
        * set all necessary ?s and execute the query
        */
  -    protected int processRow ( Request request, Connection conn, PreparedStatement statement, Configuration table,
  -							   CacheHelper queryData, Object[][] columnValues, int rowIndex, Map results )
  +    protected int processRow ( Map objectModel, Connection conn, PreparedStatement statement, String outputMode,
  +                               Configuration table, CacheHelper queryData, Object[][] columnValues, 
  +                               int rowIndex, Map results )
           throws SQLException, ConfigurationException, Exception {
   
   
  @@ -182,25 +179,21 @@
           for (int i = 0; i < queryData.columns.length; i++) {
               Column col = queryData.columns[i];
               if ( !col.isKey ) {
  -                this.setColumn( statement, currentIndex, request, col.columnConf,
  -                                getOutputName( table, col.columnConf, rowIndex ),
  -                                columnValues[ i ][ ( col.isSet ? rowIndex : 0 ) ],
  -                                rowIndex);
  +                this.setColumn( objectModel, outputMode, results, table, col.columnConf, rowIndex,
  +                                columnValues[ i ][ ( col.isSet ? rowIndex : 0 ) ], statement, currentIndex );
                   currentIndex++;
               }
           }
           for (int i = 0; i < queryData.columns.length; i++) {
               Column col = queryData.columns[i];
               if ( col.isKey ) {
  -                this.setColumn( statement, currentIndex, request, col.columnConf,
  -                                getOutputName( table, col.columnConf, rowIndex ),
  -                                columnValues[ i ][ ( col.isSet ? rowIndex : 0 ) ],
  -                                rowIndex);
  +                this.setColumn( objectModel, outputMode, results, table, col.columnConf, rowIndex,
  +                                columnValues[ i ][ ( col.isSet ? rowIndex : 0 ) ], statement, currentIndex );
                   currentIndex++;
               }
           }
  -		int rowCount = statement.executeUpdate();
  -		return rowCount;
  +        int rowCount = statement.executeUpdate();
  +        return rowCount;
       }
   
   }
  
  
  
  1.3       +8 -13     xml-cocoon2/src/java/org/apache/cocoon/acting/modular/TestAction.java
  
  Index: TestAction.java
  ===================================================================
  RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/acting/modular/TestAction.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- TestAction.java	28 Apr 2002 20:02:22 -0000	1.2
  +++ TestAction.java	28 May 2002 13:42:50 -0000	1.3
  @@ -121,11 +121,6 @@
                       String source, Parameters param ) throws Exception {
   
           // general setup
  -        Request request = (Request) objectModel.get(Constants.REQUEST_OBJECT);
  -        if (request == null) {
  -          getLogger().error("no request object!");
  -          return(null);
  -        }
           String parameterName = param.getParameter("parameter-name",this.defaultParameterName);
           boolean useGetValues = param.getParameterAsBoolean("use-getValues",this.useGetValues);
           InputModule input = null;
  @@ -154,11 +149,11 @@
                       if (getLogger().isDebugEnabled()) getLogger().debug("reading all parameter values");
                       // for a test, read all parameters from input and write them to outout
                       // get names first, then (one) value per name
  -                    Enumeration enum = input.getAttributeNames(this.inputConf,request);
  +                    Enumeration enum = input.getAttributeNames(this.inputConf,objectModel);
                       while (enum.hasMoreElements()) {
                           parameterName = (String) enum.nextElement();
  -                        Object value = input.getAttribute(parameterName, this.inputConf, request);
  -                        output.setAttribute(this.outputConf, request, parameterName, value);
  +                        Object value = input.getAttribute(parameterName, this.inputConf, objectModel);
  +                        output.setAttribute(this.outputConf, objectModel, parameterName, value);
                           
                           if (getLogger().isDebugEnabled()) 
                               getLogger().debug("["+parameterName+"] = ["+value+"]");
  @@ -168,8 +163,8 @@
   
                       if (useGetValues) {
                           // get all existing values
  -                        Object[] value = input.getAttributeValues(parameterName, this.inputConf, request);
  -                        output.setAttribute(this.outputConf, request, parameterName, value);
  +                        Object[] value = input.getAttributeValues(parameterName, this.inputConf, objectModel);
  +                        output.setAttribute(this.outputConf, objectModel, parameterName, value);
                           
                           if (getLogger().isDebugEnabled()) 
                               for (int i=0; i<value.length; i++)
  @@ -181,14 +176,14 @@
                           if (getLogger().isDebugEnabled()) 
                               getLogger().debug("reading parameter values for "+parameterName);
                           
  -                        Object value = input.getAttribute(parameterName, this.inputConf, request);
  -                        output.setAttribute(this.outputConf, request, parameterName, value);
  +                        Object value = input.getAttribute(parameterName, this.inputConf, objectModel);
  +                        output.setAttribute(this.outputConf, objectModel, parameterName, value);
                           
                           if (getLogger().isDebugEnabled()) getLogger().debug("["+parameterName+"] = ["+value+"]");
                           // ------------------------------------------------------------------------
                       }
                   }
  -                output.commit(this.outputConf,request);
  +                output.commit(this.outputConf,objectModel);
                   if (getLogger().isDebugEnabled()) getLogger().debug("done commit");
                   // done
               }
  
  
  

----------------------------------------------------------------------
In case of troubles, e-mail:     webmaster@xml.apache.org
To unsubscribe, e-mail:          cocoon-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: cocoon-cvs-help@xml.apache.org


Mime
View raw message