This is an automated email from the ASF dual-hosted git repository.

robertlazarski pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/axis-axis2-java-core.git


The following commit(s) were added to refs/heads/master by this push:
     new 16e832e71e AXIS2-6081 JSON with XML Stream API, support XML attributes 
in XmlNodeGenerator
16e832e71e is described below

commit 16e832e71ef809ddd85de386b43719575d0a7b7c
Author: Robert Lazarski <robertlazar...@gmail.com>
AuthorDate: Thu Feb 27 05:31:44 2025 -1000

    AXIS2-6081 JSON with XML Stream API, support XML attributes in 
XmlNodeGenerator
---
 .../axis2/json/factory/XmlNodeGenerator.java       | 63 ++++++++++++++++-
 .../axis2/json/moshi/MoshiXMLStreamReader.java     | 79 +++++++++++++++++-----
 2 files changed, 123 insertions(+), 19 deletions(-)

diff --git 
a/modules/json/src/org/apache/axis2/json/factory/XmlNodeGenerator.java 
b/modules/json/src/org/apache/axis2/json/factory/XmlNodeGenerator.java
index 7c65d2b7fe..c125e4d01b 100644
--- a/modules/json/src/org/apache/axis2/json/factory/XmlNodeGenerator.java
+++ b/modules/json/src/org/apache/axis2/json/factory/XmlNodeGenerator.java
@@ -22,7 +22,12 @@ package org.apache.axis2.json.factory;
 import org.apache.axis2.AxisFault;
 import org.apache.ws.commons.schema.utils.XmlSchemaRef;
 
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
 import org.apache.ws.commons.schema.XmlSchema;
+import org.apache.ws.commons.schema.XmlSchemaAttribute;
+import org.apache.ws.commons.schema.XmlSchemaAttributeOrGroupRef;
 import org.apache.ws.commons.schema.XmlSchemaComplexType;
 import org.apache.ws.commons.schema.XmlSchemaElement;
 import org.apache.ws.commons.schema.XmlSchemaParticle;
@@ -32,12 +37,15 @@ import org.apache.ws.commons.schema.XmlSchemaSimpleType;
 import org.apache.ws.commons.schema.XmlSchemaType;
 
 import javax.xml.namespace.QName;
+import java.util.ArrayList;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Queue;
 
 public class XmlNodeGenerator {
 
+    private static final Log log = LogFactory.getLog(XmlNodeGenerator.class);
+
     List<XmlSchema> xmlSchemaList;
 
     QName elementQname;
@@ -45,6 +53,7 @@ public class XmlNodeGenerator {
     private XmlNode mainXmlNode;
 
     Queue<JsonObject> queue = new LinkedList<JsonObject>();
+    Queue<JsonObject> attribute_queue = new LinkedList<JsonObject>();
 
     public XmlNodeGenerator(List<XmlSchema> xmlSchemaList, QName elementQname) 
{
         this.xmlSchemaList = xmlSchemaList;
@@ -84,6 +93,7 @@ public class XmlNodeGenerator {
     }
 
     private void processElement(XmlSchemaElement element, XmlNode parentNode , 
XmlSchema schema) throws AxisFault {
+        log.debug("XmlNodeGenerator.processElement() found parentNode node 
name: " + parentNode.getName() + " , isAttribute: " + parentNode.isAttribute() 
+ " , element name: " + element.getName());
         String targetNamespace = schema.getTargetNamespace();
         XmlNode xmlNode;
         QName schemaTypeName = element.getSchemaTypeName();
@@ -147,6 +157,48 @@ public class XmlNodeGenerator {
                     }
                 }
             }
+           /*
+            TODO: attribute support Proof of Concept (POC) by adding currency 
attribute to:
+
+                
samples/quickstartadb/resources/META-INF/StockQuoteService.wsdl:
+
+                <xs:element name="getPrice">
+                        <xs:complexType>
+                                <xs:sequence>
+                                        <xs:element name="symbol" 
nillable="true" type="xs:string"/>
+                                </xs:sequence>
+                                <xs:attribute name="currency" type="xs:string" 
use="required"/>
+                        </xs:complexType>
+                </xs:element>
+
+               resulting in this SOAP Envelope:
+
+               <soapenv:Envelope 
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/";><soapenv:Header/><soapenv:Body><ns1:getPrice
 xmlns:ns1="http://quickstart.samples/xsd"; 
ns1:currency="USD"><ns1:symbol>ABC</ns1:symbol></ns1:getPrice></soapenv:Body></soapenv:Envelope>
+
+               Below, add complexType.getAttributes() code to support this 
JSON: 
+
+               { "getPrice" : {"symbol": "IBM","currency":USD}}
+
+               Possibly using @ as @currency to flag a variable name as as 
attribute. 
+
+               One thing to note is XmlNode has isAttribute() but was never 
used
+           */
+            if (complexType.getAttributes() != null && 
complexType.getAttributes().size() > 0) {
+                log.debug("XmlNodeGenerator.processSchemaType() found 
attribute size from complexType: " + complexType.getAttributes().size());
+                List<XmlSchemaAttributeOrGroupRef> list = 
complexType.getAttributes();
+                for (XmlSchemaAttributeOrGroupRef ref : list) {
+                   XmlSchemaAttribute xsa = (XmlSchemaAttribute)ref;
+                    String name = xsa.getName();
+                    QName schemaTypeName = xsa.getSchemaTypeName();
+                   if (schema != null && schema.getTargetNamespace() != null 
&& schemaTypeName != null && schemaTypeName.getLocalPart() != null) {
+                        log.debug("XmlNodeGenerator.processSchemaType() found 
attribute name from complexType: " + name + " , adding it to parentNode");
+                        XmlNode xmlNode = new XmlNode(name, 
schema.getTargetNamespace(), true, false, schemaTypeName.getLocalPart());
+                        parentNode.addChildToList(xmlNode);
+                   } else {
+                        log.debug("XmlNodeGenerator.processSchemaType() found 
attribute name from complexType: " + name + " , however could not resolve 
namespace and localPart");
+                   }
+                }
+            }
         }else if (xmlSchemaType instanceof XmlSchemaSimpleType) {
             // nothing to do with simpleType
         }
@@ -163,6 +215,11 @@ public class XmlNodeGenerator {
     }
 
     private void generateQueue(XmlNode node) {
+        log.debug("XmlNodeGenerator.generateQueue() found node name: " + 
node.getName() + " , isAttribute: " + node.isAttribute());
+       if (node.isAttribute()) {
+            attribute_queue.add(new JsonObject(node.getName(), JSONType.OBJECT 
, node.getValueType() , node.getNamespaceUri()));
+           return;
+       }
         if (node.isArray()) {
             if (node.getChildrenList().size() > 0) {
                 queue.add(new JsonObject(node.getName(), 
JSONType.NESTED_ARRAY, node.getValueType() , node.getNamespaceUri()));
@@ -186,7 +243,6 @@ public class XmlNodeGenerator {
         }
     }
 
-
     public XmlNode getMainXmlNode() throws AxisFault {
         if (mainXmlNode == null) {
             try {
@@ -203,4 +259,9 @@ public class XmlNodeGenerator {
         return queue;
     }
 
+    // need to invoke getQueue() before getAttributeQueue()
+    public Queue<JsonObject> getAttributeQueue() {
+        return attribute_queue;
+    }
+
 }
diff --git 
a/modules/json/src/org/apache/axis2/json/moshi/MoshiXMLStreamReader.java 
b/modules/json/src/org/apache/axis2/json/moshi/MoshiXMLStreamReader.java
index 67009026a4..ad5994ea3c 100644
--- a/modules/json/src/org/apache/axis2/json/moshi/MoshiXMLStreamReader.java
+++ b/modules/json/src/org/apache/axis2/json/moshi/MoshiXMLStreamReader.java
@@ -74,6 +74,10 @@ public class MoshiXMLStreamReader implements XMLStreamReader 
{
 
     private Queue<JsonObject> queue = new LinkedList<JsonObject>();
 
+    private Queue<JsonObject> attribute_queue = new LinkedList<JsonObject>();
+
+    private List<Attribute> attributes;
+
     private XmlNodeGenerator xmlNodeGenerator;
 
     private Stack<JsonObject> stackObj = new Stack<JsonObject>();
@@ -134,6 +138,17 @@ public class MoshiXMLStreamReader implements 
XMLStreamReader {
             newNodeMap.put(elementQname, mainXmlNode);
             configContext.setProperty(JsonConstant.XMLNODES, newNodeMap);
         }
+        log.debug("MoshiXMLStreamReader.process() completed on queue size: " + 
queue.size());
+       // XML Elements
+        for (JsonObject jsonobject : queue) {
+            log.debug("moshixmlstreamreader.process() found Element to process 
as jsonobject name: " + jsonobject.getName() + " , type: " + 
jsonobject.getType());
+       }
+
+       // XML attributes
+        attribute_queue = xmlNodeGenerator.getAttributeQueue();
+        for (JsonObject jsonobject : attribute_queue) {
+            log.debug("moshixmlstreamreader.process() found Attribute to 
process as jsonobject name: " + jsonobject.getName() + " , type: " + 
jsonobject.getType());
+       }
         isProcessed = true;
         log.debug("MoshiXMLStreamReader.process() completed");
     }
@@ -231,12 +246,9 @@ public class MoshiXMLStreamReader implements 
XMLStreamReader {
     }
 
 
-    public String getAttributeValue(String namespaceURI, String localName) {
-        throw new UnsupportedOperationException("Method is not implemented");
-    }
-
-
     public int getAttributeCount() {
+       // TODO populate the List of the class Attributes here by readName() 
+       // and using the attribute_queue instead of queue if attribute_queue 
not empty
         if (isStartElement()) {
             return 0; // don't support attributes on tags  in JSON convention
         } else {
@@ -245,38 +257,60 @@ public class MoshiXMLStreamReader implements 
XMLStreamReader {
     }
 
 
-    public QName getAttributeName(int index) {
-        throw new UnsupportedOperationException("Method is not implemented");
+    public String getAttributeLocalName(int index) {
+        if ((null == attributes) || (index >= attributes.size())) {
+            throw new IndexOutOfBoundsException();
+        }
+        return attributes.get(index).name.getLocalPart();
     }
 
 
-    public String getAttributeNamespace(int index) {
-        throw new UnsupportedOperationException("Method is not implemented");
+    public QName getAttributeName(int index) {
+        return attributes.get(index).name;
     }
 
 
-    public String getAttributeLocalName(int index) {
-        throw new UnsupportedOperationException("Method is not implemented");
+    public String getAttributePrefix(int index) {
+        if ((null == attributes) || (index >= attributes.size())) {
+            throw new IndexOutOfBoundsException();
+        }
+        return null;
     }
 
 
-    public String getAttributePrefix(int index) {
-        throw new UnsupportedOperationException("Method is not implemented");
+    public String getAttributeType(int index) {
+        return null;
     }
 
 
-    public String getAttributeType(int index) {
-        throw new UnsupportedOperationException("Method is not implemented");
+    public String getAttributeNamespace(int index) {
+        return null;
     }
 
 
     public String getAttributeValue(int index) {
-        throw new UnsupportedOperationException("Method is not implemented");
+        if ((null == attributes) || (index >= attributes.size())) {
+            throw new IndexOutOfBoundsException();
+        }
+        return attributes.get(index).value;
+    }
+
+
+    public String getAttributeValue(String namespaceURI, String localName) {
+        if ((null == attributes) || (null == localName) || 
("".equals(localName))) {
+            throw new NoSuchElementException();
+        }
+        for (Attribute a : attributes) {
+            if (localName.equals(a.name.getLocalPart())) {
+                return a.value;
+            }
+        }
+        throw new NoSuchElementException();
     }
 
 
     public boolean isAttributeSpecified(int index) {
-        throw new UnsupportedOperationException("Method is not implemented");
+        return (null != attributes) && (attributes.size() >= index);
     }
 
 
@@ -542,7 +576,6 @@ public class MoshiXMLStreamReader implements 
XMLStreamReader {
                 localName = "";
             }
         } else {
-            System.out.println("stackObj is empty");
             throw new XMLStreamException("Error while processing input JSON 
stream, JSON request may not valid ," +
                     " it may has more end object characters ");
         }
@@ -736,4 +769,14 @@ public class MoshiXMLStreamReader implements 
XMLStreamReader {
         EndObjectBeginObject_START,
         EndObjectEndDocument,
     }
+
+    private static class Attribute {
+        private final QName name;
+        private final String value;
+
+        Attribute(QName name, String value) {
+            this.name = name;
+            this.value = value;
+        }
+    }
 }

Reply via email to