| 1 | ## Copyright 2005, 2006, 2007 Virginia Polytechnic Institute and State University |
|---|
| 2 | ## |
|---|
| 3 | ## This file is part of the OSSIE Waveform Developer. |
|---|
| 4 | ## |
|---|
| 5 | ## OSSIE Waveform Developer is free software; you can redistribute it and/or modify |
|---|
| 6 | ## it under the terms of the GNU General Public License as published by |
|---|
| 7 | ## the Free Software Foundation; either version 2 of the License, or |
|---|
| 8 | ## (at your option) any later version. |
|---|
| 9 | ## |
|---|
| 10 | ## OSSIE Waveform Developer is distributed in the hope that it will be useful, |
|---|
| 11 | ## but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 12 | ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 13 | ## GNU General Public License for more details. |
|---|
| 14 | ## |
|---|
| 15 | ## You should have received a copy of the GNU General Public License |
|---|
| 16 | ## along with OSSIE Waveform Developer; if not, write to the Free Software |
|---|
| 17 | ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|---|
| 18 | |
|---|
| 19 | import os, sys |
|---|
| 20 | |
|---|
| 21 | import xml.dom.minidom |
|---|
| 22 | from xml.dom.minidom import Node |
|---|
| 23 | from importResource import getSimpleProperty, getSimpleSequenceProperty |
|---|
| 24 | |
|---|
| 25 | import ComponentClass as CC |
|---|
| 26 | from errorMsg import * |
|---|
| 27 | |
|---|
| 28 | availableTypes = ["boolean", "char", "double", "float", "short", "long", |
|---|
| 29 | "objref", "octet", "string", "ulong","ushort"] |
|---|
| 30 | availableKinds = ["allocation", "configure", "test", "execparam", "factoryparam"] |
|---|
| 31 | availableActions = ["eq", "ne", "gt", "lt", "ge", "le", "external"] |
|---|
| 32 | availableModes = ["readonly", "readwrite", "writeonly"] |
|---|
| 33 | |
|---|
| 34 | def getNode(inpath,Nname,parent): |
|---|
| 35 | |
|---|
| 36 | scdPath = inpath + "DeviceManager" + ".scd.xml" |
|---|
| 37 | spdPath = inpath + "DeviceManager" + ".spd.xml" |
|---|
| 38 | prfPath = inpath + "DeviceManager" + ".prf.xml" |
|---|
| 39 | dcdPath = inpath + "DeviceManager" + ".dcd.xml" |
|---|
| 40 | |
|---|
| 41 | # import the node description from the node's .spd.xml file |
|---|
| 42 | doc_node_spd = xml.dom.minidom.parse(spdPath) |
|---|
| 43 | softpkgNode = doc_node_spd.getElementsByTagName("softpkg")[0] |
|---|
| 44 | Ndescription = '' |
|---|
| 45 | for n in softpkgNode.childNodes: |
|---|
| 46 | if n.nodeName == "description": |
|---|
| 47 | nDescriptionNode = doc_node_spd.getElementsByTagName("description") |
|---|
| 48 | try: |
|---|
| 49 | Ndescription = nDescriptionNode[0].firstChild.data |
|---|
| 50 | except: |
|---|
| 51 | pass |
|---|
| 52 | break |
|---|
| 53 | |
|---|
| 54 | newNode = CC.Node(name=Nname, path=inpath, description=Ndescription, generate=False) |
|---|
| 55 | |
|---|
| 56 | # |
|---|
| 57 | # Build the node from the DCD |
|---|
| 58 | # |
|---|
| 59 | doc_dcd = xml.dom.minidom.parse(dcdPath) |
|---|
| 60 | partitioningNodeList = doc_dcd.getElementsByTagName('partitioning') |
|---|
| 61 | if len(partitioningNodeList) != 1: |
|---|
| 62 | errorMsg(parent,"Invalid file: " + dcdPath + " (partitioning)") |
|---|
| 63 | return None |
|---|
| 64 | |
|---|
| 65 | try: |
|---|
| 66 | deviceconfigurationNode = doc_dcd.getElementsByTagName('deviceconfiguration')[0] |
|---|
| 67 | except: |
|---|
| 68 | errorMsg(parent,"Invalid file: " + dcdPath + " (deviceconfiguration)") |
|---|
| 69 | return None |
|---|
| 70 | newNode.id = deviceconfigurationNode.getAttribute("id") |
|---|
| 71 | |
|---|
| 72 | # |
|---|
| 73 | componentplacementNodeList = doc_dcd.getElementsByTagName("componentplacement") |
|---|
| 74 | for componentplacementNode in componentplacementNodeList: |
|---|
| 75 | newComp = CC.Component(type='executabledevice') |
|---|
| 76 | newComp.name = componentplacementNode.getElementsByTagName("usagename")[0].firstChild.data |
|---|
| 77 | |
|---|
| 78 | # componentinstantiation |
|---|
| 79 | # strip off the DCE: part of the id becuase it will get added back in later |
|---|
| 80 | tmpUUID = componentplacementNode.getElementsByTagName("componentinstantiation")[0].getAttribute("id") |
|---|
| 81 | newComp.uuid = str( tmpUUID ).strip("DCE:") |
|---|
| 82 | |
|---|
| 83 | # componentfileref |
|---|
| 84 | tmpNode = componentplacementNode.getElementsByTagName("componentfileref") |
|---|
| 85 | newComp.file_uuid = str( tmpNode[0].getAttribute("refid") ).strip("DCE:") # is this strip necessary? -JDG |
|---|
| 86 | |
|---|
| 87 | local_SPD = "" |
|---|
| 88 | componentfileNodeList = doc_dcd.getElementsByTagName("componentfile") |
|---|
| 89 | for componentfileNode in componentfileNodeList: |
|---|
| 90 | if componentfileNode.getAttribute("id") == newComp.file_uuid: |
|---|
| 91 | localfileNodeList = componentfileNode.getElementsByTagName("localfile") |
|---|
| 92 | local_SPD = localfileNodeList[0].getAttribute("name") |
|---|
| 93 | del localfileNodeList |
|---|
| 94 | break |
|---|
| 95 | pathSPD = parent.installPath + "dev/" + local_SPD |
|---|
| 96 | if not os.path.exists(pathSPD): |
|---|
| 97 | errorMsg(parent, "Warning! Could not find " + pathSPD + ".\nCannot import node " + Nname) |
|---|
| 98 | return None |
|---|
| 99 | |
|---|
| 100 | doc_spd = xml.dom.minidom.parse(pathSPD) |
|---|
| 101 | softpkgNode = doc_spd.getElementsByTagName("softpkg")[0] |
|---|
| 102 | newComp.baseName = softpkgNode.getAttribute("name") |
|---|
| 103 | #pathSCD = "/sdr/sca/xml/"+newComp.baseName+"/"+doc_spd.softpkg.descriptor.localfile.name |
|---|
| 104 | localfileNode = softpkgNode.getElementsByTagName("localfile")[0] |
|---|
| 105 | pathSCD = parent.installPath + "dev" + localfileNode.getAttribute("name") |
|---|
| 106 | |
|---|
| 107 | doc_scd = xml.dom.minidom.parse(pathSCD) |
|---|
| 108 | |
|---|
| 109 | #The new component is first created as an executable |
|---|
| 110 | #device but that may not be true |
|---|
| 111 | #grab the componenttype node from the scd file... |
|---|
| 112 | typeNode = doc_scd.getElementsByTagName("componenttype") |
|---|
| 113 | #... the pull out the actual value... |
|---|
| 114 | compType = typeNode[0].firstChild.toxml() |
|---|
| 115 | #... and assign it to the component |
|---|
| 116 | newComp.type = compType |
|---|
| 117 | |
|---|
| 118 | # Get the Ports |
|---|
| 119 | portsNodes = doc_scd.getElementsByTagName("ports") |
|---|
| 120 | for node in portsNodes: |
|---|
| 121 | providesPortsNodes = node.getElementsByTagName("provides") |
|---|
| 122 | usesPortsNodes = node.getElementsByTagName("uses") |
|---|
| 123 | |
|---|
| 124 | # Provides ports |
|---|
| 125 | for node in providesPortsNodes: |
|---|
| 126 | tmpName = node.getAttribute("providesname") |
|---|
| 127 | tmpInt = getInterface( node.getAttribute("repid"), tmpName ) |
|---|
| 128 | if tmpInt == None: |
|---|
| 129 | errorMsg(parent, "No repid found in ProvidesPort") |
|---|
| 130 | return None |
|---|
| 131 | portTypeNodeList = node.getElementsByTagName("porttype") |
|---|
| 132 | tmpType = portTypeNodeList[0].getAttribute("type") |
|---|
| 133 | newPort = CC.Port(tmpName,tmpInt,type='Provides',portType=tmpType) |
|---|
| 134 | newComp.ports.append(newPort) |
|---|
| 135 | |
|---|
| 136 | # Uses ports |
|---|
| 137 | for node in usesPortsNodes: |
|---|
| 138 | tmpName = node.getAttribute("usesname") |
|---|
| 139 | tmpInt = getInterface( node.getAttribute("repid"), tmpName ) |
|---|
| 140 | if tmpInt == None: |
|---|
| 141 | errorMsg(parent, "No repid fond in UsesPort") |
|---|
| 142 | return None |
|---|
| 143 | portTypeNodeList = node.getElementsByTagName("porttype") |
|---|
| 144 | tmpType = portTypeNodeList[0].getAttribute("type") |
|---|
| 145 | newPort = CC.Port(tmpName,tmpInt,type='Uses',portType=tmpType) |
|---|
| 146 | newComp.ports.append(newPort) |
|---|
| 147 | |
|---|
| 148 | # Make sure that xml and code are not generated for this resource |
|---|
| 149 | newComp.generate = False |
|---|
| 150 | |
|---|
| 151 | # Store the name of the file without the suffix (.scd.xml) |
|---|
| 152 | newComp.xmlName = os.path.splitext(os.path.splitext(os.path.basename(pathSCD))[0])[0] |
|---|
| 153 | |
|---|
| 154 | |
|---|
| 155 | |
|---|
| 156 | # |
|---|
| 157 | # Import the properties from the PRF file |
|---|
| 158 | # |
|---|
| 159 | # If there are no properties, just return the component as is |
|---|
| 160 | #if pathPRF == None: |
|---|
| 161 | # return newComp |
|---|
| 162 | # |
|---|
| 163 | #doc_prf = amara.parse(stripDoctype(prfPath)) |
|---|
| 164 | ##doc_prf = binderytools.bind_file(prfPath) |
|---|
| 165 | #if not hasattr(doc_prf,'properties'): |
|---|
| 166 | # errorMsg(parent,"Invalid file: " + prfPath) |
|---|
| 167 | # return None |
|---|
| 168 | # |
|---|
| 169 | #if hasattr(doc_prf.properties,"simple"): |
|---|
| 170 | # for s in doc_prf.properties.simple: |
|---|
| 171 | # p = getSimpleProperty(s) |
|---|
| 172 | # if p == None: |
|---|
| 173 | # #errorMsg(parent,"Invalid file: " + prfPath) |
|---|
| 174 | # continue |
|---|
| 175 | # newComp.properties.append(p) |
|---|
| 176 | # |
|---|
| 177 | #if hasattr(doc_prf.properties,"simplesequence"): |
|---|
| 178 | # for s in doc_prf.properties.simplesequence: |
|---|
| 179 | # p = getSimpleSequenceProperty(s) |
|---|
| 180 | # if p == None: |
|---|
| 181 | # #errorMsg(parent,"Invalid file: " + prfPath) |
|---|
| 182 | # continue |
|---|
| 183 | # newComp.properties.append(p) |
|---|
| 184 | # |
|---|
| 185 | # Import the properties from the PRF file |
|---|
| 186 | # |
|---|
| 187 | |
|---|
| 188 | # If there are no properties, just return the component as is |
|---|
| 189 | tmp = doc_spd.getElementsByTagName("propertyfile") |
|---|
| 190 | if len(tmp) > 0: |
|---|
| 191 | propertyFileNode = tmp[0] |
|---|
| 192 | propertyFile = '/sdr/dev' + propertyFileNode.getElementsByTagName("localfile")[0].getAttribute("name") |
|---|
| 193 | propertyDoc = xml.dom.minidom.parse(propertyFile) |
|---|
| 194 | simplePropNodes = propertyDoc.getElementsByTagName("simple") |
|---|
| 195 | simpleProps = getSimpleProperties(simplePropNodes, propertyFile) |
|---|
| 196 | |
|---|
| 197 | for prop in simpleProps: |
|---|
| 198 | newComp.properties.append(prop) |
|---|
| 199 | |
|---|
| 200 | simpleSequencePropNodes = propertyDoc.getElementsByTagName("simplesequence") |
|---|
| 201 | simpleSequenceProps = getSimpleSequenceProperties(simpleSequencePropNodes, propertyFile) |
|---|
| 202 | |
|---|
| 203 | for prop in simpleSequenceProps: |
|---|
| 204 | newComp.properties.append(prop) |
|---|
| 205 | else: |
|---|
| 206 | propertyFile = None |
|---|
| 207 | |
|---|
| 208 | |
|---|
| 209 | |
|---|
| 210 | newNode.Devices.append(newComp) |
|---|
| 211 | |
|---|
| 212 | return newNode |
|---|
| 213 | |
|---|
| 214 | |
|---|
| 215 | |
|---|
| 216 | def getInterface(repid,name): |
|---|
| 217 | try: |
|---|
| 218 | repid = repid.strip('IDL:') |
|---|
| 219 | repid = repid[:repid.rfind(':')] |
|---|
| 220 | tmpNS = repid[:repid.find('/')] |
|---|
| 221 | tmpName = repid[repid.find('/')+1:] |
|---|
| 222 | newInt = CC.Interface(tmpName,nameSpace=tmpNS) |
|---|
| 223 | return newInt |
|---|
| 224 | |
|---|
| 225 | except: |
|---|
| 226 | errorMsg(parent,"Can't read the Interface information for port: " + name) |
|---|
| 227 | return None |
|---|
| 228 | |
|---|
| 229 | |
|---|
| 230 | def findFile(path,Rname,suf): |
|---|
| 231 | tmpf = None |
|---|
| 232 | if os.path.isfile(path + '/' + Rname +'Resource'+suf): |
|---|
| 233 | tmpf = path + '/' + Rname +'Resource' + suf |
|---|
| 234 | elif os.path.isfile(path + '/' + Rname + suf): |
|---|
| 235 | tmpf = path + '/' + Rname + suf |
|---|
| 236 | else: |
|---|
| 237 | tmpFiles = os.listdir(path) |
|---|
| 238 | for f in tmpFiles: |
|---|
| 239 | if len(f)>=8 and f[-8:] == suf: |
|---|
| 240 | tmpf = path + '/' + f |
|---|
| 241 | break |
|---|
| 242 | return tmpf |
|---|
| 243 | |
|---|
| 244 | def stripDoctype(xmlfile): |
|---|
| 245 | """Strips out the DOCTYPE checking because the dtd files are positioned |
|---|
| 246 | in a relative location to the SCA (OSSIE) filesystem, so when Amara |
|---|
| 247 | trys to validate against them, it bails out looking for the file. |
|---|
| 248 | Returns a string representation of the xml file without the DOCTYPE line.""" |
|---|
| 249 | |
|---|
| 250 | file = open(xmlfile, 'r') |
|---|
| 251 | xml = '' |
|---|
| 252 | line = file.readline() |
|---|
| 253 | while len(line) > 0: |
|---|
| 254 | if "DOCTYPE" in line: |
|---|
| 255 | break |
|---|
| 256 | xml += line |
|---|
| 257 | line = file.readline() |
|---|
| 258 | xml += file.read() |
|---|
| 259 | |
|---|
| 260 | return xml |
|---|
| 261 | |
|---|
| 262 | def getSimpleProperties(simplePropertyNodeList, propertyFile): |
|---|
| 263 | props = [] |
|---|
| 264 | for node in simplePropertyNodeList: |
|---|
| 265 | p = getSimpleProperty(node) |
|---|
| 266 | if p == None: |
|---|
| 267 | print "There was an error parsing simple properties in the PRF file " + propertyFile |
|---|
| 268 | continue |
|---|
| 269 | props.append(p) |
|---|
| 270 | |
|---|
| 271 | return props |
|---|
| 272 | |
|---|
| 273 | def getSimpleSequenceProperties(simpleSequencePropertyNodeList, propertyFile): |
|---|
| 274 | props = [] |
|---|
| 275 | for node in simpleSequencePropertyNodeList: |
|---|
| 276 | p = getSimpleSequenceProperty(node, propertyFile) |
|---|
| 277 | if p == None: |
|---|
| 278 | print "There was an error parsing simple sequence properties in the PRF file " + propertyFile |
|---|
| 279 | continue |
|---|
| 280 | props.append(p) |
|---|
| 281 | |
|---|
| 282 | return props |
|---|
| 283 | |
|---|
| 284 | def getSimpleProperty(n): |
|---|
| 285 | tmpName = n.getAttribute("name") |
|---|
| 286 | tmpID = n.getAttribute("id") |
|---|
| 287 | tmpType = n.getAttribute("type") |
|---|
| 288 | tmpMode = n.getAttribute("mode") |
|---|
| 289 | tmpDes = n.getAttribute("description") |
|---|
| 290 | |
|---|
| 291 | if tmpName == "" or tmpID == "" or tmpType == "" or tmpMode == "": |
|---|
| 292 | return None |
|---|
| 293 | if tmpMode not in availableModes: |
|---|
| 294 | return None |
|---|
| 295 | if tmpType not in availableTypes: |
|---|
| 296 | return None |
|---|
| 297 | |
|---|
| 298 | newProp = CC.SimpleProperty(tmpName,tmpMode,tmpType,description=tmpDes) |
|---|
| 299 | |
|---|
| 300 | # Set ID |
|---|
| 301 | #UUID in the sad file will need to match the UUID in the prf (tmpID is from prf) |
|---|
| 302 | newProp.id = tmpID |
|---|
| 303 | |
|---|
| 304 | # Get/set property value |
|---|
| 305 | valueNodeList = n.getElementsByTagName("value") |
|---|
| 306 | value = valueNodeList[0].childNodes[0].data |
|---|
| 307 | newProp.value = newProp.defaultValue = str(value) |
|---|
| 308 | del valueNodeList, value |
|---|
| 309 | |
|---|
| 310 | # Get/set property units |
|---|
| 311 | unitsNodeList = n.getElementsByTagName("units") |
|---|
| 312 | if len(unitsNodeList) > 0: |
|---|
| 313 | units = unitsNodeList[0].childNodes[0].data |
|---|
| 314 | newProp.units = str(s.units) |
|---|
| 315 | #del unitsNodeList, units |
|---|
| 316 | |
|---|
| 317 | # TODO: Get/set min/max values |
|---|
| 318 | # TODO: Get/set enum |
|---|
| 319 | |
|---|
| 320 | # Get/set kind |
|---|
| 321 | kindNodeList = n.getElementsByTagName("kind") |
|---|
| 322 | kindtype = kindNodeList[0].getAttribute("kindtype") |
|---|
| 323 | if kindtype == "": |
|---|
| 324 | return None |
|---|
| 325 | newProp.kind = str(kindtype) |
|---|
| 326 | del kindNodeList, kindtype |
|---|
| 327 | |
|---|
| 328 | # Get/set action |
|---|
| 329 | actionNodeList = n.getElementsByTagName("action") |
|---|
| 330 | if len(actionNodeList) > 0: |
|---|
| 331 | actiontype = actionNodeList[0].getAttribute("type") |
|---|
| 332 | newProp.action = str(actiontype) |
|---|
| 333 | #del actionNodeList, actiontype |
|---|
| 334 | |
|---|
| 335 | return newProp |
|---|
| 336 | |
|---|
| 337 | def getSimpleSequenceProperty(n, prfPath): |
|---|
| 338 | tmpName = n.getAttribute("name") |
|---|
| 339 | tmpID = n.getAttribute("id") |
|---|
| 340 | tmpType = n.getAttribute("type") |
|---|
| 341 | tmpMode = n.getAttribute("mode") |
|---|
| 342 | tmpDes = n.getAttribute("description") |
|---|
| 343 | |
|---|
| 344 | if tmpName == "" or tmpID == "" or tmpType == "" or tmpMode == "": |
|---|
| 345 | return None |
|---|
| 346 | if tmpMode not in availableModes: |
|---|
| 347 | return None |
|---|
| 348 | if tmpType not in availableTypes: |
|---|
| 349 | return None |
|---|
| 350 | |
|---|
| 351 | newProp = CC.SimpleSequenceProperty(tmpName,tmpMode,tmpType,description=tmpDes) |
|---|
| 352 | |
|---|
| 353 | # Set ID |
|---|
| 354 | #UUID in the sad file will need to match the UUID in the prf (tmpID is from prf) |
|---|
| 355 | newProp.id = tmpID |
|---|
| 356 | |
|---|
| 357 | |
|---|
| 358 | # Get/set property values |
|---|
| 359 | newProp.values = [] |
|---|
| 360 | newProp.defaultValues = [] |
|---|
| 361 | valuesNodeList = n.getElementsByTagName("values") |
|---|
| 362 | |
|---|
| 363 | try: |
|---|
| 364 | valueNodeList = valuesNodeList[0].getElementsByTagName("value") |
|---|
| 365 | except: |
|---|
| 366 | valueNodeList = n.getElementsByTagName("value") #cbd |
|---|
| 367 | #print "\nERROR in " + prfPath |
|---|
| 368 | #print "ERROR parsing prf file. You may be missing a values tag in a simple sequence property.\n" |
|---|
| 369 | #sys.exit() |
|---|
| 370 | print "\nWarning in " + prfPath |
|---|
| 371 | print "Warning parsing prf file. You may be missing a values tag in a simple sequence property.\n" |
|---|
| 372 | |
|---|
| 373 | for valueNode in valueNodeList: |
|---|
| 374 | tmpVal = valueNode.childNodes[0].data |
|---|
| 375 | newProp.values.append(str(tmpVal)) |
|---|
| 376 | newProp.defaultValues.append(str(tmpVal)) |
|---|
| 377 | del valueNodeList |
|---|
| 378 | |
|---|
| 379 | # Get/set property units |
|---|
| 380 | unitsNodeList = n.getElementsByTagName("units") |
|---|
| 381 | if len(unitsNodeList) > 0: |
|---|
| 382 | units = unitsNodeList[0].childNodes[0].data |
|---|
| 383 | newProp.units = str(s.units) |
|---|
| 384 | #del unitsNodeList, units |
|---|
| 385 | |
|---|
| 386 | # TODO: Get/set min/max values |
|---|
| 387 | # TODO: Get/set enum |
|---|
| 388 | |
|---|
| 389 | # Get/set kind |
|---|
| 390 | kindNodeList = n.getElementsByTagName("kind") |
|---|
| 391 | kindtype = kindNodeList[0].getAttribute("kindtype") |
|---|
| 392 | if kindtype == "": |
|---|
| 393 | return None |
|---|
| 394 | newProp.kind = str(kindtype) |
|---|
| 395 | del kindNodeList, kindtype |
|---|
| 396 | |
|---|
| 397 | # Get/set action |
|---|
| 398 | actionNodeList = n.getElementsByTagName("action") |
|---|
| 399 | if len(actionNodeList) > 0: |
|---|
| 400 | actiontype = actionNodeList[0].getAttribute("type") |
|---|
| 401 | newProp.action = str(actiontype) |
|---|
| 402 | #del actionNodeList, actiontype |
|---|
| 403 | |
|---|
| 404 | return newProp |
|---|
| 405 | |
|---|
| 406 | |
|---|