cocoon-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From anto...@apache.org
Subject svn commit: r464376 - in /cocoon/branches/BRANCH_2_1_X: src/blocks/databases/java/org/apache/cocoon/transformation/SQLTransformer.java status.xml
Date Mon, 16 Oct 2006 04:57:20 GMT
Author: antonio
Date: Sun Oct 15 21:57:17 2006
New Revision: 464376

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

<action dev="AG" type="fix" fixes-bug="COCOON-1894" due-to="Geurt Wisselink" due-to-email="gwk@home.nl">
  Databases: Added support for the SQL:XML tag in SQLTransformer.
</action>

Modified:
    cocoon/branches/BRANCH_2_1_X/src/blocks/databases/java/org/apache/cocoon/transformation/SQLTransformer.java
    cocoon/branches/BRANCH_2_1_X/status.xml

Modified: cocoon/branches/BRANCH_2_1_X/src/blocks/databases/java/org/apache/cocoon/transformation/SQLTransformer.java
URL: http://svn.apache.org/viewvc/cocoon/branches/BRANCH_2_1_X/src/blocks/databases/java/org/apache/cocoon/transformation/SQLTransformer.java?view=diff&rev=464376&r1=464375&r2=464376
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/blocks/databases/java/org/apache/cocoon/transformation/SQLTransformer.java
(original)
+++ cocoon/branches/BRANCH_2_1_X/src/blocks/databases/java/org/apache/cocoon/transformation/SQLTransformer.java
Sun Oct 15 21:57:17 2006
@@ -16,7 +16,6 @@
  */
 package org.apache.cocoon.transformation;
 
-import java.io.InputStream;
 import java.io.IOException;
 import java.io.Reader;
 import java.io.StringReader;
@@ -32,6 +31,7 @@
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
+import java.util.Properties;
 import java.util.TreeMap;
 import java.util.List;
 import java.util.ArrayList;
@@ -103,10 +103,10 @@
  * The following DTD is valid:
  * <code>
  * &lt;!ENTITY % param "(own-connection?,(use-connection|(dburl,username,password))?,show-nr-or-rows?,doc-element?,row-element?,namespace-uri?,namespace-prefix?,clob-encoding?)"&gt;<br>
- * &lt;!ELEMENT execute-query (query,(in-parameter|out-parameter)*,execute-query?, %param;)&gt;<br>
+ * &lt;!ELEMENT execute-query (query,(in-parameter|in-xml-parameter|out-parameter)*,execute-query?,
%param;)&gt;<br>
  * &lt;!ELEMENT own-connection (#PCDATA)&gt;<br>
  * &lt;!ELEMENT use-connection (#PCDATA)&gt;<br>
- * &lt;!ELEMENT query (#PCDATA | substitute-value | ancestor-value | escape-string)*&gt;<br>
+ * &lt;!ELEMENT query (#PCDATA | substitute-value | ancestor-value | escape-string| xml)*&gt;<br>
  * &lt;!ATTLIST query name CDATA #IMPLIED isstoredprocedure (true|false) "false" isupdate
(true|false) "false"&gt;<br>
  * &lt;!ELEMENT substitute-value EMPTY&gt;<br>
  * &lt;!ATTLIST substitute-value name CDATA #REQUIRED&gt;<br>
@@ -114,9 +114,12 @@
  * &lt;!ATTLIST ancestor-value name CDATA #REQUIRED level CDATA #REQUIRED&gt;<br>
  * &lt;!ELEMENT in-parameter EMPTY&gt;<br>
  * &lt;!ATTLIST in-parameter nr CDATA #REQUIRED type CDATA #REQUIRED&gt;<br>
+ * &lt;!ELEMENT in-xml-parameter EMPTY&gt;<br>
+ * &lt;!ATTLIST in-xml-parameter nr CDATA #REQUIRED type CDATA #REQUIRED&gt;<br>
  * &lt;!ELEMENT out-parameter EMPTY&gt;<br>
  * &lt;!ATTLIST out-parameter nr CDATA #REQUIRED name CDATA #REQUIRED type CDATA #REQUIRED&gt;<br>
  * &lt;!ELEMENT escape-string (#PCDATA)&gt;<br>
+ * &lt;!ELEMENT xml (#PCDATA)&gt;<br>
  * </code>
  * </p>
  *
@@ -133,16 +136,16 @@
  * </p>
  *
  * <p>
- * By default, CLOBs are read from the database using character stream, so that character
+ * By default, CLOBs are read from the database using getSubString, so that character
  * decoding is performed by the database. Using <code>clob-encoding</code> parameter,
  * this behavior can be overrided, so that data is read as byte stream and decoded using
  * specified character encoding.
  * </p>
  *
  * <p>
- * TODO: Support inserting of the XML data into the database without need to escape it.
- *       Can be implemented by introducing new &lt;sql:xml/&gt; tag to indicate that
- *       startSerializedXMLRecording(...) should be used.
+ * Inserting of XML data can be done by using the new sql:xml or SQL:in-xml-parameter tags.
+ * - sql:xml must be used like sql:escape-string
+ * - sql:in-xml-parameter must be used like sql:in-parameter.
  * </p>
  *
  * @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
@@ -169,6 +172,7 @@
     public static final String MAGIC_DBURL = "dburl";
     public static final String MAGIC_USERNAME = "username";
     public static final String MAGIC_PASSWORD = "password";
+    public static final String MAGIC_PROP = "prop";
     public static final String MAGIC_NR_OF_ROWS = "show-nr-of-rows";
     public static final String MAGIC_QUERY = "query";
     public static final String MAGIC_VALUE = "value";
@@ -183,6 +187,8 @@
     public static final String MAGIC_OUT_PARAMETER_NR_ATTRIBUTE = "nr";
     public static final String MAGIC_OUT_PARAMETER_TYPE_ATTRIBUTE = "type";
     public static final String MAGIC_ESCAPE_STRING = "escape-string";
+    public static final String MAGIC_XML = "xml";
+    public static final String MAGIC_IN_XML_PARAMETER = "in-xml-parameter";
     public static final String MAGIC_ERROR = "error";
 
     public static final String MAGIC_NS_URI_ELEMENT = "namespace-uri";
@@ -208,6 +214,8 @@
     protected static final int STATE_INSIDE_IN_PARAMETER_ELEMENT = 6;
     protected static final int STATE_INSIDE_OUT_PARAMETER_ELEMENT = 7;
     protected static final int STATE_INSIDE_ESCAPE_STRING = 8;
+    protected static final int STATE_INSIDE_XML = 9;
+    protected static final int STATE_INSIDE_IN_XML_PARAMETER_ELEMENT = 10;
 
     //
     // Configuration
@@ -586,6 +594,82 @@
         }
     }
 
+    /** &lt;xml&gt; */
+    protected void startXmlElement(Attributes attributes)
+    throws ProcessingException, SAXException {
+        switch (state) {
+            case SQLTransformer.STATE_INSIDE_QUERY_ELEMENT:
+                final String value = endTextRecording();
+                if (value.length() > 0) {
+                    query.addQueryPart(value);
+                }
+                startSerializedXMLRecording( null);
+
+                state = SQLTransformer.STATE_INSIDE_XML;
+                //this.getLogger().debug("startXmlElement: ");
+                break;
+
+            default:
+                throwIllegalStateException("Not expecting a start escape-string element");
+        }
+    }
+
+    /** &lt;/xml&gt; */
+    protected void endXmlElement()
+    throws ProcessingException, SAXException {
+        switch (state) {
+            case SQLTransformer.STATE_INSIDE_XML:
+                String value = endSerializedXMLRecording();
+               //this.getLogger().debug("endXmlElement: " + value);
+                if (value.length() > 0) {
+                    value = StringEscapeUtils.escapeSql(value);
+                    query.addQueryPart(value);
+                }
+                startTextRecording();
+                state = SQLTransformer.STATE_INSIDE_QUERY_ELEMENT;
+                break;
+
+            default:
+                throwIllegalStateException("Not expecting a end escape-string element");
+        }
+    }
+
+    /** &lt;xml&gt; */
+    protected void startInXmlParameterElement(Attributes attributes)
+    throws ProcessingException, SAXException {
+        switch (state) {
+            case SQLTransformer.STATE_INSIDE_EXECUTE_QUERY_ELEMENT:
+                String nr = getAttributeValue(attributes, SQLTransformer.MAGIC_IN_PARAMETER_NR_ATTRIBUTE);
+                this.stack.push(nr);
+                startSerializedXMLRecording( null);
+
+                state = SQLTransformer.STATE_INSIDE_IN_XML_PARAMETER_ELEMENT;
+                //this.getLogger().debug("startXmlElement: ");
+                break;
+
+            default:
+                throwIllegalStateException("Not expecting a start escape-string element");
+        }
+    }
+
+    /** &lt;/xml&gt; */
+    protected void endInXmlParameterElement()
+    throws ProcessingException, SAXException {
+        switch (state) {
+            case SQLTransformer.STATE_INSIDE_IN_XML_PARAMETER_ELEMENT:
+                String value = endSerializedXMLRecording();
+                //this.getLogger().debug("endXmlElement: "+value);
+                if (value.length() > 0) {
+                    int position = Integer.parseInt((String)this.stack.pop());
+                    query.setInXmlParameter(position, value);
+                }
+                state = SQLTransformer.STATE_INSIDE_EXECUTE_QUERY_ELEMENT;
+                break;
+
+            default:
+                throwIllegalStateException("Not expecting a end escape-string element");
+        }
+    }
     /** &lt;in-parameter&gt; */
     protected void startInParameterElement(Attributes attributes) {
         switch (state) {
@@ -656,6 +740,10 @@
             startOutParameterElement(attributes);
         } else if (name.equals(SQLTransformer.MAGIC_ESCAPE_STRING)) {
             startEscapeStringElement(attributes);
+        } else if (name.equals(SQLTransformer.MAGIC_XML)) {
+            startXmlElement(attributes);
+        } else if (name.equals(SQLTransformer.MAGIC_IN_XML_PARAMETER)) {
+           startInXmlParameterElement(attributes);
         } else {
             startValueElement(name);
         }
@@ -680,6 +768,10 @@
             endOutParameterElement();
         } else if (name.equals(SQLTransformer.MAGIC_ESCAPE_STRING)) {
             endEscapeStringElement();
+        } else if (name.equals(SQLTransformer.MAGIC_XML)) {
+            endXmlElement();
+        } else if (name.equals(SQLTransformer.MAGIC_IN_XML_PARAMETER)) {
+           endInXmlParameterElement();
         } else {
             endValueElement();
         }
@@ -835,17 +927,28 @@
             if (dburl != null) {
                 final String username = params.getParameter(SQLTransformer.MAGIC_USERNAME,
null);
                 final String password = params.getParameter(SQLTransformer.MAGIC_PASSWORD,
null);
+                final String prop = params.getParameter(SQLTransformer.MAGIC_PROP, null);
 
                 if (username == null || password == null) {
                     result = DriverManager.getConnection(dburl);
-                } else {
+                } else if (prop == null) {
                     result = DriverManager.getConnection(dburl, username, password);
-                }
+                } else {
+                    Properties props = new Properties();
+                    props.put("user", username );
+                    props.put("password", password);
+                    int proppos = prop.indexOf('=');
+                    if (proppos > 0) {
+                       String propname = prop.substring(0, proppos);
+                       String propvalue = prop.substring(proppos+1);
+                       props.put(propname, propvalue);
+                    }
+                    result = DriverManager.getConnection(dburl, props);
+               }
             } else {
                 // Nothing configured
             }
         }
-
         return result;
     }
 
@@ -941,6 +1044,9 @@
         /** Registered IN parameters */
         protected Map inParameters;
 
+        /** Registered IN XML parameters */
+        protected Map inXmlParameters;
+
         /** Registered OUT parameters */
         protected Map outParameters;
 
@@ -1030,6 +1136,13 @@
             inParameters.put(new Integer(pos), val);
         }
 
+        protected void setInXmlParameter(int pos, String val) {
+            if (inXmlParameters == null) {
+                inXmlParameters = new HashMap();
+            }
+            inXmlParameters.put(new Integer(pos), val);
+        }
+
         protected void setOutParameter(int pos, String type, String name) {
             if (outParameters == null) {
                 // make sure output parameters are ordered
@@ -1055,49 +1168,61 @@
         }
 
         private void registerInParameters() throws SQLException {
-            if (inParameters == null) {
-                return;
+            if (inParameters != null) {
+                Iterator i = inParameters.keySet().iterator();
+                while (i.hasNext()) {
+                    Integer counter = (Integer) i.next();
+                    String value = (String) inParameters.get(counter);
+                    try {
+                        pst.setObject(counter.intValue(), value);
+                    } catch (SQLException e) {
+                        getLogger().error("Caught a SQLException", e);
+                        throw e;
+                    }
+                }
             }
+        }
 
-            Iterator i = inParameters.keySet().iterator();
-            while (i.hasNext()) {
-                Integer counter = (Integer) i.next();
-                String value = (String) inParameters.get(counter);
-                try {
-                    pst.setObject(counter.intValue(), value);
-                } catch (SQLException e) {
-                    getLogger().error("Caught a SQLException", e);
-                    throw e;
+        private void registerInXmlParameters() throws SQLException {
+            if (inXmlParameters != null) {
+                Iterator i = inXmlParameters.keySet().iterator();
+                while (i.hasNext()) {
+                    Integer counter = (Integer) i.next();
+                    String value = (String) inXmlParameters.get(counter);
+                    try {
+                       pst.setString(counter.intValue(), value);
+                    } catch (SQLException e) {
+                        getLogger().error("Caught a SQLException", e);
+                        throw e;
+                    }
                 }
             }
         }
 
         private void registerOutParameters(CallableStatement cst) throws SQLException {
-            if (outParameters == null) {
-                return;
-            }
-
-            Iterator i = outParameters.keySet().iterator();
-            while (i.hasNext()) {
-                Integer counter = (Integer) i.next();
-                String type = (String) outParameters.get(counter);
-
-                int index = type.lastIndexOf(".");
-                String className, fieldName;
-                if (index == -1) {
-                    getLogger().error("Invalid SQLType: " + type, null);
-                    throw new SQLException("Invalid SQLType: " + type);
-                }
-                className = type.substring(0, index);
-                fieldName = type.substring(index + 1, type.length());
-
-                try {
-                    Class clss = Class.forName(className);
-                    Field fld = clss.getField(fieldName);
-                    cst.registerOutParameter(counter.intValue(), fld.getInt(fieldName));
-                } catch (Exception e) {
-                    // Lots of different exceptions to catch
-                    getLogger().error("Invalid SQLType: " + className + "." + fieldName,
e);
+            if (outParameters != null) {
+                Iterator i = outParameters.keySet().iterator();
+                while (i.hasNext()) {
+                    Integer counter = (Integer) i.next();
+                    String type = (String) outParameters.get(counter);
+    
+                    int index = type.lastIndexOf(".");
+                    String className, fieldName;
+                    if (index == -1) {
+                        getLogger().error("Invalid SQLType: " + type, null);
+                        throw new SQLException("Invalid SQLType: " + type);
+                    }
+                    className = type.substring(0, index);
+                    fieldName = type.substring(index + 1, type.length());
+    
+                    try {
+                        Class clss = Class.forName(className);
+                        Field fld = clss.getField(fieldName);
+                        cst.registerOutParameter(counter.intValue(), fld.getInt(fieldName));
+                    } catch (Exception e) {
+                        // Lots of different exceptions to catch
+                        getLogger().error("Invalid SQLType: " + className + "." + fieldName,
e);
+                    }
                 }
             }
         }
@@ -1280,6 +1405,7 @@
             }
 
             registerInParameters();
+            registerInXmlParameters();
             boolean result = pst.execute();
             if (result) {
                 rs = pst.getResultSet();
@@ -1533,14 +1659,21 @@
             if (object instanceof Clob && this.clobEncoding != null) {
                 Clob clob = (Clob) object;
                 StringBuffer buffer = new StringBuffer();
-                InputStream is = clob.getAsciiStream();
                 try {
-                    byte[] bytes = new byte[BUFFER_SIZE];
-                    int n;
-                    while ((n = is.read(bytes)) > -1) {
-                        buffer.append(new String(bytes, 0, n, this.clobEncoding));
-                    }
-                } catch (IOException e) {
+                   int blocksize = BUFFER_SIZE;
+                   long length = clob.length();
+                   long nMax = length / blocksize;
+                   for (int n = 0; n < nMax; n++) {
+                       String sText = clob.getSubString(n*blocksize+1, blocksize);
+                       buffer.append( sText);
+                   }
+                   //Read the last block
+                   int lastblocksize = (int)length%blocksize;
+                   if (lastblocksize > 0) {
+                       String sText = clob.getSubString(nMax*blocksize+1, lastblocksize);
+                       buffer.append( sText);
+                   }
+                } catch (Exception e) {
                     throw new SQLException("Error reading stream from CLOB");
                 }
                 return buffer.toString();

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=464376&r1=464375&r2=464376
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/status.xml (original)
+++ cocoon/branches/BRANCH_2_1_X/status.xml Sun Oct 15 21:57:17 2006
@@ -184,6 +184,9 @@
   <release version="@version@" date="@date@">
 -->
   <release version="2.1.10" date="TBD">
+    <action dev="AG" type="fix" fixes-bug="COCOON-1894" due-to="Geurt Wisselink" due-to-email="gwk@home.nl">
+      Databases: Added support for the SQL:XML tag in SQLTransformer.
+    </action>
     <action dev="JH" type="fix" fixes-bug="COCOON-1878">
       Validation: Replaced references to constant declarations in
       <code>javax.xml.XMLConstants</code>, which are not in the official API.



Mime
View raw message