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

hutcheb pushed a commit to branch feature/native_opua_client
in repository https://gitbox.apache.org/repos/asf/plc4x.git


The following commit(s) were added to refs/heads/feature/native_opua_client by 
this push:
     new 37e612d  Implemented a node rearrange for opc:fields based on bit order
37e612d is described below

commit 37e612d9a0d0886fd6cade1ec27cfbab0f446579
Author: hutcheb <[email protected]>
AuthorDate: Mon Apr 19 06:56:26 2021 -0400

    Implemented a node rearrange for opc:fields based on bit order
---
 build-utils/language-base-freemarker/pom.xml       |   6 +
 .../BaseFreemarkerLanguageTemplateHelper.java      |   7 +
 .../templates/java/pojo-template.java.ftlh         |   1 -
 .../definitions/DefaultComplexTypeDefinition.java  |   5 +
 .../java/opcua/protocol/OpcuaProtocolLogic.java    |   2 +-
 protocols/opcua/pom.xml                            |  10 +-
 .../apache/plc4x/protocol/opcua/OpcuaProtocol.java |   4 +
 protocols/opcua/src/main/xslt/opc-types.xsl        | 160 ++++++++++++++++++++-
 8 files changed, 186 insertions(+), 9 deletions(-)

diff --git a/build-utils/language-base-freemarker/pom.xml 
b/build-utils/language-base-freemarker/pom.xml
index 8a7602e..727084c 100644
--- a/build-utils/language-base-freemarker/pom.xml
+++ b/build-utils/language-base-freemarker/pom.xml
@@ -61,6 +61,12 @@
           <version>0.9.0-SNAPSHOT</version>
           <scope>compile</scope>
       </dependency>
+    <dependency>
+      <groupId>net.sf.saxon</groupId>
+      <artifactId>Saxon-HE</artifactId>
+      <version>10.5</version>
+    </dependency>
+
   </dependencies>
 
 </project>
diff --git 
a/build-utils/language-base-freemarker/src/main/java/org/apache/plc4x/plugins/codegenerator/protocol/freemarker/BaseFreemarkerLanguageTemplateHelper.java
 
b/build-utils/language-base-freemarker/src/main/java/org/apache/plc4x/plugins/codegenerator/protocol/freemarker/BaseFreemarkerLanguageTemplateHelper.java
index 19fceaa..7e0ef70 100644
--- 
a/build-utils/language-base-freemarker/src/main/java/org/apache/plc4x/plugins/codegenerator/protocol/freemarker/BaseFreemarkerLanguageTemplateHelper.java
+++ 
b/build-utils/language-base-freemarker/src/main/java/org/apache/plc4x/plugins/codegenerator/protocol/freemarker/BaseFreemarkerLanguageTemplateHelper.java
@@ -29,6 +29,7 @@ import 
org.apache.plc4x.plugins.codegenerator.types.references.SimpleTypeReferen
 import 
org.apache.plc4x.plugins.codegenerator.types.references.StringTypeReference;
 import org.apache.plc4x.plugins.codegenerator.types.references.TypeReference;
 import org.apache.plc4x.plugins.codegenerator.types.terms.*;
+import org.w3c.dom.Node;
 
 import java.util.*;
 import java.util.stream.Collectors;
@@ -988,4 +989,10 @@ public abstract class BaseFreemarkerLanguageTemplateHelper 
implements Freemarker
         return null;
     }
 
+    public static String parseStructuredFields(Object nodeList) {
+        System.out.println((Node) nodeList);
+        System.out.println(nodeList.getClass().getName());
+        return "//Hello";
+    }
+
 }
diff --git 
a/build-utils/language-java/src/main/resources/templates/java/pojo-template.java.ftlh
 
b/build-utils/language-java/src/main/resources/templates/java/pojo-template.java.ftlh
index 11d5fb5..f61ff7e 100644
--- 
a/build-utils/language-java/src/main/resources/templates/java/pojo-template.java.ftlh
+++ 
b/build-utils/language-java/src/main/resources/templates/java/pojo-template.java.ftlh
@@ -161,7 +161,6 @@ public<#if helper.isDiscriminatedParentTypeDefinition()> 
abstract</#if> class ${
     }
 
 </#list>
-
 <#list type.virtualFields as field>
     <#if !helper.isDiscriminatorField(field.name)>
     public ${helper.getLanguageTypeNameForField(field)}<#if 
field.loopType??>[]</#if> get${field.name?cap_first}() {
diff --git 
a/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/model/definitions/DefaultComplexTypeDefinition.java
 
b/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/model/definitions/DefaultComplexTypeDefinition.java
index ac2dc4f..0fd24a5 100644
--- 
a/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/model/definitions/DefaultComplexTypeDefinition.java
+++ 
b/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/model/definitions/DefaultComplexTypeDefinition.java
@@ -72,6 +72,11 @@ public class DefaultComplexTypeDefinition extends 
DefaultTypeDefinition implemen
             field -> (AbstractField) field).collect(Collectors.toList());
     }
 
+    public List<ImplicitField> getImplicitFields() {
+        return fields.stream().filter(field -> field instanceof 
ImplicitField).map(
+            field -> (ImplicitField) field).collect(Collectors.toList());
+    }
+
     @Override
     public List<VirtualField> getVirtualFields() {
         return fields.stream().filter(field -> (field instanceof 
VirtualField)).map(field -> (VirtualField) field)
diff --git 
a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaProtocolLogic.java
 
b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaProtocolLogic.java
index 459b098..4c14583 100644
--- 
a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaProtocolLogic.java
+++ 
b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaProtocolLogic.java
@@ -186,7 +186,7 @@ public class OpcuaProtocolLogic extends 
Plc4xProtocolBase<OpcuaAPU> implements H
 
         int requestHandle = getRequestHandle();
 
-        ExpandedNodeId expandedNodeId = new ExpandedNodeIdFourByte(false,      
     //Namespace Uri Specified
+        ExpandedNodeId expandedNodeId = new ExpandedNodeId(false,           
//Namespace Uri Specified
             false,            //Server Index Specified
             NULL_STRING,                      //Namespace Uri
             1L,                     //Server Index
diff --git a/protocols/opcua/pom.xml b/protocols/opcua/pom.xml
index 172539a..1cc42a8 100644
--- a/protocols/opcua/pom.xml
+++ b/protocols/opcua/pom.xml
@@ -162,10 +162,16 @@
               </transformationSets>
             </configuration>
             <dependencies>
+              <!-- https://mvnrepository.com/artifact/net.sf.saxon/Saxon-HE -->
               <dependency>
                 <groupId>net.sf.saxon</groupId>
-                <artifactId>saxon</artifactId>
-                <version>8.7</version>
+                <artifactId>Saxon-HE</artifactId>
+                <version>10.5</version>
+              </dependency>
+              <dependency>
+                <groupId>org.apache.plc4x</groupId>
+                
<artifactId>plc4x-build-utils-language-base-freemarker</artifactId>
+                <version>0.9.0-SNAPSHOT</version>
               </dependency>
             </dependencies>
           </plugin>
diff --git 
a/protocols/opcua/src/main/java/org/apache/plc4x/protocol/opcua/OpcuaProtocol.java
 
b/protocols/opcua/src/main/java/org/apache/plc4x/protocol/opcua/OpcuaProtocol.java
index 1985acc..e220182 100644
--- 
a/protocols/opcua/src/main/java/org/apache/plc4x/protocol/opcua/OpcuaProtocol.java
+++ 
b/protocols/opcua/src/main/java/org/apache/plc4x/protocol/opcua/OpcuaProtocol.java
@@ -23,6 +23,7 @@ import 
org.apache.plc4x.plugins.codegenerator.language.mspec.parser.MessageForma
 import org.apache.plc4x.plugins.codegenerator.protocol.Protocol;
 import org.apache.plc4x.plugins.codegenerator.types.definitions.TypeDefinition;
 import 
org.apache.plc4x.plugins.codegenerator.types.exceptions.GenerationException;
+import org.w3c.dom.NodeList;
 
 import java.io.InputStream;
 import java.util.LinkedHashMap;
@@ -55,4 +56,7 @@ public class OpcuaProtocol implements Protocol {
         return typeDefinitionMap;
     }
 
+
+
+
 }
diff --git a/protocols/opcua/src/main/xslt/opc-types.xsl 
b/protocols/opcua/src/main/xslt/opc-types.xsl
index 2d96d04..7a382db 100644
--- a/protocols/opcua/src/main/xslt/opc-types.xsl
+++ b/protocols/opcua/src/main/xslt/opc-types.xsl
@@ -19,7 +19,10 @@
 -->
 <xsl:stylesheet version="2.0"
                 xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
+                xmlns:xs="http://www.w3.org/2001/XMLSchema";
                 xmlns:opc="http://opcfoundation.org/BinarySchema/";
+                xmlns:plc4x="https://plc4x.apache.org/";
+                xmlns:map="http://www.w3.org/2005/xpath-functions/map";
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
                 xmlns:ua="http://opcfoundation.org/UA/";
                 xmlns:tns="http://opcfoundation.org/UA/";
@@ -37,6 +40,23 @@
 
     <xsl:variable name="originaldoc" select="/"/>
 
+    <xsl:variable name="dataTypeLength" as="map(xs:string, xs:int)">
+        <xsl:map>
+            <xsl:for-each select="//opc:EnumeratedType">
+                <xsl:choose>
+                    <xsl:when test="@Name != '' or @LengthInBits != ''">
+                        <xsl:map-entry key="concat('ua:', xs:string(@Name))" 
select="xs:int(@LengthInBits)"/>
+                    </xsl:when>
+                </xsl:choose>
+            </xsl:for-each>
+        </xsl:map>
+    </xsl:variable>
+
+    <xsl:variable name="bitBuffer" as="map(xs:string, xs:int)">
+        <xsl:map>
+        </xsl:map>
+    </xsl:variable>
+
     <xsl:param name="file" select="document($services)"/>
     <xsl:param name="statusCodeFile" select="unparsed-text($statusCodes)"/>
     <xsl:param name="servicesEnumFile" select="unparsed-text($servicesEnum)"/>
@@ -105,6 +125,7 @@
     ]
 ]
 
+
 [type 'RequestHeader'
     <xsl:apply-templates 
select="/opc:TypeDictionary/opc:StructuredType[@Name='RequestHeader']"/>
 ]
@@ -419,6 +440,10 @@
     [optional uint 32 'serverIndex' 'serverIndexSpecified']
 ]
 
+[type 'ExpandedNodeId'
+    <xsl:apply-templates 
select="/opc:TypeDictionary/opc:StructuredType[@Name='ExpandedNodeId']"/>
+]
+
 [discriminatedType 'ExtensionObject'
     //A serialized object prefixed with its data type identifier.
     [simple ExpandedNodeId 'nodeId']
@@ -434,8 +459,9 @@
 ]
 
 [type 'PascalString'
-    [simple int 32 'stringLength']
-    [optional string 'stringLength == -1 ? 0 : stringLength * 8' 'UTF-8' 
'stringValue' 'stringLength >= 0']
+    [implicit int 32 'sLength'          'stringValue.length == 0 ? -1 : 
stringValue.length']
+    [virtual  int 32 'stringLength'     'stringValue.length == -1 ? 0 : 
stringValue.length']
+    [simple string 'stringLength * 8' 'UTF-8' 'stringValue']
 ]
 
 [type 'PascalByteString'
@@ -547,6 +573,7 @@
     </xsl:template>
 
     <xsl:template match="opc:EnumeratedType">
+        <xsl:message>[INFO] Parsing Enumerated Datatype - <xsl:value-of 
select="@Name"/></xsl:message>
         <xsl:apply-templates select="opc:Documentation"/>
         <xsl:apply-templates select="opc:EnumeratedValue"/>
     </xsl:template>
@@ -556,6 +583,7 @@
     </xsl:template>
 
     <xsl:template match="opc:EnumeratedValue">
+        <xsl:message>[INFO] Parsing Enumerated Value - <xsl:value-of 
select="@Name"/></xsl:message>
         <xsl:variable name="objectTypeId">
             <xsl:call-template name="clean-id-string">
                 <xsl:with-param name="text" select="@Name"/>
@@ -566,6 +594,7 @@
     </xsl:template>
 
     <xsl:template match="opc:OpaqueType[not(@Name = 'Duration')]">
+        <xsl:message>[INFO] Parsing Opaque Datatype - <xsl:value-of 
select="@Name"/></xsl:message>
         <xsl:variable name="objectTypeId">
             <xsl:call-template name="clean-id-string">
                 <xsl:with-param name="text" select="@Name"/>
@@ -578,6 +607,7 @@
     </xsl:template>
 
     <xsl:template match="opc:StructuredType[not(@Name = 'Vector')]">
+        <xsl:message>[INFO] Parsing Structured Datatype - <xsl:value-of 
select="@Name"/></xsl:message>
         <xsl:variable name="objectTypeId">
             <xsl:call-template name="clean-id-string">
                 <xsl:with-param name="text" select="@Name"/>
@@ -586,10 +616,20 @@
             </xsl:call-template>
         </xsl:variable>
         <xsl:apply-templates select="opc:Documentation"/>
-        <xsl:apply-templates select="opc:Field"/>
+        <xsl:choose>
+            <xsl:when test="@Name = 'ExpandedNodeId'">
+                <xsl:call-template name="plc4x:parseFields">
+                    <xsl:with-param name="baseNode" select="."/>
+                    <xsl:with-param 
name="currentNodePosition">1</xsl:with-param>
+                    <xsl:with-param 
name="currentBytePosition">0</xsl:with-param>
+                    <xsl:with-param 
name="currentBitPosition">0</xsl:with-param>
+                </xsl:call-template>
+            </xsl:when>
+        </xsl:choose>
     </xsl:template>
 
     <xsl:template match="opc:Field">
+        <xsl:message>[INFO] Parsing Field - <xsl:value-of 
select="@Name"/></xsl:message>
         <xsl:variable name="objectTypeId">
             <xsl:value-of select="@Name"/>
         </xsl:variable>
@@ -615,10 +655,12 @@
 
         <xsl:choose>
             <xsl:when test="@LengthField">[array <xsl:value-of 
select="$dataType"/>  '<xsl:value-of select="$lowerCaseName"/>' count 
'<xsl:value-of select="$lowerCaseLengthField"/>']
-    </xsl:when>
+            </xsl:when>
             <xsl:otherwise>[<xsl:value-of select="$mspecType"/><xsl:text> 
</xsl:text><xsl:value-of select="$dataType"/> '<xsl:value-of 
select="$lowerCaseName"/>']
-    </xsl:otherwise>
+            </xsl:otherwise>
         </xsl:choose>
+
+
     </xsl:template>
 
     <xsl:template name="clean-id-string">
@@ -692,4 +734,112 @@
 ]
     </xsl:template>
 
+    <!-- Gets the length in bits of a data type -->
+    <xsl:function name="plc4x:getDataTypeLength" as="xs:integer">
+        <xsl:param name="lengthMap" as="map(xs:string, xs:int)"/>
+        <xsl:param name="datatype"/>
+        <xsl:message>[DEBUG] Getting length of Data Type</xsl:message>
+        <xsl:message>[DEBUG] Data type <xsl:value-of 
select="xs:string($datatype/[@TypeName])"/></xsl:message>
+        <xsl:choose>
+            <xsl:when test="map:contains($lengthMap, 
xs:string($datatype/[@TypeName]))">
+                <xsl:message>[DEBUG] Bit Length <xsl:value-of 
select="$lengthMap(xs:string($datatype/[@TypeName]))"/></xsl:message>
+                <xsl:value-of select="map:get($lengthMap, 
xs:string($datatype/[@TypeName]))"/>
+            </xsl:when>
+            <xsl:when test="$datatype/[@TypeName] = 'opc:Bit'">
+                <xsl:choose>
+                    <xsl:when test="$datatype/[@Length] != ''">
+                        <xsl:value-of select="xs:int($datatype/[@Length])"/>
+                    </xsl:when>
+                    <xsl:otherwise>1</xsl:otherwise>
+                </xsl:choose>
+            </xsl:when>
+            <xsl:otherwise>8</xsl:otherwise>
+        </xsl:choose>
+    </xsl:function>
+
+    <!-- Parse the fields for each type, rearranging all of the bit based 
fields -->
+    <xsl:template name="plc4x:parseFields">
+        <xsl:param name="baseNode"/>
+        <xsl:param name="currentNodePosition" as="xs:int"/>
+        <xsl:param name="currentBitPosition" as="xs:int"/>
+        <xsl:param name="currentBytePosition" as="xs:int"/>
+        <xsl:message>Current node Position - <xsl:value-of 
select="$currentNodePosition"/>, Bit Position - <xsl:value-of 
select="$currentBitPosition"/>, Byte Position - <xsl:value-of 
select="$currentBytePosition"/></xsl:message>
+
+        <xsl:for-each select="$baseNode/opc:Field">
+            <xsl:message><xsl:value-of select="position()"/> - <xsl:value-of 
select="@TypeName"/></xsl:message>
+        </xsl:for-each>
+        <xsl:choose>
+            <xsl:when test="$currentNodePosition = count($baseNode/opc:Field)">
+                <xsl:apply-templates select="$baseNode/opc:Field"/>
+            </xsl:when>
+            <xsl:otherwise>
+                <xsl:for-each 
select="($baseNode/opc:Field)[$currentNodePosition]">
+                    <xsl:message><xsl:value-of select="position()"/> - 
<xsl:value-of select="@TypeName"/></xsl:message>
+                </xsl:for-each>
+                <xsl:choose>
+                    <xsl:when test="plc4x:getDataTypeLength($dataTypeLength, 
$baseNode/opc:Field[$currentNodePosition][@TypeName]) lt 8">
+                        <xsl:choose>
+                            <xsl:when test="$currentBitPosition=0">
+                                <!-- Put node into current position -->
+                                <xsl:message>[DEBUG] First Bit in 
Byte</xsl:message>
+                                <xsl:call-template name="plc4x:parseFields">
+                                    <xsl:with-param name="baseNode">
+                                        <xsl:copy-of 
select="$baseNode/opc:Field[position() lt $currentNodePosition]"/>
+                                        <xsl:copy-of 
select="$baseNode/opc:Field[position()=$currentNodePosition]"/>
+                                        <xsl:copy-of 
select="$baseNode/opc:Field[position() gt $currentNodePosition]"/>
+                                    </xsl:with-param>
+                                    <xsl:with-param name="currentNodePosition">
+                                        <xsl:value-of 
select="$currentNodePosition + 1"/>
+                                    </xsl:with-param>
+                                    <xsl:with-param name="currentBitPosition">
+                                        <xsl:value-of 
select="plc4x:getDataTypeLength($dataTypeLength, $baseNode/opc:Field[position() 
= $currentNodePosition][@TypeName]) + $currentBitPosition"/>
+                                    </xsl:with-param>
+                                    <xsl:with-param name="currentBytePosition">
+                                        <xsl:value-of 
select="$currentBytePosition + 1"/>
+                                    </xsl:with-param>
+                                </xsl:call-template>
+                            </xsl:when>
+                            <xsl:otherwise>
+                                <!-- Put node into correct position based on 
bit and byte position -->
+                                <xsl:message>[DEBUG] Additional Bit in 
Byte</xsl:message>
+                                <xsl:call-template name="plc4x:parseFields">
+                                    <xsl:with-param name="baseNode">
+                                        <xsl:copy-of 
select="$baseNode/opc:Field[position() lt ($currentNodePosition - 
$currentBytePosition)]"/>
+                                        <xsl:copy-of 
select="$baseNode/opc:Field[position()=$currentNodePosition]"/>
+                                        <xsl:copy-of 
select="$baseNode/opc:Field[(position() gt ($currentNodePosition - 
$currentBytePosition - 1)) and (position() lt ($currentNodePosition))]"/>
+                                        <xsl:copy-of 
select="$baseNode/opc:Field[position() gt $currentNodePosition]"/>
+                                    </xsl:with-param>
+                                    <xsl:with-param name="currentNodePosition">
+                                        <xsl:value-of 
select="$currentNodePosition + 1"/>
+                                    </xsl:with-param>
+                                    <xsl:with-param name="currentBitPosition">
+                                        <xsl:value-of 
select="plc4x:getDataTypeLength($dataTypeLength, $baseNode/opc:Field[position() 
= $currentNodePosition][@TypeName]) + $currentBitPosition"/>
+                                    </xsl:with-param>
+                                    <xsl:with-param name="currentBytePosition">
+                                        <xsl:value-of 
select="$currentBytePosition + 1"/>
+                                    </xsl:with-param>
+                                </xsl:call-template>
+                            </xsl:otherwise>
+                        </xsl:choose>
+                    </xsl:when>
+                    <xsl:otherwise>
+                        <!-- Put node into current position -->
+                        <xsl:message>[DEBUG] not a bit data type</xsl:message>
+                        <xsl:call-template name="plc4x:parseFields">
+                            <xsl:with-param name="baseNode">
+                                <xsl:copy-of 
select="$baseNode/opc:Field[position() lt $currentNodePosition]"/>
+                                <xsl:copy-of 
select="$baseNode/opc:Field[position()=$currentNodePosition]"/>
+                                <xsl:copy-of 
select="$baseNode/opc:Field[position() gt $currentNodePosition]"/>
+                            </xsl:with-param>
+                            <xsl:with-param name="currentNodePosition">
+                                <xsl:value-of select="$currentNodePosition + 
1"/>
+                            </xsl:with-param>
+                            <xsl:with-param 
name="currentBitPosition">0</xsl:with-param>
+                            <xsl:with-param 
name="currentBytePosition">0</xsl:with-param>
+                        </xsl:call-template>
+                    </xsl:otherwise>
+                </xsl:choose>
+            </xsl:otherwise>
+        </xsl:choose>
+    </xsl:template>
 </xsl:stylesheet>

Reply via email to