root/ossiedev/trunk/tools/OEF/PythonSrc/MainFrameGlue.py @ 10021

Revision 10021, 23.3 KB (checked in by deepan, 3 years ago)

initial check-ins for OEF node generation

  • Property svn:keywords set to LastChangedDate Date LastChangedRevision Revision LastChangedBy Author URL Id
Line 
1## Copyright 2008 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
6## modify 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## $Author$
20## $Id$
21
22import sys, os, copy, operator
23import importResource
24import importNode
25import WaveformClass
26from WaveformClass import Waveform
27import PlatformClass
28import ComponentClass
29import threading
30import cPickle
31from edu.vt.ossie.jyinterface.interfaces import MainFrame
32import traceback
33import generate.templates.custom_ports.genStructure as genStruct
34import generate.genNode as genNode
35import XML_gen.application_gen as xml_gen
36from errorMsg import errorMsg
37import commands
38import string
39import ComponentClass as CC
40import cfg
41import shutil
42
43
44class MainFrameTreeNode:
45    def __init__(self, name, contents = []):
46        self.name = name
47        self.contents = contents
48        self.allowChildrenToExpand = True
49        self.iconName = None
50
51
52class RunInNewThread(threading.Thread):
53    def __init__(self, inCommand):
54        self.command = inCommand
55        threading.Thread.__init__(self)
56
57
58    def run(self):
59        os.system(self.command)
60
61
62
63class MainFrameGlue(MainFrame):
64    def __init__(self):
65        self.active_waveform = Waveform()
66        self.active_platform = PlatformClass.Platform()
67        self.installPath = "/sdr/"
68        self.ossieIncludePath = "/usr/local/include/ossie/"
69        self.stdIdlPath = "/usr/local/include/standardinterfaces/"
70        self.customIdlPath = "/usr/local/include/custominterfaces/"
71        self.pluginHome = ''
72        self.Available_Ints = []
73        self.CF_Available_Ints = []
74        self.Standard_Available_Ints = []
75        self.Custom_Available_Ints = []
76
77
78    def loadResources(self):
79        self.Available_Components = []
80        self.Available_Devices = []
81        self.Available_Nodes = []
82        resList = []
83
84        # List possible resource directories (components)
85        baseComponentPath = self.installPath + 'dom/xml/'
86        if os.path.isdir(baseComponentPath):
87            for r in os.listdir(baseComponentPath):
88                if r != 'dtd' and r != '.DS_Store' :  # ignore dtd directory, OSX sometimes creates a hidden file called .DS_Store that screws things up
89                    resList.append( (baseComponentPath,r) )
90        else:
91            errorMsg(self,"No component resources could be found in: " + self.installPath)
92            return
93       
94        # List possible resource directories (devices)
95        baseComponentPath = self.installPath + 'dev/xml/'
96        if os.path.isdir(baseComponentPath):
97            for r in os.listdir(baseComponentPath):
98                if r != 'dtd' and r != '.DS_Store' :  # ignore dtd directory, OSX sometimes creates a hidden file called .DS_Store that screws things up
99                    resList.append( (baseComponentPath,r) )
100        else:
101            errorMsg(self,"No component resources could be found in: " + self.installPath)
102            return
103
104        # find the .scd.xml files for each resource
105
106        for r in resList:
107            tmpResName = r[1]
108            tmpResPath = r[0] + r[1]
109            tmpComp = importResource.getResource(tmpResPath,tmpResName,self)
110
111            if tmpComp == None:
112                continue
113            if tmpComp.type == 'resource':
114                self.Available_Components.append(tmpComp)
115
116            elif tmpComp.type == 'executabledevice':
117                self.Available_Devices.append(tmpComp)
118
119            elif tmpComp.type == 'loadabledevice':
120                self.Available_Devices.append(tmpComp)
121
122            elif tmpComp.type == 'device':
123                self.Available_Devices.append(tmpComp)
124
125               
126        nodeList = []
127        if os.path.isdir(self.installPath + 'dev/nodes'):
128            nodeList = os.listdir(self.installPath + 'dev/nodes')
129            # print nodeList
130        else:
131            errorMsg(self, "No nodes could be found in: " + self.installPath)
132
133        # find the scd files for each node
134        for node_name in nodeList:
135
136            # check for existence of DomainManager XML files
137            nodes_root_path = self.installPath + 'dev/nodes' + os.path.sep + node_name + os.path.sep
138            if not os.path.exists(nodes_root_path + 'DeviceManager.dcd.xml'):
139                errorMsg(self, "Could not find DeviceManager.dcd.xml in: " + nodes_root_path)
140                continue
141            elif not os.path.exists(nodes_root_path + 'DeviceManager.prf.xml'):
142                errorMsg(self, "Could not find DeviceManager.prf.xml in: " + nodes_root_path)
143                continue
144            elif not os.path.exists(nodes_root_path + 'DeviceManager.scd.xml'):
145                errorMsg(self, "Could not find DeviceManager.scd.xml in: " + nodes_root_path)
146                continue
147            elif not os.path.exists(nodes_root_path + 'DeviceManager.spd.xml'):
148                errorMsg(self, "Could not find DeviceManager.spd.xml in: " + nodes_root_path)
149                continue
150
151            nodeName = node_name
152            nodePath = self.installPath + 'dev/nodes/' + nodeName + '/'
153
154            # print "calling getNode(", nodePath, ",", nodeName, ")"
155            tmpNode = importNode.getNode(nodePath,nodeName,self)
156
157            if tmpNode == None:
158                print "WARNING: possibly an error reading node " + nodePath + "/" + nodeName
159                continue
160            self.Available_Nodes.append(tmpNode)
161       
162        self.Available_Components.sort(key=operator.attrgetter("name"))
163        self.Available_Devices.sort(key=operator.attrgetter("name"))
164        self.Available_Nodes.sort(key=operator.attrgetter("name"))
165
166        return [MainFrameTreeNode("Components", self.Available_Components),
167                MainFrameTreeNode("Devices", self.Available_Devices),
168                MainFrameTreeNode("Nodes", self.Available_Nodes)]
169
170
171    def getActiveWaveform(self):
172        return self.active_waveform
173
174    def getActivePlatform(self):
175        return self.active_platform
176
177
178    def pathWithSlash(self, path):
179        length = len(path)
180        if length > 0 and path[length - 1] != '/':
181            path = path + '/'
182        return path
183
184
185    def pathWithoutSlash(self, path):
186        length = len(path)
187        if length > 0 and path[length - 1] == '/':
188            path = path[0:length - 1]
189        return path
190
191
192    def setOssiePluginHome(self, path):
193        self.pluginHome = self.pathWithSlash(path)
194
195    def getOssieInstallPath(self):
196        return self.installPath
197
198
199    def setOssieInstallPath(self, path):
200        self.installPath = self.pathWithSlash(path)
201        cfg.overrideCfgValue('installpath', self.pathWithoutSlash(path))
202
203
204    def setOssiePluginHome(self, path):
205        self.pluginHome = self.pathWithSlash(path)
206
207
208    def setIncludePath(self, path):
209        self.ossieIncludePath = path
210        cfg.setCfgValueIfNecessary('ossieincludepath',
211                                   self.pathWithoutSlash(path))
212
213
214    def setStandardIdlPath(self, path):
215        self.stdIdlPath = path
216        cfg.setCfgValueIfNecessary('stdidlpath', self.pathWithoutSlash(path))
217
218
219    def setCstmIdlPath(self, path):
220        self.customIdlPath = path
221
222
223    def generateTestWaveform(self):
224        self.active_waveform = Waveform()
225        int1 = ComponentClass.Interface('complexShort')
226        op1 = ComponentClass.Operation('pushPacket','void')
227        param1 = ComponentClass.Param('I','PortTypes::ShortSequence','in')
228        param2 = ComponentClass.Param('Q','PortTypes::ShortSequence','in')
229        op1.params.extend([param1,param2])
230        int1.operations.append(op1)
231
232        t2 = ComponentClass.Component("Transmitter", AC=True, generate=False)
233        p1 = ComponentClass.Port('inPortTx1',copy.deepcopy(int1),'Provides')
234        p2 = ComponentClass.Port('outPortTx1',copy.deepcopy(int1),'Uses')
235        t2.ports.append(p1)
236        t2.ports.append(p2)
237        self.active_waveform.components.append(t2)
238
239        t3 = ComponentClass.Component("Channel", generate=False)
240        p1 = ComponentClass.Port('inPortCh1',copy.deepcopy(int1),'Provides')
241        p2 = ComponentClass.Port('inPortCh2',copy.deepcopy(int1),'Provides')
242        p3 = ComponentClass.Port('inPortCh3',copy.deepcopy(int1),'Provides')
243        p4 = ComponentClass.Port('outPortCh1',copy.deepcopy(int1),'Uses')
244        p5 = ComponentClass.Port('outPortCh2',copy.deepcopy(int1),'Uses')
245        p6 = ComponentClass.Port('outPortCh3',copy.deepcopy(int1),'Uses')
246        t3.ports.extend([p1,p2,p3,p4,p5,p6])
247        self.active_waveform.components.append(t3)
248
249        t4 = ComponentClass.Component("Receiver", generate=False)
250        p1 = ComponentClass.Port('inPortRx1',copy.deepcopy(int1),'Provides')
251        p2 = ComponentClass.Port('outPortRx1',copy.deepcopy(int1),'Uses')
252        t4.ports.append(p1)
253        t4.ports.append(p2)
254        self.active_waveform.components.append(t4)
255
256        #temp_dev = ComponentClass.Component("GPP", generate=False)
257        #self.active_waveform.devices.append(temp_dev)
258        return [MainFrameTreeNode("Sample Waveform", self.active_waveform)]
259
260
261    def displayDoxygen(self, referenceMaterials):
262        defaultHtml = 'index.html'
263        defaultPdf = 'refman.pdf'
264        docList = None
265
266        docsPath = self.installPath + 'docs/' + referenceMaterials.name
267        print docsPath
268        if os.path.isdir(docsPath):
269            docList = os.listdir(docsPath)
270            if os.path.isfile(docsPath + '/' + defaultHtml):
271                webbrowser.open_new('file://' + docsPath + '/' + defaultHtml)
272            elif os.path.isfile(docsPath + '/' + defaultPdf):
273                #find more portable way to view pdf?
274                try:
275                    RunInNewThread('evince ' + docsPath + '/' + defaultPdf + ' &')
276                finally:
277                    errorMsg(self,'evince pdf viewer threw exception or not found')
278                #webbrowser.open('file://' + docsPath + '/' + defaultPdf, 1)
279            else:
280                errorMsg(self,'Neither index.html nor refman.pdf found in ' + docsPath + ': directory listing: ' + str(docList))
281        else:
282            errorMsg(self,'No directory for ' + referenceMaterials.name + ' could be found in: ' + self.installPath + 'docs')
283            return
284
285
286       
287    def errorMsg(self, message):
288        print >>sys.stderr, message
289
290
291    def saveProject(self, saveProjectPath):
292        f = open(saveProjectPath,'w')
293        cPickle.dump(('project',self.active_waveform,self.active_platform),f)
294        f.close()
295
296
297    def loadProject(self, projectPath):
298        f = open(projectPath,'r')
299        tmpObject = cPickle.load(f)
300        if tmpObject[0] == 'waveform':
301            self.active_waveform = tmpObject[1]
302        elif tmpObject[0] == 'platform':
303            self.active_platform =  tmpObject[1]
304        elif tmpObject[0] == 'project':
305            self.active_waveform = tmpObject[1]
306            self.active_platform = tmpObject[2]
307        f.close()
308
309
310    def wavedevPath(self):
311        if not hasattr(self, '__wavedevPath'):
312            self.__wavedevPath = self.pluginHome
313            if self.__wavedevPath == None:
314                self.__wavedevPath = ''
315            if len(self.__wavedevPath) > 0 and \
316                self.__wavedevPath[len(self.__wavedevPath)-1] != '/':
317                self.__wavedevPath = self.__wavedevPath + '/'
318            self.__wavedevPath = self.__wavedevPath + 'WaveDev/wavedev/'
319        return self.__wavedevPath
320
321
322    def generateProject(self, path):
323        gen = genStruct.genAll(path, self.wavedevPath(), copy.deepcopy(self.active_waveform))
324        gen.genDirs()
325        # Only include the device manager files if there is just one node
326        if len(self.active_platform.nodes) == 1:
327            gen.writeMakefiles(True)
328        else:
329            gen.writeMakefiles(False)
330        # TODO: use different configure.ac file for application -JDG
331        gen.genConfigureACFiles(self.installPath)
332        for c in self.active_waveform.components:
333            if c.generate:
334                gen.genCompFiles(c)
335
336        xml_gen.genxml(copy.deepcopy(self.active_waveform.components), path, self.wavedevPath(), self.active_waveform.name)
337        xml_gen.genDAS(copy.deepcopy(self.active_waveform.components), path, self.wavedevPath(), self.active_waveform.name)
338        xml_gen.writeWaveSetuppy(path, self.wavedevPath(), self.active_waveform.name)
339
340        gen.cleanUp()
341
342
343    def dump(self, x):
344        from Utilities import dumpObj
345        dumpObj(x)
346
347    def uuidgen(self):
348        result = commands.getoutput('uuidgen -t')
349        # On some linux-like OSes, uuidgen does not take any parameter to specify
350        # the kind of uuid to generate
351        if (result.find('usage:') >= 0):
352            result = commands.getoutput('uuidgen')
353        return result
354
355    def importStandardIDL(self):
356        '''Imports IDL from cf, standardinterfaces, and custominterfaces'''
357
358        # If we've computed this value before, just reuse it
359        if len(self.Available_Ints) > 0:
360            return [MainFrameTreeNode('CF', self.CF_Available_Ints),
361                    MainFrameTreeNode('Standard Interfaces', self.Standard_Available_Ints),
362                    MainFrameTreeNode('Custom Interfaces', self.Custom_Available_Ints)]
363
364        #temporarily change self.parent to self so this works
365        #normally this function looks at the MainFrame - but not in standalone
366        self.parent = self
367        changedParent = True
368
369
370        if os.path.isfile(self.ossieIncludePath + "cf.idl"):
371            cfIdl_file = self.ossieIncludePath + "cf.idl"
372        else:
373            print self.ossieIncludePath + "cf.idl"
374            tmpstr = "Cannot find cf.idl in the OSSIE installation location:\n"
375            tmpstr += self.ossieIncludePath
376            errorMsg(self,tmpstr)
377
378        # for each file in the standardinterfaces directory, import all available
379        # interfaces (skip standardIdl files)
380
381        standard_idl_list = os.listdir(self.stdIdlPath)
382
383        try:
384            custom_idl_list = os.listdir(self.customIdlPath)
385        except OSError: # this will occur if customIdlPath was never set
386                        # as a result of customInterfaces not being found
387            custom_idl_list = []
388
389        if len(standard_idl_list) <= 0:
390            tmpstr = "Can't find any files in: " + self.stdIdlPath
391            errorMsg(self,tmpstr)
392            return
393
394        # Add the CF interfaces first - in case another file includes them, we
395        # don't want them asscociated with anything other than cf.idl
396        self.CF_Available_Ints.extend(self.getInterfaces(cfIdl_file))
397        self.Available_Ints.extend(self.CF_Available_Ints)
398
399        # import standard interfaces
400        for standard_idl_file in standard_idl_list:
401            # standardIdl files are not included because they are aggregates of the other interfaces
402            if 'standardIdl' in standard_idl_file:
403                continue
404
405            if string.lower(os.path.splitext(standard_idl_file)[1]) != ".idl":
406                # ignore non idl files
407                continue
408
409            tempInts = self.getInterfaces(self.stdIdlPath + standard_idl_file)
410            for t in tempInts:
411                if t not in self.Available_Ints:
412                    self.Standard_Available_Ints.append(t)
413                    self.Available_Ints.append(t)
414
415        # import custom interfaces
416        for custom_idl_file in custom_idl_list:
417            # ignore aggregate 'customInterfaces.idl' file
418            if 'customInterfaces' in custom_idl_file:
419                continue
420
421            if string.lower(os.path.splitext(custom_idl_file)[1]) != ".idl":
422                # ignore non idl files
423                continue
424
425            tempInts = self.getInterfaces(self.customIdlPath + custom_idl_file)
426            for t in tempInts:
427                if t not in self.Available_Ints:
428                   # print "Testing: " + t.name + " " + idl_file + " " + str(len(self.Available_Ints))
429                    self.Custom_Available_Ints.append(t)
430                    self.Available_Ints.append(t)
431                    if t.name == 'timingStatus':
432                        self.timing_interface = CC.Interface(t.name, t.nameSpace, t.operations, t.filename, t.fullpath)
433                        self.timing_port = CC.Port('send_timing_report', self.timing_interface, "Uses", "data")
434#                    print "CF.py: " + t.name + "  " + str(len(t.operations))
435        if changedParent == True:
436            self.parent = None
437        return [MainFrameTreeNode('CF', self.CF_Available_Ints),
438                MainFrameTreeNode('Standard Interfaces', self.Standard_Available_Ints),
439                MainFrameTreeNode('Custom Interfaces', self.Custom_Available_Ints)]
440
441
442    def importNewIdl(self, newImportPath):
443        newInts = self.getInterfaces(newImportPath)
444        tmpMsg = 'You will need to copy <' + newImportPath[(newImportPath.rfind('/')+1):]
445        tmpMsg += '> to /usr/local/include/standardinterfaces in order to '
446        tmpMsg += 'use the generated code.'
447
448
449
450        self.Available_Ints.extend(newInts)
451        return [MainFrameTreeNode('CF', self.CF_Available_Ints),
452                MainFrameTreeNode('Standard Interfaces', self.Standard_Available_Ints),
453                MainFrameTreeNode('Custom Interfaces', self.Custom_Available_Ints),
454                MainFrameTreeNode('New Interfaces', newInts)]
455
456    def getCFInterfaces(self):
457        if len(self.CF_Available_Ints) > 0:
458            return self.CF_Available_Ints
459        else:
460            self.importStandardIDL()
461            return self.CF_Available_Ints
462
463    def getStandardInterfaces(self):
464        if len(self.Standard_Available_Ints) > 0:
465            return self.Standard_Available_Ints
466        else:
467            self.importStandardIDL()
468            return self.Standard_Available_Ints
469
470    def getCustomInterfaces(self):
471        if len(self.Custom_Available_Ints) > 0:
472            return self.Custom_Available_Ints
473        else:
474            self.importStandardIDL()
475            return self.Custom_Available_Ints
476
477    def getInterFaceList(self):
478        if len(self.AvailableInts) > 0:
479            return self.AvailableInts
480        else:
481            self.importStandardIDL()
482            return self.AvailableInts
483
484
485    def getInterfaces(self, file):
486        f = os.popen('python '
487            + self.pluginHome + 'PythonSrc/getInterfaces.py '
488            + self.pluginHome + 'WaveDev/wavedev '
489            + file)
490        result = cPickle.load(f)
491        f.close()
492        return result
493
494
495    def createNewComponent(self, name, path):
496        c = ComponentClass.Component(name)
497        c.generate = False
498        f = open(path,'w')
499        cPickle.dump(('component', c), f)
500        f.close()
501
502
503    def loadComponent(self, path):
504        f = open(path,'r')
505        tmpObject = cPickle.load(f)
506        component = None
507        if tmpObject[0] == 'component':
508            component = tmpObject[1]
509        else:
510            errorMsg(self, 'File ' + path + ' is not a component file.')
511        f.close()
512        return component
513
514    def saveComponent(self, component, path):
515        f = open(path,'w')
516        cPickle.dump(('component', component), f)
517        f.close()
518
519    def createNewNode(self, name, path):
520        newNode = ComponentClass.Node(name, path)
521        newNode.generate = False
522        f = open(path, 'w')
523        cPickle.dump(('node', newNode, self.active_platform), f)
524        f.close()
525   
526    def loadNode(self, path):
527        f = open(path,'r')
528        tmpObject = cPickle.load(f)
529        newNode = None
530        if tmpObject[0] == 'node':
531            newNode = tmpObject[1]
532            self.active_platform = tmpObject[2]
533        else:
534            errorMsg(self, 'File ' + path + ' is not a node file.')
535        f.close()
536        return newNode
537
538    def saveNode(self, node, path):
539        f = open(path,'w')
540        cPickle.dump(('node', node, self.active_platform), f)
541        f.close()
542
543
544    ############################################################################
545    ## Generate the Component XML and C++
546    ############################################################################
547    def generateComponentFiles(self, component, savepath):
548        import XML_gen.component_gen as component_gen
549        if not hasattr(component, 'xTemplate'):
550            component.xTemplate = 'basic_ports'
551        #select which template to use
552
553        if component.xTemplate == "basic_ports":
554            import WaveDev.wavedev.generate.templates.basic_ports.genStructure as genStruct
555        elif component.xTemplate == "custom_ports":
556            import WaveDev.wavedev.generate.templates.custom_ports.genStructure as genStruct
557        elif component.xTemplate == "py_comp":
558            import WaveDev.wavedev.generate.templates.py_comp.genStructure as genStruct
559        else:
560            return component.xTemplate + ' is not supported in OnMenuComponentGenerateMenu within the componentFrame'
561
562        if savepath[len(savepath)-1] != '/':
563            savepath = savepath + '/'
564
565        compPath = savepath + component.name
566
567        if os.path.exists(compPath) == False:
568            os.mkdir(compPath)
569
570        #if component.xTemplate != "py_comp":
571        shutil.copy(self.wavedevPath() + 'generate/reconf', compPath)
572        licensefile = cfg.ossieCfgValue('licensefile')
573        if licensefile != None and licensefile != '':
574            shutil.copy(licensefile, self.path + '/LICENSE')
575
576        if component.timing:
577            found_timing = False
578            for p in component.ports:
579                if p.interface.name == 'timingStatus':
580                    found_timing = True
581            if not found_timing and hasattr(self, 'timing_port'):
582                component.ports.append(self.timing_port)
583
584        gen = genStruct.genAll(savepath, self.wavedevPath(), None)
585        gen.writeCompMakefile(component, compPath)
586        gen.writeConfAC(compPath, component.name, component.ace, False, self.installPath)
587        gen.genCompFiles(component)
588
589        component_gen.gen_scd(component, savepath, self.wavedevPath())
590        if ( component.xTemplate == "py_comp" ):
591            component_gen.gen_spd(component, savepath, self.wavedevPath(), True)
592        else:
593            component_gen.gen_spd(component, savepath, self.wavedevPath())
594        component_gen.gen_prf(component, savepath, self.wavedevPath())
595        return None
596
597    def getTemplates(self):
598        availableTemplates = commands.getoutput("cd " + self.wavedevPath() + "generate/templates; ls")
599        availableTemplates = availableTemplates.split()
600        availableTemplates.remove("__init__.py");
601        availableTemplates.remove("__init__$py.class");
602        return availableTemplates
603
604    def formatSequenceValues(self, values):
605        returnValues = values.replace(",", " ")
606        returnValues = returnValues.replace("[", "")
607        returnValues = returnValues.replace("]", "")
608        returnValues = returnValues.replace("\"", "")
609        returnValues = returnValues.replace("\'", "")
610        returnValues = returnValues.split()
611        return returnValues
612   
613   
614   
615
Note: See TracBrowser for help on using the browser.