You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by vg...@apache.org on 2006/10/03 13:18:48 UTC

svn commit: r452425 - in /cocoon/branches/BRANCH_2_1_X: ./ src/blocks/databases/java/org/apache/cocoon/acting/ src/blocks/databases/java/org/apache/cocoon/components/language/markup/xsp/ src/blocks/databases/java/org/apache/cocoon/components/source/imp...

Author: vgritsenko
Date: Tue Oct  3 04:18:47 2006
New Revision: 452425

URL: http://svn.apache.org/viewvc?view=rev&rev=452425
Log:
cleanup

Modified:
    cocoon/branches/BRANCH_2_1_X/src/blocks/databases/java/org/apache/cocoon/acting/AbstractDatabaseAction.java
    cocoon/branches/BRANCH_2_1_X/src/blocks/databases/java/org/apache/cocoon/components/language/markup/xsp/EsqlHelper.java
    cocoon/branches/BRANCH_2_1_X/src/blocks/databases/java/org/apache/cocoon/components/source/impl/BlobSource.java
    cocoon/branches/BRANCH_2_1_X/src/blocks/databases/java/org/apache/cocoon/util/JDBCTypeConversions.java
    cocoon/branches/BRANCH_2_1_X/status.xml

Modified: cocoon/branches/BRANCH_2_1_X/src/blocks/databases/java/org/apache/cocoon/acting/AbstractDatabaseAction.java
URL: http://svn.apache.org/viewvc/cocoon/branches/BRANCH_2_1_X/src/blocks/databases/java/org/apache/cocoon/acting/AbstractDatabaseAction.java?view=diff&rev=452425&r1=452424&r2=452425
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/blocks/databases/java/org/apache/cocoon/acting/AbstractDatabaseAction.java (original)
+++ cocoon/branches/BRANCH_2_1_X/src/blocks/databases/java/org/apache/cocoon/acting/AbstractDatabaseAction.java Tue Oct  3 04:18:47 2006
@@ -5,9 +5,9 @@
  * The ASF licenses this file to You under the Apache License, Version 2.0
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -171,15 +171,19 @@
  * @author <a href="mailto:balld@apache.org">Donald Ball</a>
  * @version $Id$
  */
-public abstract class AbstractDatabaseAction extends AbstractComplementaryConfigurableAction implements Disposable {
+public abstract class AbstractDatabaseAction extends AbstractComplementaryConfigurableAction
+                                             implements Disposable {
+
     protected Map files = new HashMap();
     protected static final Map typeConstants;
     protected ServiceSelector dbselector;
 
     static {
-        /** Initialize the map of type names to jdbc column types.
-            Note that INTEGER, BLOB, and VARCHAR column types map to more than
-            one type name. **/
+        /*
+         * Initialize the map of type names to jdbc column types.
+         * 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("big-decimal", new Integer(Types.BIGINT));
@@ -218,6 +222,7 @@
         super.service(manager);
         this.dbselector = (ServiceSelector) manager.lookup(DataSourceComponent.ROLE + "Selector");
     }
+
     /**
      * Get the Datasource we need.
      */
@@ -250,13 +255,17 @@
         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;
+                if (dbClob != null) {
+                    int length = (int) dbClob.length();
+                    InputStream is = new BufferedInputStream(dbClob.getAsciiStream());
+                    try {
+                        byte[] buffer = new byte[length];
+                        length = is.read(buffer);
+                        value = new String(buffer, 0, length);
+                    } finally {
+                        is.close();
+                    }
+                }
                 break;
             case Types.BIGINT:
                 value = set.getBigDecimal(dbcol);
@@ -695,7 +704,7 @@
     }
 
     /**
-     * Build a separed list with the Values of a Configuration Array  
+     * Build a separed list with the Values of a Configuration Array
      * @param values - build the list from
      * @param separator - Put a separator between the values of the list
      * @return - an StringBuffer with the builded List
@@ -714,7 +723,7 @@
     }
 
     /**
-     * Build a separed list with the Values of a Configuration Array  
+     * Build a separed list with the Values of a Configuration Array
      * @param values - build the list from
      * @param begin - Initial index
      * @return - an StringBuffer with the builded List

Modified: cocoon/branches/BRANCH_2_1_X/src/blocks/databases/java/org/apache/cocoon/components/language/markup/xsp/EsqlHelper.java
URL: http://svn.apache.org/viewvc/cocoon/branches/BRANCH_2_1_X/src/blocks/databases/java/org/apache/cocoon/components/language/markup/xsp/EsqlHelper.java?view=diff&rev=452425&r1=452424&r2=452425
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/blocks/databases/java/org/apache/cocoon/components/language/markup/xsp/EsqlHelper.java (original)
+++ cocoon/branches/BRANCH_2_1_X/src/blocks/databases/java/org/apache/cocoon/components/language/markup/xsp/EsqlHelper.java Tue Oct  3 04:18:47 2006
@@ -5,9 +5,9 @@
  * The ASF licenses this file to You under the Apache License, Version 2.0
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -16,33 +16,140 @@
  */
 package org.apache.cocoon.components.language.markup.xsp;
 
-import org.apache.avalon.framework.CascadingRuntimeException;
-
-import java.io.BufferedInputStream;
-import java.io.BufferedReader;
-import java.io.Reader;
-import java.sql.CallableStatement;
-import java.sql.ResultSet;
+import java.io.IOException;
 import java.io.InputStream;
+import java.io.Reader;
+import java.lang.reflect.InvocationTargetException;
 import java.sql.Blob;
+import java.sql.CallableStatement;
 import java.sql.Clob;
+import java.sql.ResultSet;
+import java.sql.SQLException;
 import java.sql.Types;
 
+import org.apache.avalon.framework.CascadingRuntimeException;
+
 /**
  * This is a helper class to remove redundant code in
- * esql pages
+ * esql pages.
+ *
+ * Based on the orginal esql.xsl.
  *
- * based on the orginal esql.xsl
  * @author <a href="mailto:tcurdt@dff.st">Torsten Curdt</a>
  * @version CVS $Id$
  */
-
 public class EsqlHelper {
 
-    /** returns byte array from BLOB
-     */
-    public final static byte[] getBlob(ResultSet set, String column) throws RuntimeException {
+    private static void close(Object lob) {
+        if (lob == null) {
+            return;
+        }
+
+        // ORACLE 'temporary lob' problem patch start
+        Class clazz = lob.getClass();
+        String name = clazz.getName();
+        if (name.equals("oracle.sql.BLOB") || name.equals("oracle.sql.CLOB")) {
+            try {
+                if (clazz.getMethod("isTemporary", new Class[0]).invoke(lob, new Object[0]).equals(Boolean.TRUE)) {
+                    clazz.getMethod("freeTemporary", new Class[0]).invoke(lob, new Object[0]);
+                }
+            } catch (IllegalAccessException e) {
+                /* ignored */
+            } catch (InvocationTargetException e) {
+                /* ignored */
+            } catch (NoSuchMethodException e) {
+                /* ignored */
+            }
+        }
+    }
+
+    private static byte[] readBytes(Blob blob, byte[] defaultValue)
+    throws SQLException, IOException {
+        if (blob == null) {
+            return defaultValue;
+        }
+
+        InputStream is = null;
+        try {
+            int length = (int) blob.length();
+            if (length == 0) {
+                return defaultValue;
+            }
+
+            byte[] buffer = new byte[length];
+            is = blob.getBinaryStream();
+            is.read(buffer);
 
+            return buffer;
+        } finally {
+            try {
+                if (is != null) {
+                    is.close();
+                }
+            } catch (IOException e) { /* ignored */ }
+            close(blob);
+        }
+    }
+
+    private static String readAscii(Clob clob, String defaultValue)
+    throws SQLException, IOException {
+        if (clob == null) {
+            return defaultValue;
+        }
+
+        InputStream is = null;
+        try {
+            int length = (int) clob.length();
+            if (length == 0) {
+                return defaultValue;
+            }
+
+            byte[] buffer = new byte[length];
+            is = clob.getAsciiStream();
+            is.read(buffer);
+
+            return new String(buffer, 0, length);
+        } finally {
+            try {
+                if (is != null) {
+                    is.close();
+                }
+            } catch (IOException e) { /* ignored */ }
+            close(clob);
+        }
+    }
+
+    private static String read(Clob clob, String defaultValue)
+    throws SQLException, IOException {
+        if (clob == null) {
+            return defaultValue;
+        }
+
+        Reader r = null;
+        try {
+            int length = (int) clob.length();
+            if (length == 0) {
+                return defaultValue;
+            }
+
+            char[] buffer = new char[length];
+            r = clob.getCharacterStream();
+            r.read(buffer);
+
+            return new String(buffer, 0, length);
+        } finally {
+            try {
+                if (r != null) {
+                    r.close();
+                }
+            } catch (IOException e) { /* ignored */ }
+            close(clob);
+        }
+    }
+
+    /** returns byte array from BLOB */
+    public static byte[] getBlob(ResultSet set, String column)
+    throws RuntimeException {
         try {
             return EsqlHelper.getBlob(set, set.findColumn(column));
         } catch (Exception e) {
@@ -50,91 +157,51 @@
         }
     }
 
-    /** returns byte array from BLOB
-     */
-    public final static byte[] getBlob(ResultSet set, int column) throws java.lang.Exception {
-
-        InputStream reader = null;
-        byte[] buffer = null;
-        Blob dbBlob = null;
-
+    /** returns byte array from BLOB */
+    public static byte[] getBlob(ResultSet set, int column)
+    throws Exception {
         try {
             if (set.getMetaData().getColumnType(column) == java.sql.Types.BLOB) {
-                dbBlob = set.getBlob(column);
-                int length = (int) dbBlob.length();
-                reader = dbBlob.getBinaryStream();
-                buffer = new byte[length];
-                reader.read(buffer);
-                reader.close();
-                return buffer != null ? buffer : null;
+                return readBytes(set.getBlob(column), null);
             } else {
-                return set.getString(column).getBytes();
+                String value = set.getString(column);
+                if (value == null) {
+                    return null;
+                }
+                return value.getBytes();
             }
         } catch (Exception e) {
             throw new CascadingRuntimeException("Error getting blob data for column " + column, e);
-        } finally {
-            // ORACLE 'temporary lob' problem patch start
-            if (dbBlob != null && dbBlob.getClass().getName().equals("oracle.sql.BLOB")) {
-                if (dbBlob
-                    .getClass()
-                    .getMethod("isTemporary", new Class[0])
-                    .invoke(dbBlob, new Object[0])
-                    .equals(Boolean.TRUE))
-                    dbBlob.getClass().getMethod("freeTemporary", new Class[0]).invoke(
-                        dbBlob,
-                        new Object[0]);
-            }
         }
     }
 
-    /** returns byte array from BLOB
-     */
-    public final static byte[] getBlob(CallableStatement cs, int column, String defaultString)
-        throws java.lang.Exception {
-
-        InputStream reader = null;
-        byte[] buffer = null;
-        byte[] result = null;
-        Blob dbBlob = null;
-
-        try {
-            dbBlob = cs.getBlob(column);
-            int length = (int) dbBlob.length();
-            reader = dbBlob.getBinaryStream();
-            buffer = new byte[length];
-            reader.read(buffer);
-            reader.close();
-            if (buffer != null) {
-                result = buffer;
-            } else if (defaultString != null && !defaultString.equals("_null_")) {
-                result = defaultString.getBytes();
+    /** returns byte array from BLOB */
+    public static byte[] getBlob(CallableStatement cs, int column, String defaultString)
+    throws Exception {
+
+        byte[] defaultValue = null;
+        if (defaultString != null && !defaultString.equals("_null_")) {
+            defaultValue = defaultString.getBytes();
+        }
+
+        try {
+            if (cs.getMetaData().getColumnType(column) == java.sql.Types.BLOB) {
+                return readBytes(cs.getBlob(column), defaultValue);
             } else {
-                result = null;
+                String value = cs.getString(column);
+                if (value == null) {
+                    return defaultValue;
+                }
+                return value.getBytes();
             }
         } catch (Exception e) {
             throw new CascadingRuntimeException("Error getting blob data for column " + column, e);
-        } finally {
-            // ORACLE 'temporary lob' problem patch start
-            if (dbBlob != null && dbBlob.getClass().getName().equals("oracle.sql.BLOB")) {
-                if (dbBlob
-                    .getClass()
-                    .getMethod("isTemporary", new Class[0])
-                    .invoke(dbBlob, new Object[0])
-                    .equals(Boolean.TRUE)) {
-                    dbBlob.getClass().getMethod("freeTemporary", new Class[0]).invoke(
-                        dbBlob,
-                        new Object[0]);
-                }
-            }
         }
-        return result;
     }
 
-    /** returns Unicode encoded string from CLOB or String column 
-     */
-    public final static String getStringOrClob(ResultSet set, String column, String defaultString)
-        throws RuntimeException {
-
+    /** returns Unicode encoded string from CLOB or String column */
+    public static String getStringOrClob(ResultSet set, String column, String defaultString)
+    throws RuntimeException {
         try {
             return EsqlHelper.getStringOrClob(set, set.findColumn(column), defaultString);
         } catch (Exception e) {
@@ -142,117 +209,47 @@
         }
     }
 
-    /** returns Unicode encoded string from CLOB or String column 
-     */
-    public final static String getStringOrClob(ResultSet set, int column, String defaultString)
-        throws java.lang.Exception {
-
-        Reader reader = null;
-        char[] buffer = null;
-        String result = null;
-        Clob dbClob = null;
+    /** returns Unicode encoded string from CLOB or String column */
+    public static String getStringOrClob(ResultSet set, int column, String defaultString)
+    throws Exception {
+        if (defaultString != null && defaultString.equals("_null_")) {
+            defaultString = null;
+        }
 
         try {
             if (set.getMetaData().getColumnType(column) == java.sql.Types.CLOB) {
-                dbClob = set.getClob(column);
-                int length = (int) dbClob.length();
-                reader = new BufferedReader(dbClob.getCharacterStream());
-                buffer = new char[length];
-                reader.read(buffer);
-                if (buffer != null) {
-                    result = new String(buffer);
-                } else if (defaultString != null && !defaultString.equals("_null_")) {
-                    result = defaultString;
-                } else {
-                    result = null;
-                }
+                return read(set.getClob(column), defaultString);
             } else {
-                result = set.getString(column);
-                if (result == null && defaultString != null && !defaultString.equals("_null_"))
+                String result = set.getString(column);
+                if (result == null) {
                     result = defaultString;
+                }
+                return result;
             }
         } catch (Exception e) {
             throw new CascadingRuntimeException("Error getting text from column " + column, e);
-        } finally {
-            if (reader != null) {
-                reader.close();
-            }
-            // ORACLE 'temporary lob' problem patch start
-            if (dbClob != null && dbClob.getClass().getName().equals("oracle.sql.CLOB")) {
-                try {
-                    if (dbClob
-                        .getClass()
-                        .getMethod("isTemporary", new Class[0])
-                        .invoke(dbClob, new Object[0])
-                        .equals(Boolean.TRUE)) {
-                        dbClob.getClass().getMethod("freeTemporary", new Class[0]).invoke(
-                            dbClob,
-                            new Object[0]);
-                    }
-                } catch (Exception e1) {
-                    // swallow
-                }
-            }
         }
-        return result;
     }
 
-    /** returns Unicode encoded string from CLOB or String column 
-     */
-    public final static String getStringOrClob(
-        CallableStatement cs,
-        int column,
-        String defaultString)
-        throws java.lang.Exception {
-
-        Reader reader = null;
-        char[] buffer = null;
-        String result = null;
-        Clob dbClob = null;
-
-        try {
-            dbClob = cs.getClob(column);
-            int length = (int) dbClob.length();
-            reader = new BufferedReader(dbClob.getCharacterStream());
-            buffer = new char[length];
-            reader.read(buffer);
-            if (buffer != null) {
-                result = new String(buffer);
-            } else if (defaultString != null && !defaultString.equals("_null_")) {
-                result = defaultString;
-            } else {
-                result = null;
-            }
+    /** returns Unicode encoded string from CLOB or String column */
+    public static String getStringOrClob(CallableStatement cs,
+                                         int column,
+                                         String defaultString)
+    throws Exception {
+        if (defaultString != null && defaultString.equals("_null_")) {
+            defaultString = null;
+        }
+
+        try {
+            return read(cs.getClob(column), defaultString);
         } catch (Exception e) {
             throw new CascadingRuntimeException("Error getting text from column " + column, e);
-        } finally {
-            if (reader != null) {
-                reader.close();
-            }
-            // ORACLE 'temporary lob' problem patch start
-            if (dbClob != null && dbClob.getClass().getName().equals("oracle.sql.CLOB")) {
-                try {
-                    if (dbClob
-                        .getClass()
-                        .getMethod("isTemporary", new Class[0])
-                        .invoke(dbClob, new Object[0])
-                        .equals(Boolean.TRUE))
-                        dbClob.getClass().getMethod("freeTemporary", new Class[0]).invoke(
-                            dbClob,
-                            new Object[0]);
-                } catch (Exception e1) {
-                    // swallow
-                }
-            }
         }
-        return result;
     }
 
-    /** returns ascii string from CLOB or String column 
-     */
-    public final static String getAscii(ResultSet set, String column, String defaultString)
-        throws RuntimeException {
-
+    /** returns ascii string from CLOB or String column */
+    public static String getAscii(ResultSet set, String column, String defaultString)
+    throws RuntimeException {
         try {
             int colIndex = set.findColumn(column);
             return EsqlHelper.getAscii(set, colIndex, defaultString);
@@ -261,122 +258,39 @@
         }
     }
 
-    /** returns ascii string from CLOB or String column 
-     */
-    public final static String getAscii(ResultSet set, int column, String defaultString) {
-        InputStream asciiStream = null;
-        String result = null;
-        Clob dbClob = null;
+    /** returns ascii string from CLOB or String column */
+    public static String getAscii(ResultSet set, int column, String defaultString) {
+        if (defaultString != null && defaultString.equals("_null_")) {
+            defaultString = null;
+        }
 
         try {
             if (set.getMetaData().getColumnType(column) == Types.CLOB) {
-                byte[] buffer = null;
-                dbClob = set.getClob(column);
-                int length = (int) dbClob.length();
-                asciiStream = new BufferedInputStream(dbClob.getAsciiStream());
-                buffer = new byte[length];
-                asciiStream.read(buffer);
-                asciiStream.close();
-                if (buffer != null) {
-                    result = new String(buffer);
-                } else if (defaultString != null && !defaultString.equals("_null_")) {
-                    result = defaultString;
-                } else {
-                    result = null;
-                }
+                return readAscii(set.getClob(column), defaultString);
             } else {
-                result = set.getString(column);
-                if (result == null && defaultString != null && !defaultString.equals("_null_")) {
+                String result = set.getString(column);
+                if (result == null) {
                     result = defaultString;
                 }
+                return result;
             }
         } catch (Exception e) {
-            throw new CascadingRuntimeException(
-                "Error getting ascii data from column " + column, e);
-        } finally {
-            if (asciiStream != null) {
-                try {
-                    asciiStream.close();
-                } catch (Exception ase) {
-                    throw new CascadingRuntimeException("Error closing clob stream", ase);
-                }
-            }
-            // ORACLE 'temporary lob' problem patch start
-            if (dbClob != null && dbClob.getClass().getName().equals("oracle.sql.CLOB")) {
-                try {
-                    if (dbClob
-                        .getClass()
-                        .getMethod("isTemporary", new Class[0])
-                        .invoke(dbClob, new Object[0])
-                        .equals(Boolean.TRUE)) {
-                        dbClob.getClass().getMethod("freeTemporary", new Class[0]).invoke(
-                            dbClob,
-                            new Object[0]);
-                    }
-                } catch (Exception e1) {
-                    // swallow
-                }
-            }
+            throw new CascadingRuntimeException("Error getting ascii data from column " + column, e);
         }
-        return result;
     }
 
-    /** returns ascii string from CLOB or String column 
-     */
-    public final static String getAscii(CallableStatement cs, int column, String defaultString) {
-        InputStream asciiStream = null;
-        String result = null;
-        Clob dbClob = null;
-
-        try {
-            byte[] buffer = null;
-            dbClob = cs.getClob(column);
-            int length = (int) dbClob.length();
-            asciiStream = new BufferedInputStream(dbClob.getAsciiStream());
-            buffer = new byte[length];
-            asciiStream.read(buffer);
-            asciiStream.close();
-            if (buffer != null) {
-                result = new String(buffer);
-            } else if (defaultString != null && !defaultString.equals("_null_")) {
-                result = defaultString;
-            } else {
-                result = null;
-            }
+    /** returns ascii string from CLOB or String column */
+    public static String getAscii(CallableStatement cs, int column, String defaultString) {
+        try {
+            return readAscii(cs.getClob(column), defaultString);
         } catch (Exception e) {
             throw new CascadingRuntimeException("Error getting ascii data for column " + column, e);
-        } finally {
-            if (asciiStream != null) {
-                try {
-                    asciiStream.close();
-                } catch (Exception ase) {
-                    throw new CascadingRuntimeException("Error closing clob stream", ase);
-                }
-            }
-            // ORACLE 'temporary lob' problem patch start
-            if (dbClob != null && dbClob.getClass().getName().equals("oracle.sql.CLOB")) {
-                try {
-                    if (dbClob
-                        .getClass()
-                        .getMethod("isTemporary", new Class[0])
-                        .invoke(dbClob, new Object[0])
-                        .equals(Boolean.TRUE)) {
-                        dbClob.getClass().getMethod("freeTemporary", new Class[0]).invoke(
-                            dbClob,
-                            new Object[0]);
-                    }
-                } catch (Exception e1) {
-                    // swallow
-                }
-            }
         }
-        return result;
     }
 
-    public final static String getStringFromByteArray(
-        byte[] bytes,
-        String encoding,
-        String defaultString) {
+    public static String getStringFromByteArray(byte[] bytes,
+                                                String encoding,
+                                                String defaultString) {
         if (bytes != null) {
             try {
                 return new String(bytes, encoding);

Modified: cocoon/branches/BRANCH_2_1_X/src/blocks/databases/java/org/apache/cocoon/components/source/impl/BlobSource.java
URL: http://svn.apache.org/viewvc/cocoon/branches/BRANCH_2_1_X/src/blocks/databases/java/org/apache/cocoon/components/source/impl/BlobSource.java?view=diff&rev=452425&r1=452424&r2=452425
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/blocks/databases/java/org/apache/cocoon/components/source/impl/BlobSource.java (original)
+++ cocoon/branches/BRANCH_2_1_X/src/blocks/databases/java/org/apache/cocoon/components/source/impl/BlobSource.java Tue Oct  3 04:18:47 2006
@@ -5,9 +5,9 @@
  * The ASF licenses this file to You under the Apache License, Version 2.0
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -30,19 +30,18 @@
 import java.sql.Types;
 import java.util.Iterator;
 
+import org.apache.avalon.excalibur.datasource.DataSourceComponent;
 import org.apache.avalon.framework.logger.AbstractLogEnabled;
 import org.apache.avalon.framework.service.ServiceManager;
 import org.apache.avalon.framework.service.ServiceSelector;
 import org.apache.avalon.framework.service.Serviceable;
-
-import org.apache.avalon.excalibur.datasource.DataSourceComponent;
-
-import org.apache.cocoon.CascadingIOException;
-
 import org.apache.excalibur.source.Source;
 import org.apache.excalibur.source.SourceException;
+import org.apache.excalibur.source.SourceNotFoundException;
 import org.apache.excalibur.source.SourceValidity;
 
+import org.apache.cocoon.CascadingIOException;
+
 /**
  * A <code>Source</code> that takes its content in a single JDBC column. Any
  * kind of column can be used (clob, blob, varchar, etc), but "Blob" means
@@ -63,14 +62,16 @@
  * @author <a href="mailto:stephan@apache.org">Stephan Michels</a>
  * @version CVS $Id$
  */
-public class BlobSource extends AbstractLogEnabled implements Source, Serviceable {
+public class BlobSource extends AbstractLogEnabled
+                        implements Source, Serviceable {
+
+    private static final String URL_PREFIX = "blob:/";
+    private static final int URL_PREFIX_LEN = URL_PREFIX.length();
 
     /** The ServiceManager instance */
-    private ServiceManager manager = null;
+    private ServiceManager manager;
 
-    /**
-     * The system ID for this source
-     */
+    /** The system ID for this source */
     private String systemId;
 
     private String datasourceName;
@@ -81,23 +82,18 @@
 
     private String condition;
 
-    private final static String URL_PREFIX = "blob:/";
-    private final static int URL_PREFIX_LEN = URL_PREFIX.length();
-
     /**
      * Create a file source from a 'blob:' url and a component manager.
      * <p>The url is of the form "blob:/datasource/table/column[condition]
      */
     public BlobSource(String url) throws MalformedURLException {
-
         this.systemId = url;
 
         // Parse the url
         int start = URL_PREFIX_LEN;
-        int end;
 
         // Datasource
-        end = url.indexOf('/', start);
+        int end = url.indexOf('/', start);
         if (end == -1) {
             throw new MalformedURLException("Malformed blob source (cannot find datasource) : " + url);
         }
@@ -165,12 +161,11 @@
             );
         }
 
-        Connection cnx = null;
+        Connection conn = null;
         Statement stmt = null;
-
         try {
-            cnx = getConnection();
-            stmt = cnx.createStatement();
+            conn = getConnection();
+            stmt = conn.createStatement();
 
             StringBuffer selectBuf = new StringBuffer("SELECT ").append(this.columnName).
                 append(" FROM ").append(this.tableName);
@@ -185,42 +180,50 @@
             }
 
             ResultSet rs = stmt.executeQuery(select);
-            rs.next();
+            if (!rs.next()) {
+                throw new SourceNotFoundException("Source not found.");
+            }
 
             int colType = rs.getMetaData().getColumnType(1);
-
             switch(colType) {
                 case Types.BLOB :
                     Blob blob = rs.getBlob(1);
-                    return new JDBCInputStream(blob.getBinaryStream(), cnx);
-                //break;
+                    if (blob != null) {
+                        return new JDBCInputStream(blob.getBinaryStream(), conn);
+                    }
+                    break;
 
                 case Types.CLOB :
                     Clob clob = rs.getClob(1);
-                    return new JDBCInputStream(clob.getAsciiStream(), cnx);
-                //break;
+                    if (clob != null) {
+                        return new JDBCInputStream(clob.getAsciiStream(), conn);
+                    }
+                    break;
 
                 default :
                     String value = rs.getString(1);
-                    return new ByteArrayInputStream(value.getBytes());
+                    if (value != null) {
+                        return new ByteArrayInputStream(value.getBytes());
+                    }
             }
-        } catch(SQLException sqle) {
+
+            return new ByteArrayInputStream(new byte[0]);
+        } catch (SQLException e) {
             String msg = "Cannot retrieve content from " + this.systemId;
-            getLogger().error(msg, sqle);
-            // IOException would be more adequate, but ProcessingException is cascaded...
-            throw new SourceException(msg, sqle);
+            getLogger().error(msg, e);
+            // IOException would be more adequate, but SourceException is cascaded...
+            throw new SourceException(msg, e);
         } finally {
             try {
                 if (stmt != null) {
                     stmt.close();
                 }
-                if (cnx != null) {
-                    cnx.close();
+            } catch (SQLException e) { /* ignored */ }
+            try {
+                if (conn != null) {
+                    conn.close();
                 }
-            } catch(SQLException sqle2) {
-                // PITA
-                throw new SourceException("Cannot close connection", sqle2);
-            }
+            } catch (SQLException e) { /* ignored */ }
         }
     }
 
@@ -233,23 +236,23 @@
     public SourceValidity getValidity() {
         return null;
     }
-    
+
     /**
      * Refresh the content of this object after the underlying data
      * content has changed.
      */
     public void refresh() {
     }
-    
+
     /**
-     * 
+     *
      * @see org.apache.excalibur.source.Source#exists()
      */
     public boolean exists() {
         // FIXME
         return true;
     }
-    
+
     /**
      * The mime-type of the content described by this object.
      * If the source is not able to determine the mime-type by itself
@@ -258,7 +261,7 @@
     public String getMimeType() {
         return null;
     }
-    
+
     /**
      * Return the content length of the content or -1 if the length is
      * unknown
@@ -320,7 +323,7 @@
 
                 datasource = (DataSourceComponent)selector.select(this.datasourceName);
 
-            } catch(Exception e) {
+            } catch (Exception e) {
                 String msg = "Cannot get datasource '" + this.datasourceName + "'";
                 getLogger().error(msg);
                 throw new SourceException(msg, e);
@@ -328,7 +331,7 @@
 
             try {
                 return datasource.getConnection();
-            } catch(Exception e) {
+            } catch (Exception e) {
                 String msg = "Cannot get connection for datasource '" + this .datasourceName + "'";
                 getLogger().error(msg);
                 throw new SourceException(msg, e);
@@ -347,18 +350,18 @@
      */
     private class JDBCInputStream extends FilterInputStream {
 
-        Connection cnx;
+        private Connection cnx;
 
-        private final void closeCnx() throws IOException {
+        private void closeCnx() throws IOException {
             if (this.cnx != null) {
                 try {
-                    Connection tmp = cnx;
-                    cnx = null;
-                    tmp.close();
-                } catch(Exception e) {
+                    cnx.close();
+                } catch (Exception e) {
                     String msg = "Error closing the connection for " + BlobSource.this.getURI();
                     BlobSource.this.getLogger().warn(msg, e);
                     throw new CascadingIOException(msg + " : " + e.getMessage(), e);
+                } finally {
+                    cnx = null;
                 }
             }
         }
@@ -413,4 +416,3 @@
         }
     }
 }
-

Modified: cocoon/branches/BRANCH_2_1_X/src/blocks/databases/java/org/apache/cocoon/util/JDBCTypeConversions.java
URL: http://svn.apache.org/viewvc/cocoon/branches/BRANCH_2_1_X/src/blocks/databases/java/org/apache/cocoon/util/JDBCTypeConversions.java?view=diff&rev=452425&r1=452424&r2=452425
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/blocks/databases/java/org/apache/cocoon/util/JDBCTypeConversions.java (original)
+++ cocoon/branches/BRANCH_2_1_X/src/blocks/databases/java/org/apache/cocoon/util/JDBCTypeConversions.java Tue Oct  3 04:18:47 2006
@@ -5,9 +5,9 @@
  * The ASF licenses this file to You under the Apache License, Version 2.0
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -21,6 +21,7 @@
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.InputStream;
+import java.io.Reader;
 import java.math.BigDecimal;
 import java.sql.Array;
 import java.sql.Blob;
@@ -42,7 +43,6 @@
 import org.apache.commons.lang.BooleanUtils;
 import org.apache.excalibur.source.Source;
 
-
 /**
  * Provide some utility methods to read from JDBC result sets or store
  * them to JDBC statements. Largely copied from
@@ -146,30 +146,35 @@
         }
         return object;
     }
-                    
-      
 
     /**
      * Get the Statement column so that the results are mapped correctly.
      * (this has been copied from AbstractDatabaseAction and modified slightly)
      */
-    public static Object getColumn(ResultSet set, Configuration column ) throws Exception {
+    public static Object getColumn(ResultSet set, Configuration column)
+    throws Exception {
 
         Integer type = (Integer) JDBCTypeConversions.typeConstants.get(column.getAttribute("type"));
         String dbcol = column.getAttribute("name");
-        Object value = null;
+        Object value;
 
         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());
-            byte[] buffer = new byte[length];
-            asciiStream.read(buffer);
-            String str = new String(buffer);
-            asciiStream.close();
-            value = str;
+            if (dbClob != null) {
+                int length = (int) dbClob.length();
+                char[] buffer = new char[length];
+                Reader r = dbClob.getCharacterStream();
+                try {
+                    length = r.read(buffer);
+                    value = new String(buffer, 0, length);
+                } finally {
+                    r.close();
+                }
+            } else {
+                value = null;
+            }
             break;
         case Types.BIGINT:
             value = set.getBigDecimal(dbcol);
@@ -262,16 +267,16 @@
             }
         }
 
-        File file = null;
-        int length = -1;
-        InputStream asciiStream = null;
+        File file;
+        int length;
+        InputStream asciiStream;
 
         //System.out.println("========================================================================");
         //System.out.println("JDBCTypeConversions: setting type "+typeObject.intValue());
         switch (typeObject.intValue()) {
         case Types.CLOB:
             //System.out.println("CLOB");
-            Clob clob = null;
+            Clob clob;
             if (value instanceof Clob) {
                 clob = (Clob) value;
             } else if (value instanceof File) {
@@ -298,13 +303,13 @@
                 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));
@@ -325,13 +330,13 @@
                 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;
-            
+            BigDecimal bd;
+
             if (value instanceof BigDecimal) {
                 bd = (BigDecimal) value;
             } else if (value instanceof Number) {
@@ -339,13 +344,12 @@
             } else {
                 bd = new BigDecimal(value.toString());
             }
-            
+
             statement.setBigDecimal(position, bd);
             break;
         case Types.TINYINT:
             //System.out.println("TINYINT");
-            Byte b = null;
-            
+            Byte b;
             if (value instanceof Byte) {
                 b = (Byte) value;
             } else if (value instanceof Number) {
@@ -353,13 +357,12 @@
             } else {
                 b = new Byte(value.toString());
             }
-            
+
             statement.setByte(position, b.byteValue());
             break;
         case Types.DATE:
             //System.out.println("DATE");
-            Date d = null;
-            
+            Date d;
             if (value instanceof Date) {
                 d = (Date) value;
             } else if (value instanceof java.util.Date) {
@@ -369,13 +372,13 @@
             } else {
                 d = Date.valueOf(value.toString());
             }
-            
+
             statement.setDate(position, d);
             break;
         case Types.DOUBLE:
             //System.out.println("DOUBLE");
             double db;
-            
+
             if (value instanceof Number) {
                 db = (((Number) value).doubleValue());
             } else {
@@ -386,7 +389,7 @@
         case Types.FLOAT:
             //System.out.println("FLOAT");
             float f;
-            
+
             if (value instanceof Number) {
                 f = (((Number) value).floatValue());
             } else {
@@ -397,19 +400,18 @@
         case Types.NUMERIC:
             //System.out.println("NUMERIC");
             long l;
-            
+
             if (value instanceof Number) {
                 l = (((Number) value).longValue());
             } else {
                 l = Long.parseLong(value.toString());
             }
-            
+
             statement.setLong(position, l);
             break;
         case Types.SMALLINT:
             //System.out.println("SMALLINT");
-            Short s = null;
-            
+            Short s;
             if (value instanceof Short) {
                 s = (Short) value;
             } else if (value instanceof Number) {
@@ -417,13 +419,12 @@
             } else {
                 s = new Short(value.toString());
             }
-            
+
             statement.setShort(position, s.shortValue());
             break;
         case Types.TIME:
             //System.out.println("TIME");
-            Time t = null;
-            
+            Time t;
             if (value instanceof Time) {
                 t = (Time) value;
             } else if (value instanceof java.util.Date){
@@ -431,13 +432,12 @@
             } else {
                 t = Time.valueOf(value.toString());
             }
-            
+
             statement.setTime(position, t);
             break;
         case Types.TIMESTAMP:
             //System.out.println("TIMESTAMP");
-            Timestamp ts = null;
-            
+            Timestamp ts;
             if (value instanceof Time) {
                 ts = (Timestamp) value;
             } else if (value instanceof java.util.Date) {
@@ -445,7 +445,7 @@
             } else {
                 ts = Timestamp.valueOf(value.toString());
             }
-            
+
             statement.setTimestamp(position, ts);
             break;
         case Types.ARRAY:
@@ -473,7 +473,7 @@
             } else if (value instanceof Source){
                 statement.setBinaryStream(position, ((Source)value).getInputStream(), (int)((Source)value).getContentLength());
             } else {
-                Blob blob = null;
+                Blob blob;
                 if (value instanceof Blob) {
                     blob = (Blob) value;
                 } else if( value instanceof File) {
@@ -501,7 +501,7 @@
             } else if (value instanceof Part) {
                 statement.setBinaryStream(position, ((Part)value).getInputStream(), ((Part)value).getSize());
             } else {
-                if (value instanceof File) {           
+                if (value instanceof File) {
                    file = (File)value;
                } else if (value instanceof String) {
                    file = new File((String)value);
@@ -515,7 +515,7 @@
             break;
         case Types.INTEGER:
             //System.out.println("INTEGER");
-            Integer i = null;
+            Integer i;
             if (value instanceof Integer) {
                 i = (Integer) value;
             } else if (value instanceof Number) {
@@ -527,7 +527,7 @@
             break;
         case Types.BIT:
             //System.out.println("BIT");
-            Boolean bo = null;
+            Boolean bo;
             if (value instanceof Boolean) {
                 bo = (Boolean)value;
             } else if (value instanceof Number) {

Modified: cocoon/branches/BRANCH_2_1_X/status.xml
URL: http://svn.apache.org/viewvc/cocoon/branches/BRANCH_2_1_X/status.xml?view=diff&rev=452425&r1=452424&r2=452425
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/status.xml (original)
+++ cocoon/branches/BRANCH_2_1_X/status.xml Tue Oct  3 04:18:47 2006
@@ -184,6 +184,9 @@
   <release version="@version@" date="@date@">
 -->
   <release version="2.1.10" date="TBD">
+    <action dev="VG" type="fix" fixes-bug="COCOON-1462">
+      Databases: Check for null LOBs.
+    </action>
     <action dev="JH" type="fix" fixes-bug="COCOON-1866" due-to="Ellis Pritchard" due-to-email="ellis@nukinetics.com">
       JXTemplate: Fix an ArrrayIndexOutOfBoundsException with jx:comment.
     </action>