root/ossiedev/trunk/tools/wavedash/src/WavedashUtils.py @ 10139

Revision 10139, 22.7 KB (checked in by Snyder.Jason, 3 years ago)

fixes so can be used without wx

Line 
1## Copyright 2005, 2006, 2007, 2008 Virginia Polytechnic Institute and State University
2##
3## This file is part of the OSSIE Waveform Application Visualization Environment
4##
5## WaveDash 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## WaveDash is distributed in the hope that it will be useful, but WITHOUT ANY
11## 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 WaveDash; if not, write to the Free Software
17## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
19from ossie.cf import CF
20from omniORB import CORBA
21import sys
22import CosNaming
23import WaveDev.wavedev.importResource as importResource
24import wx
25import xml.dom.minidom
26from xml.dom.minidom import Node
27from namingserviceDialog import NamingserviceDialog
28
29[NON_FATAL, FATAL, INFO] = [1,2,3]
30[SUCCESS, FAILURE] = [True, False]
31LOCAL_HOST = '127.0.0.1'
32
33def showMessage(msg, sev, enableGUI = True):
34    if(not enableGUI):
35        print msg
36        return
37    if (sev == FATAL or sev == NON_FATAL ):
38        dlg = wx.MessageDialog(None, msg, 'Error', wx.OK | wx.ICON_ERROR)
39    elif sev == INFO:
40        dlg = wx.MessageDialog(None, msg, 'Info', wx.OK | wx.ICON_INFORMATION)
41       
42    try:
43       dlg.ShowModal()
44    finally:
45       dlg.Destroy()
46    if sev == FATAL:
47        sys.exit()
48    return
49
50class ConfigureWidget(wx.Dialog):
51    """ This utility class launches a dialog box to configure the min and max values of
52    a slider or spinctrl"""
53    def __init__(self, parent, title, propCurVal):
54        wx.Dialog.__init__(self, parent, -1, title, size = (250,200))
55        self.minValue = 0
56        self.maxValue = 10000
57        self.propCurVal = propCurVal
58        panel = wx.Panel(self, -1)
59        vbox = wx.BoxSizer(wx.VERTICAL)
60        #wx.StaticBox(panel, -1, 'Colors', (5, 5), (240, 150))
61        minHBox = wx.BoxSizer(wx.HORIZONTAL)
62        minLabel = wx.StaticText(self, -1, 'Min Value', name = 'minValue')
63        self.minText = wx.TextCtrl(self, -1, str(self.minValue))
64        minHBox.Add(minLabel, 1, wx.ALIGN_LEFT | wx.TOP | wx.BOTTOM, 5)
65        minHBox.Add(self.minText, 1, wx.ALIGN_RIGHT | wx.TOP | wx.BOTTOM, 5)
66       
67        maxHBox = wx.BoxSizer(wx.HORIZONTAL)
68        maxLabel = wx.StaticText(self, -1, 'Max Value', name = 'maxValue')
69        self.maxText = wx.TextCtrl(self, -1, str(self.maxValue))
70        maxHBox.Add(maxLabel, 1, wx.ALIGN_LEFT | wx.TOP | wx.BOTTOM, 5)
71        maxHBox.Add(self.maxText, 1, wx.ALIGN_RIGHT | wx.TOP | wx.BOTTOM, 5)
72
73        btnHBox = wx.BoxSizer(wx.HORIZONTAL)
74        OkBtn = wx.Button(self, -1, 'Ok')
75        CancelBtn = wx.Button(self, -1, 'Cancel')
76        self.Bind(wx.EVT_BUTTON, self.OnOk, OkBtn)
77        self.Bind(wx.EVT_BUTTON, self.OnCancel, CancelBtn)
78       
79        btnHBox.Add(OkBtn, 1,  wx.ALIGN_LEFT | wx.TOP | wx.BOTTOM, 10)
80        btnHBox.AddSpacer((10,10))
81        btnHBox.Add(CancelBtn, 1, wx.ALIGN_RIGHT | wx.TOP | wx.BOTTOM, 10)
82       
83        vbox.Add(minHBox, 1, wx.ALIGN_CENTER | wx.TOP | wx.BOTTOM, 5)
84        vbox.Add(maxHBox, 1,  wx.ALIGN_CENTER | wx.TOP | wx.BOTTOM, 5)
85        vbox.Add(btnHBox, 1, wx.ALIGN_CENTER | wx.TOP | wx.BOTTOM , 5)
86       
87        self.SetSizer(vbox)
88       
89   
90    def OnOk(self, event):
91        try:
92            self.minValue = int(self.minText.GetValue())
93            self.maxValue = int(self.maxText.GetValue())
94           
95            if ( self.propCurVal < self.minValue or self.propCurVal > self.maxValue ):
96                warningMsg = "Current Value " + str(self.propCurVal) + " is not in the newly configured range ("
97                warningMsg = warningMsg + str(self.minValue) + "," + str(self.maxValue) + ")"
98                warningMsg = warningMsg + "The current value will be rest accordingly. \nDo you wish to continue?"
99                optDialog = wx.MessageDialog(self, warningMsg, "Warning" , wx.YES_NO | wx.ICON_QUESTION)
100                userOption = optDialog.ShowModal()
101                if ( userOption == wx.ID_NO ):
102                    return
103                else:
104                    pass
105            self.Destroy()
106        except(ValueError):
107            msg = 'Invalid values. Please enter only numeric(integer) values'
108            showMessage(msg, NON_FATAL)
109   
110    def OnCancel(self, event):
111        self.Destroy()
112   
113    def getMin(self):
114        #return int(self.minText.GetValue())
115        return self.minValue
116   
117    def getMax(self):
118        #return int(self.maxText.GetValue())
119        return self.maxValue
120   
121    def setMin(self, newVal):
122        self.minText.SetValue(str(newVal))
123   
124    def setMax(self, newVal):
125        self.maxText.SetValue(str(newVal))
126       
127
128class WaveAppStatusBar(wx.StatusBar):
129    def __init__(self, parent):
130        wx.StatusBar.__init__(self, parent)
131        self.SetFieldsCount(2)
132        #self.SetStatusText("Welcome to OSSIE WaveApp", 0)
133        self.SetStatusWidths([-5,-1])
134             
135        startIconPath = "../resources/start.png"
136        stopIconPath = "../resources/stop.png"
137        self.startIcon = wx.Image(startIconPath, wx.BITMAP_TYPE_ANY).ConvertToBitmap()
138        self.stopIcon = wx.Image(stopIconPath, wx.BITMAP_TYPE_ANY).ConvertToBitmap()
139       
140        self.startBtn = wx.BitmapButton(self, -1, self.startIcon)
141        self.uninstall = wx.Button(self, -1, 'U')
142       
143        self.startBtn.SetSize((23,23))
144        self.uninstall.SetSize((23,23))
145       
146        self.Bind(wx.EVT_SIZE, self.OnResize)
147        self.Bind(wx.EVT_BUTTON, self.OnStart, self.startBtn)
148        self.running = True
149        self.placeButtons()
150   
151    def placeButtons(self):
152        rect = self.GetFieldRect(1)
153        print rect.x, rect.y
154        self.startBtn.SetPosition((rect.x+5, rect.y))
155        stSize = self.startBtn.GetSize()
156        self.uninstall.SetPosition((rect.x + stSize[0]+5, rect.y))
157   
158    def OnStart(self, event):
159        if (self.running):
160            self.startBtn.SetBitmapLabel(self.stopIcon)
161            self.running = False
162        else:
163            self.startBtn.SetBitmapLabel(self.startIcon)
164            self.running = True
165    def OnResize(self, event):
166        self.placeButtons()
167
168
169
170class WaveAppCORBA:
171    def __init__(self):
172        self.rootContext = None
173        self.availableWforms = {}
174        self.__namingservice = LOCAL_HOST
175        #self.init_CORBA()
176           
177    def selectNamingService(self):
178        newNS = NamingserviceDialog(self)
179        #return TRUE if new naming service is selected
180        if newNS.GetReturnCode() == 1:
181            return True
182        else:
183            return False
184   
185    def init_CORBA(self, enableGUI = True):
186        self.enableGUI = enableGUI
187        self.domMgr = None
188        #Add naming service address to sys.argv
189        try:
190            sys.argv.index('-ORBInitRef')
191        except ValueError:
192            sys.argv.append('-ORBInitRef')
193            sys.argv.append('NameService=corbaname::'+self.__namingservice)
194       
195        #orb object has to be destroyed before moving to new naming service
196        try:
197            self.orb.destroy()
198        except:
199            pass
200         
201        self.orb = CORBA.ORB_init(sys.argv, CORBA.ORB_ID)
202        self.obj = self.orb.resolve_initial_references("NameService")
203        if self.obj is None:
204            print "init_CORBA(): FATAL Error: Could not resolve initial references"
205            showMessage('Could not resolve initial references' , FATAL, self.enableGUI)
206            return
207        try:
208            self.rootContext = self.obj._narrow(CosNaming.NamingContext)
209        except(Exception), val:
210            #print "init_CORBA(): FATAL Error: Failed to get naming context"
211            #showMessage('Could not initialize CORBA. Failed to get naming context \n The application will now exit.', FATAL)
212           
213            newNS = False
214            while not newNS:
215                ts = "Failed to narrow the root naming context.\n"
216                ts += "Are the Naming Service and nodeBooter running on "+self.__namingservice+"?"
217               
218                showMessage(ts, NON_FATAL, self.enableGUI)
219                nsDialog = NamingserviceDialog(self)
220                if nsDialog.GetReturnCode() == 1:
221                    newNS = True
222                elif nsDialog.GetReturnCode() == -2:
223                        sys.exit(-1)
224               
225            return
226       
227        if self.rootContext is None:
228            print "init_CORBA(): FATAL Error: Failed to get root context"
229           
230            showMessage('Could not initialize CORBA.\nFailed to get root context', FATAL, self.enableGUI)
231            return
232        name = [CosNaming.NameComponent("DomainName1",""), CosNaming.NameComponent("DomainManager","")]
233        try:
234            self.obj = self.rootContext.resolve(name)
235        except:
236            print "init_CORBA(): FATAL Error: Could not find domain manager"
237            showMessage('Could not find Domain Manager', FATAL, self.enableGUI)
238            return
239        self.domMgr = self.obj._narrow(CF.DomainManager)
240        if self.domMgr is None:
241            print "init_CORBA(): FATAL Error: Could not resolve domain manager"
242            showMessage('Could not resolve Domain Manager', FATAL, self.enableGUI)
243       
244        #get the reference to FileManager to perform all file operations (list, open etc.. )
245        try:
246            self.fileMgr = self.domMgr._get_fileMgr()
247        except:
248            print "init_CORBA(): FATAL Error: Could not get file Manager from Domain manager"
249            showMessage('FATAL: Could not get file manager reference', FATAL, self.enableGUI)
250   
251    def setNamingService (self, newNS):
252        self.__namingservice = newNS
253   
254    def getNamingService(self):
255        return self.__namingservice
256       
257    def getApplications(self):
258        dom_obj = self.rootContext.resolve([CosNaming.NameComponent("DomainName1","")])
259        dom_context = dom_obj._narrow(CosNaming.NamingContext)
260       
261        if dom_context is None:
262            print 'In getApplications() : dom_context not found'
263            return
264        self.availableWforms.clear()
265       
266        try:
267            appSeq = self.domMgr._get_applications()
268        except(CORBA.TRANSIENT), val:
269            #print "In getApplications():",  str(val)
270            showMessage("Exception! " + str(val) + "\n Could not get applications from Domain Manager \n Exiting now!!!" , FATAL, self.enableGUI)
271            sys.exit(-1)
272        members = dom_context.list(100)
273        for m in members[0]:
274            wformName = str(m.binding_name[0].id)
275            wformObj = dom_context.resolve([CosNaming.NameComponent(wformName,"")])
276            wformContext = wformObj._narrow(CosNaming.NamingContext)
277            if wformContext is None:
278                #print wformName
279                continue
280           
281                       
282            foundApp = False
283            for app in appSeq:
284                appName = app._get_name()
285                if appName in wformName:
286                    if self.availableWforms.has_key(appName):
287                        if wformName not in self.availableWforms[appName]:
288                            self.availableWforms[appName].append(wformName)
289                    else:
290                        self.availableWforms[appName] = [wformName]
291        #returns a dictionary of applications and theri corresponding installed waveforms
292        return self.availableWforms
293   
294    def installWaveform(self, wformSAD, wformDAS, start):
295       
296        #sadxml = importResource.stripDoctype(wformSAD)
297        #doc_sad = xml.dom.minidom.parse(wformSAD)
298        doc_sad = self.getDOM(wformSAD)
299        if doc_sad is None:
300            return
301        app_name = doc_sad.getElementsByTagName("softwareassembly")[0].getAttribute("name")
302        _appFacProps = []
303        devMgrSeq = None
304        try:
305            devMgrSeq = self.domMgr._get_deviceManagers()
306        except(CORBA.COMM_FAILURE, CORBA.TRANSIENT), val:
307            showMessage("Exception: " + str(val) + "\n - Could not get device managers!" , NON_FATAL, self.enableGUI)
308            return
309           
310        available_dev_seq = []
311        for devmgr in range(len(devMgrSeq)):
312            devMgr = devMgrSeq[devmgr]
313            curr_devSeq = devMgr._get_registeredDevices()
314            for dev in range(len(curr_devSeq)):
315                curr_dev = curr_devSeq[dev]
316                available_dev_seq.append(curr_dev._get_identifier())
317                #print curr_dev._get_identifier()
318
319        #clean_SAD = wformSAD.split("/sdr/dom")
320        #rel_wformSAD = clean_SAD[1]
321        self.domMgr.installApplication(wformSAD)
322
323       
324        # Parse the device assignment sequence, ensure
325        #doc_das = xml.dom.minidom.parse(wformDAS)
326        doc_das = self.getDOM(wformDAS)
327        deviceassignmenttypeNodeList = doc_das.getElementsByTagName("deviceassignmenttype")
328
329        for deviceassignmenttypeNode in deviceassignmenttypeNodeList:
330            # look for assigndeviceid nodes
331            assigndeviceidNodeList = deviceassignmenttypeNode.getElementsByTagName("assigndeviceid")
332            if len(assigndeviceidNodeList) == 0:
333                ts = "Could not find \"assigndeviceid\" tag\nAborting install"
334                showMessage(ts, NON_FATAL, self.enableGUI)
335                #errorMsg(self, ts)
336                return
337
338            # get assigndeviceid tag value (DCE:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)
339            assigndeviceid = assigndeviceidNodeList[0].firstChild.data
340
341            # ensure assigndeviceid is in list of available devices
342            if assigndeviceid not in available_dev_seq:
343                ts = "Could not find the required device: " + str(assigndeviceid)
344                ts += "\nAborting install"
345                showMessage(ts, NON_FATAL, self.enableGUI)
346                #errorMsg(self, ts)
347                return
348               
349        _devSeq = self.BuildDevSeq(wformDAS)
350        _applicationFactories = self.domMgr._get_applicationFactories()
351
352        # attempt to match up the waveform application name to
353        # a application factory of the same name
354        app_factory_num = -1
355        for app_num in range(len(_applicationFactories)):
356            if _applicationFactories[app_num]._get_name()==app_name:
357                app_factory_num = app_num
358                break
359   
360        if app_factory_num == -1:
361            showMessage ("Application factory not found", NON_FATAL, self.enableGUI)
362           
363
364        # use the application factor I found above to create an instance
365        # of an application
366        try:
367            app = _applicationFactories[app_factory_num].create(_applicationFactories[app_factory_num]._get_name(),_appFacProps,_devSeq)
368        except:
369            showMessage("Unable to create application\nMake sure that all appropriate nodes are installed", NON_FATAL, self.enableGUI)
370            return(None)
371       
372        if start:
373            # start the application
374            app.start()
375       
376        naming_context_list = app._get_componentNamingContexts()
377        naming_context = naming_context_list[0].elementId.split("/")
378        application_name = app._get_name()
379        newInstance = naming_context[1]
380        return newInstance
381   
382    def uninstallWaveform(self, wformName):
383        try:
384            appRef = self.getAppRef(wformName)
385            if appRef is None:
386                showMessage("Error: Failed to get application reference for " + wformName, NON_FATAL, self.enableGUI)
387                return False
388            appRef.releaseObject()
389        except(CORBA.COMM_FAILURE, CORBA.INV_OBJREF), val:
390            showMessage("Exception: " + str(val) + "\n - Could not uninstall " + wformName, NON_FATAL, self.enableGUI)
391            return False
392        return True
393   
394    def startWaveform(self, wformName):
395        appRef = self.getAppRef(wformName)
396        appRef.start()
397        return True
398   
399    def stopWaveform(self, wformName):
400        appRef = self.getAppRef(wformName)
401        appRef.stop()
402        return True
403   
404    def BuildDevSeq(self, dasXML):
405        #doc_das = xml.dom.minidom.parse(dasXML)
406        doc_das = self.getDOM(dasXML)
407         
408        # create node list of "deviceassignmenttype"
409        deviceassignmenttypeNodeList = doc_das.getElementsByTagName("deviceassignmenttype")
410
411        ds = []
412        for n in deviceassignmenttypeNodeList:
413            componentid = n.getElementsByTagName("componentid")[0].firstChild.data
414            assigndeviceid = n.getElementsByTagName("assigndeviceid")[0].firstChild.data
415            ds.append(CF.DeviceAssignmentType(str(componentid),str(assigndeviceid)))
416
417        return ds
418   
419    def getAppRef(self, selWform):
420        dom_obj = self.rootContext.resolve([CosNaming.NameComponent("DomainName1","")])
421        dom_context = dom_obj._narrow(CosNaming.NamingContext)
422        try:
423            if dom_context is None:
424                showMessage('Could not reference for DomainName1', NON_FATAL, self.enableGUI)
425                return
426            appSeq = self.domMgr._get_applications()
427            members = dom_context.list(100)
428            for m in members[0]:
429                wformName = str(m.binding_name[0].id)
430               
431                wformObj = dom_context.resolve([CosNaming.NameComponent(wformName,"")])
432                wformContext = wformObj._narrow(CosNaming.NamingContext)
433                if wformContext is None:
434                    #print wformName
435                    continue
436               
437                wformName = wformName[wformName.index("::") + 2:] #strip off OSSIE:: from wform naem           
438                foundApp = False
439                wformApp = None
440                for app in appSeq:
441                    compNameCon = app._get_componentNamingContexts()
442                    for compElementType in compNameCon:
443                        if (wformName in compElementType.elementId) and (wformName == selWform):
444                            wformApp = app
445                            break
446               
447                if wformApp is not None:
448                    break
449            return wformApp
450        except:
451            #errorMsg = sys.exc_info()[1]
452            #showMessage(str(errorMsg), NON_FATAL)
453            return None
454           
455    def query(self, wformName, compName, prpList):
456        wformName = "OSSIE::" + wformName
457       
458        try:
459            prp = [CosNaming.NameComponent("DomainName1", ''),
460                   CosNaming.NameComponent(wformName,''),
461                   CosNaming.NameComponent(compName,'')]
462   
463            prpRsrcRef = self.rootContext.resolve(prp)
464            if prpRsrcRef is None:
465                showMessage(("Unable to find rootContext for %s/%s" % (wformName,compName)), NON_FATAL, self.enableGUI)
466                return None
467       
468            prpRsrcHandle = prpRsrcRef._narrow(CF.Resource)
469            prpSetHandle = prpRsrcRef._narrow(CF.PropertySet)
470       
471            if prpSetHandle is None:
472                showMessage(("Unable to get PropertySet reference for %s/%s" % (wformName, compName)), NON_FATAL, self.enableGUI)
473   
474            if len(prpList) == 0:
475                prpList = prpSetHandle.query(prpList)
476                       
477        except:
478            errorMsg = sys.exc_info()[1]
479            showMessage(str(errorMsg), NON_FATAL, self.enableGUI)
480            return None
481       
482        return prpList
483   
484    def configure(self, wformName, compName, prpList):
485        wformName = "OSSIE::" + wformName
486        try:
487            prpRef = [CosNaming.NameComponent("DomainName1", ''),
488                      CosNaming.NameComponent(wformName,''),
489                      CosNaming.NameComponent(compName,'')]
490       
491            prpRsrcRef = self.rootContext.resolve(prpRef)
492            if prpRsrcRef is None:
493                showMessage(("Unable to find rootContext for %s/%s" % (wformName,compName)), NON_FATAL, self.enableGUI)
494                return False
495       
496            prpRsrcHandle = prpRsrcRef._narrow(CF.Resource)
497            prpSetHandle = prpRsrcRef._narrow(CF.PropertySet)
498            if prpSetHandle is None:
499                showMessage(("Unable to get PropertySet reference for %s/%s" % (wformName, compName)), NON_FATAL, self.enableGUI)
500                return False
501            prpSetHandle.configure(prpList)
502       
503            return True
504        except:
505            errorMsg = str(sys.exc_info()[1])
506            showMessage("Exception! " + errorMsg + "\n Connection to Domain Manager Failed", NON_FATAL, self.enableGUI)
507            return False
508       
509    def getDOM(self, fileName):
510        #get the file descriptor from the framework
511        #file path should be absolute to the Framework file system
512        #e.g. if framework is mounted on /sdr/dom, then the path of a
513        #sad file would like "/waveforms/ossie_demo/ossie_demo.sad.xml
514       
515        try:
516            #print "getDOM() - fileName = ", fileName
517            fd = self.fileMgr.open(fileName, True)
518            domObj = xml.dom.minidom.parse(fd)
519            fd.close()
520            return domObj
521        except:
522            errorMsg = str(sys.exc_info()[1])
523            errorMsg = errorMsg + "\n getDOM(): Could not create DOM for file '" + fileName + "'"
524            showMessage(str(errorMsg), NON_FATAL, self.enableGUI)
525            return None
526   
527    def getFileList(self, dir=None, filetype= ""):
528        """ This function searches for the given filetype (e.g. *.sad.xml)
529        under the dir through the FileManager. the directory dir is relative
530        to the FileManager mount directory (/sdr/dom)
531        """
532       
533        fileNames = []
534        try:
535            fileObjList = self.fileMgr.list("/"+filetype) #FileMgr list func demands a /
536            #fileObjList is a CORBA sequence of CF:File objects. extract the file name
537           
538            if fileObjList is not None:
539                for fileObj in fileObjList:
540                    #the file name is stored as an absolute path to the FileManager file system
541                    #e.g file name = dom/waveforms/ossie_demo/ossie_demo.sad.xml
542                    #throughout wavedash,we store the filenames in the model as relative to the
543                    #FileManager root dir (/sdr/dom). Hence strip off dom/ from the returned filename
544                    if dir is not None:
545                        if ( fileObj.name.find(dir) != -1 ):
546                            fName = fileObj.name[fileObj.name.find("/"):]
547                            fileNames.append(fName)
548        except:
549            errorMsg = str(sys.exc_info()[1])
550            errorMsg = errorMsg + "\n getFileList(): Could not get list of files from FileManager '"
551            showMessage(str(errorMsg), NON_FATAL, self.enableGUI)
552            return None
553       
554        return fileNames
Note: See TracBrowser for help on using the browser.