Author: rr
Date: Fri Feb  5 13:09:39 2010
New Revision: 906927

URL: http://svn.apache.org/viewvc?rev=906927&view=rev
Log:
ODE-759: Unintended modifications of dateTime values while doing copy (fix + 
test)

Added:
    
ode/branches/APACHE_ODE_1.X/bpel-runtime/src/test/java/org/apache/ode/bpel/elang/xpath20/runtime/XsdTypesTest.java
   (with props)
Modified:
    
ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/elang/xpath20/runtime/JaxpVariableResolver.java
    
ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/elang/xquery10/runtime/XQuery10ExpressionRuntime.java
    
ode/branches/APACHE_ODE_1.X/bpel-test/src/test/resources/bpel/2.0/TestXQueryExpression/HelloXQueryWorld.bpel

Modified: 
ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/elang/xpath20/runtime/JaxpVariableResolver.java
URL: 
http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/elang/xpath20/runtime/JaxpVariableResolver.java?rev=906927&r1=906926&r2=906927&view=diff
==============================================================================
--- 
ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/elang/xpath20/runtime/JaxpVariableResolver.java
 (original)
+++ 
ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/elang/xpath20/runtime/JaxpVariableResolver.java
 Fri Feb  5 13:09:39 2010
@@ -25,6 +25,14 @@
 import javax.xml.xpath.XPathVariableResolver;
 
 import net.sf.saxon.Configuration;
+import net.sf.saxon.om.Item;
+import net.sf.saxon.type.AtomicType;
+import net.sf.saxon.type.SchemaType;
+import net.sf.saxon.type.ValidationException;
+import net.sf.saxon.value.AtomicValue;
+import net.sf.saxon.value.EmptySequence;
+import net.sf.saxon.value.StringValue;
+import net.sf.saxon.value.Value;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -36,6 +44,7 @@
 import org.apache.ode.bpel.o.OMessageVarType;
 import org.apache.ode.bpel.o.OScope;
 import org.apache.ode.bpel.o.OXsdTypeVarType;
+import org.apache.ode.utils.DOMUtils;
 import org.apache.ode.utils.Namespaces;
 import org.apache.ode.utils.xsd.XSTypes;
 import org.w3c.dom.Document;
@@ -61,7 +70,7 @@
     public Object resolveVariable(QName variableName) {
         __log.debug("Resolving variable " + variableName);
 
-        if(!(_oxpath instanceof OXPath10ExpressionBPEL20)){
+        if (!(_oxpath instanceof OXPath10ExpressionBPEL20)) {
             throw new IllegalStateException("XPath variables not supported for 
bpel 1.1");
         }
 
@@ -78,7 +87,7 @@
         }
 
         OXPath10ExpressionBPEL20 expr = _oxpath;
-        if(expr.isJoinExpression){
+        if (expr.isJoinExpression) {
             OLink olink = _oxpath.links.get(variableName.getLocalPart());
 
             try {
@@ -86,7 +95,7 @@
             } catch (FaultException e) {
                 throw new WrappedResolverException(e);
             }
-        }else{
+        } else {
             String varName;
             String partName;
             int dotloc = variableName.getLocalPart().indexOf('.');
@@ -98,58 +107,52 @@
                 partName = variableName.getLocalPart().substring(dotloc + 1);
             }
             OScope.Variable variable = _oxpath.vars.get(varName);
-            OMessageVarType.Part part = partName == null ? null : 
((OMessageVarType)variable.type).parts.get(partName);
+            OMessageVarType.Part part = partName == null ? null : 
((OMessageVarType) variable.type).parts.get(partName);
 
-            try{
+            try {
                 final Node variableNode = _ectx.readVariable(variable, part);
                 if (variableNode == null)
-                    throw new 
FaultException(variable.getOwner().constants.qnSelectionFailure,
-                            "Unknown variable " + variableName.getLocalPart());
+                    throw new 
FaultException(variable.getOwner().constants.qnSelectionFailure, "Unknown 
variable " + variableName.getLocalPart());
                 if (_ectx.narrowTypes()) {
-                    if (variable.type instanceof OXsdTypeVarType && 
((OXsdTypeVarType)variable.type).simple)
-                        return 
getSimpleContent(variableNode,((OXsdTypeVarType)variable.type).xsdType);
-                    if (part != null && part.type instanceof OXsdTypeVarType 
&& ((OXsdTypeVarType)part.type).simple)
-                        return 
getSimpleContent(variableNode,((OXsdTypeVarType)part.type).xsdType);
+                    if (variable.type instanceof OXsdTypeVarType && 
((OXsdTypeVarType) variable.type).simple)
+                        return getSimpleContent(variableNode, 
((OXsdTypeVarType) variable.type).xsdType);
+                    if (part != null && part.type instanceof OXsdTypeVarType 
&& ((OXsdTypeVarType) part.type).simple)
+                        return getSimpleContent(variableNode, 
((OXsdTypeVarType) part.type).xsdType);
                 }
 
                 // Saxon used to expect a node list, but now a regular node 
will suffice.
                 return variableNode;
-            }catch(FaultException e){
+            } catch (FaultException e) {
                 throw new WrappedResolverException(e);
             }
         }
     }
-    
-    private Object getSimpleContent(Node simpleNode, QName type) {
-        Document doc = (simpleNode instanceof Document) 
-               ? ((Document) simpleNode) 
-               : simpleNode.getOwnerDocument();
-        String text = simpleNode.getTextContent();
-        try {
-            Object jobj = XSTypes.toJavaObject(type,text);
-            if (jobj instanceof Calendar) {
-                // Saxon 9.x prefers Dates over Calendars.
-                return ((Calendar) jobj).getTime();
-            } else if (jobj instanceof String) {
-                // Saxon 9.x has a bug for which this is a workaround.
-                return doc.createTextNode(jobj.toString());
-            } 
-            return jobj;
-        } catch (Exception e) {
-               // Elegant way failed, trying brute force 
-               try {
-                   return Integer.valueOf(text);
-               } catch (NumberFormatException nfe) { }
-               try {
-                       return Double.valueOf(text);
-               } catch (NumberFormatException nfe) { }
-             
-               // Remember: always a node set
-               if (simpleNode.getParentNode() != null)
-                   return simpleNode.getParentNode().getChildNodes();
-               else {          
-                   return doc.createTextNode(text);
-               }
+
+    public static Value convertSimpleTypeToSaxon(QName type, String value, 
Configuration _config) {
+        int fp = _config.getNamePool().allocate("", type.getNamespaceURI(), 
type.getLocalPart());
+        SchemaType type2 = _config.getSchemaType(fp);
+        if (type2 == null || !type2.isAtomicType()) {
+            __log.warn("Can't find simple type " + type + " value " + value + 
" result: " + null);
+            return null;
+        } else {
+            try {
+                AtomicValue value2 = 
StringValue.convertStringToAtomicType(value, (AtomicType) type2, 
null).asAtomic();
+                if (__log.isDebugEnabled()) {
+                    __log.debug("converting " + type + " value " + value + " 
result: " + value2);
+                }
+                return value2;
+            } catch (ValidationException e) {
+                __log.debug("Can't convert " + value + " to " + type + " 
returning empty sequence");
+                return EmptySequence.getInstance();
+            }
         }
     }
+
+    public static Object getSimpleContent(Node simpleNode, QName type) {
+        Document doc = (simpleNode instanceof Document) ? ((Document) 
simpleNode) : simpleNode.getOwnerDocument();
+        String text = simpleNode.getTextContent();
+        Object o = convertSimpleTypeToSaxon(type, text, 
Configuration.makeConfiguration(null, null));
+        __log.debug("getSimpleContent for " + DOMUtils.domToString(simpleNode) 
+ " " + type + " returned " + o);
+        return o;
+    }
 }

Modified: 
ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/elang/xquery10/runtime/XQuery10ExpressionRuntime.java
URL: 
http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/elang/xquery10/runtime/XQuery10ExpressionRuntime.java?rev=906927&r1=906926&r2=906927&view=diff
==============================================================================
--- 
ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/elang/xquery10/runtime/XQuery10ExpressionRuntime.java
 (original)
+++ 
ode/branches/APACHE_ODE_1.X/bpel-runtime/src/main/java/org/apache/ode/bpel/elang/xquery10/runtime/XQuery10ExpressionRuntime.java
 Fri Feb  5 13:09:39 2010
@@ -363,34 +363,54 @@
                // Evaluate referenced variable
                 Object value = variableResolver.resolveVariable(variable);
                 
-                // Figure out type of variable
-                XQSequenceType xqType = getItemType(xqconn, value);
-                
-                // Saxon doesn't like binding sequences to variables
-                if (value instanceof Node) {
-                       // a node is a node-list, but the inverse isn't true.
-                       // so, if the value is truly a node, leave it alone.
-                } else if (value instanceof NodeList) {
-                    // So extract the first item from the node list
-                       NodeList nodeList = (NodeList) value;
-                       ArrayList nodeArray = new ArrayList();
-                       for (int i = 0; i < nodeList.getLength(); i++) {
-                               nodeArray.add(nodeList.item(i));
-                       }
-                       value = xqconn.createSequence(nodeArray.iterator());
-                }
-                
-                
-                // Bind value with external variable
-                if (value != null && xqType != null) {
-                       if (value instanceof XQSequence) {
-                               exp.bindSequence(variable, (XQSequence) value);
-                       } else {
-                               if (xqType instanceof XQItemType) {
-                                       exp.bindObject(variable, value, 
(XQItemType) xqType);
-                               }
-                       }
-                }
+                 if (value instanceof Value) {
+                     SaxonXQConnection saxonConn = (SaxonXQConnection) xqconn;
+                     try {
+                         Item item = ((Value) value).asItem();
+                         if (item == null) {
+                             exp.bindSequence(variable, 
xqconn.createSequence(Collections.EMPTY_LIST.iterator()));
+                         } else {
+                             XQItem item2 = new SaxonXQItem(item, saxonConn);
+                             exp.bindItem(variable, item2);
+                         }
+                     } catch (XPathException e) {
+                         __log.warn("", e);
+                     }
+                 } else {
+                     
+                     if (value instanceof Date) {
+                         Date d = (Date) value;
+                         value = 
org.apache.ode.utils.ISO8601DateParser.format(d);
+                     }
+ 
+                     // Figure out type of variable
+                     XQSequenceType xqType = getItemType(xqconn, value);
+ 
+                     // Saxon doesn't like binding sequences to variables
+                     if (value instanceof Node) {
+                         // a node is a node-list, but the inverse isn't true.
+                         // so, if the value is truly a node, leave it alone.
+                     } else if (value instanceof NodeList) {
+                         // So extract the first item from the node list
+                         NodeList nodeList = (NodeList) value;
+                         ArrayList nodeArray = new ArrayList();
+                         for (int i = 0; i < nodeList.getLength(); i++) {
+                             nodeArray.add(nodeList.item(i));
+                         }
+                         value = xqconn.createSequence(nodeArray.iterator());
+                     }
+ 
+                     // Bind value with external variable
+                     if (value != null && xqType != null) {
+                         if (value instanceof XQSequence) {
+                             exp.bindSequence(variable, (XQSequence) value);
+                         } else {
+                             if (xqType instanceof XQItemType) {
+                                 exp.bindObject(variable, value, (XQItemType) 
xqType);
+                             }
+                         }
+                     }
+                  }
             }
 
             // Set context node

Added: 
ode/branches/APACHE_ODE_1.X/bpel-runtime/src/test/java/org/apache/ode/bpel/elang/xpath20/runtime/XsdTypesTest.java
URL: 
http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/bpel-runtime/src/test/java/org/apache/ode/bpel/elang/xpath20/runtime/XsdTypesTest.java?rev=906927&view=auto
==============================================================================
--- 
ode/branches/APACHE_ODE_1.X/bpel-runtime/src/test/java/org/apache/ode/bpel/elang/xpath20/runtime/XsdTypesTest.java
 (added)
+++ 
ode/branches/APACHE_ODE_1.X/bpel-runtime/src/test/java/org/apache/ode/bpel/elang/xpath20/runtime/XsdTypesTest.java
 Fri Feb  5 13:09:39 2010
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  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.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.ode.bpel.elang.xpath20.runtime;
+
+import javax.xml.namespace.QName;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ode.utils.DOMUtils;
+
+import junit.framework.TestCase;
+
+public class XsdTypesTest extends TestCase {
+    private static Log __log = LogFactory.getLog(XsdTypesTest.class);
+    
+    public void testDateTime() throws Exception {
+        Object o = 
JaxpVariableResolver.getSimpleContent(DOMUtils.stringToDOM("<temporary-simple-type-wrapper>2010-01-25T15:38:54.82Z</temporary-simple-type-wrapper>"),
 QName.valueOf("{http://www.w3.org/2001/XMLSchema}dateTime";));
+        __log.debug(o);
+        assertTrue(o.toString().contains("2010-01-25T15:38:54.82Z"));
+    }
+
+    public void testEmptyDateTime() throws Exception {
+        Object o = 
JaxpVariableResolver.getSimpleContent(DOMUtils.stringToDOM("<temporary-simple-type-wrapper></temporary-simple-type-wrapper>"),
 QName.valueOf("{http://www.w3.org/2001/XMLSchema}dateTime";));
+        __log.debug(o);
+        assertTrue(o.toString().equals(""));
+    }
+    
+}

Propchange: 
ode/branches/APACHE_ODE_1.X/bpel-runtime/src/test/java/org/apache/ode/bpel/elang/xpath20/runtime/XsdTypesTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: 
ode/branches/APACHE_ODE_1.X/bpel-test/src/test/resources/bpel/2.0/TestXQueryExpression/HelloXQueryWorld.bpel
URL: 
http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/bpel-test/src/test/resources/bpel/2.0/TestXQueryExpression/HelloXQueryWorld.bpel?rev=906927&r1=906926&r2=906927&view=diff
==============================================================================
--- 
ode/branches/APACHE_ODE_1.X/bpel-test/src/test/resources/bpel/2.0/TestXQueryExpression/HelloXQueryWorld.bpel
 (original)
+++ 
ode/branches/APACHE_ODE_1.X/bpel-test/src/test/resources/bpel/2.0/TestXQueryExpression/HelloXQueryWorld.bpel
 Fri Feb  5 13:09:39 2010
@@ -46,6 +46,9 @@
         <variable name="stringVar" type="xsd:string"/>
         <variable name="boolVar" type="xsd:boolean"/>
         <variable name="i" type="xsd:int"/>
+        <variable name="myVar2" messageType="test:HelloXQueryMessage"/>
+        <variable name="date1" type="xsd:date"/>
+        <variable name="dateTime1" type="xsd:dateTime"/>
     </variables>
             
     <sequence>   
@@ -61,6 +64,43 @@
             operation="HelloXQuery"
             variable="myVar"
             createInstance="yes"/>
+            
+        <bpws:assign>
+          <copy>
+            <from>''</from>
+            <to variable="date1"/>
+          </copy>
+        </bpws:assign>
+        <if>
+            <condition>not(empty($date1))</condition>
+            <throw faultName="error"/>
+        </if>
+        
+        <bpws:assign>
+          <copy>
+            <from>'2009-01-01'</from>
+            <to variable="date1"/>
+          </copy>
+          <copy>
+            <from>'2009-01-02T12:32:32'</from>
+            <to variable="dateTime1"/>
+          </copy>
+          <copy>
+            <bpws:from 
expressionLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xquery1.0">
+                                      <![CDATA[
+                                      <test:test1 xmlns:test="http://test.org";>
+                                          <test:test2>{ if 
(string-length(xsd:string($date1)) != 0) then $date1 else $dateTime1 
}</test:test2>
+                                      </test:test1>
+                                      ]]>
+            </bpws:from>
+            <to variable="myVar2" part="TestPart"/>
+          </copy>
+        </bpws:assign>
+        <if>
+            <condition>not($myVar2.TestPart/*/text() eq 
'2009-01-01')</condition>
+            <throw faultName="error"/>
+        </if>
+        
         <assign name="assign1">
             <copy>
                 <from variable="myVar" part="TestPart"/>


Reply via email to