root/ossiedev/branches/jsnyder/trunk/tools/WaveDev/wavedev/importResource.py @ 11083

Revision 11083, 14.3 KB (checked in by Snyder.Jason, 15 months ago)

changes related to alternate component implementations

  • Property svn:eol-style set to native
Line 
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
19import os, sys
20import xml.dom.minidom
21from xml.dom.minidom import Node
22import ComponentClass as CC
23from errorMsg import *
24
25availableTypes = ["boolean", "char", "double", "float", "short", "long",
26                    "objref", "octet", "string", "ulong","ushort"]
27availableKinds = ["allocation", "configure", "test", "execparam", "factoryparam"]
28availableActions = ["eq", "ne", "gt", "lt", "ge", "le", "external"]
29availableModes = ["readonly", "readwrite", "writeonly"]
30
31def getResource(path,Rname,parent):
32    scdPath = findFile(path,Rname,".scd.xml")
33    if scdPath == None:         
34        errorMsg(parent,"No scd file found for: " + Rname)
35        return
36   
37    spdPath = findFile(path,Rname,".spd.xml")
38    prfPath = findFile(path,Rname,".prf.xml")
39   
40    prefix = "/sdr/dom"
41    if path.startswith("/sdr/dev"):
42        prefix = "/sdr/dev"
43    #
44    # Build the main component or device from the SCD file   
45    #
46    doc_scd = xml.dom.minidom.parse(scdPath)
47    try:
48        componenttypeNode = doc_scd.getElementsByTagName("componenttype")
49        componenttype = componenttypeNode[0].childNodes[0].data
50    except:
51        errorMsg(parent,"Invalid file: " + scdPath)
52        return None
53   
54    doc_spd = xml.dom.minidom.parse(spdPath)
55
56    # get resource description
57    # note: this is not the same as the implementation description
58    softpkgNode = doc_spd.getElementsByTagName("softpkg")[0]
59    Rdescription = ''
60    for n in softpkgNode.childNodes:
61        if n.nodeName == "description":
62            resDescriptionNode = doc_spd.getElementsByTagName("description")
63            try:
64                Rdescription = resDescriptionNode[0].firstChild.data
65            except:
66                pass
67            break
68
69    #Instantiate a new component of the appropriate type
70    if componenttype == u'resource':
71        newComp = CC.Component(name=Rname,type='resource',description=Rdescription)
72    elif componenttype == u'executabledevice':
73        newComp = CC.Component(name=Rname,type='executabledevice',description=Rdescription)
74    elif componenttype == u'loadabledevice':
75        newComp = CC.Component(name=Rname,type='loadabledevice',description=Rdescription)
76    elif componenttype == u'device':
77        newComp = CC.Component(name=Rname,type='device',description=Rdescription)
78    else:
79        errorMsg(parent,"Can't identify resource type for: " + Rname)
80        return None
81       
82    # Get the Ports
83    portsNodes = doc_scd.getElementsByTagName("ports")
84    for node in portsNodes:
85        providesPortsNodes = node.getElementsByTagName("provides")
86        usesPortsNodes = node.getElementsByTagName("uses")
87
88    # Provides ports
89    for node in providesPortsNodes:
90        tmpName = node.getAttribute("providesname")
91        tmpInt = getInterface( node.getAttribute("repid"), tmpName )
92        if tmpInt == None:
93            return None
94        portTypeNodeList = node.getElementsByTagName("porttype")
95        tmpType = portTypeNodeList[0].getAttribute("type")
96        newPort = CC.Port(tmpName,tmpInt,type='Provides',portType=tmpType)
97        newComp.ports.append(newPort)
98
99    # Uses ports
100    for node in usesPortsNodes:
101        tmpName = node.getAttribute("usesname")
102        tmpInt = getInterface( node.getAttribute("repid"), tmpName )
103        if tmpInt == None:
104            return None
105        portTypeNodeList = node.getElementsByTagName("porttype")
106        tmpType = portTypeNodeList[0].getAttribute("type")
107        newPort = CC.Port(tmpName,tmpInt,type='Uses',portType=tmpType)
108        newComp.ports.append(newPort)
109
110    # Make sure that xml and code are not generated for this resource
111    newComp.generate = False       
112   
113    # Store the name of the file without the suffix (.scd.xml)
114    i = scdPath.rfind("/")
115    if i != -1:
116        newComp.xmlName = scdPath[i+1:-8]
117    else:
118        newComp.xmlName = scdPath[:-8]
119   
120    #
121    # Import the properties from the PRF file
122    #
123    # If there are no properties, just return the component as is
124    if prfPath == None:
125        return newComp
126    doc_prf = xml.dom.minidom.parse(prfPath)
127    try:
128        propertyNodeList = doc_prf.getElementsByTagName("properties")
129    except:
130        errorMsg(parent,"Invalid file: " + prfPath)
131        return None
132   
133    # get simple properties
134    simplePropertyNodeList = doc_prf.getElementsByTagName("simple")
135    props = getSimpleProperties(simplePropertyNodeList, prfPath)
136    for prop in props:
137        newComp.properties.append(prop)
138   
139
140    # get simple sequence properties
141    simpleSequencePropertyNodeList = doc_prf.getElementsByTagName("simplesequence")
142    sequenceProps = getSimpleSequenceProperties(simpleSequencePropertyNodeList, prfPath)
143    for prop in sequenceProps:
144        newComp.properties.append(prop)
145       
146   
147    # read additional implementations from the spd file if necessary
148   
149    # example implementation node from an spd file
150    #<implementation id="DCE:f559a6a6-a1b3-4acd-b926-d194be1b9930">
151    #    <description>Virtex4 FPGA Implementation, Controller Component</description>
152    #    <propertyfile type="PRF">
153    #        <localfile name="/xml/TxDemo/TxDemo_v4.prf.xml"/>
154    #    </propertyfile>
155    #    <code type="Executable">
156    #        <localfile name="/bin/TxDemo_v4"/>
157    #    </code>
158    #    <os name="Linux" version="2.6.27-rc9-xlnx"/>
159    #    <processor name="powerpc"/>
160    #    <!-- this id points to the impl ID in the XilinxFPGA SPD -->
161    #    <dependency type="Device" softpkgref="DCE:e6d7ca42-e4c9-482c-a9ed-23901f15a465"/>
162    #</implementation>   
163
164    simpleProps = []
165    simpleSequenceProps = []
166    implementationNodes = doc_spd.getElementsByTagName("implementation")
167    for node in implementationNodes:
168        simpleProps = []
169        simpleSequenceProps = []
170        propertyFile = ''
171        id = node.getAttribute("id")
172        tmp = node.getElementsByTagName("description")
173        if len(tmp) > 0:
174            descriptionNode = tmp[0]
175            description = descriptionNode.firstChild.data
176        else:
177            description = ''
178        tmp = node.getElementsByTagName("propertyfile")
179        if len(tmp) > 0:
180            propertyFileNode = tmp[0]
181            propertyFile = prefix + propertyFileNode.getElementsByTagName("localfile")[0].getAttribute("name")
182            propertyDoc = xml.dom.minidom.parse(propertyFile)
183            simplePropNodes = propertyDoc.getElementsByTagName("simple")
184            simpleProps = getSimpleProperties(simplePropNodes, propertyFile)
185           
186            simpleSequencePropNodes = propertyDoc.getElementsByTagName("simplesequence")
187            simpleSequenceProps = getSimpleSequenceProperties(simpleSequencePropNodes, propertyFile)
188        else:
189            propertyFile = None
190        tmp = node.getElementsByTagName("processor")
191        if len(tmp) > 0:
192            processorNode = tmp[0]
193            processor = processorNode.getAttribute("name")
194        else:
195            processor = ''
196       
197        newImplementation = CC.Implementation(id, description, propertyFile, processor)
198        for prop in simpleProps:
199            newImplementation.properties.append(prop)
200        for prop in simpleSequenceProps:
201            newImplementation.properties.append(prop)
202       
203        newComp.implementations.append(newImplementation)
204#    print newComp.name + ' summary:'
205#    print 'Main properties: '
206#    for prop in newComp.properties:
207#        print '    ' + prop.name
208#    print 'Implementations:'
209#    for imp in newComp.implementations:
210#        print imp.processor
211#        for prop in imp.properties:
212#            print '    ' + prop.name
213    return newComp
214
215def getInterface(repid,name):
216    try:
217        repid = repid.strip('IDL:')
218        repid = repid[:repid.rfind(':')]
219        tmpNS = repid[:repid.find('/')]
220        tmpName = repid[repid.find('/')+1:]
221        newInt = CC.Interface(tmpName,nameSpace=tmpNS)
222        return newInt
223       
224    except:
225        errorMsg(parent,"Can't read the Interface information for port: " + name)
226        return None
227   
228   
229def findFile(path,Rname,suf):
230    tmpf = None
231    if os.path.isfile(path + '/' + Rname +'Resource'+suf):
232        tmpf = path + '/' + Rname +'Resource' + suf
233    elif os.path.isfile(path + '/' + Rname + suf):
234        tmpf = path + '/' + Rname + suf     
235    else:
236        tmpFiles = os.listdir(path)
237        for f in tmpFiles:
238            if len(f)>=8 and f[-8:] == suf:
239                tmpf = path + '/' + f
240                break
241    return tmpf
242
243def stripDoctype(xmlfile):
244    """Strips out the DOCTYPE checking because the dtd files are positioned
245       in a relative location to the SCA (OSSIE) filesystem, so when Amara
246       trys to validate against them, it bails out looking for the file.
247       Returns a string representation of the xml file without the DOCTYPE line."""
248   
249    file = open(xmlfile, 'r')
250    xml = ''
251    line = file.readline()
252    while len(line) > 0:
253        if "DOCTYPE" in line:
254            break
255        xml += line
256        line = file.readline()
257    xml += file.read()
258
259    return xml
260
261def getSimpleProperties(simplePropertyNodeList, propertyFile):
262    props = []
263    for node in simplePropertyNodeList:
264        p = getSimpleProperty(node)
265        if p == None:
266            print "There was an error parsing simple properties in the PRF file " + propertyFile
267            continue
268        props.append(p)
269       
270    return props
271
272def getSimpleSequenceProperties(simpleSequencePropertyNodeList, propertyFile):
273    props = []
274    for node in simpleSequencePropertyNodeList:
275        p = getSimpleSequenceProperty(node, propertyFile)
276        if p == None:
277            print "There was an error parsing simple sequence properties in the PRF file " + propertyFile
278            continue
279        props.append(p)
280       
281    return props
282
283def getSimpleProperty(n):
284    tmpName = n.getAttribute("name")
285    tmpID   = n.getAttribute("id")
286    tmpType = n.getAttribute("type")
287    tmpMode = n.getAttribute("mode")
288    tmpDes = n.getAttribute("description")
289
290    if tmpName == "" or tmpID == "" or tmpType == "" or tmpMode == "":
291        return None
292    if tmpMode not in availableModes:
293        return None
294    if tmpType not in availableTypes:
295        return None
296   
297    newProp = CC.SimpleProperty(tmpName,tmpMode,tmpType,description=tmpDes)
298   
299    # Set ID
300    #UUID in the sad file will need to match the UUID in the prf (tmpID is from prf)
301    newProp.id = tmpID
302
303    # Get/set property value
304    valueNodeList = n.getElementsByTagName("value")
305    value = valueNodeList[0].childNodes[0].data
306    newProp.value = newProp.defaultValue = str(value)
307    del valueNodeList, value
308   
309    # Get/set property units
310    unitsNodeList = n.getElementsByTagName("units")
311    if len(unitsNodeList) > 0:
312        units = unitsNodeList[0].childNodes[0].data
313        newProp.units = str(s.units)
314    #del unitsNodeList, units
315   
316    # TODO: Get/set min/max values
317    # TODO: Get/set enum
318   
319    # Get/set kind
320    kindNodeList = n.getElementsByTagName("kind")
321    kindtype = kindNodeList[0].getAttribute("kindtype")
322    if kindtype == "":
323        return None
324    newProp.kind = str(kindtype)
325    del kindNodeList, kindtype
326   
327    # Get/set action
328    actionNodeList = n.getElementsByTagName("action")
329    if len(actionNodeList) > 0:
330        actiontype = actionNodeList[0].getAttribute("type")
331        newProp.action = str(actiontype)
332    #del actionNodeList, actiontype
333       
334    return newProp
335   
336def getSimpleSequenceProperty(n, prfPath):
337    tmpName = n.getAttribute("name")
338    tmpID   = n.getAttribute("id")
339    tmpType = n.getAttribute("type")
340    tmpMode = n.getAttribute("mode")
341    tmpDes = n.getAttribute("description")
342
343    if tmpName == "" or tmpID == "" or tmpType == "" or tmpMode == "":
344        return None
345    if tmpMode not in availableModes:
346        return None
347    if tmpType not in availableTypes:
348        return None
349   
350    newProp = CC.SimpleSequenceProperty(tmpName,tmpMode,tmpType,description=tmpDes)
351   
352    # Set ID
353    #UUID in the sad file will need to match the UUID in the prf (tmpID is from prf)
354    newProp.id = tmpID
355
356
357    # Get/set property values
358    newProp.values = []
359    newProp.defaultValues = []
360    valuesNodeList = n.getElementsByTagName("values")
361   
362    try:
363        valueNodeList = valuesNodeList[0].getElementsByTagName("value")
364    except:
365        valueNodeList = n.getElementsByTagName("value") #cbd
366        #print "\nERROR in " + prfPath
367        #print "ERROR parsing prf file.  You may be missing a values tag in a simple sequence property.\n"
368        #sys.exit()
369        print "\nWarning in " + prfPath
370        print "Warning parsing prf file.  You may be missing a values tag in a simple sequence property.\n"
371
372    for valueNode in valueNodeList:
373        tmpVal = valueNode.childNodes[0].data
374        newProp.values.append(str(tmpVal))
375        newProp.defaultValues.append(str(tmpVal))
376    del valueNodeList
377
378    # Get/set property units
379    unitsNodeList = n.getElementsByTagName("units")
380    if len(unitsNodeList) > 0:
381        units = unitsNodeList[0].childNodes[0].data
382        newProp.units = str(s.units)
383    #del unitsNodeList, units
384   
385    # TODO: Get/set min/max values
386    # TODO: Get/set enum
387   
388    # Get/set kind
389    kindNodeList = n.getElementsByTagName("kind")
390    kindtype = kindNodeList[0].getAttribute("kindtype")
391    if kindtype == "":
392        return None
393    newProp.kind = str(kindtype)
394    del kindNodeList, kindtype
395
396    # Get/set action
397    actionNodeList = n.getElementsByTagName("action")
398    if len(actionNodeList) > 0:
399        actiontype = actionNodeList[0].getAttribute("type")
400        newProp.action = str(actiontype)
401    #del actionNodeList, actiontype
402
403    return newProp
Note: See TracBrowser for help on using the browser.