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

Revision 10108, 22.4 KB (checked in by Snyder.Jason, 3 years ago)

made changes to enable using this with WavedashHeadlessController?

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           
206            showMessage('Could not resolve initial references' , FATAL, self.enableGUI)
207            return
208        try:
209            self.rootContext = self.obj._narrow(CosNaming.NamingContext)
210        except(Exception), val:
211            #print "init_CORBA(): FATAL Error: Failed to get naming context"
212            #showMessage('Could not initialize CORBA. Failed to get naming context \n The application will now exit.', FATAL)
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                showMessage(ts, NON_FATAL, self.enableGUI)
218                nsDialog = NamingserviceDialog(self)
219                if nsDialog.GetReturnCode() == 1:
220                    newNS = True
221                elif nsDialog.GetReturnCode() == -2:
222                    sys.exit(-1)
223            return
224       
225        if self.rootContext is None:
226            print "init_CORBA(): FATAL Error: Failed to get root context"
227           
228            showMessage('Could not initialize CORBA.\nFailed to get root context', FATAL, self.enableGUI)
229            return
230        name = [CosNaming.NameComponent("DomainName1",""), CosNaming.NameComponent("DomainManager","")]
231        try:
232            self.obj = self.rootContext.resolve(name)
233        except:
234            print "init_CORBA(): FATAL Error: Could not find domain manager"
235            showMessage('Could not find Domain Manager', FATAL, self.enableGUI)
236            return
237        self.domMgr = self.obj._narrow(CF.DomainManager)
238        if self.domMgr is None:
239            print "init_CORBA(): FATAL Error: Could not resolve domain manager"
240            showMessage('Could not resolve Domain Manager', FATAL, self.enableGUI)
241       
242        #get the reference to FileManager to perform all file operations (list, open etc.. )
243        try:
244            self.fileMgr = self.domMgr._get_fileMgr()
245        except:
246            print "init_CORBA(): FATAL Error: Could not get file Manager from Domain manager"
247            showMessage('FATAL: Could not get file manager reference', FATAL, self.enableGUI)
248   
249    def setNamingService (self, newNS):
250        self.__namingservice = newNS
251   
252    def getNamingService(self):
253        return self.__namingservice
254       
255    def getApplications(self):
256        dom_obj = self.rootContext.resolve([CosNaming.NameComponent("DomainName1","")])
257        dom_context = dom_obj._narrow(CosNaming.NamingContext)
258       
259        if dom_context is None:
260            print 'In getApplications() : dom_context not found'
261            return
262        self.availableWforms.clear()
263       
264        try:
265            appSeq = self.domMgr._get_applications()
266        except(CORBA.TRANSIENT), val:
267            #print "In getApplications():",  str(val)
268            showMessage("Exception! " + str(val) + "\n Could not get applications from Domain Manager \n Exiting now!!!" , FATAL)
269            sys.exit(-1)
270        members = dom_context.list(100)
271        for m in members[0]:
272            wformName = str(m.binding_name[0].id)
273            wformObj = dom_context.resolve([CosNaming.NameComponent(wformName,"")])
274            wformContext = wformObj._narrow(CosNaming.NamingContext)
275            if wformContext is None:
276                #print wformName
277                continue
278           
279                       
280            foundApp = False
281            for app in appSeq:
282                appName = app._get_name()
283                if appName in wformName:
284                    if self.availableWforms.has_key(appName):
285                        if wformName not in self.availableWforms[appName]:
286                            self.availableWforms[appName].append(wformName)
287                    else:
288                        self.availableWforms[appName] = [wformName]
289        #returns a dictionary of applications and theri corresponding installed waveforms
290        return self.availableWforms
291   
292    def installWaveform(self, wformSAD, wformDAS, start):
293       
294        #sadxml = importResource.stripDoctype(wformSAD)
295        #doc_sad = xml.dom.minidom.parse(wformSAD)
296        doc_sad = self.getDOM(wformSAD)
297        if doc_sad is None:
298            return
299        app_name = doc_sad.getElementsByTagName("softwareassembly")[0].getAttribute("name")
300        _appFacProps = []
301        devMgrSeq = None
302        try:
303            devMgrSeq = self.domMgr._get_deviceManagers()
304        except(CORBA.COMM_FAILURE, CORBA.TRANSIENT), val:
305            showMessage("Exception: " + str(val) + "\n - Could not get device managers!" , NON_FATAL)
306            return
307           
308        available_dev_seq = []
309        for devmgr in range(len(devMgrSeq)):
310            devMgr = devMgrSeq[devmgr]
311            curr_devSeq = devMgr._get_registeredDevices()
312            for dev in range(len(curr_devSeq)):
313                curr_dev = curr_devSeq[dev]
314                available_dev_seq.append(curr_dev._get_identifier())
315                #print curr_dev._get_identifier()
316
317        #clean_SAD = wformSAD.split("/sdr/dom")
318        #rel_wformSAD = clean_SAD[1]
319        self.domMgr.installApplication(wformSAD)
320
321       
322        # Parse the device assignment sequence, ensure
323        #doc_das = xml.dom.minidom.parse(wformDAS)
324        doc_das = self.getDOM(wformDAS)
325        deviceassignmenttypeNodeList = doc_das.getElementsByTagName("deviceassignmenttype")
326
327        for deviceassignmenttypeNode in deviceassignmenttypeNodeList:
328            # look for assigndeviceid nodes
329            assigndeviceidNodeList = deviceassignmenttypeNode.getElementsByTagName("assigndeviceid")
330            if len(assigndeviceidNodeList) == 0:
331                ts = "Could not find \"assigndeviceid\" tag\nAborting install"
332                showMessage(ts, NON_FATAL)
333                #errorMsg(self, ts)
334                return
335
336            # get assigndeviceid tag value (DCE:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)
337            assigndeviceid = assigndeviceidNodeList[0].firstChild.data
338
339            # ensure assigndeviceid is in list of available devices
340            if assigndeviceid not in available_dev_seq:
341                ts = "Could not find the required device: " + str(assigndeviceid)
342                ts += "\nAborting install"
343                showMessage(ts, NON_FATAL)
344                #errorMsg(self, ts)
345                return
346               
347        _devSeq = self.BuildDevSeq(wformDAS)
348        _applicationFactories = self.domMgr._get_applicationFactories()
349
350        # attempt to match up the waveform application name to
351        # a application factory of the same name
352        app_factory_num = -1
353        for app_num in range(len(_applicationFactories)):
354            if _applicationFactories[app_num]._get_name()==app_name:
355                app_factory_num = app_num
356                break
357   
358        if app_factory_num == -1:
359            showMessage ("Application factory not found", NON_FATAL)
360           
361
362        # use the application factor I found above to create an instance
363        # of an application
364        try:
365            app = _applicationFactories[app_factory_num].create(_applicationFactories[app_factory_num]._get_name(),_appFacProps,_devSeq)
366        except:
367            showMessage("Unable to create application\nMake sure that all appropriate nodes are installed", NON_FATAL)
368            return(None)
369       
370        if start:
371            # start the application
372            app.start()
373       
374        naming_context_list = app._get_componentNamingContexts()
375        naming_context = naming_context_list[0].elementId.split("/")
376        application_name = app._get_name()
377        newInstance = naming_context[1]
378        return newInstance
379   
380    def uninstallWaveform(self, wformName):
381        try:
382            appRef = self.getAppRef(wformName)
383            if appRef is None:
384                showMessage("Error: Failed to get application reference for " + wformName, NON_FATAL)
385                return False
386            appRef.releaseObject()
387        except(CORBA.COMM_FAILURE, CORBA.INV_OBJREF), val:
388            showMessage("Exception: " + str(val) + "\n - Could not uninstall " + wformName, NON_FATAL)
389            return False
390        return True
391   
392    def startWaveform(self, wformName):
393        appRef = self.getAppRef(wformName)
394        appRef.start()
395        return True
396   
397    def stopWaveform(self, wformName):
398        appRef = self.getAppRef(wformName)
399        appRef.stop()
400        return True
401   
402    def BuildDevSeq(self, dasXML):
403        #doc_das = xml.dom.minidom.parse(dasXML)
404        doc_das = self.getDOM(dasXML)
405         
406        # create node list of "deviceassignmenttype"
407        deviceassignmenttypeNodeList = doc_das.getElementsByTagName("deviceassignmenttype")
408
409        ds = []
410        for n in deviceassignmenttypeNodeList:
411            componentid = n.getElementsByTagName("componentid")[0].firstChild.data
412            assigndeviceid = n.getElementsByTagName("assigndeviceid")[0].firstChild.data
413            ds.append(CF.DeviceAssignmentType(str(componentid),str(assigndeviceid)))
414
415        return ds
416   
417    def getAppRef(self, selWform):
418        dom_obj = self.rootContext.resolve([CosNaming.NameComponent("DomainName1","")])
419        dom_context = dom_obj._narrow(CosNaming.NamingContext)
420        try:
421            if dom_context is None:
422                showMessage('Could not reference for DomainName1', NON_FATAL)
423                return
424            appSeq = self.domMgr._get_applications()
425            members = dom_context.list(100)
426            for m in members[0]:
427                wformName = str(m.binding_name[0].id)
428               
429                wformObj = dom_context.resolve([CosNaming.NameComponent(wformName,"")])
430                wformContext = wformObj._narrow(CosNaming.NamingContext)
431                if wformContext is None:
432                    #print wformName
433                    continue
434               
435                wformName = wformName[wformName.index("::") + 2:] #strip off OSSIE:: from wform naem           
436                foundApp = False
437                wformApp = None
438                for app in appSeq:
439                    compNameCon = app._get_componentNamingContexts()
440                    for compElementType in compNameCon:
441                        if (wformName in compElementType.elementId) and (wformName == selWform):
442                            wformApp = app
443                            break
444               
445                if wformApp is not None:
446                    break
447            return wformApp
448        except:
449            #errorMsg = sys.exc_info()[1]
450            #showMessage(str(errorMsg), NON_FATAL)
451            return None
452           
453    def query(self, wformName, compName, prpList):
454        wformName = "OSSIE::" + wformName
455       
456        try:
457            prp = [CosNaming.NameComponent("DomainName1", ''),
458                   CosNaming.NameComponent(wformName,''),
459                   CosNaming.NameComponent(compName,'')]
460   
461            prpRsrcRef = self.rootContext.resolve(prp)
462            if prpRsrcRef is None:
463                showMessage(("Unable to find rootContext for %s/%s" % (wformName,compName)), NON_FATAL)
464                return None
465       
466            prpRsrcHandle = prpRsrcRef._narrow(CF.Resource)
467            prpSetHandle = prpRsrcRef._narrow(CF.PropertySet)
468       
469            if prpSetHandle is None:
470                showMessage(("Unable to get PropertySet reference for %s/%s" % (wformName, compName)), NON_FATAL)
471   
472            if len(prpList) == 0:
473                prpList = prpSetHandle.query(prpList)
474                       
475        except:
476            errorMsg = sys.exc_info()[1]
477            showMessage(str(errorMsg), NON_FATAL)
478            return None
479       
480        return prpList
481   
482    def configure(self, wformName, compName, prpList):
483        wformName = "OSSIE::" + wformName
484        try:
485            prpRef = [CosNaming.NameComponent("DomainName1", ''),
486                      CosNaming.NameComponent(wformName,''),
487                      CosNaming.NameComponent(compName,'')]
488       
489            prpRsrcRef = self.rootContext.resolve(prpRef)
490            if prpRsrcRef is None:
491                showMessage(("Unable to find rootContext for %s/%s" % (wformName,compName)), NON_FATAL)
492                return False
493       
494            prpRsrcHandle = prpRsrcRef._narrow(CF.Resource)
495            prpSetHandle = prpRsrcRef._narrow(CF.PropertySet)
496            if prpSetHandle is None:
497                showMessage(("Unable to get PropertySet reference for %s/%s" % (wformName, compName)), NON_FATAL)
498                return False
499            prpSetHandle.configure(prpList)
500       
501            return True
502        except:
503            errorMsg = str(sys.exc_info()[1])
504            showMessage("Exception! " + errorMsg + "\n Connection to Domain Manager Failed", NON_FATAL)
505            return False
506       
507    def getDOM(self, fileName):
508        #get the file descriptor from the framework
509        #file path should be absolute to the Framework file system
510        #e.g. if framework is mounted on /sdr/dom, then the path of a
511        #sad file would like "/waveforms/ossie_demo/ossie_demo.sad.xml
512       
513        try:
514            #print "getDOM() - fileName = ", fileName
515            fd = self.fileMgr.open(fileName, True)
516            domObj = xml.dom.minidom.parse(fd)
517            fd.close()
518            return domObj
519        except:
520            errorMsg = str(sys.exc_info()[1])
521            errorMsg = errorMsg + "\n getDOM(): Could not create DOM for file '" + fileName + "'"
522            showMessage(str(errorMsg), NON_FATAL, self.enableGUI)
523            return None
524   
525    def getFileList(self, dir=None, filetype= ""):
526        """ This function searches for the given filetype (e.g. *.sad.xml)
527        under the dir through the FileManager. the directory dir is relative
528        to the FileManager mount directory (/sdr/dom)
529        """
530       
531        fileNames = []
532        try:
533            fileObjList = self.fileMgr.list("/"+filetype) #FileMgr list func demands a /
534            #fileObjList is a CORBA sequence of CF:File objects. extract the file name
535           
536            if fileObjList is not None:
537                for fileObj in fileObjList:
538                    #the file name is stored as an absolute path to the FileManager file system
539                    #e.g file name = dom/waveforms/ossie_demo/ossie_demo.sad.xml
540                    #throughout wavedash,we store the filenames in the model as relative to the
541                    #FileManager root dir (/sdr/dom). Hence strip off dom/ from the returned filename
542                    if dir is not None:
543                        if ( fileObj.name.find(dir) != -1 ):
544                            fName = fileObj.name[fileObj.name.find("/"):]
545                            fileNames.append(fName)
546        except:
547            errorMsg = str(sys.exc_info()[1])
548            errorMsg = errorMsg + "\n getFileList(): Could not get list of files from FileManager '"
549            showMessage(str(errorMsg), NON_FATAL, self.enableGUI)
550            return None
551       
552        return fileNames
Note: See TracBrowser for help on using the browser.