GetPouInstanceTagName optimized with XSLTModelQuery.
authorEdouard Tisserant
Mon, 19 Feb 2018 15:46:50 +0100
changeset 1950 752ec68da94d
parent 1949 c266fbaae0f6
child 1951 bbd1e1744c91
GetPouInstanceTagName optimized with XSLTModelQuery.
PLCControler.py
plcopen/InstanceTagnameCollector.py
plcopen/instance_tagname.xslt
plcopen/instance_tagname.ysl2
--- a/PLCControler.py	Mon Feb 19 15:15:36 2018 +0100
+++ b/PLCControler.py	Mon Feb 19 15:46:50 2018 +0100
@@ -42,6 +42,7 @@
 from plcopen.XSLTModelQuery import  _StringValue, _BoolValue, _translate_args
 from plcopen.InstancesPathCollector import InstancesPathCollector
 from plcopen.POUVariablesCollector import POUVariablesCollector
+from plcopen.InstanceTagnameCollector import InstanceTagnameCollector
 from graphics.GraphicCommons import *
 from PLCGenerator import *
 
@@ -125,31 +126,6 @@
             _translate_args([_StringValue] * 5 + [_BoolValue] + [_StringValue], args) +
             [self.GetType(), self.GetTree()])))
 
-class InstanceTagName(object):
-    """Helpers object for generating instance tagname"""
-
-    def __init__(self, controller):
-        self.Controller = controller
-        self.TagName = None
-
-    def GetTagName(self):
-        return self.TagName
-
-    def ConfigTagName(self, context, *args):
-        self.TagName = ComputeConfigurationName(args[0][0])
-
-    def ResourceTagName(self, context, *args):
-        self.TagName = ComputeConfigurationResourceName(args[0][0], args[1][0])
-
-    def PouTagName(self, context, *args):
-        self.TagName = ComputePouName(args[0][0])
-
-    def ActionTagName(self, context, *args):
-        self.TagName = ComputePouActionName(args[0][0], args[0][1])
-
-    def TransitionTagName(self, context, *args):
-        self.TagName = ComputePouTransitionName(args[0][0], args[0][1])
-
 
 # -------------------------------------------------------------------------------
 #           Helpers object for generating pou block instances list
@@ -408,6 +384,7 @@
         self.Reset()
         self.InstancesPathCollector = InstancesPathCollector(self)
         self.POUVariablesCollector = POUVariablesCollector(self)
+        self.InstanceTagnameCollector = InstanceTagnameCollector(self)
 
     # Reset PLCControler internal variables
     def Reset(self):
@@ -662,26 +639,10 @@
 
     def GetPouInstanceTagName(self, instance_path, debug=False):
         project = self.GetProject(debug)
-        factory = InstanceTagName(self)
-
-        parser = etree.XMLParser()
-        parser.resolvers.add(LibraryResolver(self, debug))
-
-        instance_tagname_xslt_tree = etree.XSLT(
-            etree.parse(
-                os.path.join(ScriptDirectory, "plcopen", "instance_tagname.xslt"),
-                parser),
-            extensions={("instance_tagname_ns", name): getattr(factory, name)
-                        for name in ["ConfigTagName",
-                                     "ResourceTagName",
-                                     "PouTagName",
-                                     "ActionTagName",
-                                     "TransitionTagName"]})
-
-        instance_tagname_xslt_tree(
-            project, instance_path=etree.XSLT.strparam(instance_path))
-
-        return factory.GetTagName()
+        if project is not None :
+            return self.InstanceTagnameCollector.Collect(project,
+                                                         debug,
+                                                         instance_path)
 
     def GetInstanceInfos(self, instance_path, debug=False):
         tagname = self.GetPouInstanceTagName(instance_path)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plcopen/InstanceTagnameCollector.py	Mon Feb 19 15:46:50 2018 +0100
@@ -0,0 +1,58 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# This file is part of Beremiz.
+# See COPYING file for copyrights details.
+
+from __future__ import absolute_import
+from plcopen.XSLTModelQuery import XSLTModelQuery, _StringValue, _BoolValue, _translate_args
+from plcopen.types_enums import *
+
+class InstanceTagName(object):
+    """Helpers object for generating instance tagname"""
+
+    def __init__(self):
+        self.TagName = None
+
+    def GetTagName(self):
+        return self.TagName
+
+    def ConfigTagName(self, context, *args):
+        self.TagName = ComputeConfigurationName(args[0][0])
+
+    def ResourceTagName(self, context, *args):
+        self.TagName = ComputeConfigurationResourceName(args[0][0], args[1][0])
+
+    def PouTagName(self, context, *args):
+        self.TagName = ComputePouName(args[0][0])
+
+    def ActionTagName(self, context, *args):
+        self.TagName = ComputePouActionName(args[0][0], args[0][1])
+
+    def TransitionTagName(self, context, *args):
+        self.TagName = ComputePouTransitionName(args[0][0], args[0][1])
+
+
+class InstanceTagnameCollector(XSLTModelQuery):
+    """ object for collecting instances path list"""
+    def __init__(self, controller):
+        XSLTModelQuery.__init__(self,
+                                controller,
+                                "instance_tagname.xslt",
+                                [(name, self.FactoryCaller(name)) 
+                                    for name in ["ConfigTagName",
+                                                 "ResourceTagName",
+                                                 "PouTagName",
+                                                 "ActionTagName",
+                                                 "TransitionTagName"]])
+
+    def FactoryCaller(self, funcname):
+        def CallFactory(*args):
+            return getattr(self.factory, funcname)(*args)
+        return CallFactory
+
+    def Collect(self, root, debug, instance_path):
+        self.factory = InstanceTagName()
+        self._process_xslt(root, debug, instance_path=instance_path)
+        res = self.factory.GetTagName()
+        self.factory = None
+        return res
--- a/plcopen/instance_tagname.xslt	Mon Feb 19 15:15:36 2018 +0100
+++ b/plcopen/instance_tagname.xslt	Mon Feb 19 15:46:50 2018 +0100
@@ -1,16 +1,11 @@
 <?xml version="1.0"?>
-<xsl:stylesheet xmlns:exsl="http://exslt.org/common" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:ppx="http://www.plcopen.org/xml/tc6_0201" xmlns:ns="instance_tagname_ns" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" extension-element-prefixes="ns" version="1.0" exclude-result-prefixes="ns">
+<xsl:stylesheet xmlns:exsl="http://exslt.org/common" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:ppx="http://www.plcopen.org/xml/tc6_0201" xmlns:ns="beremiz" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" extension-element-prefixes="ns" version="1.0" exclude-result-prefixes="ns">
   <xsl:output method="xml"/>
   <xsl:param name="instance_path"/>
-  <xsl:variable name="project">
-    <xsl:copy-of select="document('project')/project/*"/>
-  </xsl:variable>
-  <xsl:variable name="stdlib">
-    <xsl:copy-of select="document('stdlib')/stdlib/*"/>
-  </xsl:variable>
-  <xsl:variable name="extensions">
-    <xsl:copy-of select="document('extensions')/extensions/*"/>
-  </xsl:variable>
+  <xsl:variable name="project" select="ns:GetProject()"/>
+  <xsl:variable name="stdlib" select="ns:GetStdLibs()"/>
+  <xsl:variable name="extensions" select="ns:GetExtensions()"/>
+  <xsl:variable name="all_types" select="($project | $stdlib | $extensions)/ppx:types"/>
   <xsl:template name="element_name">
     <xsl:param name="path"/>
     <xsl:choose>
@@ -95,7 +90,7 @@
     <xsl:variable name="type_name">
       <xsl:value-of select="@typeName"/>
     </xsl:variable>
-    <xsl:apply-templates select="exsl:node-set($project)/ppx:project/ppx:types/ppx:pous/ppx:pou[@name=$type_name] |&#10;                 exsl:node-set($project)/ppx:project/ppx:types/ppx:dataTypes/ppx:dataType[@name=$type_name] |&#10;                 exsl:node-set($stdlib)/ppx:project/ppx:types/ppx:pous/ppx:pou[@name=$type_name] |&#10;                 exsl:node-set($stdlib)/ppx:project/ppx:types/ppx:dataTypes/ppx:dataType[@name=$type_name] |&#10;                 exsl:node-set($extensions)/ppx:project/ppx:types/ppx:pous/ppx:pou[@name=$type_name] |&#10;                 exsl:node-set($extensions)/ppx:project/ppx:types/ppx:dataTypes/ppx:dataType[@name=$type_name]">
+    <xsl:apply-templates select="$all_types/ppx:pous/ppx:pou[@name=$type_name] |                  $all_types/ppx:dataTypes/ppx:dataType[@name=$type_name]">
       <xsl:with-param name="element_path" select="$element_path"/>
     </xsl:apply-templates>
   </xsl:template>
@@ -142,7 +137,7 @@
     <xsl:variable name="type_name">
       <xsl:value-of select="@name"/>
     </xsl:variable>
-    <xsl:apply-templates select="exsl:node-set($project)/ppx:project/ppx:types/ppx:pous/ppx:pou[@name=$type_name] |&#10;                 exsl:node-set($project)/ppx:project/ppx:types/ppx:dataTypes/ppx:dataType[@name=$type_name] |&#10;                 exsl:node-set($stdlib)/ppx:project/ppx:types/ppx:pous/ppx:pou[@name=$type_name] |&#10;                 exsl:node-set($stdlib)/ppx:project/ppx:types/ppx:dataTypes/ppx:dataType[@name=$type_name] |&#10;                 exsl:node-set($extensions)/ppx:project/ppx:types/ppx:pous/ppx:pou[@name=$type_name] |&#10;                 exsl:node-set($extensions)/ppx:project/ppx:types/ppx:dataTypes/ppx:dataType[@name=$type_name]">
+    <xsl:apply-templates select="$all_types/ppx:pous/ppx:pou[@name=$type_name] |                  $all_types/ppx:dataTypes/ppx:dataType[@name=$type_name]">
       <xsl:with-param name="element_path" select="$element_path"/>
     </xsl:apply-templates>
   </xsl:template>
--- a/plcopen/instance_tagname.ysl2	Mon Feb 19 15:15:36 2018 +0100
+++ b/plcopen/instance_tagname.ysl2	Mon Feb 19 15:46:50 2018 +0100
@@ -1,22 +1,19 @@
 include yslt_noindent.yml2
 istylesheet xmlns:ppx="http://www.plcopen.org/xml/tc6_0201"
             xmlns:xhtml="http://www.w3.org/1999/xhtml"
-            xmlns:ns="instance_tagname_ns" 
+            xmlns:ns="beremiz" 
             extension-element-prefixes="ns" 
             exclude-result-prefixes="ns" {
     
     param "instance_path";
     
-    variable "project" {
-        copy "document('project')/project/*";
-    }
+    variable "project", "ns:GetProject()";
     
-    variable "stdlib" {
-        copy "document('stdlib')/stdlib/*";
-    }
-    variable "extensions" {
-        copy "document('extensions')/extensions/*";
-    }
+    variable "stdlib", "ns:GetStdLibs()";
+
+    variable "extensions", "ns:GetExtensions()";
+
+    variable "all_types", "($project | $stdlib | $extensions)/ppx:types";
     
     function "element_name" {
         param "path";
@@ -97,12 +94,8 @@
     template "ppx:pouInstance" {
         param "element_path";
         variable "type_name" > «@typeName»
-        apply """exsl:node-set($project)/ppx:project/ppx:types/ppx:pous/ppx:pou[@name=$type_name] |
-                 exsl:node-set($project)/ppx:project/ppx:types/ppx:dataTypes/ppx:dataType[@name=$type_name] |
-                 exsl:node-set($stdlib)/ppx:project/ppx:types/ppx:pous/ppx:pou[@name=$type_name] |
-                 exsl:node-set($stdlib)/ppx:project/ppx:types/ppx:dataTypes/ppx:dataType[@name=$type_name] |
-                 exsl:node-set($extensions)/ppx:project/ppx:types/ppx:pous/ppx:pou[@name=$type_name] |
-                 exsl:node-set($extensions)/ppx:project/ppx:types/ppx:dataTypes/ppx:dataType[@name=$type_name]""" {
+        apply """$all_types/ppx:pous/ppx:pou[@name=$type_name] | \
+                 $all_types/ppx:dataTypes/ppx:dataType[@name=$type_name]""" {
             with "element_path", "$element_path";
         }
     }
@@ -150,12 +143,8 @@
     template "ppx:derived" {
         param "element_path";
         variable "type_name" > «@name»
-        apply """exsl:node-set($project)/ppx:project/ppx:types/ppx:pous/ppx:pou[@name=$type_name] |
-                 exsl:node-set($project)/ppx:project/ppx:types/ppx:dataTypes/ppx:dataType[@name=$type_name] |
-                 exsl:node-set($stdlib)/ppx:project/ppx:types/ppx:pous/ppx:pou[@name=$type_name] |
-                 exsl:node-set($stdlib)/ppx:project/ppx:types/ppx:dataTypes/ppx:dataType[@name=$type_name] |
-                 exsl:node-set($extensions)/ppx:project/ppx:types/ppx:pous/ppx:pou[@name=$type_name] |
-                 exsl:node-set($extensions)/ppx:project/ppx:types/ppx:dataTypes/ppx:dataType[@name=$type_name]""" {
+        apply """$all_types/ppx:pous/ppx:pou[@name=$type_name] | \
+                 $all_types/ppx:dataTypes/ppx:dataType[@name=$type_name]""" {
             with "element_path", "$element_path";
         }
     }