You are viewing a plain text version of this content. The canonical link for it is here.
Posted to axis-cvs@ws.apache.org by ds...@apache.org on 2006/12/19 03:29:15 UTC

svn commit: r488505 - in /webservices/axis2/branches/java/1_1: etc/ modules/jibx/src/org/apache/axis2/jibx/ modules/jibx/src/org/apache/axis2/jibx/template/

Author: dsosnoski
Date: Mon Dec 18 18:29:14 2006
New Revision: 488505

URL: http://svn.apache.org/viewvc?view=rev&rev=488505
Log:
JIRA-1855, JIRA-1856 fixes
Support header messages with JiBX binding
Fix namespace handling when using type definitions from binding

Modified:
    webservices/axis2/branches/java/1_1/etc/project.properties
    webservices/axis2/branches/java/1_1/modules/jibx/src/org/apache/axis2/jibx/CodeGenerationUtility.java
    webservices/axis2/branches/java/1_1/modules/jibx/src/org/apache/axis2/jibx/JiBXDataSource.java
    webservices/axis2/branches/java/1_1/modules/jibx/src/org/apache/axis2/jibx/template/JibXDatabindingTemplate.xsl

Modified: webservices/axis2/branches/java/1_1/etc/project.properties
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/java/1_1/etc/project.properties?view=diff&rev=488505&r1=488504&r2=488505
==============================================================================
--- webservices/axis2/branches/java/1_1/etc/project.properties (original)
+++ webservices/axis2/branches/java/1_1/etc/project.properties Mon Dec 18 18:29:14 2006
@@ -110,7 +110,7 @@
 jaxbri.version=2.0.2
 jaxen.version=1.1-beta-10
 jaxme.version=0.5.2
-jibx.version=1.1.2
+jibx.version=1.1.3
 junit.version=3.8.2
 maven.itest.plugin.version=1.0
 maven.jar.plugin.version=1.8-SNAPSHOT

Modified: webservices/axis2/branches/java/1_1/modules/jibx/src/org/apache/axis2/jibx/CodeGenerationUtility.java
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/java/1_1/modules/jibx/src/org/apache/axis2/jibx/CodeGenerationUtility.java?view=diff&rev=488505&r1=488504&r2=488505
==============================================================================
--- webservices/axis2/branches/java/1_1/modules/jibx/src/org/apache/axis2/jibx/CodeGenerationUtility.java (original)
+++ webservices/axis2/branches/java/1_1/modules/jibx/src/org/apache/axis2/jibx/CodeGenerationUtility.java Mon Dec 18 18:29:14 2006
@@ -21,6 +21,7 @@
 import java.io.FileNotFoundException;
 import java.net.MalformedURLException;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -36,6 +37,7 @@
 import org.apache.axis2.description.AxisMessage;
 import org.apache.axis2.description.AxisOperation;
 import org.apache.axis2.description.Parameter;
+import org.apache.axis2.wsdl.SOAPHeaderMessage;
 import org.apache.axis2.wsdl.WSDLConstants;
 import org.apache.axis2.wsdl.WSDLUtil;
 import org.apache.axis2.wsdl.codegen.CodeGenConfiguration;
@@ -61,6 +63,7 @@
 import org.jibx.runtime.JiBXException;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
+import org.w3c.dom.Node;
 
 /**
  * Framework-linked code used by JiBX data binding support. This is accessed via
@@ -293,9 +296,10 @@
             // collect all the top-level mapping and format definitions
             Map elementMap = new HashMap();
             Map complexTypeMap = new HashMap();
+            Map bindingMap = new HashMap();
             if (binding != null) {
                 collectTopLevelComponents(binding, null, elementMap,
-                    complexTypeMap, simpleTypeMap);
+                    complexTypeMap, simpleTypeMap, bindingMap);
             }
             
             // make sure classes will be generated for abstract mappings
@@ -305,7 +309,7 @@
             
             // force off inappropriate option (set by error in options handling)
             codeGenConfig.setPackClasses(false);
-
+            
             // configure handling for all operations of service
             codeGenConfig.setTypeMapper(new NamedParameterTypeMapper());
             Iterator operations = codeGenConfig.getAxisService().getOperations();
@@ -316,6 +320,8 @@
             Set objins = new HashSet();
             Set objouts = new HashSet();
             Set objfaults = new HashSet();
+            Map nsMap = new HashMap();
+            ArrayList wrappers = new ArrayList();
             while (operations.hasNext()) {
                 
                 // get the basic operation information
@@ -328,12 +334,24 @@
                     if (inmsg == null) {
                         throw new RuntimeException("Expected input message not found for operation " + op.getName());
                     }
+                    ArrayList headers = inmsg.getSoapHeaders();
+                    for (int i = 0; i < headers.size(); i++) {
+                        SOAPHeaderMessage header = (SOAPHeaderMessage)headers.get(i);
+                        mappedclass = mapMessage(header, elementMap);
+                        objins.add(mappedclass);
+                    }
                 }
                 if (WSDLUtil.isOutputPresentForMEP(mep)) {
                     outmsg = op.getMessage(WSDLConstants.MESSAGE_LABEL_OUT_VALUE);
                     if (outmsg == null) {
                         throw new RuntimeException("Expected output message not found for operation " + op.getName());
                     }
+                    ArrayList headers = outmsg.getSoapHeaders();
+                    for (int i = 0; i < headers.size(); i++) {
+                        SOAPHeaderMessage header = (SOAPHeaderMessage)headers.get(i);
+                        mappedclass = mapMessage(header, elementMap);
+                        objouts.add(mappedclass);
+                    }
                 }
                 if (unwrap) {
                     
@@ -344,10 +362,14 @@
                     dbmethod.setAttribute("method-name", op.getName().getLocalPart());
                     Set nameset = new HashSet(s_reservedWords);
                     if (inmsg != null) {
-                        dbmethod.appendChild(unwrapMessage(inmsg, false, simpleTypeMap, complexTypeMap, typeMappedClassMap, nameset, doc));
+                        Element wrapper = unwrapMessage(inmsg, false, simpleTypeMap, complexTypeMap, typeMappedClassMap, bindingMap, nameset, nsMap, doc);
+                        dbmethod.appendChild(wrapper);
+                        wrappers.add(wrapper);
                     }
                     if (outmsg != null) {
-                        dbmethod.appendChild(unwrapMessage(outmsg, true, simpleTypeMap, complexTypeMap, typeMappedClassMap, nameset, doc));
+                        Element wrapper = unwrapMessage(outmsg, true, simpleTypeMap, complexTypeMap, typeMappedClassMap, bindingMap, nameset, nsMap, doc);
+                        dbmethod.appendChild(wrapper);
+                        wrappers.add(wrapper);
                     }
                     
                     // save unwrapping information for use in code generation
@@ -376,7 +398,131 @@
                 }
             }
             
-            // add type usage information as service parameter
+            // check for default namespace usage within bindings or wrappers
+            //  (meaning we can't declare a conflicting default namespace)
+            Collection prefixes = nsMap.values();
+            boolean dfltns = prefixes.contains("");
+            boolean wrapdflt = false;
+            if (!dfltns) {
+                for (int i = 0; i < wrappers.size(); i++) {
+                    Element wrapper = (Element)wrappers.get(i);
+                    if ("true".equals(wrapper.getAttribute("uses-default"))) {
+                        wrapdflt = true;
+                        break;
+                    }
+                }
+            }
+            
+            // find a prefix that we can use where needed for extra namespace
+            String xtrapref = "";
+            if (dfltns || wrapdflt) {
+                xtrapref = "_";
+                int index = 0;
+                while (prefixes.contains(xtrapref)) {
+                    xtrapref = "_" + index++;
+                }
+            }
+            
+            // for each wrapper (input and output), determine what additional
+            //  namespaces need to be declared, what prefix is to be used for
+            //  the wrapper element, and what prefix to be used for each child
+            //  element
+            for (int i = 0; i < wrappers.size(); i++) {
+                Element wrapper = (Element)wrappers.get(i);
+                boolean addns = false;
+                String ns = wrapper.getAttribute("ns");
+                String prefix = "";
+                if ("true".equals(wrapper.getAttribute("need-namespaces"))) {
+                    
+                    // check extra definition needed for wrapper namespace
+                    if (!"".equals(ns)) {
+                        if (dfltns || wrapdflt) {
+                            
+                            // need a namespace, can't be default, get or set it
+                            prefix = (String)nsMap.get(ns);
+                            if (prefix == null) {
+                                prefix = xtrapref;
+                                addns = true;
+                            }
+                            
+                        } else {
+                            
+                            // just make the wrapper namespace the default
+                            prefix = "";
+                            addns = true;
+                            
+                        }
+                    }
+                    wrapper.setAttribute("prefix", prefix);
+                    
+                    // set prefixes for child elements of wrapper
+                    Node node = wrapper.getFirstChild();
+                    while (node != null) {
+                        if (node.getNodeType() == Node.ELEMENT_NODE) {
+                            Element element = (Element)node;
+                            String lname = element.getNodeName();
+                            if ("parameter-element".equals(lname) || "return-element".equals(lname)) {
+                                String childns = element.getAttribute("ns");
+                                if ("".equals(childns)) {
+                                    element.setAttribute("prefix", "");
+                                } else if (ns.equals(childns)) {
+                                    element.setAttribute("prefix", prefix);
+                                } else {
+                                    String childprefix = (String)nsMap.get(childns);
+                                    if (childprefix == null) {
+                                        throw new RuntimeException("Unable to set namespace " +
+                                            childns + " for child element");
+                                    }
+                                    element.setAttribute("prefix", childprefix);
+                                }
+                            }
+                        }
+                        node = node.getNextSibling();
+                    }
+                    
+                } else {
+                    
+                    // check extra definition needed for wrapper namespace
+                    if (!"".equals(ns)) {
+                        
+                        // just make the wrapper namespace the default
+                        prefix = "";
+                        addns = true;
+                        
+                    }
+                    wrapper.setAttribute("prefix", prefix);
+                    
+                    // set prefixes for child elements of wrapper
+                    Node node = wrapper.getFirstChild();
+                    while (node != null) {
+                        if (node.getNodeType() == Node.ELEMENT_NODE) {
+                            Element element = (Element)node;
+                            String lname = element.getNodeName();
+                            if ("parameter-element".equals(lname) || "return-element".equals(lname)) {
+                                String childns = element.getAttribute("ns");
+                                if ("".equals(childns)) {
+                                    element.setAttribute("prefix", "");
+                                } else if (ns.equals(childns)) {
+                                    element.setAttribute("prefix", prefix);
+                                } else {
+                                    throw new RuntimeException("Unable to set namespace " +
+                                        childns + " for child element");
+                                }
+                            }
+                        }
+                        node = node.getNextSibling();
+                    }
+                    
+                }
+                if (addns) {
+                    Element addedns = doc.createElement("extra-namespace");
+                    addedns.setAttribute("ns", ns);
+                    addedns.setAttribute("prefix", prefix);
+                    wrapper.appendChild(addedns);
+                }
+            }
+            
+            // add type usage information for binding initialization
             List details = new ArrayList();
             Element bindinit = doc.createElement("initialize-binding");
             if (!typeMappedClassMap.isEmpty()) {
@@ -398,6 +544,16 @@
                 mappedclass = "";
             }
             bindinit.setAttribute("bound-class", mappedclass);
+            
+            // include binding namespaces in initialization data
+            for (Iterator iter = nsMap.keySet().iterator(); iter.hasNext();) {
+                String ns = (String)iter.next();
+                String prefix = (String)nsMap.get(ns);
+                Element detail = doc.createElement("binding-namespace");
+                detail.setAttribute("ns", ns);
+                detail.setAttribute("prefix", prefix);
+                bindinit.appendChild(detail);
+            }
             details.add(bindinit);
             
             // add details for all objects used as inputs/outputs/faults
@@ -465,13 +621,17 @@
      * @param simpleTypeMap binding formats
      * @param complexTypeMap binding mappings
      * @param typeMappedClassMap map from type qname to index
+     * @param bindingMap map from mapping components to containing binding
+     * definition
      * @param nameset parameter variable names used in method
+     * @param nsmap mapr from URI to prefix for namespaces to be defined on
+     * wrapper element
      * @param doc document used for DOM components
      * @return detailed description element for code generation
      */
     private Element unwrapMessage(AxisMessage msg, boolean isout,
         Map simpleTypeMap, Map complexTypeMap, Map typeMappedClassMap,
-        Set nameset, Document doc) {
+        Map bindingMap, Set nameset, Map nsmap, Document doc) {
         
         // find the schema definition for this message element
         QName qname = msg.getElementQName();
@@ -492,6 +652,9 @@
         // dig down to the sequence
         List partNameList = new ArrayList();
         String wrappertype = "";
+        boolean nons = qname.getNamespaceURI().length() == 0;
+        boolean dfltns = false;
+        boolean complex = false;
         if (type instanceof XmlSchemaComplexType) {
             XmlSchemaComplexType ctype = (XmlSchemaComplexType)type;
             if (ctype.getAttributes().getCount() != 0) {
@@ -530,6 +693,7 @@
                 // add element to output with details of this element handling
                 Element param = doc.createElement(isout ? "return-element" : "parameter-element");
                 QName itemname = element.getQName();
+                nons = nons || itemname.getNamespaceURI().length() == 0;
                 param.setAttribute("ns", itemname.getNamespaceURI());
                 param.setAttribute("name", itemname.getLocalPart());
                 param.setAttribute("java-name", toJavaName(itemname.getLocalPart(), nameset));
@@ -571,6 +735,7 @@
                 } else {
                     
                     // complex type translates to abstract mapping in binding
+                    complex = true;
                     MappingElement mapping = (MappingElement)complexTypeMap.get(typename);
                     if (mapping == null) {
                         throw new RuntimeException("Cannot unwrap element " +
@@ -586,6 +751,28 @@
                     param.setAttribute("form", "complex");
                     param.setAttribute("type-index", tindex.toString());
                     
+                    // merge contained namespace definitions into set for operation
+                    Iterator citer = mapping.topChildIterator();
+                    while (citer.hasNext()) {
+                        ElementBase child = (ElementBase)citer.next();
+                        if (child.type() == ElementBase.NAMESPACE_ELEMENT) {
+                            dfltns = mapNamespace((NamespaceElement)child, dfltns, nsmap);
+                        } else {
+                           break;
+                        }
+                    }
+                    
+                    // also merge namespace definitions from binding
+                    BindingElement binding = (BindingElement)bindingMap.get(mapping);
+                    citer = binding.topChildIterator();
+                    while (citer.hasNext()) {
+                        ElementBase child = (ElementBase)citer.next();
+                        if (child.type() == ElementBase.NAMESPACE_ELEMENT) {
+                            dfltns = mapNamespace((NamespaceElement)child, dfltns, nsmap);
+                        } else if (child.type() != ElementBase.INCLUDE_ELEMENT) {
+                           break;
+                        }
+                    }
                 }
                 param.setAttribute("java-type", javatype);
                 boolean isobj = !s_primitiveSet.contains(javatype);
@@ -612,12 +799,23 @@
                 codeGenConfig.getTypeMapper().addTypeMappingName(partqname, fulltype);
             }
             
+            // check namespace prefix usage
+            if (nons && dfltns) {
+                throw new RuntimeException("Cannot unwrap element " + qname +
+                    ": no-namespace element(s) conflict with default namespace use in binding");
+            }
+            wrapdetail.setAttribute("uses-default", Boolean.toString(nons));
+            
+            // set flag for namespace declarations needed on wrapper
+            wrapdetail.setAttribute("need-namespaces", Boolean.toString(complex));
+            
         } else if (type != null) {
             throw new RuntimeException("Cannot unwrap element " + qname +
                 ": not a complexType definition");
         }
         if (wrapdetail.getFirstChild() == null) {
             wrapdetail.setAttribute("empty", "true");
+            wrapdetail.setAttribute("need-namespaces", "false");
             wrappertype = "";
         } else {
             wrapdetail.setAttribute("empty", "false");
@@ -647,6 +845,33 @@
         // return the unwrapping details
         return wrapdetail;
     }
+
+    /**
+     * Add mapping from namespace URI to prefix. In the case where multiple
+     * prefixes are used with a single URI, this will preserve the last
+     * non-empty prefix for that URI.
+     * 
+     * @param ns namespace definition
+     * @param dfltns flag for default namespace used in binding
+     * @param nsmap map from namespace URIs to prefixes
+     * @return flag for default namespace used in binding
+     */
+    private boolean mapNamespace(NamespaceElement ns, boolean dfltns, Map nsmap) {
+        String prefix = ns.getPrefix();
+        if (prefix == null) {
+            prefix = "";
+        }
+        String prior = (String)nsmap.get(ns.getUri());
+        if (prior != null) {
+            if (prefix.length() == 0) {
+                return dfltns;
+            } else if (prior.length() == 0) {
+                dfltns = false;
+            }
+        }
+        nsmap.put(ns.getUri(), prefix);
+        return dfltns || prefix.length() == 0;
+    }
     
     private static String toJavaName(String name, Set nameset) {
         StringBuffer buff = new StringBuffer(name.length());
@@ -674,6 +899,18 @@
         if (qname == null) {
             throw new RuntimeException("No element reference in message " + msg.getName());
         }
+        return mapQName(qname, complexTypeMap);
+    }
+    
+    private String mapMessage(SOAPHeaderMessage msg, Map complexTypeMap) {
+        QName qname = msg.getElement();
+        if (qname == null) {
+            throw new RuntimeException("No element reference in header");
+        }
+        return mapQName(qname, complexTypeMap);
+    }
+    
+    private String mapQName(QName qname, Map complexTypeMap) throws RuntimeException {
         Object obj = complexTypeMap.get(qname);
         if (obj == null) {
             throw new RuntimeException("No mapping defined for element " + qname);
@@ -697,10 +934,12 @@
      * components of binding
      * @param simpleTypeMap map from type names to format definition components
      * of binding
+     * @param bindingMap map from mapping components to containing binding
+     * definition
      */
     private static void collectTopLevelComponents(BindingElement binding,
-        String dns, Map elementMap, Map complexTypeMap,
-        Map simpleTypeMap) {
+        String dns, Map elementMap, Map complexTypeMap, Map simpleTypeMap,
+        Map bindingMap) {
         
         // check default namespace set at top level of binding
         String defaultns = findDefaultNS(binding.topChildIterator(), dns);
@@ -713,16 +952,18 @@
                 // recurse to process included binding definitions
                 IncludeElement include = (IncludeElement)child;
                 collectTopLevelComponents(include.getBinding(), defaultns,
-                    elementMap, complexTypeMap, simpleTypeMap);
+                    elementMap, complexTypeMap, simpleTypeMap, bindingMap);
                 
             } else if (child.type() == ElementBase.FORMAT_ELEMENT) {
                 
                 // register named formats as simple type conversions
                 FormatElement format = (FormatElement)child;
                 registerElement(format.getQName(), format, simpleTypeMap);
+                bindingMap.put(format, binding);
                 
             } else if (child.type() == ElementBase.MAPPING_ELEMENT) {
                 MappingElement mapping = (MappingElement)child;
+                bindingMap.put(mapping, binding);
                 if (mapping.isAbstract()) {
                     
                     // register named abstract mappings as complex type conversions
@@ -802,6 +1043,8 @@
          */
         public boolean visit(IncludeElement node) {
             try {
+                // force creation of defintions context for containing binding
+                m_context.getFormatDefinitions();
                 node.prevalidate(m_context);
             } catch (Throwable t) {
                 m_context.addFatal("Error during validation: " +

Modified: webservices/axis2/branches/java/1_1/modules/jibx/src/org/apache/axis2/jibx/JiBXDataSource.java
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/java/1_1/modules/jibx/src/org/apache/axis2/jibx/JiBXDataSource.java?view=diff&rev=488505&r1=488504&r2=488505
==============================================================================
--- webservices/axis2/branches/java/1_1/modules/jibx/src/org/apache/axis2/jibx/JiBXDataSource.java (original)
+++ webservices/axis2/branches/java/1_1/modules/jibx/src/org/apache/axis2/jibx/JiBXDataSource.java Mon Dec 18 18:29:14 2006
@@ -48,8 +48,14 @@
     /** Element name (only used with {@link #marshallerIndex}). */
     private final String elementName;
     
-    /** Element namespace URI (only used with {@link #marshallerIndex}). */
-    private final String elementNamespaceUri;
+    /** Element namespace prefix (only used with {@link #marshallerIndex}). */
+    private final String elementNamespacePrefix;
+    
+    /** Indexes of namespaces to be opened (only used with {@link #marshallerIndex}). */
+    private final int[] openNamespaceIndexes;
+    
+    /** Prefixes of namespaces to be opened (only used with {@link #marshallerIndex}). */
+    private final String[] openNamespacePrefixes;
     
     /** Data object for output. */
     private final Object dataObject;
@@ -67,7 +73,9 @@
         marshallerIndex = -1;
         dataObject = obj;
         bindingFactory = factory;
-        elementName = elementNamespaceUri = null;
+        elementName = elementNamespacePrefix = null;
+        openNamespaceIndexes = null;
+        openNamespacePrefixes = null;
     }
     
     /**
@@ -76,18 +84,22 @@
      * @param obj
      * @param index
      * @param name
-     * @param uri
+     * @param prefix
+     * @param nsindexes
+     * @param nsprefixes
      * @param factory
      */
-    public JiBXDataSource(Object obj, int index, String name, String uri,
-        IBindingFactory factory) {
+    public JiBXDataSource(Object obj, int index, String name, String prefix,
+        int[] nsindexes, String[] nsprefixes, IBindingFactory factory) {
         if (index < 0) {
             throw new
                 IllegalArgumentException("index value must be non-negative");
         }
         marshallerIndex = index;
         elementName = name;
-        elementNamespaceUri = uri;
+        elementNamespacePrefix = prefix;
+        openNamespaceIndexes = nsindexes;
+        openNamespacePrefixes = nsprefixes;
         dataObject = obj;
         bindingFactory = factory;
     }
@@ -102,39 +114,25 @@
         if (marshallerIndex < 0) {
             ((IMarshallable)dataObject).marshal(ctx);
         } else {
-            IXMLWriter wrtr = ctx.getXmlWriter();
-            int nsidx = 0;
-            boolean nsfound = true;
-            if (!"".equals(elementNamespaceUri)) {
-                nsfound = false;
-                for (nsidx = wrtr.getNamespaceCount()-1; nsidx > 1; nsidx--) {
-                    if (elementNamespaceUri.equals(wrtr.getNamespaceUri(nsidx))) {
-                        nsfound = true;
-                        break;
-                    }
-                }
-            }
             try {
-                if (nsfound) {
-                    wrtr.startTagOpen(nsidx, elementName);
-                } else {
-                    nsidx = wrtr.getNamespaceCount();
-                    String[] uris = new String[] { elementNamespaceUri };
-                    int[] indexes = new int[] { nsidx };
-                    String[] prefixes = new String[] { "" };
-                    wrtr.pushExtensionNamespaces(uris);
-                    wrtr.startTagNamespaces(nsidx, elementName, indexes, prefixes);
+                
+                // open namespaces from wrapper element
+                IXMLWriter wrtr = ctx.getXmlWriter();
+                wrtr.openNamespaces(openNamespaceIndexes, openNamespacePrefixes);
+                String name = elementName;
+                if (!"".equals(elementNamespacePrefix)) {
+                    name = elementNamespacePrefix + ':' + name;
                 }
+                wrtr.startTagOpen(0, name);
+                
+                // marshal object representation (may include attributes) into element
                 IMarshaller mrsh = ctx.getMarshaller(marshallerIndex,
                     bindingFactory.getMappedClasses()[marshallerIndex]);
                 mrsh.marshal(dataObject, ctx);
-                wrtr.endTag(nsidx, elementName);
-                if (!nsfound) {
-                    wrtr.popExtensionNamespaces();
-                }
+                wrtr.endTag(0, name);
+                
             } catch (IOException e) {
-                // TODO Auto-generated catch block
-                e.printStackTrace();
+                throw new JiBXException("Error marshalling XML representation", e);
             }
         }
     }

Modified: webservices/axis2/branches/java/1_1/modules/jibx/src/org/apache/axis2/jibx/template/JibXDatabindingTemplate.xsl
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/java/1_1/modules/jibx/src/org/apache/axis2/jibx/template/JibXDatabindingTemplate.xsl?view=diff&rev=488505&r1=488504&r2=488505
==============================================================================
--- webservices/axis2/branches/java/1_1/modules/jibx/src/org/apache/axis2/jibx/template/JibXDatabindingTemplate.xsl (original)
+++ webservices/axis2/branches/java/1_1/modules/jibx/src/org/apache/axis2/jibx/template/JibXDatabindingTemplate.xsl Mon Dec 18 18:29:14 2006
@@ -135,7 +135,13 @@
       <!-- returning an array of values -->
       <xsl:when test="out-wrapper/@empty='false' and out-wrapper/return-element/@array='true'">
               envelope = factory.getDefaultEnvelope();
-              org.apache.axiom.om.OMElement wrapper = factory.createOMElement("<xsl:value-of select='out-wrapper/@name'/>", "<xsl:value-of select='out-wrapper/@ns'/>", "");
+              org.apache.axiom.om.OMElement wrapper = factory.createOMElement("<xsl:value-of select='out-wrapper/@name'/>", "<xsl:value-of select='out-wrapper/@ns'/>", "<xsl:value-of select='out-wrapper/@prefix'/>");
+        <xsl:if test="out-wrapper/@need-namespaces='true'">
+              addMappingNamespaces(factory, wrapper);
+        </xsl:if>
+        <xsl:if test="count(out-wrapper/extra-namespace) &gt; 0">
+              wrapper.declareNamespace(factory.createOMNamespace("<xsl:value-of select='out-wrapper/extra-namespace/@ns'/>", "<xsl:value-of select='out-wrapper/extra-namespace/@prefix'/>"));
+        </xsl:if>
               envelope.getBody().addChild(wrapper);
               <xsl:value-of select="out-wrapper/return-element/@java-type"/>[] results = skel.<xsl:call-template name="call-arg-list"/>;
               if (results == null || results.length == 0) {
@@ -146,8 +152,6 @@
           </xsl:otherwise>
         </xsl:choose>
               } else {
-                  org.apache.axiom.om.OMNamespace appns = factory.createOMNamespace("<xsl:value-of select='out-wrapper/return-element/@ns'/>", "app");
-                  wrapper.declareNamespace(appns);
         <xsl:choose>
           <xsl:when test="out-wrapper/return-element/@form='complex'">
                   for (int i = 0; i &lt; results.length; i++) {
@@ -155,7 +159,7 @@
                       if (result == null) {
             <xsl:choose>
               <xsl:when test="out-wrapper/return-element/@nillable='true'">
-                          org.apache.axiom.om.OMElement child = factory.createOMElement("<xsl:value-of select='out-wrapper/return-element/@name'/>", appns);
+                          org.apache.axiom.om.OMElement child = factory.createOMElement("<xsl:value-of select='out-wrapper/return-element/@name'/>", "<xsl:value-of select='out-wrapper/return-element/@ns'/>", "<xsl:value-of select='out-wrapper/return-element/@prefix'/>");
                           org.apache.axiom.om.OMNamespace xsins = factory.createOMNamespace("http://www.w3.org/2001/XMLSchema-instance", "xsi");
                           child.declareNamespace(xsins);
                           child.addAttribute("nil", "true", xsins);
@@ -166,7 +170,11 @@
               </xsl:otherwise>
             </xsl:choose>
                       } else {
-                          org.apache.axiom.om.OMDataSource src = new org.apache.axis2.jibx.JiBXDataSource(result, _type_index<xsl:value-of select="out-wrapper/return-element/@type-index"/>, "<xsl:value-of select='out-wrapper/return-element/@name'/>", "<xsl:value-of select='out-wrapper/return-element/@ns'/>", bindingFactory);
+                          if (bindingFactory == null) {
+                              throw new RuntimeException(bindingErrorMessage);
+                          }
+                          org.apache.axiom.om.OMDataSource src = new org.apache.axis2.jibx.JiBXDataSource(result, _type_index<xsl:value-of select="out-wrapper/return-element/@type-index"/>, "<xsl:value-of select='out-wrapper/return-element/@name'/>", "<xsl:value-of select='out-wrapper/return-element/@prefix'/>", bindingNamespaceIndexes, bindingNamespacePrefixes, bindingFactory);
+                          org.apache.axiom.om.OMNamespace appns = factory.createOMNamespace("<xsl:value-of select='out-wrapper/return-element/@ns'/>", "");
                           org.apache.axiom.om.OMElement child = factory.createOMElement(src, "<xsl:value-of select='out-wrapper/return-element/@name'/>", appns);
                           wrapper.addChild(child);
                       }
@@ -175,7 +183,7 @@
           <xsl:otherwise>
                   for (int i = 0; i &lt; results.length; i++) {
                       <xsl:value-of select="out-wrapper/return-element/@java-type"/> result = results[i];
-                      org.apache.axiom.om.OMElement child = factory.createOMElement("<xsl:value-of select='out-wrapper/return-element/@name'/>", appns);
+                      org.apache.axiom.om.OMElement child = factory.createOMElement("<xsl:value-of select='out-wrapper/return-element/@name'/>", "<xsl:value-of select='out-wrapper/return-element/@ns'/>", "<xsl:value-of select='out-wrapper/return-element/@prefix'/>");
             <xsl:choose>
               <xsl:when test="out-wrapper/return-element/@serializer=''">
                       child.setText(result.toString());
@@ -194,18 +202,22 @@
       <!-- returning a single value -->
       <xsl:when test="out-wrapper/@empty='false'">
               envelope = factory.getDefaultEnvelope();
-              org.apache.axiom.om.OMElement wrapper = factory.createOMElement("<xsl:value-of select='out-wrapper/@name'/>", "<xsl:value-of select='out-wrapper/@ns'/>", "");
+              org.apache.axiom.om.OMElement wrapper = factory.createOMElement("<xsl:value-of select='out-wrapper/@name'/>", "<xsl:value-of select='out-wrapper/@ns'/>", "<xsl:value-of select='out-wrapper/@prefix'/>");
+        <xsl:if test="out-wrapper/@need-namespaces='true'">
+              addMappingNamespaces(factory, wrapper);
+        </xsl:if>
+        <xsl:if test="count(out-wrapper/extra-namespace) &gt; 0">
+              wrapper.declareNamespace(factory.createOMNamespace("<xsl:value-of select='out-wrapper/extra-namespace/@ns'/>", "<xsl:value-of select='out-wrapper/extra-namespace/@prefix'/>"));
+        </xsl:if>
               envelope.getBody().addChild(wrapper);
               <xsl:value-of select="out-wrapper/return-element/@java-type"/> result = skel.<xsl:call-template name="call-arg-list"/>;
-              org.apache.axiom.om.OMNamespace appns = factory.createOMNamespace("<xsl:value-of select='out-wrapper/return-element/@ns'/>", "app");
-              wrapper.declareNamespace(appns);
         <xsl:choose>
           <xsl:when test="out-wrapper/return-element/@form='complex'">
               if (result == null) {
             <xsl:choose>
               <xsl:when test="out-wrapper/return-element/@optional='true'"/>
               <xsl:when test="out-wrapper/return-element/@nillable='true'">
-                  org.apache.axiom.om.OMElement child = factory.createOMElement("<xsl:value-of select='out-wrapper/return-element/@name'/>", appns);
+                  org.apache.axiom.om.OMElement child = factory.createOMElement("<xsl:value-of select='out-wrapper/return-element/@name'/>", "<xsl:value-of select='out-wrapper/return-element/@ns'/>", "<xsl:value-of select='out-wrapper/return-element/@prefix'/>");
                   org.apache.axiom.om.OMNamespace xsins = factory.createOMNamespace("http://www.w3.org/2001/XMLSchema-instance", "xsi");
                   child.declareNamespace(xsins);
                   child.addAttribute("nil", "true", xsins);
@@ -216,13 +228,17 @@
               </xsl:otherwise>
             </xsl:choose>
               } else {
-                  org.apache.axiom.om.OMDataSource src = new org.apache.axis2.jibx.JiBXDataSource(result, _type_index<xsl:value-of select="out-wrapper/return-element/@type-index"/>, "<xsl:value-of select='out-wrapper/return-element/@name'/>", "<xsl:value-of select='out-wrapper/return-element/@ns'/>", bindingFactory);
+                  if (bindingFactory == null) {
+                      throw new RuntimeException(bindingErrorMessage);
+                  }
+                  org.apache.axiom.om.OMDataSource src = new org.apache.axis2.jibx.JiBXDataSource(result, _type_index<xsl:value-of select="out-wrapper/return-element/@type-index"/>, "<xsl:value-of select='out-wrapper/return-element/@name'/>", "<xsl:value-of select='out-wrapper/return-element/@prefix'/>", bindingNamespaceIndexes, bindingNamespacePrefixes, bindingFactory);
+                  org.apache.axiom.om.OMNamespace appns = factory.createOMNamespace("<xsl:value-of select='out-wrapper/return-element/@ns'/>", "");
                   org.apache.axiom.om.OMElement child = factory.createOMElement(src, "<xsl:value-of select='out-wrapper/return-element/@name'/>", appns);
                   wrapper.addChild(child);
               }
           </xsl:when>
           <xsl:otherwise>
-              org.apache.axiom.om.OMElement child = factory.createOMElement("<xsl:value-of select='out-wrapper/return-element/@name'/>", appns);
+              org.apache.axiom.om.OMElement child = factory.createOMElement("<xsl:value-of select='out-wrapper/return-element/@name'/>",  "<xsl:value-of select='out-wrapper/return-element/@ns'/>", "<xsl:value-of select='out-wrapper/return-element/@prefix'/>");
             <xsl:choose>
               <xsl:when test="out-wrapper/return-element/@object='true'">
               if (result == null) {
@@ -354,7 +370,13 @@
                 // create SOAP envelope with the payload
                 org.apache.axiom.soap.SOAPEnvelope env = createEnvelope(_operationClient.getOptions());
                 org.apache.axiom.soap.SOAPFactory factory = getFactory(_operationClient.getOptions().getSoapVersionURI());
-                org.apache.axiom.om.OMElement wrapper = factory.createOMElement("<xsl:value-of select='in-wrapper/@name'/>", "<xsl:value-of select='in-wrapper/@ns'/>", "");
+                org.apache.axiom.om.OMElement wrapper = factory.createOMElement("<xsl:value-of select='in-wrapper/@name'/>", "<xsl:value-of select='in-wrapper/@ns'/>", "<xsl:value-of select='in-wrapper/@prefix'/>");
+    <xsl:if test="in-wrapper/@need-namespaces='true'">
+                addMappingNamespaces(factory, wrapper);
+    </xsl:if>
+    <xsl:if test="count(in-wrapper/extra-namespace) &gt; 0">
+                wrapper.declareNamespace(factory.createOMNamespace("<xsl:value-of select='in-wrapper/extra-namespace/@ns'/>", "<xsl:value-of select='in-wrapper/extra-namespace/@prefix'/>"));
+    </xsl:if>
                 env.getBody().addChild(wrapper);
                 org.apache.axiom.om.OMElement child;
     <xsl:apply-templates select="in-wrapper/parameter-element" mode="interface-implementation"/>
@@ -468,7 +490,7 @@
     <xsl:choose>
       <xsl:when test="@optional='true'"></xsl:when>
       <xsl:when test="@nillable='true'">
-        child = factory.createOMElement("<xsl:value-of select='@name'/>", "<xsl:value-of select='@ns'/>", "");
+        child = factory.createOMElement("<xsl:value-of select='@name'/>", "<xsl:value-of select='@ns'/>", "<xsl:value-of select='@prefix'/>");
         org.apache.axiom.om.OMNamespace xsins = factory.createOMNamespace("http://www.w3.org/2001/XMLSchema-instance", "xsi");
         child.declareNamespace(xsins);
         child.addAttribute("nil", "true", xsins);
@@ -484,7 +506,7 @@
     <xsl:choose>
       <xsl:when test="@object='true' and @nillable='true'">
             if (_item == null) {
-                child = factory.createOMElement("<xsl:value-of select='@name'/>", "<xsl:value-of select='@ns'/>", "");
+                child = factory.createOMElement("<xsl:value-of select='@name'/>", "<xsl:value-of select='@ns'/>", "<xsl:value-of select='@prefix'/>");
                 org.apache.axiom.om.OMNamespace xsins = factory.createOMNamespace("http://www.w3.org/2001/XMLSchema-instance", "xsi");
                 child.declareNamespace(xsins);
                 child.addAttribute("nil", "true", xsins);
@@ -513,7 +535,7 @@
     <xsl:choose>
       <xsl:when test="@object='true' and @nillable='true'">
         if (<xsl:value-of select="@java-name"/> == null) {
-            child = factory.createOMElement("<xsl:value-of select='@name'/>", "<xsl:value-of select='@ns'/>", "");
+            child = factory.createOMElement("<xsl:value-of select='@name'/>", "<xsl:value-of select='@ns'/>", "<xsl:value-of select='@prefix'/>");
             org.apache.axiom.om.OMNamespace xsins = factory.createOMNamespace("http://www.w3.org/2001/XMLSchema-instance", "xsi");
             child.declareNamespace(xsins);
             child.addAttribute("nil", "true", xsins);
@@ -539,19 +561,22 @@
   <xsl:template name="serialize-value-to-child">
     <xsl:choose>
       <xsl:when test="@java-type='String' and @serializer=''">
-        child = factory.createOMElement("<xsl:value-of select='@name'/>", "<xsl:value-of select='@ns'/>", "");
+        child = factory.createOMElement("<xsl:value-of select='@name'/>", "<xsl:value-of select='@ns'/>", "<xsl:value-of select='@prefix'/>");
         child.setText(<xsl:call-template name="parameter-or-array-item"/>);
       </xsl:when>
       <xsl:when test="@form='simple' and @serializer=''">
-        child = factory.createOMElement("<xsl:value-of select='@name'/>", "<xsl:value-of select='@ns'/>", "");
+        child = factory.createOMElement("<xsl:value-of select='@name'/>", "<xsl:value-of select='@ns'/>", "<xsl:value-of select='@prefix'/>");
         child.setText(<xsl:call-template name="parameter-or-array-item"/>.toString());
       </xsl:when>
       <xsl:when test="@form='simple'">
-        child = factory.createOMElement("<xsl:value-of select='@name'/>", "<xsl:value-of select='@ns'/>", "");
+        child = factory.createOMElement("<xsl:value-of select='@name'/>", "<xsl:value-of select='@ns'/>", "<xsl:value-of select='@prefix'/>");
         child.setText(<xsl:value-of select="@serializer"/>(<xsl:call-template name="parameter-or-array-item"/>));
       </xsl:when>
       <xsl:when test="@form='complex'">
-        org.apache.axiom.om.OMDataSource src = new org.apache.axis2.jibx.JiBXDataSource(<xsl:call-template name="parameter-or-array-item"/>, _type_index<xsl:value-of select="@type-index"/>, "<xsl:value-of select='@name'/>", "<xsl:value-of select='@ns'/>", bindingFactory);
+        if (bindingFactory == null) {
+            throw new RuntimeException(bindingErrorMessage);
+        }
+        org.apache.axiom.om.OMDataSource src = new org.apache.axis2.jibx.JiBXDataSource(<xsl:call-template name="parameter-or-array-item"/>, _type_index<xsl:value-of select="@type-index"/>, "<xsl:value-of select='@name'/>", "<xsl:value-of select='@prefix'/>", bindingNamespaceIndexes, bindingNamespacePrefixes, bindingFactory);
         org.apache.axiom.om.OMNamespace appns = factory.createOMNamespace("<xsl:value-of select='@ns'/>", "");
         child = factory.createOMElement(src, "<xsl:value-of select='@name'/>", appns);
       </xsl:when>
@@ -653,8 +678,11 @@
   
   <!-- Called by main template to handle static binding data and methods. -->
   <xsl:template match="initialize-binding">
+    <xsl:variable name="nscount" select="count(binding-namespace)"/>
       private static final org.jibx.runtime.IBindingFactory bindingFactory;
       private static final String bindingErrorMessage;
+      private static final int[] bindingNamespaceIndexes;
+      private static final String[] bindingNamespacePrefixes;
     <xsl:apply-templates mode="generate-index-fields" select="abstract-type"/>
         static {
             org.jibx.runtime.IBindingFactory factory = null;
@@ -673,6 +701,58 @@
             bindingFactory = factory;
             bindingErrorMessage = message;
     <xsl:apply-templates mode="set-index-fields" select="abstract-type"/>
+            int[] indexes = null;
+            String[] prefixes = null;
+            if (factory != null) {
+                
+                // check for xsi namespace included
+                String[] nsuris = factory.getNamespaces();
+                int xsiindex = nsuris.length;
+                while (--xsiindex >= 0 &amp;&amp;
+                    !"http://www.w3.org/2001/XMLSchema-instance".equals(nsuris[xsiindex]));
+                
+                // get actual size of index and prefix arrays to be allocated
+                int nscount = <xsl:value-of select="$nscount"/>;
+                int usecount = nscount;
+                if (xsiindex >= 0) {
+                    usecount++;
+                }
+                
+                // allocate and initialize the arrays
+                indexes = new int[usecount];
+                prefixes = new String[usecount];
+      <xsl:for-each select="binding-namespace">
+        <xsl:variable name="nsindex" select="count(preceding-sibling::binding-namespace)"/>
+                indexes[<xsl:value-of select="$nsindex"/>] = nsIndex("<xsl:value-of select='@ns'/>", nsuris);
+                prefixes[<xsl:value-of select="$nsindex"/>] = "<xsl:value-of select='@prefix'/>";
+      </xsl:for-each>
+                if (xsiindex >= 0) {
+                    indexes[nscount] = xsiindex;
+                    prefixes[nscount] = "xsi";
+                }
+                
+            }
+            bindingNamespaceIndexes = indexes;
+            bindingNamespacePrefixes = prefixes;
+        }
+        
+        private static int nsIndex(String uri, String[] uris) {
+            for (int i = 0; i &lt; uris.length; i++) {
+                if (uri.equals(uris[i])) {
+                    return i;
+                }
+            }
+            throw new IllegalArgumentException("Namespace " + uri + " not found in binding directory information");
+        }
+        
+        private static void addMappingNamespaces(org.apache.axiom.soap.SOAPFactory factory, org.apache.axiom.om.OMElement wrapper) {
+            String[] nss = bindingFactory.getNamespaces();
+            for (int i = 0; i &lt; bindingNamespaceIndexes.length; i++) {
+                int index = bindingNamespaceIndexes[i];
+                String uri = nss[index];
+                String prefix = bindingNamespacePrefixes[i];
+                wrapper.declareNamespace(factory.createOMNamespace(uri, prefix));
+            }
         }
         
         private static org.jibx.runtime.impl.UnmarshallingContext getNewUnmarshalContext(org.apache.axiom.om.OMElement param)
@@ -688,7 +768,7 @@
             return ctx;
         }
         
-    <!-- shouldn't be needed when no actual binding, but called by fault conversion code so must be left in for now -->
+        <!-- shouldn't be needed when no actual binding, but called by fault conversion code so must be left in for now -->
         private static Object fromOM(org.apache.axiom.om.OMElement param, Class type,
             java.util.Map extraNamespaces) {
             try {



---------------------------------------------------------------------
To unsubscribe, e-mail: axis-cvs-unsubscribe@ws.apache.org
For additional commands, e-mail: axis-cvs-help@ws.apache.org