You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by ha...@apache.org on 2002/11/17 20:13:53 UTC

cvs commit: xml-cocoon2/src/java/org/apache/cocoon/transformation SimpleFormTransformer.java

haul        2002/11/17 11:13:53

  Modified:    src/java/org/apache/cocoon/util Tag: cocoon_2_0_3_branch
                        JDBCTypeConversions.java
               src/java/org/apache/cocoon/transformation Tag:
                        cocoon_2_0_3_branch SimpleFormTransformer.java
  Added:       src/java/org/apache/cocoon/util Tag: cocoon_2_0_3_branch
                        BlobHelper.java ClobHelper.java
  Log:
    <action dev="CH" type="update">
     Changed SimpleFormTransformer to use InputModules.
    </action>
    <action dev="CH" type="update">
     Changed InputModules to return Iterator instead of Enumeration. New abstract
     "meta" module to make new meta modules easier. Stripped "meta" from defaults
     module. Added JXPathMetaModule. Added extension classes and packages to all
     modules that are based on JXPath.
    </action>
    <action dev="CH" type="update">
     Improved support for CLOB and BLOB columns in modular database actions.
    </action>
    <action dev="CH" type="add">
     New chaining InputModule that allows to use additional modules when an attribute is not
     present or null.
    </action>
    <action dev="CH" type="update">
     Changed defaults of InputModule names in many places to new names.
    </action>
  
  Revision  Changes    Path
  No                   revision
  
  
  No                   revision
  
  
  1.3.2.2   +305 -194  xml-cocoon2/src/java/org/apache/cocoon/util/Attic/JDBCTypeConversions.java
  
  Index: JDBCTypeConversions.java
  ===================================================================
  RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/util/Attic/JDBCTypeConversions.java,v
  retrieving revision 1.3.2.1
  retrieving revision 1.3.2.2
  diff -u -r1.3.2.1 -r1.3.2.2
  --- JDBCTypeConversions.java	11 Aug 2002 20:04:26 -0000	1.3.2.1
  +++ JDBCTypeConversions.java	17 Nov 2002 19:13:52 -0000	1.3.2.2
  @@ -52,7 +52,6 @@
   
   import java.io.*;
   import java.sql.PreparedStatement;
  -import java.sql.Statement;
   import java.sql.ResultSet;
   import java.sql.SQLException;
   import java.sql.Timestamp;
  @@ -61,15 +60,14 @@
   import java.sql.Array;
   import java.sql.Types;
   import java.sql.Clob;
  +import java.sql.Blob;
   import java.sql.Struct;
   import java.math.BigDecimal;
   import java.util.Map;
  +import java.util.Calendar;
   import java.util.HashMap;
   import java.util.Collections;
  -import java.text.DateFormat;
  -import java.text.SimpleDateFormat;
   import org.apache.avalon.framework.configuration.Configuration;
  -import org.apache.avalon.framework.configuration.ConfigurationException;
   import org.apache.excalibur.source.Source;
   
   
  @@ -78,6 +76,35 @@
    * them to JDBC statements. Largely copied from
    * org.apache.cocoon.acting.AbstractDatabaseAction.
    *
  + * <p>The following table lists all available column type names
  + * together with the JDBC methods used to get or set a column with
  + * that type. In some cases the returned type differs from the type
  + * returned by the getXXX method. To set a column, a number of
  + * conversions are automatically used. For details, please see the
  + * actual code.</p>
  + *
  + * <p><table border="1">
  + * <tr><th>type       </th><th>getXXX      </th><th>returns </th><th>setXXX       </th></tr>
  + * <tr><td>clob       </td><td>Clob        </td><td>String  </td><td>Clob         </td></tr>
  + * <tr><td>ascii      </td><td>Clob        </td><td>String  </td><td>asciStream   </td></tr>
  + * <tr><td>big-decimal</td><td>BigDecimal  </td><td>        </td><td>BigDecimal   </td></tr>
  + * <tr><td>binary     </td><td>            </td><td>        </td><td>BinaryStream </td></tr>
  + * <tr><td>blob       </td><td>            </td><td>        </td><td>Blob         </td></tr>
  + * <tr><td>boolean    </td><td>Bit         </td><td>Integer </td><td>Boolean      </td></tr>
  + * <tr><td>byte       </td><td>Byte        </td><td>Byte    </td><td>Byte         </td></tr>
  + * <tr><td>string     </td><td>String      </td><td>        </td><td>String       </td></tr>
  + * <tr><td>date       </td><td>Date        </td><td>        </td><td>Date         </td></tr>
  + * <tr><td>double     </td><td>Double      </td><td>Double  </td><td>Double       </td></tr>
  + * <tr><td>float      </td><td>Float       </td><td>Float   </td><td>Float        </td></tr>
  + * <tr><td>int        </td><td>Int         </td><td>Integer </td><td>Int          </td></tr>
  + * <tr><td>long       </td><td>Long        </td><td>Long    </td><td>Long         </td></tr>
  + * <tr><td>short      </td><td>Short       </td><td>        </td><td>Short        </td></tr>
  + * <tr><td>time       </td><td>Time        </td><td>        </td><td>Time         </td></tr>
  + * <tr><td>time-stamp </td><td>Timestamp   </td><td>        </td><td>Timestamp    </td></tr>
  + * <tr><td>array      </td><td>Array       </td><td>        </td><td>Array        </td></tr>
  + * <tr><td>row        </td><td>Object      </td><td>Struct  </td><td>Object       </td></tr>
  + * <tr><td>object     </td><td>Object      </td><td>        </td><td>Object       </td></tr>
  + * </table></p>
    */
   public class JDBCTypeConversions {
       public static final Map typeConstants;
  @@ -87,9 +114,11 @@
               Note that INTEGER, BLOB, and VARCHAR column types map to more than
               one type name. **/
           Map constants = new HashMap();
  -        constants.put("ascii", new Integer(Types.CLOB));
  +        constants.put("clob", new Integer(Types.CLOB));
  +        constants.put("ascii", new Integer(Types.CHAR));
           constants.put("big-decimal", new Integer(Types.BIGINT));
  -        constants.put("binary", new Integer(Types.BLOB));
  +        constants.put("binary", new Integer(Types.VARBINARY));
  +        constants.put("blob", new Integer(Types.BLOB));
           constants.put("boolean", new Integer(Types.BIT));
           constants.put("byte", new Integer(Types.TINYINT));
           constants.put("string", new Integer(Types.VARCHAR));
  @@ -158,6 +187,7 @@
   
           switch (type.intValue()) {
           case Types.CLOB:
  +        case Types.CHAR:
               Clob dbClob = set.getClob(dbcol);
               int length = (int) dbClob.length();
               InputStream asciiStream = new BufferedInputStream(dbClob.getAsciiStream());
  @@ -206,9 +236,6 @@
           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;
  @@ -231,11 +258,7 @@
        *
        * @param statement the prepared statement
        * @param position the position of the column
  -     * @param request the request
  -     * @param entry the configuration object
  -     * @param param the name of the request parameter
        * @param value the value of the column
  -     * @param rowIndex the index of the current row for manyrows inserts
        */
       public static void setColumn(PreparedStatement statement, int position, Object value, Integer typeObject) throws Exception {
           if (value instanceof String) {
  @@ -251,197 +274,285 @@
           }
           if ("".equals(value)) {
               switch (typeObject.intValue()) {
  -                case Types.CHAR:
  -                case Types.CLOB:
  -                case Types.VARCHAR:
  -                    /** If the value is an empty string and the column is
  -                        a string type, we can continue **/
  -                    break;
  -                default:
  -                    /** If the value is an empty string and the column
  -                        is something else, we treat it as a null value **/
  -                    statement.setNull(position, typeObject.intValue());
  -                    return;
  +            case Types.CHAR:
  +            case Types.CLOB:
  +            case Types.VARCHAR:
  +                /** If the value is an empty string and the column is
  +                    a string type, we can continue **/
  +                break;
  +            default:
  +                /** If the value is an empty string and the column
  +                    is something else, we treat it as a null value **/
  +                statement.setNull(position, typeObject.intValue());
  +                return;
               }
           }
   
           File file = null;
  +        int length = -1;
  +        InputStream asciiStream = null;
   
  +        //System.out.println("========================================================================");
  +        //System.out.println("JDBCTypeConversions: setting type "+typeObject.intValue());
           switch (typeObject.intValue()) {
  -            case Types.CLOB:
  -                int length = -1;
  -                InputStream asciiStream = null;
  -
  -                if (value instanceof File) {
  -                    File asciiFile = (File) value;
  -                    asciiStream = new BufferedInputStream(new FileInputStream(asciiFile));
  -                    length = (int) asciiFile.length();
  -                } else if (value instanceof JDBCxlobHelper) {
  -                    asciiStream = ((JDBCxlobHelper) value).inputStream;
  -                    length = ((JDBCxlobHelper) value).length;
  -                } else if (value instanceof Source) {
  -                    asciiStream = ((Source) value).getInputStream();
  -                    length = (int)((Source) value).getContentLength();
  -                } else {
  -                    String asciiText = (String) value;
  -                    asciiStream = new BufferedInputStream(new ByteArrayInputStream(asciiText.getBytes()));
  -                    length = asciiText.length();
  -                }
  -
  -                statement.setAsciiStream(position, asciiStream, length);
  -                break;
  -            case Types.BIGINT:
  -                BigDecimal bd = null;
  -
  -                if (value instanceof BigDecimal) {
  -                    bd = (BigDecimal) value;
  -                } else {
  -                    bd = new BigDecimal((String) value);
  -                }
  -
  -                statement.setBigDecimal(position, bd);
  -                break;
  -            case Types.TINYINT:
  -                Byte b = null;
  -
  -                if (value instanceof Byte) {
  -                    b = (Byte) value;
  -                } else {
  -                    b = new Byte((String) value);
  -                }
  -
  -                statement.setByte(position, b.byteValue());
  -                break;
  -            case Types.DATE:
  -                Date d = null;
  -
  -                if (value instanceof Date) {
  -                    d = (Date) value;
  -                } else if (value instanceof java.util.Date) {
  -                    d = new Date(((java.util.Date) value).getTime());
  -                }
  -
  -                statement.setDate(position, d);
  -                break;
  -            case Types.DOUBLE:
  -                Double db = null;
  -
  -                if (value instanceof Double) {
  -                    db = (Double) value;
  -                } else {
  -                    db = new Double((String) value);
  -                }
  -
  -                statement.setDouble(position, db.doubleValue());
  -                break;
  -            case Types.FLOAT:
  -                Float f = null;
  -
  -                if (value instanceof Float) {
  -                    f = (Float) value;
  -                } else {
  -                    f = new Float((String) value);
  -                }
  -
  -                statement.setFloat(position, f.floatValue());
  -                break;
  -            case Types.NUMERIC:
  -                Long l = null;
  -
  -                if (value instanceof Long) {
  -                    l = (Long) value;
  -                } else {
  -                    l = new Long((String) value);
  -                }
  -
  -                statement.setLong(position, l.longValue());
  -                break;
  -            case Types.SMALLINT:
  -                Short s = null;
  -
  -                if (value instanceof Short) {
  -                    s = (Short) value;
  -                } else {
  -                    s = new Short((String) value);
  -                }
  -
  -                statement.setShort(position, s.shortValue());
  -                break;
  -            case Types.TIME:
  -                Time t = null;
  -
  -                if (value instanceof Time) {
  -                    t = (Time) value;
  -                }
  -
  -                statement.setTime(position, t);
  -                break;
  -            case Types.TIMESTAMP:
  -                Timestamp ts = null;
  -
  -                if (value instanceof Time) {
  -                    ts = (Timestamp) value;
  -                }
  -
  -                statement.setTimestamp(position, ts);
  -                break;
  -            case Types.ARRAY:
  -                statement.setArray(position, (Array) value); // no way to convert string to array
  -                break;
  -            case Types.STRUCT:
  -            case Types.OTHER:
  -                statement.setObject(position, value);
  -                break;
  -            case Types.LONGVARBINARY:
  -                statement.setTimestamp(position, new Timestamp((new java.util.Date()).getTime()));
  -            case Types.VARCHAR:
  -                statement.setString(position, (String) value);
  -                break;
  -            case Types.BLOB:
  -                if (value instanceof JDBCxlobHelper) {
  -                    statement.setBinaryStream(position, ((JDBCxlobHelper)value).inputStream, ((JDBCxlobHelper)value).length);
  -                } else if (value instanceof Source){
  -                    statement.setBinaryStream(position, ((Source)value).getInputStream(), (int)((Source)value).getContentLength());
  -                } else {
  -                    if (value instanceof File) {
  -                        file = (File)value;
  -                    } else if (value instanceof String) {
  -                        file = new File((String)value);
  -                    } else {
  -                        throw new SQLException("Invalid type for blob: "+value.getClass().getName());
  -                    }
  -                    //InputStream input = new BufferedInputStream(new FileInputStream(file));
  -                    FileInputStream input = new FileInputStream(file);
  -                    statement.setBinaryStream(position, input, (int)file.length());
  -                }
  -                break;
  -            case Types.INTEGER:
  -                Integer i = null;
  -                if (value instanceof Integer) {
  -                    i = (Integer) value;
  -                } else if (value instanceof java.lang.Number) {
  -                    i = new Integer(((java.lang.Number) value).intValue());
  +        case Types.CLOB:
  +            //System.out.println("CLOB");
  +            Clob clob = null;
  +            if (value instanceof Clob) {
  +                clob = (Clob) value;
  +            } else if (value instanceof File) {
  +                File asciiFile = (File) value;
  +                asciiStream = new BufferedInputStream(new FileInputStream(asciiFile));
  +                length = (int) asciiFile.length();
  +                clob = new ClobHelper(asciiStream, length);
  +            } else if (value instanceof JDBCxlobHelper) {
  +                asciiStream = ((JDBCxlobHelper) value).inputStream;
  +                length = ((JDBCxlobHelper) value).length;
  +                clob = new ClobHelper(asciiStream, length);
  +            } else if (value instanceof Source) {
  +                asciiStream = ((Source) value).getInputStream();
  +                length = (int)((Source) value).getContentLength();
  +                clob = new ClobHelper(asciiStream, length);
  +            } else {
  +                String asciiText = (String) value;
  +                asciiStream = new ByteArrayInputStream(asciiText.getBytes());
  +                length = asciiText.length();
  +                clob = new ClobHelper(asciiStream, length);
  +            }
  +            
  +            statement.setClob(position, clob);
  +            break;
  +        case Types.CHAR:
  +            // simple large object, e.g. Informix's TEXT
  +            //System.out.println("CHAR");
  +            
  +            if (value instanceof File) {
  +                File asciiFile = (File) value;
  +                asciiStream = new BufferedInputStream(new FileInputStream(asciiFile));
  +                length = (int) asciiFile.length();
  +            } else if (value instanceof JDBCxlobHelper) {
  +                asciiStream = ((JDBCxlobHelper) value).inputStream;
  +                length = ((JDBCxlobHelper) value).length;
  +            } else if (value instanceof Source) {
  +                asciiStream = ((Source) value).getInputStream();
  +                length = (int)((Source) value).getContentLength();
  +            } else {
  +                String asciiText = (String) value;
  +                asciiStream = new BufferedInputStream(new ByteArrayInputStream(asciiText.getBytes()));
  +                length = asciiText.length();
  +            }
  +            
  +            statement.setAsciiStream(position, asciiStream, length);
  +            break;
  +        case Types.BIGINT:
  +            //System.out.println("BIGINT");
  +            BigDecimal bd = null;
  +            
  +            if (value instanceof BigDecimal) {
  +                bd = (BigDecimal) value;
  +            } else if (value instanceof Number) {
  +                bd = BigDecimal.valueOf(((Number)value).longValue());
  +            } else {
  +                bd = new BigDecimal((String) value);
  +            }
  +            
  +            statement.setBigDecimal(position, bd);
  +            break;
  +        case Types.TINYINT:
  +            //System.out.println("TINYINT");
  +            Byte b = null;
  +            
  +            if (value instanceof Byte) {
  +                b = (Byte) value;
  +            } else if (value instanceof Number) {
  +                b = new Byte(((Number) value).byteValue());
  +            } else {
  +                b = new Byte((String) value);
  +            }
  +            
  +            statement.setByte(position, b.byteValue());
  +            break;
  +        case Types.DATE:
  +            //System.out.println("DATE");
  +            Date d = null;
  +            
  +            if (value instanceof Date) {
  +                d = (Date) value;
  +            } else if (value instanceof java.util.Date) {
  +                d = new Date(((java.util.Date) value).getTime());
  +            } else if (value instanceof Calendar) {
  +                d = new Date(((Calendar) value).getTime().getTime());
  +            }
  +            
  +            statement.setDate(position, d);
  +            break;
  +        case Types.DOUBLE:
  +            //System.out.println("DOUBLE");
  +            double db;
  +            
  +            if (value instanceof Number) {
  +                db = (((Number) value).doubleValue());
  +            } else {
  +                db = Double.parseDouble(String.valueOf(value));
  +            }
  +            statement.setDouble(position, db);
  +            break;
  +        case Types.FLOAT:
  +            //System.out.println("FLOAT");
  +            float f;
  +            
  +            if (value instanceof Number) {
  +                f = (((Number) value).floatValue());
  +            } else {
  +                f = Float.parseFloat(String.valueOf(value));
  +            }
  +            statement.setFloat(position, f);
  +            break;
  +        case Types.NUMERIC:
  +            //System.out.println("NUMERIC");
  +            long l;
  +            
  +            if (value instanceof Number) {
  +                l = (((Number) value).longValue());
  +            } else {
  +                l = Long.parseLong(String.valueOf(value));
  +            }
  +            
  +            statement.setLong(position, l);
  +            break;
  +        case Types.SMALLINT:
  +            //System.out.println("SMALLINT");
  +            Short s = null;
  +            
  +            if (value instanceof Short) {
  +                s = (Short) value;
  +            } else if (value instanceof Number) {
  +                s = new Short(((Number) value).shortValue());
  +            } else {
  +                s = new Short((String) value);
  +            }
  +            
  +            statement.setShort(position, s.shortValue());
  +            break;
  +        case Types.TIME:
  +            //System.out.println("TIME");
  +            Time t = null;
  +            
  +            if (value instanceof Time) {
  +                t = (Time) value;
  +            } else if (value instanceof java.util.Date){
  +                t = new Time(((java.util.Date) value).getTime());
  +            } else {
  +                t = Time.valueOf(value.toString());
  +            }
  +            
  +            statement.setTime(position, t);
  +            break;
  +        case Types.TIMESTAMP:
  +            //System.out.println("TIMESTAMP");
  +            Timestamp ts = null;
  +            
  +            if (value instanceof Time) {
  +                ts = (Timestamp) value;
  +            } else if (value instanceof java.util.Date) {
  +                ts = new Timestamp(((java.util.Date) value).getTime());
  +            } else {
  +                ts = Timestamp.valueOf(value.toString());
  +            }
  +            
  +            statement.setTimestamp(position, ts);
  +            break;
  +        case Types.ARRAY:
  +            //System.out.println("ARRAY");
  +            statement.setArray(position, (Array) value); // no way to convert string to array
  +            break;
  +        case Types.STRUCT:
  +            //System.out.println("STRUCT");
  +        case Types.OTHER:
  +            //System.out.println("OTHER");
  +            statement.setObject(position, value);
  +            break;
  +        case Types.LONGVARBINARY:
  +            //System.out.println("LONGVARBINARY");
  +            statement.setTimestamp(position, new Timestamp((new java.util.Date()).getTime()));
  +            break;
  +        case Types.VARCHAR:
  +            //System.out.println("VARCHAR");
  +            statement.setString(position, (String) value);
  +            break;
  +        case Types.BLOB:
  +            //System.out.println("BLOB");
  +            if (value instanceof JDBCxlobHelper) {
  +                statement.setBinaryStream(position, ((JDBCxlobHelper)value).inputStream, ((JDBCxlobHelper)value).length);
  +            } else if (value instanceof Source){
  +                statement.setBinaryStream(position, ((Source)value).getInputStream(), (int)((Source)value).getContentLength());
  +            } else {
  +                Blob blob = null;
  +                if (value instanceof Blob) {
  +                    blob = (Blob) value;
  +                } else if( value instanceof File) {
  +                    file = (File)value;
  +                    blob = new BlobHelper(new FileInputStream(file), (int) file.length());
  +                } else if (value instanceof String) {
  +                    file = new File((String)value);
  +                    blob = new BlobHelper(new FileInputStream(file), (int) file.length());
                   } else {
  -                    i = new Integer(value.toString());
  +                    throw new SQLException("Invalid type for blob: "+value.getClass().getName());
                   }
  -                statement.setInt(position, i.intValue());
  -                break;
  -            case Types.BIT:
  -                Boolean bo = null;
  -                if (value instanceof Boolean) {
  -                    bo = (Boolean) value;
  -                } else if (value instanceof java.lang.Number) {
  -                    bo = new Boolean(((java.lang.Number) value).intValue()==1);
  +                //InputStream input = new BufferedInputStream(new FileInputStream(file));
  +                statement.setBlob(position, blob);
  +            }
  +            break;
  +        case Types.VARBINARY:
  +            //System.out.println("VARBINARY");
  +            if (value instanceof JDBCxlobHelper) {
  +                statement.setBinaryStream(position, ((JDBCxlobHelper)value).inputStream, ((JDBCxlobHelper)value).length);
  +            } else if (value instanceof Source){
  +                statement.setBinaryStream(position, ((Source)value).getInputStream(), (int)((Source)value).getContentLength());
  +            } else {
  +                if (value instanceof File) {
  +                    file = (File)value;
  +                } else if (value instanceof String) {
  +                    file = new File((String)value);
                   } else {
  -                    bo = new Boolean(value.toString());
  +                    throw new SQLException("Invalid type for blob: "+value.getClass().getName());
                   }
  -                statement.setBoolean(position, bo.booleanValue());
  -                break;
  -                    
  -            default:
  -                throw new SQLException("Impossible exception - invalid type ");
  +                //InputStream input = new BufferedInputStream(new FileInputStream(file));
  +                FileInputStream input = new FileInputStream(file);
  +                statement.setBinaryStream(position, input, (int)file.length());
  +            }
  +            break;
  +        case Types.INTEGER:
  +            //System.out.println("INTEGER");
  +            Integer i = null;
  +            if (value instanceof Integer) {
  +                i = (Integer) value;
  +            } else if (value instanceof java.lang.Number) {
  +                i = new Integer(((java.lang.Number) value).intValue());
  +            } else {
  +                i = new Integer(value.toString());
  +            }
  +            statement.setInt(position, i.intValue());
  +            break;
  +        case Types.BIT:
  +            //System.out.println("BIT");
  +            Boolean bo = null;
  +            if (value instanceof Boolean) {
  +                bo = (Boolean) value;
  +            } else if (value instanceof java.lang.Number) {
  +                bo = new Boolean(((java.lang.Number) value).intValue()==1);
  +            } else {
  +                bo = new Boolean(value.toString());
  +            }
  +            statement.setBoolean(position, bo.booleanValue());
  +            break;
  +            
  +        default:
  +            //System.out.println("default");
  +            throw new SQLException("Impossible exception - invalid type ");
           }
  +        //System.out.println("========================================================================");
       }
  -
  -
  +    
  +    
   }
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.1.2.1   +144 -0    xml-cocoon2/src/java/org/apache/cocoon/util/Attic/BlobHelper.java
  
  
  
  
  1.1.2.1   +160 -0    xml-cocoon2/src/java/org/apache/cocoon/util/Attic/ClobHelper.java
  
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.1.2.2   +197 -43   xml-cocoon2/src/java/org/apache/cocoon/transformation/SimpleFormTransformer.java
  
  Index: SimpleFormTransformer.java
  ===================================================================
  RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/transformation/SimpleFormTransformer.java,v
  retrieving revision 1.1.2.1
  retrieving revision 1.1.2.2
  diff -u -r1.1.2.1 -r1.1.2.2
  --- SimpleFormTransformer.java	11 Aug 2002 20:16:08 -0000	1.1.2.1
  +++ SimpleFormTransformer.java	17 Nov 2002 19:13:53 -0000	1.1.2.2
  @@ -52,17 +52,20 @@
   
   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.component.Composable;
   import org.apache.avalon.framework.parameters.Parameters;
   import org.apache.avalon.framework.configuration.Configurable;
   import org.apache.avalon.framework.configuration.Configuration;
   import org.apache.avalon.framework.configuration.ConfigurationException;
  +import org.apache.avalon.framework.thread.ThreadSafe;
   
   import org.apache.avalon.excalibur.pool.Recyclable;
   
   import org.apache.cocoon.ProcessingException;
   import org.apache.cocoon.acting.ValidatorActionResult;
   import org.apache.cocoon.components.language.markup.xsp.XSPFormValidatorHelper;
  +import org.apache.cocoon.components.modules.input.InputModule;
   import org.apache.cocoon.environment.ObjectModelHelper;
   import org.apache.cocoon.environment.Request;
   import org.apache.cocoon.environment.SourceResolver;
  @@ -81,9 +84,9 @@
    * Select options need a value attribute to work correctly.
    *
    * <p>This transformer fills all HTML 4 form elements with values from
  - * parameters of the request object with the same name. It handles
  - * select boxes, textareas, checkboxes, radio buttons, password and
  - * text fields, and buttons.</p>
  + * an InputModule, e.g. request, with the same name. It handles select
  + * boxes, textareas, checkboxes, radio buttons, password and text
  + * fields, and buttons.</p>
    *
    * <p>In addition, it handles FormValidatorAction results by
    * selectively omitting &lt;error/&gt; elements. These elements need a
  @@ -107,6 +110,22 @@
    *   &lt;map:transform type="simple-form"/&gt;
    * </pre></p>
    *
  + * <p>Configuration elements:
  + * <table>
  + *   <tr><td>input-module</td><td>(String) InputModule configuration, 
  + *           defaults to an empty configuration and the "request-param" module</td></tr>
  + * </table>
  + * </p>
  + *
  + * <p>Sitemap parameters:
  + * <table>
  + *   <tr><td>fixed</td><td>(boolean) Do not change values</td></tr>
  + *   <tr><td>prefix</td><td>(String) Added to the input element's name</td></tr>
  + *   <tr><td>postfix</td><td>(String) Added to the input element's name</td></tr>
  + *   <tr><td>input</td><td>(String) InputModule name</td></tr>
  + * </table>
  + * </p>
  + *
    * <p>Example:<pre>
    *     &lt;input name="user.name" size="50" maxlength="60"/&gt;
    *     &lt;error name="user.name" when-ge="error"&gt;required&lt;/error&gt;
  @@ -143,6 +162,8 @@
       /** default input type as Integer (needed as default in org.apache.cocoon.util.HashMap.get()) */
       private static final Integer defaultType = new Integer(TYPE_DEFAULT);
       
  +    protected static final String INPUT_MODULE_ROLE = InputModule.ROLE;
  +    protected static final String INPUT_MODULE_SELECTOR = INPUT_MODULE_ROLE+"Selector";
   
       /** map element name string to symbolic name */
       private static final HashMap elementNames;
  @@ -197,11 +218,8 @@
       /** stack of ignored element names */
       protected Stack   stack = new Stack();
   
  -    /** name attribute of current select element */
  -    protected String selectName = null;
  -
       /** current element's request parameter values */
  -    protected String[] values = null;
  +    protected Object[] values = null;
       
       /** current request's validation results (all validated elements) */
       protected Map validationResults = null;
  @@ -215,8 +233,19 @@
       /** The Avalon ComponentManager for getting Components */
       protected ComponentManager   manager;
   
  -    /** Are we already initialized for the current request? */
  -    private boolean isInitialized;
  +    /** Should we skip inserting values? */
  +    private boolean fixed = false;
  +
  +    private String prefix = null;
  +    private String postfix = null; 
  +
  +    private String defaultInput = "request-param";
  +    private Configuration defaultInputConf = null;
  +    private Configuration inputConf = null;
  +    private InputModule input = null;
  +    private ComponentSelector inputSelector = null;
  +    private String inputName = null;
  +
   
       /** Empty attributes (for performance). This can be used
        *  do create own attributes, but make sure to clean them
  @@ -231,17 +260,24 @@
           this.parameters = null;
           this.stack.clear();
           this.ignoreCount = 0;
  -        this.selectName = null;
           this.values = null;
           this.validationResults = null;
  +
  +        if (this.inputSelector != null) {
  +            if (this.input != null)
  +                this.inputSelector.release(this.input);
  +            this.manager.release(this.inputSelector);
  +        }
       }
   
   
       /**
        * Avalon Configurable Interface
        */
  -    public void configure(Configuration configuration)
  +    public void configure(Configuration config)
       throws ConfigurationException {
  +        this.defaultInputConf = config.getChild("input-module");
  +        this.defaultInput = this.defaultInputConf.getAttribute("name",this.defaultInput);
       }
   
   
  @@ -265,8 +301,46 @@
               throw new ProcessingException("no request object");
           }
           this.parameters = par;
  -        this.isInitialized = false;
  +        this.fixed = par.getParameterAsBoolean("fixed",false);
  +        this.prefix = par.getParameter("prefix",null);
  +        this.postfix = par.getParameter("postfix",null);
  +        this.inputName = par.getParameter("input",null);
  +        this.inputConf = null;
           this.validationResults = XSPFormValidatorHelper.getResults(objectModel);
  +
  +        if (this.inputName == null) {
  +            this.inputName = this.defaultInput;
  +            this.inputConf = this.defaultInputConf;
  +        }
  +        
  +        try {
  +            // obtain input module
  +            this.inputSelector=(ComponentSelector) this.manager.lookup(INPUT_MODULE_SELECTOR); 
  +            if (this.inputName != null && 
  +                this.inputSelector != null && 
  +                this.inputSelector.hasComponent(this.inputName)
  +                ){
  +                this.input = (InputModule) this.inputSelector.select(this.inputName);
  +                if (!(this.input instanceof ThreadSafe && this.inputSelector instanceof ThreadSafe) ) {
  +                    this.inputSelector.release(this.input);
  +                    this.manager.release(this.inputSelector);
  +                    this.input = null;
  +                    this.inputSelector = null;
  +                }
  +            } else {
  +                if (this.inputName != null)
  +                    if (getLogger().isErrorEnabled())
  +                        getLogger().error("A problem occurred setting up '" + this.inputName 
  +                                          +"': Selector is "+(this.inputSelector!=null?"not ":"")
  +                                          +"null, Component is "
  +                                          +(this.inputSelector!=null&&this.inputSelector.hasComponent(this.inputName)?"known":"unknown"));
  +            }
  +        } catch (Exception e) {
  +            if (getLogger().isWarnEnabled()) 
  +                getLogger().warn("A problem occurred setting up '" + this.inputName + "': " + e.getMessage());
  +        }
  +        
  +
       }
   
       /**
  @@ -307,17 +381,22 @@
       /**
        * Handle input elements that may have a "checked" attributes,
        * i.e. checkbox and radio.
  -     * @param aName name of input element from "name" attribute.
        */
  -    protected void startCheckableElement(String uri, String name, String raw, AttributesImpl attributes, String aName)
  +    protected void startCheckableElement(String uri, String name, String raw, AttributesImpl attributes)
           throws SAXException {
   
  +        // @fixed and this.fixed already considered in startInputElement
           String checked = attributes.getValue("checked");
           String value = attributes.getValue("value");
  -        if (aName != null){
  -            boolean found = false;
  +        boolean found = false;
  +                
  +        if (getLogger().isDebugEnabled())
  +            getLogger().debug("startCheckableElement "+name+" attributes "+this.printAttributes(attributes));
  +        if (this.values != null) {
  +            if (getLogger().isDebugEnabled())
  +                getLogger().debug("replacing");
               for (int i=0; i<this.values.length; i++) {
  -                if (this.values[i].equals(String.valueOf(value))) {
  +                if (this.values[i].equals(value)) {
                       found = true;
                       if (checked == null) {
                           attributes.addAttribute("","checked","checked","CDATA","");
  @@ -336,22 +415,24 @@
       /**
        * Handle input elements that may don't have a "checked"
        * attributes, e.g. text, password, button.
  -     * @param aName name of input element from "name" attribute.
        */
  -    protected void startNonCheckableElement(String uri, String name, String raw, AttributesImpl attributes, String aName)
  +    protected void startNonCheckableElement(String uri, String name, String raw, AttributesImpl attributes)
           throws SAXException {
   
  +        // @fixed and this.fixed already considered in startInputElement
           String value = attributes.getValue("value");
  -        this.values = (aName != null ? this.request.getParameterValues(aName) : null);
  +        if (getLogger().isDebugEnabled())
  +            getLogger().debug("startNonCheckableElement "+name+" attributes "+this.printAttributes(attributes));
           if (this.values != null) {
  +            if (getLogger().isDebugEnabled())
  +                getLogger().debug("replacing");
               if (value != null) {
  -                attributes.setValue(attributes.getIndex("value"), this.values[0]);
  +                attributes.setValue(attributes.getIndex("value"), String.valueOf(this.values[0]));
               } else {
  -                attributes.addAttribute("", "value","value","CDATA",this.values[0]);
  +                attributes.addAttribute("", "value","value","CDATA",String.valueOf(this.values[0]));
               }
           }
           super.startElement(uri, name, raw, (Attributes)attributes);
  -        this.values = null;
       }
   
       /**
  @@ -365,11 +446,18 @@
           String aName = attr.getValue("name");
           String fixed = attr.getValue("fixed");
   
  -        this.values = request.getParameterValues(aName);
  -        if (aName == null || this.values == null || (fixed != null && parseBoolean(fixed))) {
  +        if (getLogger().isDebugEnabled())
  +            getLogger().debug("startInputElement "+name+" attributes "+this.printAttributes(attr));
  +        if (aName == null || this.fixed || (fixed != null && parseBoolean(fixed))) {
               super.startElement(uri, name, raw, attr);
   
           } else {
  +            if (getLogger().isDebugEnabled())
  +                getLogger().debug("replacing");
  +            
  +            if (this.prefix != null) aName = this.prefix + aName;
  +            if (this.postfix != null) aName = aName + this.postfix;
  +            this.values = this.getValues(aName);
           
               AttributesImpl attributes = null;
               if (attr instanceof AttributesImpl) {
  @@ -381,11 +469,11 @@
               switch (((Integer)inputTypes.get(type,defaultType)).intValue()) {
               case TYPE_CHECKBOX:
               case TYPE_RADIO:
  -                this.startCheckableElement(uri, name, raw, attributes, aName);
  +                this.startCheckableElement(uri, name, raw, attributes);
                   break;
                   
               case TYPE_DEFAULT:
  -                this.startNonCheckableElement(uri, name, raw, attributes, aName);
  +                this.startNonCheckableElement(uri, name, raw, attributes);
                   break;
               }
               this.values=null;
  @@ -400,13 +488,17 @@
       protected void startSelectElement(String uri, String name, String raw, Attributes attr)
           throws SAXException {
   
  -        // this.selectName = @name
           // this.values = request.getParameterValues(@name)
           String aName = attr.getValue("name");
           String fixed = attr.getValue("fixed");
  -        this.selectName = attr.getValue("name");
  -        if (aName != null && (this.selectName != null || (fixed != null && parseBoolean(fixed))))
  -            this.values = this.request.getParameterValues(this.selectName);
  +        this.values = null;
  +        if (getLogger().isDebugEnabled())
  +            getLogger().debug("startSelectElement "+name+" attributes "+this.printAttributes(attr));
  +        if (aName != null && !(this.fixed || (fixed != null && parseBoolean(fixed)))) {
  +            if (this.prefix != null) aName = this.prefix + aName;
  +            if (this.postfix != null) aName = aName + this.postfix;
  +            this.values = this.getValues(aName);
  +        }
           super.startElement(uri, name, raw, attr);
       }
   
  @@ -421,9 +513,13 @@
           throws SAXException {
   
           // add @selected if @value in request.getParameterValues(@name)
  -        if (this.values == null) {
  +        if (getLogger().isDebugEnabled())
  +            getLogger().debug("startOptionElement "+name+" attributes "+this.printAttributes(attr));
  +        if (this.values == null || this.fixed) {
               super.startElement(uri, name, raw, attr);
           } else {
  +            if (getLogger().isDebugEnabled())
  +                getLogger().debug("replacing");
               AttributesImpl attributes = null;
               if (attr instanceof AttributesImpl) {
                   attributes = (AttributesImpl) attr;
  @@ -435,7 +531,7 @@
               boolean found = false;
               
               for (int i=0; i<this.values.length; i++) {
  -                if (this.values[i].equals(String.valueOf(value))) {
  +                if (this.values[i].equals(value)) {
                       found = true;
                       if (selected == null) {
                           attributes.addAttribute("","selected","selected","CDATA","");
  @@ -460,16 +556,24 @@
   
           String aName = attributes.getValue("name");
           String fixed = attributes.getValue("fixed");
  -        String[] value = null;
  -        if (aName != null) 
  -            value = this.request.getParameterValues(aName);
  -        if (value!=null || (fixed != null && (parseBoolean(fixed)))) {
  -            this.ignoreCount++;
  -            this.stack.push(name);
  +        Object[] value = null;
  +        if (getLogger().isDebugEnabled())
  +            getLogger().debug("startTextareaElement "+name+" attributes "+this.printAttributes(attributes));
  +        if (aName != null) {
  +            if (this.prefix != null) aName = this.prefix + aName;
  +            if (this.postfix != null) aName = aName + this.postfix;
  +            value = this.getValues(aName);
  +        }
  +        if (value == null || this.fixed || (fixed != null && parseBoolean(fixed))) {
               super.startElement(uri, name, raw, attributes);
  -            super.characters(value[0].toCharArray(), 0, value[0].length());
           } else {
  +            if (getLogger().isDebugEnabled())
  +                getLogger().debug("replacing");
  +            this.ignoreCount++;
  +            this.stack.push(name);
               super.startElement(uri, name, raw, attributes);
  +            String valString = String.valueOf(value[0]);
  +            super.characters(valString.toCharArray(), 0, valString.length());
           }
       }
   
  @@ -484,7 +588,9 @@
       protected void startErrorElement(String uri, String name, String raw, Attributes attr)
           throws SAXException {
           
  -        if (this.validationResults == null) {
  +        if (getLogger().isDebugEnabled())
  +            getLogger().debug("startErrorElement "+name+" attributes "+this.printAttributes(attr));
  +        if (this.validationResults == null || this.fixed) {
               this.ignoreCount++;
               this.stack.push(name);
           } else {
  @@ -492,6 +598,8 @@
               if (aName == null) {
                   super.startElement(uri, name, raw, attr);
               } else {
  +                if (this.prefix != null) aName = this.prefix + aName;
  +                if (this.postfix != null) aName = aName + this.postfix;
                   ValidatorActionResult validation = XSPFormValidatorHelper.getParamResult(this.objectModel, aName);
                   String when = attr.getValue("when");
                   String when_ge = attr.getValue("when-ge");
  @@ -593,7 +701,6 @@
                       super.endElement(uri, name, raw);
                       break;
                   case ELEMENT_SELECT:
  -                    this.selectName = null;
                       this.values = null;
                       super.endElement(uri, name, raw);
                       break;
  @@ -663,4 +770,51 @@
       private static  boolean parseBoolean(String aBoolean){
           return "true".equalsIgnoreCase(aBoolean);
       }
  +
  +    /**
  +     * Obtain values from the used InputModule.
  +     */
  +    private Object[] getValues(String name) {
  +        Object[] values = null;
  +        ComponentSelector iputSelector = null;
  +        InputModule iput = null;
  +        try {
  +            if (this.input != null) {
  +                // input module is thread safe
  +                // thus we still have a reference to it
  +                values = input.getAttributeValues(name,this.inputConf,objectModel);
  +                if (getLogger().isDebugEnabled())
  +                    getLogger().debug("cached module "+this.input+" attribute "+name+" returns "+values);
  +            } else {
  +                // input was not thread safe
  +                // so acquire it again
  +                iputSelector=(ComponentSelector) this.manager.lookup(INPUT_MODULE_SELECTOR); 
  +                if (this.inputName != null 
  +                    && iputSelector != null 
  +                    && iputSelector.hasComponent(this.inputName)) {
  +                    
  +                    iput = (InputModule) iputSelector.select(this.inputName);
  +                }
  +                if (iput != null) {
  +                    values = iput.getAttributeValues(name, this.inputConf, objectModel);
  +                }           
  +                if (getLogger().isDebugEnabled())
  +                    getLogger().debug("fresh module "+iput+" attribute "+name+" returns "+values);
  +            }
  +        } catch (Exception e) {
  +            if (getLogger().isWarnEnabled()) 
  +                getLogger().warn("A problem occurred acquiring a value from '" 
  +                                 + this.inputName + "' for '"+name+"': " + e.getMessage());
  +        } finally {
  +            // release components if necessary
  +            if (iputSelector != null) {
  +                if (iput != null)
  +                    iputSelector.release(iput);
  +                this.manager.release(iputSelector);
  +            }
  +        }
  +
  +        return values;
  +    }
  +
   }
  
  
  

----------------------------------------------------------------------
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