plcopen/plcopen.py
changeset 1301 fcca121a000f
parent 1299 9ffc49bfdf9d
child 1302 7856cd7767d6
equal deleted inserted replaced
1300:8e1ee07bdff8 1301:fcca121a000f
   239         return [(tuple(parent_infos),) + result for result in TestTextElement(self.getanyText(), criteria)]
   239         return [(tuple(parent_infos),) + result for result in TestTextElement(self.getanyText(), criteria)]
   240     setattr(cls, "Search", Search)
   240     setattr(cls, "Search", Search)
   241     
   241     
   242 cls = PLCOpenParser.GetElementClass("project")
   242 cls = PLCOpenParser.GetElementClass("project")
   243 if cls:
   243 if cls:
   244     cls.EnumeratedDataTypeValues = {}
       
   245     cls.CustomDataTypeRange = {}
       
   246     cls.CustomTypeHierarchy = {}
       
   247     cls.ElementUsingTree = {}
   244     cls.ElementUsingTree = {}
   248     cls.CustomBlockTypes = OrderedDict()
   245     cls.CustomBlockTypes = OrderedDict()
   249     
   246     
   250     def setname(self, name):
   247     def setname(self, name):
   251         self.contentHeader.setname(name)
   248         self.contentHeader.setname(name)
   254     def getname(self):
   251     def getname(self):
   255         return self.contentHeader.getname()
   252         return self.contentHeader.getname()
   256     setattr(cls, "getname", getname)
   253     setattr(cls, "getname", getname)
   257     
   254     
   258     def getfileHeader(self):
   255     def getfileHeader(self):
   259         fileheader = {}
   256         fileheader_obj = self.fileHeader
   260         for name, value in [("companyName", self.fileHeader.getcompanyName()),
   257         return {
   261                             ("companyURL", self.fileHeader.getcompanyURL()),
   258             attr: value if value is not None else ""
   262                             ("productName", self.fileHeader.getproductName()),
   259             for attr, value in [
   263                             ("productVersion", self.fileHeader.getproductVersion()),
   260                 ("companyName", fileheader_obj.getcompanyName()),
   264                             ("productRelease", self.fileHeader.getproductRelease()),
   261                 ("companyURL", fileheader_obj.getcompanyURL()),
   265                             ("creationDateTime", self.fileHeader.getcreationDateTime()),
   262                 ("productName", fileheader_obj.getproductName()),
   266                             ("contentDescription", self.fileHeader.getcontentDescription())]:
   263                 ("productVersion", fileheader_obj.getproductVersion()),
   267             if value is not None:
   264                 ("productRelease", fileheader_obj.getproductRelease()),
   268                 fileheader[name] = value
   265                 ("creationDateTime", fileheader_obj.getcreationDateTime()),
   269             else:
   266                 ("contentDescription", fileheader_obj.getcontentDescription())]
   270                 fileheader[name] = ""
   267         }
   271         return fileheader
       
   272     setattr(cls, "getfileHeader", getfileHeader)
   268     setattr(cls, "getfileHeader", getfileHeader)
   273     
   269     
   274     def setfileHeader(self, fileheader):
   270     def setfileHeader(self, fileheader):
   275         if fileheader.has_key("companyName"):
   271         fileheader_obj = self.fileHeader
   276             self.fileHeader.setcompanyName(fileheader["companyName"])
   272         for attr, value in fileheader.iteritems():
   277         if fileheader.has_key("companyURL"):
   273             setattr(fileheader_obj, attr, value)
   278             self.fileHeader.setcompanyURL(fileheader["companyURL"])
       
   279         if fileheader.has_key("productName"):
       
   280             self.fileHeader.setproductName(fileheader["productName"])
       
   281         if fileheader.has_key("productVersion"):
       
   282             self.fileHeader.setproductVersion(fileheader["productVersion"])
       
   283         if fileheader.has_key("productRelease"):
       
   284             self.fileHeader.setproductRelease(fileheader["productRelease"])
       
   285         if fileheader.has_key("creationDateTime"):
       
   286             self.fileHeader.setcreationDateTime(fileheader["creationDateTime"])
       
   287         if fileheader.has_key("contentDescription"):
       
   288             self.fileHeader.setcontentDescription(fileheader["contentDescription"])
       
   289     setattr(cls, "setfileHeader", setfileHeader)
   274     setattr(cls, "setfileHeader", setfileHeader)
   290     
   275     
   291     def getcontentHeader(self):
   276     def getcontentHeader(self):
   292         contentheader = {}
   277         contentheader_obj = self.contentHeader
   293         for name, value in [("projectName", self.contentHeader.getname()),
   278         contentheader = {
   294                             ("projectVersion", self.contentHeader.getversion()),
   279             attr: value if value is not None else ""
   295                             ("modificationDateTime", self.contentHeader.getmodificationDateTime()),
   280             for attr, value in [
   296                             ("organization", self.contentHeader.getorganization()),
   281                 ("projectName", contentheader_obj.getname()),
   297                             ("authorName", self.contentHeader.getauthor()),
   282                 ("projectVersion", contentheader_obj.getversion()),
   298                             ("language", self.contentHeader.getlanguage())]:
   283                 ("modificationDateTime", contentheader_obj.getmodificationDateTime()),
   299             if value is not None:
   284                 ("organization", contentheader_obj.getorganization()),
   300                 contentheader[name] = value
   285                 ("authorName", contentheader_obj.getauthor()),
   301             else:
   286                 ("language", contentheader_obj.getlanguage())]
   302                 contentheader[name] = ""
   287         }
   303         contentheader["pageSize"] = self.contentHeader.getpageSize()
   288         contentheader["pageSize"] = self.contentHeader.getpageSize()
   304         contentheader["scaling"] = self.contentHeader.getscaling()
   289         contentheader["scaling"] = self.contentHeader.getscaling()
   305         return contentheader
   290         return contentheader
   306     setattr(cls, "getcontentHeader", getcontentHeader)
   291     setattr(cls, "getcontentHeader", getcontentHeader)
   307     
   292     
   308     def setcontentHeader(self, contentheader):
   293     def setcontentHeader(self, contentheader):
   309         if contentheader.has_key("projectName"):
   294         contentheader_obj = self.contentHeader
   310             self.contentHeader.setname(contentheader["projectName"])
   295         for attr, value in contentheader.iteritems():
   311         if contentheader.has_key("projectVersion"):
   296             if attr == "projectName":
   312             self.contentHeader.setversion(contentheader["projectVersion"])
   297                 contentheader_obj.setname(value)
   313         if contentheader.has_key("modificationDateTime"):
   298             elif attr == "projectVersion":
   314             self.contentHeader.setmodificationDateTime(contentheader["modificationDateTime"])
   299                 contentheader_obj.setversion(value)
   315         if contentheader.has_key("organization"):
   300             elif attr == "pageSize":
   316             self.contentHeader.setorganization(contentheader["organization"])
   301                 contentheader_obj.setpageSize(*contentheader["pageSize"])
   317         if contentheader.has_key("authorName"):
   302             elif attr == "scaling":
   318             self.contentHeader.setauthor(contentheader["authorName"])
   303                 contentheader_obj.setscaling(contentheader["scaling"])
   319         if contentheader.has_key("language"):
   304             else:
   320             self.contentHeader.setlanguage(contentheader["language"])
   305                 setattr(contentheader_obj, attr, value)
   321         if contentheader.has_key("pageSize"):
       
   322             self.contentHeader.setpageSize(*contentheader["pageSize"])
       
   323         if contentheader.has_key("scaling"):
       
   324             self.contentHeader.setscaling(contentheader["scaling"])
       
   325     setattr(cls, "setcontentHeader", setcontentHeader)
   306     setattr(cls, "setcontentHeader", setcontentHeader)
   326     
   307     
       
   308     def gettypeElement(self, element_type, name=None):
       
   309         filter = "[@name='%s']" % name if name is not None else ""
       
   310         elements = self.xpath("ppx:types/ppx:%(element_type)ss/ppx:%(element_type)s%(filter)s" % locals(),
       
   311                 namespaces=PLCOpenParser.NSMAP)
       
   312         if name is None:
       
   313             return elements
       
   314         elif len(elements) == 1:
       
   315             return elements[0]
       
   316         return None
       
   317     setattr(cls, "gettypeElement", gettypeElement)
       
   318     
   327     def getdataTypes(self):
   319     def getdataTypes(self):
   328         return self.types.getdataTypeElements()
   320         return self.getdataType()
   329     setattr(cls, "getdataTypes", getdataTypes)
   321     setattr(cls, "getdataTypes", getdataTypes)
   330     
   322     
   331     def getdataType(self, name):
   323     def getdataType(self, name=None):
   332         return self.types.getdataTypeElement(name)
   324         return self.gettypeElement("dataType", name)
   333     setattr(cls, "getdataType", getdataType)
   325     setattr(cls, "getdataType", getdataType)
   334     
   326     
   335     def appenddataType(self, name):
   327     def appenddataType(self, name):
   336         if self.CustomTypeHierarchy.has_key(name):
   328         if self.getdataType(name) is not None:
   337             raise ValueError, "\"%s\" Data Type already exists !!!"%name
   329             raise ValueError, "\"%s\" Data Type already exists !!!"%name
   338         self.types.appenddataTypeElement(name)
   330         self.types.appenddataTypeElement(name)
   339         self.AddCustomDataType(self.getdataType(name))
       
   340     setattr(cls, "appenddataType", appenddataType)
   331     setattr(cls, "appenddataType", appenddataType)
   341         
   332         
   342     def insertdataType(self, index, datatype):
   333     def insertdataType(self, index, datatype):
   343         self.types.insertdataTypeElement(index, datatype)
   334         self.types.insertdataTypeElement(index, datatype)
   344         self.AddCustomDataType(datatype)
       
   345     setattr(cls, "insertdataType", insertdataType)
   335     setattr(cls, "insertdataType", insertdataType)
   346     
   336     
   347     def removedataType(self, name):
   337     def removedataType(self, name):
   348         self.types.removedataTypeElement(name)
   338         self.types.removedataTypeElement(name)
   349         self.RefreshDataTypeHierarchy()
       
   350         self.RefreshElementUsingTree()
   339         self.RefreshElementUsingTree()
   351     setattr(cls, "removedataType", removedataType)
   340     setattr(cls, "removedataType", removedataType)
   352     
   341     
   353     def getpous(self):
   342     def getpous(self):
   354         return self.types.getpouElements()
   343         return self.getpou()
   355     setattr(cls, "getpous", getpous)
   344     setattr(cls, "getpous", getpous)
   356     
   345     
   357     def getpou(self, name):
   346     def getpou(self, name=None):
   358         return self.types.getpouElement(name)
   347         return self.gettypeElement("pou", name)
   359     setattr(cls, "getpou", getpou)
   348     setattr(cls, "getpou", getpou)
   360     
   349     
   361     def appendpou(self, name, pou_type, body_type):
   350     def appendpou(self, name, pou_type, body_type):
   362         self.types.appendpouElement(name, pou_type, body_type)
   351         self.types.appendpouElement(name, pou_type, body_type)
   363         self.AddCustomBlockType(self.getpou(name))
   352         self.AddCustomBlockType(self.getpou(name))
   373         self.RefreshCustomBlockTypes()
   362         self.RefreshCustomBlockTypes()
   374         self.RefreshElementUsingTree()
   363         self.RefreshElementUsingTree()
   375     setattr(cls, "removepou", removepou)
   364     setattr(cls, "removepou", removepou)
   376 
   365 
   377     def getconfigurations(self):
   366     def getconfigurations(self):
   378         configurations = self.instances.configurations.getconfiguration()
   367         return self.getconfiguration()
   379         if configurations is not None:
   368     setattr(cls, "getconfigurations", getconfigurations)
       
   369 
       
   370     def getconfiguration(self, name=None):
       
   371         configurations = self.xpath(
       
   372             "ppx:instances/ppx:configurations/ppx:configuration%s" %
       
   373                 ("[@name='%s']" % name if name is not None else ""),
       
   374             namespaces=PLCOpenParser.NSMAP)
       
   375         if name is None:
   380             return configurations
   376             return configurations
   381         return []
   377         elif len(configurations) == 1:
   382     setattr(cls, "getconfigurations", getconfigurations)
   378             return configurations[0]
   383 
       
   384     def getconfiguration(self, name):
       
   385         for configuration in self.instances.configurations.getconfiguration():
       
   386             if configuration.getname() == name:
       
   387                 return configuration
       
   388         return None
   379         return None
   389     setattr(cls, "getconfiguration", getconfiguration)
   380     setattr(cls, "getconfiguration", getconfiguration)
   390 
   381 
   391     def addconfiguration(self, name):
   382     def addconfiguration(self, name):
   392         for configuration in self.instances.configurations.getconfiguration():
   383         if self.getconfiguration(name) is not None:
   393             if configuration.getname() == name:
   384             raise ValueError, _("\"%s\" configuration already exists !!!") % name
   394                 raise ValueError, _("\"%s\" configuration already exists !!!")%name
       
   395         new_configuration = PLCOpenParser.CreateElement("configuration", "configurations")
   385         new_configuration = PLCOpenParser.CreateElement("configuration", "configurations")
   396         new_configuration.setname(name)
   386         new_configuration.setname(name)
   397         self.instances.configurations.appendconfiguration(new_configuration)
   387         self.instances.configurations.appendconfiguration(new_configuration)
   398     setattr(cls, "addconfiguration", addconfiguration)    
   388     setattr(cls, "addconfiguration", addconfiguration)    
   399 
   389 
   400     def removeconfiguration(self, name):
   390     def removeconfiguration(self, name):
   401         found = False
   391         configuration = self.getconfiguration(name)
   402         for idx, configuration in enumerate(self.instances.configurations.getconfiguration()):
   392         if configuration is None:
   403             if configuration.getname() == name:
   393             raise ValueError, ("\"%s\" configuration doesn't exist !!!") % name
   404                 self.instances.configurations.removeconfiguration(idx)
   394         self.instances.configurations.remove(configuration)
   405                 found = True
       
   406                 break
       
   407         if not found:
       
   408             raise ValueError, ("\"%s\" configuration doesn't exist !!!")%name
       
   409     setattr(cls, "removeconfiguration", removeconfiguration)
   395     setattr(cls, "removeconfiguration", removeconfiguration)
   410 
   396 
   411     def getconfigurationResource(self, config_name, name):
   397     def getconfigurationResource(self, config_name, name):
       
   398         resources = self.xpath(
       
   399             "ppx:instances/ppx:configurations/ppx:configuration[@name='%s']/ppx:resource[@name='%s']" % 
       
   400             (config_name, name),
       
   401             namespaces=PLCOpenParser.NSMAP)
       
   402         if len(resources) == 1:
       
   403             return resources[0]
       
   404         return None
       
   405     setattr(cls, "getconfigurationResource", getconfigurationResource)
       
   406 
       
   407     def addconfigurationResource(self, config_name, name):
       
   408         if self.getconfigurationResource(config_name, name) is not None:
       
   409             raise ValueError, _("\"%s\" resource already exists in \"%s\" configuration !!!") % (name, config_name)
   412         configuration = self.getconfiguration(config_name)
   410         configuration = self.getconfiguration(config_name)
   413         if configuration is not None:
   411         if configuration is not None:
   414             for resource in configuration.getresource():
       
   415                 if resource.getname() == name:
       
   416                     return resource
       
   417         return None
       
   418     setattr(cls, "getconfigurationResource", getconfigurationResource)
       
   419 
       
   420     def addconfigurationResource(self, config_name, name):
       
   421         configuration = self.getconfiguration(config_name)
       
   422         if configuration is not None:
       
   423             for resource in configuration.getresource():
       
   424                 if resource.getname() == name:
       
   425                     raise ValueError, _("\"%s\" resource already exists in \"%s\" configuration !!!")%(name, config_name)
       
   426             new_resource = PLCOpenParser.CreateElement("resource", "configuration")
   412             new_resource = PLCOpenParser.CreateElement("resource", "configuration")
   427             new_resource.setname(name)
   413             new_resource.setname(name)
   428             configuration.appendresource(new_resource)
   414             configuration.appendresource(new_resource)
   429     setattr(cls, "addconfigurationResource", addconfigurationResource)
   415     setattr(cls, "addconfigurationResource", addconfigurationResource)
   430 
   416 
   431     def removeconfigurationResource(self, config_name, name):
   417     def removeconfigurationResource(self, config_name, name):
   432         configuration = self.getconfiguration(config_name)
   418         configuration = self.getconfiguration(config_name)
       
   419         found = False
   433         if configuration is not None:
   420         if configuration is not None:
   434             found = False
   421             resource = self.getconfigurationResource(config_name, name)
   435             for idx, resource in enumerate(configuration.getresource()):
   422             if resource is not None:
   436                 if resource.getname() == name:
   423                 configuration.remove(resource)
   437                     configuration.removeresource(idx)
   424                 found = True
   438                     found = True
   425         if not found:
   439                     break
   426             raise ValueError, _("\"%s\" resource doesn't exist in \"%s\" configuration !!!")%(name, config_name)
   440             if not found:
       
   441                 raise ValueError, _("\"%s\" resource doesn't exist in \"%s\" configuration !!!")%(name, config_name)
       
   442     setattr(cls, "removeconfigurationResource", removeconfigurationResource)
   427     setattr(cls, "removeconfigurationResource", removeconfigurationResource)
   443 
   428 
   444     def updateElementName(self, old_name, new_name):
   429     def updateElementName(self, old_name, new_name):
   445         for datatype in self.types.getdataTypeElements():
   430         for datatype in self.getdataTypes():
   446             datatype.updateElementName(old_name, new_name)
   431             datatype.updateElementName(old_name, new_name)
   447         for pou in self.types.getpouElements():
   432         for pou in self.getpous():
   448             pou.updateElementName(old_name, new_name)
   433             pou.updateElementName(old_name, new_name)
   449         for configuration in self.instances.configurations.getconfiguration():
   434         for configuration in self.getconfigurations():
   450             configuration.updateElementName(old_name, new_name)
   435             configuration.updateElementName(old_name, new_name)
   451     setattr(cls, "updateElementName", updateElementName)
   436     setattr(cls, "updateElementName", updateElementName)
   452 
   437 
   453     def updateElementAddress(self, old_leading, new_leading):
   438     def updateElementAddress(self, old_leading, new_leading):
   454         address_model = re.compile(FILTER_ADDRESS_MODEL % old_leading)
   439         address_model = re.compile(FILTER_ADDRESS_MODEL % old_leading)
   455         for pou in self.types.getpouElements():
   440         for pou in self.getpous():
   456             pou.updateElementAddress(address_model, new_leading)
   441             pou.updateElementAddress(address_model, new_leading)
   457         for configuration in self.instances.configurations.getconfiguration():
   442         for configuration in self.getconfigurations():
   458             configuration.updateElementAddress(address_model, new_leading)
   443             configuration.updateElementAddress(address_model, new_leading)
   459     setattr(cls, "updateElementAddress", updateElementAddress)
   444     setattr(cls, "updateElementAddress", updateElementAddress)
   460 
   445 
   461     def removeVariableByAddress(self, address):
   446     def removeVariableByAddress(self, address):
   462         for pou in self.types.getpouElements():
   447         for pou in self.getpous():
   463             pou.removeVariableByAddress(address)
   448             pou.removeVariableByAddress(address)
   464         for configuration in self.instances.configurations.getconfiguration():
   449         for configuration in self.getconfigurations():
   465             configuration.removeVariableByAddress(address)
   450             configuration.removeVariableByAddress(address)
   466     setattr(cls, "removeVariableByAddress", removeVariableByAddress)
   451     setattr(cls, "removeVariableByAddress", removeVariableByAddress)
   467 
   452 
   468     def removeVariableByFilter(self, leading):
   453     def removeVariableByFilter(self, leading):
   469         address_model = re.compile(FILTER_ADDRESS_MODEL % leading)
   454         address_model = re.compile(FILTER_ADDRESS_MODEL % leading)
   470         for pou in self.types.getpouElements():
   455         for pou in self.getpous():
   471             pou.removeVariableByFilter(address_model)
   456             pou.removeVariableByFilter(address_model)
   472         for configuration in self.instances.configurations.getconfiguration():
   457         for configuration in self.getconfigurations():
   473             configuration.removeVariableByFilter(address_model)
   458             configuration.removeVariableByFilter(address_model)
   474     setattr(cls, "removeVariableByFilter", removeVariableByFilter)
   459     setattr(cls, "removeVariableByFilter", removeVariableByFilter)
   475 
       
   476     def RefreshDataTypeHierarchy(self):
       
   477         self.EnumeratedDataTypeValues = {}
       
   478         self.CustomDataTypeRange = {}
       
   479         self.CustomTypeHierarchy = {}
       
   480         for datatype in self.getdataTypes():
       
   481             self.AddCustomDataType(datatype)
       
   482     setattr(cls, "RefreshDataTypeHierarchy", RefreshDataTypeHierarchy)
       
   483 
       
   484     def AddCustomDataType(self, datatype):
       
   485         name = datatype.getname()
       
   486         basetype_content = datatype.getbaseType().getcontent()
       
   487         basetype_content_name = basetype_content.getLocalTag()
       
   488         if basetype_content.__class__ == DefaultElementClass:
       
   489             self.CustomTypeHierarchy[name] = basetype_content_name
       
   490         elif basetype_content_name in ["string", "wstring"]:
       
   491             self.CustomTypeHierarchy[name] = basetype_content_name.upper()
       
   492         elif basetype_content_name == "derived":
       
   493             self.CustomTypeHierarchy[name] = basetype_content.getname()
       
   494         elif basetype_content_name in ["subrangeSigned", "subrangeUnsigned"]:
       
   495             range = (basetype_content.range.getlower(), 
       
   496                      basetype_content.range.getupper())
       
   497             self.CustomDataTypeRange[name] = range
       
   498             base_type = basetype_content.baseType.getcontent()
       
   499             if base_type.__class__ == DefaultElementClass:
       
   500                 self.CustomTypeHierarchy[name] = base_type.getLocalTag()
       
   501             else:
       
   502                 self.CustomTypeHierarchy[name] = base_type.getname()
       
   503         else:
       
   504             if basetype_content_name == "enum":
       
   505                 values = []
       
   506                 for value in basetype_content.xpath("ppx:values/ppx:value", namespaces=PLCOpenParser.NSMAP):
       
   507                     values.append(value.getname())
       
   508                 self.EnumeratedDataTypeValues[name] = values
       
   509             self.CustomTypeHierarchy[name] = "ANY_DERIVED"
       
   510     setattr(cls, "AddCustomDataType", AddCustomDataType)
       
   511 
   460 
   512     # Update Block types with user-defined pou added
   461     # Update Block types with user-defined pou added
   513     def RefreshCustomBlockTypes(self):
   462     def RefreshCustomBlockTypes(self):
   514         # Reset the tree of user-defined pou cross-use
   463         # Reset the tree of user-defined pou cross-use
   515         self.CustomBlockTypes = OrderedDict()
   464         self.CustomBlockTypes = OrderedDict()
   611                         if vartype_content.getLocalTag() == "derived":
   560                         if vartype_content.getLocalTag() == "derived":
   612                             self.AddElementUsingTreeInstance(name, vartype_content)
   561                             self.AddElementUsingTreeInstance(name, vartype_content)
   613         
   562         
   614     setattr(cls, "RefreshElementUsingTree", RefreshElementUsingTree)
   563     setattr(cls, "RefreshElementUsingTree", RefreshElementUsingTree)
   615 
   564 
   616     def GetParentType(self, type):
       
   617         if self.CustomTypeHierarchy.has_key(type):
       
   618             return self.CustomTypeHierarchy[type]
       
   619         elif TypeHierarchy.has_key(type):
       
   620             return TypeHierarchy[type]
       
   621         return None
       
   622     setattr(cls, "GetParentType", GetParentType)
       
   623 
       
   624     def GetBaseType(self, type):
       
   625         parent_type = self.GetParentType(type)
       
   626         if parent_type is not None:
       
   627             if parent_type.startswith("ANY"):
       
   628                 return type
       
   629             else:
       
   630                 return self.GetBaseType(parent_type)
       
   631         return None
       
   632     setattr(cls, "GetBaseType", GetBaseType)
       
   633 
       
   634     def GetSubrangeBaseTypes(self, exclude):
       
   635         derived = []
       
   636         for type in self.CustomTypeHierarchy.keys():
       
   637             for base_type in DataTypeRange.keys():
       
   638                 if self.IsOfType(type, base_type) and not self.IsOfType(type, exclude):
       
   639                     derived.append(type)
       
   640                     break
       
   641         return derived
       
   642     setattr(cls, "GetSubrangeBaseTypes", GetSubrangeBaseTypes)
       
   643 
       
   644     """
       
   645     returns true if the given data type is the same that "reference" meta-type or one of its types.
       
   646     """
       
   647     def IsOfType(self, type, reference):
       
   648         if reference is None:
       
   649             return True
       
   650         elif type == reference:
       
   651             return True
       
   652         else:
       
   653             parent_type = self.GetParentType(type)
       
   654             if parent_type is not None:
       
   655                 return self.IsOfType(parent_type, reference)
       
   656         return False
       
   657     setattr(cls, "IsOfType", IsOfType)
       
   658 
       
   659     # Return if pou given by name is used by another pou
   565     # Return if pou given by name is used by another pou
   660     def ElementIsUsed(self, name):
   566     def ElementIsUsed(self, name):
   661         elements = self.ElementUsingTree.get(name, None)
   567         elements = self.ElementUsingTree.get(name, None)
   662         return elements is not None
   568         return elements is not None
   663     setattr(cls, "ElementIsUsed", ElementIsUsed)
   569     setattr(cls, "ElementIsUsed", ElementIsUsed)
   664 
       
   665     def DataTypeIsDerived(self, name):
       
   666         return name in self.CustomTypeHierarchy.values()
       
   667     setattr(cls, "DataTypeIsDerived", DataTypeIsDerived)
       
   668 
   570 
   669     # Return if pou given by name is directly or undirectly used by the reference pou
   571     # Return if pou given by name is directly or undirectly used by the reference pou
   670     def ElementIsUsedBy(self, name, reference):
   572     def ElementIsUsedBy(self, name, reference):
   671         elements = self.ElementUsingTree.get(name, set())
   573         elements = self.ElementUsingTree.get(name, set())
   672         # Test if pou is directly used by reference
   574         # Test if pou is directly used by reference
   680                 if selffn(element, reference):
   582                 if selffn(element, reference):
   681                     return True
   583                     return True
   682         return False
   584         return False
   683     setattr(cls, "ElementIsUsedBy", ElementIsUsedBy)
   585     setattr(cls, "ElementIsUsedBy", ElementIsUsedBy)
   684 
   586 
   685     def GetDataTypeRange(self, type):
   587     def GetEnumeratedDataTypeValues(self):
   686         if self.CustomDataTypeRange.has_key(type):
   588         return [
   687             return self.CustomDataTypeRange[type]
   589             value.getname() 
   688         elif DataTypeRange.has_key(type):
   590             for value in self.xpath(
   689             return DataTypeRange[type]
   591                 "ppx:types/ppx:dataTypes/ppx:dataType/ppx:baseType/ppx:enum/ppx:values/ppx:value",
   690         else:
   592                 namespaces=PLCOpenParser.NSMAP)]
   691             parent_type = self.GetParentType(type)
       
   692             if parent_type is not None:
       
   693                 return self.GetDataTypeRange(parent_type)
       
   694         return None
       
   695     setattr(cls, "GetDataTypeRange", GetDataTypeRange)
       
   696 
       
   697     def GetEnumeratedDataTypeValues(self, type = None):
       
   698         if type is None:
       
   699             all_values = []
       
   700             for values in self.EnumeratedDataTypeValues.values():
       
   701                 all_values.extend(values)
       
   702             return all_values
       
   703         elif self.EnumeratedDataTypeValues.has_key(type):
       
   704             return self.EnumeratedDataTypeValues[type]
       
   705         return []
       
   706     setattr(cls, "GetEnumeratedDataTypeValues", GetEnumeratedDataTypeValues)
   593     setattr(cls, "GetEnumeratedDataTypeValues", GetEnumeratedDataTypeValues)
   707 
   594 
   708     # Function that returns the block definition associated to the block type given
   595     # Function that returns the block definition associated to the block type given
   709     def GetCustomBlockType(self, typename, inputs = None):
   596     def GetCustomBlockType(self, typename, inputs = None):
   710         customblocktype = self.CustomBlockTypes.get(typename,None)
   597         customblocktype = self.CustomBlockTypes.get(typename,None)
   732     setattr(cls, "GetCustomBlockTypes", GetCustomBlockTypes)
   619     setattr(cls, "GetCustomBlockTypes", GetCustomBlockTypes)
   733 
   620 
   734     # Return Function Block types checking for recursion
   621     # Return Function Block types checking for recursion
   735     def GetCustomFunctionBlockTypes(self, exclude = None):
   622     def GetCustomFunctionBlockTypes(self, exclude = None):
   736         if exclude is not None:
   623         if exclude is not None:
   737             return [customblocktype for name,customblocktype in self.CustomBlockTypes.iteritems()
   624             return [name for name,customblocktype in self.CustomBlockTypes.iteritems()
   738                 if (customblocktype["type"] == "functionBlock" 
   625                 if (customblocktype["type"] == "functionBlock" 
   739                     and name != exclude 
   626                     and name != exclude 
   740                     and not self.ElementIsUsedBy(exclude, name))]
   627                     and not self.ElementIsUsedBy(exclude, name))]
   741         return [customblocktype for customblocktype in self.CustomBlockTypes.itervalues()
   628         return [name for customblocktype in self.CustomBlockTypes.itervalues()
   742             if customblocktype["type"] == "functionBlock"]
   629             if customblocktype["type"] == "functionBlock"]
   743     setattr(cls, "GetCustomFunctionBlockTypes", GetCustomFunctionBlockTypes)
   630     setattr(cls, "GetCustomFunctionBlockTypes", GetCustomFunctionBlockTypes)
   744 
   631 
   745     # Return Block types checking for recursion
   632     # Return Block types checking for recursion
   746     def GetCustomBlockResource(self):
   633     def GetCustomBlockResource(self):
   747         return [customblocktype for customblocktype in self.CustomBlockTypes.itervalues()
   634         return [customblocktype["name"] for customblocktype in self.CustomBlockTypes.itervalues()
   748             if customblocktype["type"] == "program"]
   635             if customblocktype["type"] == "program"]
   749     setattr(cls, "GetCustomBlockResource", GetCustomBlockResource)
   636     setattr(cls, "GetCustomBlockResource", GetCustomBlockResource)
   750 
   637 
   751     # Return Data Types checking for recursion
   638     # Return Data Types checking for recursion
   752     def GetCustomDataTypes(self, exclude = "", only_locatable = False):
   639     def GetCustomDataTypes(self, exclude = "", only_locatable = False):
   756                 customdatatype_name = customdatatype.getname()
   643                 customdatatype_name = customdatatype.getname()
   757                 if customdatatype_name != exclude and not self.ElementIsUsedBy(exclude, customdatatype_name):
   644                 if customdatatype_name != exclude and not self.ElementIsUsedBy(exclude, customdatatype_name):
   758                     customdatatypes.append({"name": customdatatype_name, "infos": customdatatype})
   645                     customdatatypes.append({"name": customdatatype_name, "infos": customdatatype})
   759         return customdatatypes
   646         return customdatatypes
   760     setattr(cls, "GetCustomDataTypes", GetCustomDataTypes)
   647     setattr(cls, "GetCustomDataTypes", GetCustomDataTypes)
   761 
       
   762     # Return if Data Type can be used for located variables
       
   763     def IsLocatableType(self, datatype):
       
   764         basetype_content = datatype.baseType.getcontent()
       
   765         basetype_content_name = basetype_content.getLocalTag()
       
   766         if basetype_content_name in ["enum", "struct"]:
       
   767             return False
       
   768         elif basetype_content_name == "derived":
       
   769             base_type = self.getdataType(basetype_content.getname())
       
   770             if base_type is not None:
       
   771                 return self.IsLocatableType(base_type)
       
   772         elif basetype_content_name == "array":
       
   773             array_base_type = basetype_content.baseType.getcontent()
       
   774             if array_base_type == DefaultElementClass and array_base_type.getLocalTag() not in ["string", "wstring"]:
       
   775                 base_type = self.getdataType(array_base_type.getname())
       
   776                 if base_type is not None:
       
   777                     return self.IsLocatableType(base_type)
       
   778         return True
       
   779     setattr(cls, "IsLocatableType", IsLocatableType)
       
   780 
   648 
   781     def Search(self, criteria, parent_infos=[]):
   649     def Search(self, criteria, parent_infos=[]):
   782         result = self.types.Search(criteria, parent_infos)
   650         result = self.types.Search(criteria, parent_infos)
   783         for configuration in self.instances.configurations.getconfiguration():
   651         for configuration in self.instances.configurations.getconfiguration():
   784             result.extend(configuration.Search(criteria, parent_infos))
   652             result.extend(configuration.Search(criteria, parent_infos))
  2478     setattr(cls, "translate", translate)
  2346     setattr(cls, "translate", translate)
  2479     
  2347     
  2480     def filterConnections(self, connections):
  2348     def filterConnections(self, connections):
  2481         _filterConnectionsSingle(self, connections)
  2349         _filterConnectionsSingle(self, connections)
  2482         condition_connection = self.getconditionConnection()
  2350         condition_connection = self.getconditionConnection()
  2483         if condition_connection:
  2351         if condition_connection is not None:
  2484             _filterConnections(condition_connection, self.localId, connections)
  2352             _filterConnections(condition_connection, self.localId, connections)
  2485     setattr(cls, "filterConnections", filterConnections)
  2353     setattr(cls, "filterConnections", filterConnections)
  2486     
  2354     
  2487     def updateConnectionsId(self, translation):
  2355     def updateConnectionsId(self, translation):
  2488         connections_end = []
  2356         connections_end = []
  2489         if self.connectionPointIn is not None:
  2357         if self.connectionPointIn is not None:
  2490             connections_end = _updateConnectionsId(self.connectionPointIn, translation)
  2358             connections_end = _updateConnectionsId(self.connectionPointIn, translation)
  2491         condition_connection = self.getconditionConnection()
  2359         condition_connection = self.getconditionConnection()
  2492         if condition_connection:
  2360         if condition_connection is not None:
  2493             connections_end.extend(_updateConnectionsId(condition_connection, translation))
  2361             connections_end.extend(_updateConnectionsId(condition_connection, translation))
  2494         return _getconnectionsdefinition(self, connections_end)
  2362         return _getconnectionsdefinition(self, connections_end)
  2495     setattr(cls, "updateConnectionsId", updateConnectionsId)
  2363     setattr(cls, "updateConnectionsId", updateConnectionsId)
  2496 
  2364 
  2497     def updateElementName(self, old_name, new_name):
  2365     def updateElementName(self, old_name, new_name):
  2498         if self.condition:
  2366         if self.condition is not None:
  2499             content = self.condition.getcontent()
  2367             content = self.condition.getcontent()
  2500             content_name = content.getLocalTag()
  2368             content_name = content.getLocalTag()
  2501             if content_name == "reference":
  2369             if content_name == "reference":
  2502                 if content.getname() == old_name:
  2370                 if content.getname() == old_name:
  2503                     content.setname(new_name)
  2371                     content.setname(new_name)
  2504             elif content_name == "inline":
  2372             elif content_name == "inline":
  2505                 content.updateElementName(old_name, new_name)
  2373                 content.updateElementName(old_name, new_name)
  2506     setattr(cls, "updateElementName", updateElementName)
  2374     setattr(cls, "updateElementName", updateElementName)
  2507 
  2375 
  2508     def updateElementAddress(self, address_model, new_leading):
  2376     def updateElementAddress(self, address_model, new_leading):
  2509         if self.condition:
  2377         if self.condition is not None:
  2510             content = self.condition.getcontent()
  2378             content = self.condition.getcontent()
  2511             content_name = content.getLocalTag()
  2379             content_name = content.getLocalTag()
  2512             if content_name == "reference":
  2380             if content_name == "reference":
  2513                 content.setname(update_address(content.getname(), address_model, new_leading))
  2381                 content.setname(update_address(content.getname(), address_model, new_leading))
  2514             elif content_name == "inline":
  2382             elif content_name == "inline":
  2515                 content.updateElementAddress(address_model, new_leading)
  2383                 content.updateElementAddress(address_model, new_leading)
  2516     setattr(cls, "updateElementAddress", updateElementAddress)
  2384     setattr(cls, "updateElementAddress", updateElementAddress)
  2517 
  2385 
  2518     def getconnections(self):
  2386     def getconnections(self):
  2519         condition_connection = self.getconditionConnection()
  2387         condition_connection = self.getconditionConnection()
  2520         if condition_connection:
  2388         if condition_connection is not None:
  2521             return condition_connection.getconnections()
  2389             return condition_connection.getconnections()
  2522         return None
  2390         return None
  2523     setattr(cls, "getconnections", getconnections)
  2391     setattr(cls, "getconnections", getconnections)
  2524     
  2392     
  2525     def Search(self, criteria, parent_infos=[]):
  2393     def Search(self, criteria, parent_infos=[]):