You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by ch...@apache.org on 2008/01/16 20:56:02 UTC

svn commit: r612559 [8/8] - in /activemq/sandbox/activemq-log-analyzer: ./ example_logs/ example_logs/correct/ example_logs/incorrect/ loganalyzerengine/ loganalyzergui/ winxp_screenshots/

Added: activemq/sandbox/activemq-log-analyzer/loganalyzergui/Application.py
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-log-analyzer/loganalyzergui/Application.py?rev=612559&view=auto
==============================================================================
--- activemq/sandbox/activemq-log-analyzer/loganalyzergui/Application.py (added)
+++ activemq/sandbox/activemq-log-analyzer/loganalyzergui/Application.py Wed Jan 16 11:55:49 2008
@@ -0,0 +1,88 @@
+"""
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+"""
+
+"""
+Module Application
+"""
+import wx
+from DirectoryPanel import DirectoryPanel
+from TabbedPanel import TabbedPanel
+
+class MainPanel(wx.Panel):
+    """
+    Panel contained into the window of the application.
+    It contains a DirectoryPanel and a TabbedPanel.
+    
+    """
+    
+    def __init__(self, parent):
+        """
+        Constructor
+        """
+        
+        wx.Panel.__init__(self, parent, -1)
+        
+        self.tabbedPanel = TabbedPanel(self)
+        
+        sizer = wx.BoxSizer(wx.VERTICAL)
+        sizer.Add(DirectoryPanel(self), 0, wx.EXPAND|wx.ALL, 5)
+        sizer.Add(self.tabbedPanel, 1, wx.EXPAND)
+        self.SetSizer(sizer)
+        
+    def logDataUpdated(self):
+        """
+        Method to be called when the parsed data has been updated.
+        The Panel will notify its children components.
+        """
+        
+        self.tabbedPanel.logDataUpdated()
+
+class MainFrame(wx.Frame):
+    """
+    This class represents the window of the application.
+    It contains a MainPanel object.
+    We need to add a wx.Panel to a wx.Frame to avoid
+    graphical problems in Windows.
+    """
+    
+    def __init__(self, parent):
+        """
+        Constructor
+        """
+        
+        wx.Frame.__init__(self, parent, 100, 
+                          'ActiveMQ Log Analyzer Tool', size=(1024,800))
+#        ib = wx.IconBundle()
+#        ib.AddIconFromFile("logparser.ico", wx.BITMAP_TYPE_ANY)
+#        self.SetIcons(ib)
+        sizer = wx.BoxSizer(wx.VERTICAL)
+        sizer.Add(MainPanel(self), 1, wx.EXPAND)
+        self.SetSizer(sizer)
+        self.Centre()
+        self.Show(True)
+
+class Application(wx.App):
+    """
+    Main class of the application
+    """
+    
+    def OnInit(self):
+        """
+        To be executed when Application is launched
+        """
+        MainFrame(None)
+        return True

Propchange: activemq/sandbox/activemq-log-analyzer/loganalyzergui/Application.py
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/sandbox/activemq-log-analyzer/loganalyzergui/Application.pyc
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-log-analyzer/loganalyzergui/Application.pyc?rev=612559&view=auto
==============================================================================
Binary file - no diff available.

Propchange: activemq/sandbox/activemq-log-analyzer/loganalyzergui/Application.pyc
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: activemq/sandbox/activemq-log-analyzer/loganalyzergui/DirectoryPanel.py
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-log-analyzer/loganalyzergui/DirectoryPanel.py?rev=612559&view=auto
==============================================================================
--- activemq/sandbox/activemq-log-analyzer/loganalyzergui/DirectoryPanel.py (added)
+++ activemq/sandbox/activemq-log-analyzer/loganalyzergui/DirectoryPanel.py Wed Jan 16 11:55:49 2008
@@ -0,0 +1,79 @@
+"""
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+"""
+
+"""
+Module DirectoryPanel
+"""
+import wx
+import os
+
+from loganalyzerengine.LogParser import LogParser
+
+class DirectoryPanel(wx.Panel):
+    """
+    Panel to choose the directory with the log files to be parsed,
+    and launch the parsing / analyzing process.
+    """
+    
+    def __init__(self, parent):
+        """
+        Constructor
+        """
+        
+        wx.Panel.__init__(self, parent, -1)
+        self.mainPanel = parent
+        #self.textctrl = wx.TextCtrl(self, -1, 'C:\logs')
+        self.textctrl = wx.TextCtrl(self, -1, '/home/david/logs')
+        
+        self.lastDirectoryOpen = ''
+        
+        sizer = wx.BoxSizer(wx.HORIZONTAL)
+        sizer.Add(wx.StaticText(self, -1, 'Directory'), 0, wx.CENTER|wx.RIGHT, 5)
+        sizer.Add(self.textctrl, 1, wx.CENTER|wx.RIGHT, 5)
+        sizer.Add(wx.Button(self, 100 , 'Choose'), 0, wx.CENTER|wx.RIGHT, 5)
+        sizer.Add(wx.Button(self, 101 , 'Parse'), 0, wx.CENTER)
+        
+        self.Bind(wx.EVT_BUTTON, self.OnChoose, id=100)
+        self.Bind(wx.EVT_BUTTON, self.OnParse, id=101)
+        
+        self.SetSizer(sizer)
+        
+    def OnChoose(self, event):
+        """
+        Action to be executed when the 'Choose' button is pressed.
+        """
+        
+        dialog = wx.DirDialog(self, defaultPath=self.lastDirectoryOpen)
+        if dialog.ShowModal() == wx.ID_OK:
+            self.textctrl.SetValue(dialog.GetPath())
+            self.lastDirectoryOpen = dialog.GetPath()
+        else:
+            wx.MessageDialog(self, 'Please choose an appropiate directory', style=wx.OK).ShowModal()
+        
+    def OnParse(self, event):
+        """
+        Action to be executed when the 'Parse' button is pressed.
+        """
+        
+        path = self.textctrl.GetValue()
+        if os.path.isdir(path):
+            LogParser.getInstance().parseDirectory(path)
+            self.mainPanel.logDataUpdated()
+            LogParser.deleteInstance()
+        else:
+            wx.MessageDialog(self, 'That directory does not exist', style=wx.OK).ShowModal()
+    

Propchange: activemq/sandbox/activemq-log-analyzer/loganalyzergui/DirectoryPanel.py
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/sandbox/activemq-log-analyzer/loganalyzergui/DirectoryPanel.pyc
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-log-analyzer/loganalyzergui/DirectoryPanel.pyc?rev=612559&view=auto
==============================================================================
Binary file - no diff available.

Propchange: activemq/sandbox/activemq-log-analyzer/loganalyzergui/DirectoryPanel.pyc
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: activemq/sandbox/activemq-log-analyzer/loganalyzergui/IncorrectSequenceList.py
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-log-analyzer/loganalyzergui/IncorrectSequenceList.py?rev=612559&view=auto
==============================================================================
--- activemq/sandbox/activemq-log-analyzer/loganalyzergui/IncorrectSequenceList.py (added)
+++ activemq/sandbox/activemq-log-analyzer/loganalyzergui/IncorrectSequenceList.py Wed Jan 16 11:55:49 2008
@@ -0,0 +1,201 @@
+"""
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+"""
+
+"""
+Module IncorrectSequenceList
+"""
+import wx
+from loganalyzerengine.Connection import Connection
+from loganalyzerengine.LogFile import LogFile
+
+def advisoryString(message):
+    """
+    Helper method
+    """
+ 
+    if message.advisory:
+        return ' (ADVISORY)'
+    else:
+        return ''
+        
+
+class IncorrectSequenceList(wx.ListCtrl):
+    """
+    List of the incorrect events detected after parsing the logs.
+    """
+    
+    def __init__(self, parent):
+        """
+        Constructor
+        """
+        
+        wx.ListCtrl.__init__(self, parent, -1, 
+                             style=wx.LC_REPORT|wx.LC_SINGLE_SEL|wx.LC_HRULES|wx.LC_VRULES)
+        
+        self.incorrectSequencePanel = parent
+        
+        self.datapresent = False
+        self.connectionForFilter = None
+        
+        self.InsertColumn(0, 'Type')
+        self.InsertColumn(1, 'Connection id / File')
+        self.InsertColumn(2, 'Message id (prod id | prod seq id)')
+        self.InsertColumn(3, 'ntimes')
+        self.InsertColumn(4, 'timestamps')
+        
+        self.SetColumnWidth(0, 150)
+        self.SetColumnWidth(1, 250)
+        self.SetColumnWidth(2, 300)
+        self.SetColumnWidth(3, 100)
+        self.SetColumnWidth(4, 300)
+        
+        
+    def logDataUpdated(self):
+        """
+        This method must be called to notify the list that the parsed data
+        has changed.
+        """
+
+        self.datapresent = True
+        self.updateList()
+        
+    def checkConnectionForFilter(self):
+        """
+        Returns True if the connection that was inputed by the user
+        to filter the events is valid.
+        self.connectionForFilter is a (string, boolean) tuple.
+        The boolean value is True if the string is a shortId, and False if it is a long id.
+        """
+        
+        if self.connectionForFilter is None:
+            return False
+        
+        if self.connectionForFilter[1]:
+            #shortId
+            return self.connectionForFilter[0].isdigit() and \
+                   int(self.connectionForFilter[0]) > -1 and \
+                   int(self.connectionForFilter[0]) < len(Connection.connectionIdList)
+        
+        else:
+            #longId
+            return self.connectionForFilter[0] in Connection.connections
+        
+    def updateList(self):
+        """
+        Updates the display of the list of incorrect events
+        """
+        
+        self.DeleteAllItems()
+        if self.datapresent:
+            options = self.incorrectSequencePanel.options
+            
+            row = 0
+            
+            # we construct a list of connection long ids to be displayed,
+            # depending on the filter desired
+            if self.checkConnectionForFilter():
+                if self.connectionForFilter[1]:
+                    #shortId
+                    connectionIds = [Connection.connectionIdList[int(self.connectionForFilter[0])]]
+                else:
+                    connectionIds = [self.connectionForFilter[0]]
+            else:
+                if self.connectionForFilter is None or self.connectionForFilter[0] == '':
+                    connectionIds = Connection.connections.keys()
+                else:
+                    connectionIds = []      
+                
+            # we display the problems tied to connections
+            showShortIDs = options['showShortIds']
+            
+            for longId in connectionIds:
+                
+                # we display long or short ids depending on the option chosen
+                connection = Connection.getConnectionByLongId(longId)
+                errors = connection.getErrors()
+                
+                if showShortIDs:
+                    printedConnectionId = connection.shortId
+                else:
+                    printedConnectionId = longId
+                
+                # sent but not received messages
+                if options['sentButNotReceived']:
+                    for storedMessage, n, timestamps in errors[0]:
+                        message = storedMessage[0]
+                        self.insertRow(row, 'sentButNotReceived' + advisoryString(message), printedConnectionId,
+                                       message.producer.shortId if showShortIDs else message.producer.longId,
+                                       message.prodSeqId, n, timestamps, wx.WHITE)
+                        row += 1
+                
+                # received but not sent messages
+                if options['receivedButNotSent']:
+                    for storedMessage, n, timestamps in errors[1]:
+                        message = storedMessage[0]
+                        self.insertRow(row, 'receivedButNotSent' + advisoryString(message), printedConnectionId,
+                                       message.producer.shortId if showShortIDs else message.producer.longId,
+                                       message.prodSeqId, n, timestamps, wx.WHITE)
+                        row += 1
+                
+                # duplicate sent or received messages through a connection
+                if options['duplicateInConnection']:
+                    for storedMessage, n, timestamps in errors[2]:
+                        message = storedMessage[0]
+                        self.insertRow(row, 'duplicateSentInConnection' + advisoryString(message), printedConnectionId,
+                                       message.producer.shortId if showShortIDs else message.producer.longId,
+                                       message.prodSeqId, n, timestamps, wx.WHITE)
+                        row += 1
+                        
+                    for storedMessage, n, timestamps in errors[3]:
+                        message = storedMessage[0]
+                        self.insertRow(row, 'duplicateReceivedInConnection' + advisoryString(message), printedConnectionId,
+                                       message.producer.shortId if showShortIDs else message.producer.longId,
+                                       message.prodSeqId, n, timestamps, wx.WHITE)
+                        row += 1
+            
+            # duplicate sent or received messages in the same log file.
+            # right now they are only shown when the connection filter is not used.
+            if options['duplicateInFile'] and not self.checkConnectionForFilter() and \
+            (self.connectionForFilter is None or self.connectionForFilter[0] == ''):
+                for logfile in LogFile.logfiles:
+                    errors = logfile.getErrors()
+                    
+                    for message, n, timestamps in errors[0]:
+                        self.insertRow(row, 'duplicateSentInFile' + advisoryString(message), str(logfile),
+                                       message.producer.shortId if showShortIDs else message.producer.longId,
+                                       message.prodSeqId, n, timestamps, wx.WHITE)
+                        row += 1
+                        
+                    for message, n, timestamps in errors[1]:
+                        self.insertRow(row, 'duplicateReceivedInFile' + advisoryString(message), str(logfile),
+                                       message.producer.shortId if showShortIDs else message.producer.longId,
+                                       message.prodSeqId, n, timestamps, wx.WHITE)
+                        row += 1
+            
+    def insertRow(self, rownumber, typeOfError, connectionId, producerId, producerSequenceId, n, timestamps, col):
+        """
+        Helper method to insert a row into the list
+        """
+        
+        self.InsertStringItem(rownumber, typeOfError)
+        self.SetStringItem(rownumber, 1, str(connectionId))
+        self.SetStringItem(rownumber, 2, str(producerId) + ' | ' + str(producerSequenceId))
+        self.SetStringItem(rownumber, 3, str(n))
+        self.SetStringItem(rownumber, 4, ' | '.join(timestamps))
+        self.SetItemBackgroundColour(rownumber, col)
+
+        

Propchange: activemq/sandbox/activemq-log-analyzer/loganalyzergui/IncorrectSequenceList.py
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/sandbox/activemq-log-analyzer/loganalyzergui/IncorrectSequenceList.pyc
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-log-analyzer/loganalyzergui/IncorrectSequenceList.pyc?rev=612559&view=auto
==============================================================================
Binary file - no diff available.

Propchange: activemq/sandbox/activemq-log-analyzer/loganalyzergui/IncorrectSequenceList.pyc
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: activemq/sandbox/activemq-log-analyzer/loganalyzergui/IncorrectSequencePanel.py
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-log-analyzer/loganalyzergui/IncorrectSequencePanel.py?rev=612559&view=auto
==============================================================================
--- activemq/sandbox/activemq-log-analyzer/loganalyzergui/IncorrectSequencePanel.py (added)
+++ activemq/sandbox/activemq-log-analyzer/loganalyzergui/IncorrectSequencePanel.py Wed Jan 16 11:55:49 2008
@@ -0,0 +1,152 @@
+"""
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+"""
+
+"""
+Module IncorrectSequencePanel
+"""
+import wx
+from IncorrectSequenceList import IncorrectSequenceList
+
+class IncorrectSequencePanel(wx.Panel):
+    """
+    This panel contains a list of incorrect events dectected by the parsing,
+    and many controls to filter which events appear.
+    Also the user can change if long ids (original ActiveMQConnection id strings, long)
+    or short ids (a different integer for each connection) is desired.
+    """
+    
+    def __init__(self, parent):
+        """
+        Constructor
+        """
+        
+        wx.Panel.__init__(self, parent, -1)
+        
+        self.parent = parent
+        self.options = {}
+        
+        self.incorrectSequenceList = IncorrectSequenceList(self)
+        self.showShortIds = wx.CheckBox(self, 100, 'Show results with short ids')
+        self.sentButNotReceived = wx.CheckBox(self, 101, 'Sent but not received')
+        self.receivedButNotSent = wx.CheckBox(self, 102, 'Received but not sent')
+        self.duplicateInConnection = wx.CheckBox(self, 103, 'Duplicate in connection')
+        self.duplicateInFile = wx.CheckBox(self, 104, 'Duplicate in log file')
+        self.connectionText = wx.TextCtrl(self, -1, '')
+        self.rbshortId = wx.RadioButton(self, -1, style=wx.RB_GROUP, label="Short id")
+        self.rblongId = wx.RadioButton(self, -1, label="Long id")
+        
+        self.showShortIds.SetValue(True)
+        self.sentButNotReceived.SetValue(True)
+        self.receivedButNotSent.SetValue(True)
+        self.duplicateInConnection.SetValue(True)
+        self.duplicateInFile.SetValue(True)
+        
+        sizer = wx.BoxSizer(wx.VERTICAL)
+        
+        sizer2 = wx.GridSizer()
+        sizer2 = wx.GridSizer(2, 2, 5, 5)
+        sizer2.AddMany([self.sentButNotReceived,
+                        self.receivedButNotSent,
+                        self.duplicateInConnection,
+                        self.duplicateInFile
+                       ])
+        
+        sizer3 = wx.BoxSizer(wx.HORIZONTAL)
+        sizerrb = wx.BoxSizer(wx.VERTICAL)
+        sizerrb.Add(self.rbshortId, 0, wx.DOWN, 5)
+        sizerrb.Add(self.rblongId, 0)
+        sizer3.Add(wx.StaticText(self, -1, 'Filter by connection\n(leave blank to view all)'), 0, wx.CENTER|wx.RIGHT, 5)
+        sizer3.Add(self.connectionText, 1, wx.CENTER|wx.RIGHT, 5)
+        sizer3.Add(sizerrb, 0, wx.CENTER|wx.RIGHT, 5)
+        sizer3.Add(wx.Button(self, 105, 'Filter'), 0, wx.CENTER)
+        
+        sizer4 = wx.BoxSizer(wx.HORIZONTAL)
+        sizer4.Add(sizer2, 0, wx.CENTER)
+        sizer4.Add(sizer3, 1, wx.EXPAND|wx.CENTER|wx.LEFT, 20)
+        
+        sizer.Add(sizer4, 0, wx.EXPAND|wx.ALL, 5)
+        
+        sizer5 = wx.BoxSizer(wx.HORIZONTAL)
+        sizer5.Add(self.showShortIds, 0, wx.RIGHT|wx.CENTER, 5)
+        sizer5.Add(wx.Button(self, 106, 'Jump to Message Browsing'), 0, wx.CENTER)
+        
+        sizer.Add(sizer5, 0, wx.ALL, 5)
+        
+        sizer.Add(self.incorrectSequenceList, 1, wx.EXPAND)
+        
+        self.Bind(wx.EVT_CHECKBOX, self.OptionsChanged, id=100)
+        self.Bind(wx.EVT_CHECKBOX, self.OptionsChanged, id=101)
+        self.Bind(wx.EVT_CHECKBOX, self.OptionsChanged, id=102)
+        self.Bind(wx.EVT_CHECKBOX, self.OptionsChanged, id=103)
+        self.Bind(wx.EVT_CHECKBOX, self.OptionsChanged, id=104)
+        self.Bind(wx.EVT_BUTTON, self.OnFilter, id=105)
+        self.Bind(wx.EVT_BUTTON, self.OnJump, id=106)
+        
+        self.parseOptions()
+        
+        self.SetSizer(sizer)
+        
+    def logDataUpdated(self):
+        """
+        This method must be called to notify the panel that the parsed data has been updated.
+        It will in turn notify the list.
+        """
+        
+        self.incorrectSequenceList.logDataUpdated()
+        
+    def parseOptions(self):
+        """
+        Stores the values of the various checkboxes into self.options.
+        """
+        
+        self.options['showShortIds'] = self.showShortIds.IsChecked()
+        self.options['sentButNotReceived'] = self.sentButNotReceived.IsChecked() 
+        self.options['receivedButNotSent'] = self.receivedButNotSent.IsChecked()
+        self.options['duplicateInConnection'] = self.duplicateInConnection.IsChecked()
+        self.options['duplicateInFile'] = self.duplicateInFile.IsChecked()
+    
+    def OptionsChanged(self, event):
+        """
+        Action to be executed every time one of the checkboxes is clicked.
+        It calls parseOptions() and then updates the display of incorrect events.
+        """
+        
+        self.parseOptions()
+        self.incorrectSequenceList.updateList()
+        
+    def OnFilter(self, event):
+        """
+        Action to be executed every time the button 'filter' is pressed.
+        """
+        
+        self.incorrectSequenceList.connectionForFilter = (self.connectionText.GetValue(), self.rbshortId.GetValue())
+        self.OptionsChanged(event)
+        
+    def OnJump(self, event):
+        """
+        Action to be executed when the 'jump' button is pressed.
+        """
+        
+        if self.incorrectSequenceList.GetFirstSelected() != -1:
+            connectionId, messageId = self.incorrectSequenceList.GetItem(self.incorrectSequenceList.GetFirstSelected(), 2).GetText().split(' | ')
+            self.parent.GetParent().browsingMessagesPanel.textctrl1.SetValue(connectionId)
+            self.parent.GetParent().browsingMessagesPanel.textctrl2.SetValue(messageId)
+            self.parent.GetParent().browsingMessagesPanel.rbshortId.SetValue(self.showShortIds.GetValue())
+            self.parent.GetParent().browsingMessagesPanel.rblongId.SetValue(not self.showShortIds.GetValue())
+            self.parent.GetParent().browsingMessagesPanel.displayMessageInfo(event)
+        
+            self.parent.SetSelection(1)

Propchange: activemq/sandbox/activemq-log-analyzer/loganalyzergui/IncorrectSequencePanel.py
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/sandbox/activemq-log-analyzer/loganalyzergui/IncorrectSequencePanel.pyc
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-log-analyzer/loganalyzergui/IncorrectSequencePanel.pyc?rev=612559&view=auto
==============================================================================
Binary file - no diff available.

Propchange: activemq/sandbox/activemq-log-analyzer/loganalyzergui/IncorrectSequencePanel.pyc
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: activemq/sandbox/activemq-log-analyzer/loganalyzergui/MessageTravelPanel.py
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-log-analyzer/loganalyzergui/MessageTravelPanel.py?rev=612559&view=auto
==============================================================================
--- activemq/sandbox/activemq-log-analyzer/loganalyzergui/MessageTravelPanel.py (added)
+++ activemq/sandbox/activemq-log-analyzer/loganalyzergui/MessageTravelPanel.py Wed Jan 16 11:55:49 2008
@@ -0,0 +1,83 @@
+"""
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+"""
+
+"""
+Module MessageTravelPanel
+"""
+import wx
+from MessageTravelText import MessageTravelText
+
+class MessageTravelPanel(wx.Panel):
+    """
+    The function of this panel is to show the travel history of a message.
+    This means the connections that the message went through.
+    """
+    
+    def __init__(self, parent):
+        """
+        Constructor
+        """
+        
+        wx.Panel.__init__(self, parent, -1)
+        
+        self.rbshortId = wx.RadioButton(self, -1, style=wx.RB_GROUP, label="Short id")
+        self.rblongId = wx.RadioButton(self, -1, label="Long id")
+        self.textctrl1 = wx.TextCtrl(self, -1, '')
+        self.textctrl2 = wx.TextCtrl(self, -1, '')
+        self.chkshowshortId = wx.CheckBox(self, 100, 'Show result with short ids')
+        self.messageTravelPanel = MessageTravelText(self)
+        
+        self.chkshowshortId.SetValue(True)
+        
+        sizerrb = wx.BoxSizer(wx.VERTICAL)
+        sizerrb.Add(self.rbshortId, 0, wx.DOWN, 5)
+        sizerrb.Add(self.rblongId, 0)
+        
+        sizerinput = wx.BoxSizer(wx.HORIZONTAL)
+        sizerinput.Add(sizerrb, 0, wx.RIGHT, 5)
+        sizerinput.Add(wx.StaticText(self, -1, 'Producer id'), 0, wx.CENTER|wx.RIGHT, 5)
+        sizerinput.Add(self.textctrl1, 2, wx.CENTER|wx.RIGHT, 5)
+        sizerinput.Add(wx.StaticText(self, -1, 'Producer Sequence id'), 0, wx.CENTER|wx.RIGHT, 5)
+        sizerinput.Add(self.textctrl2, 1, wx.CENTER|wx.RIGHT, 5)
+        sizerinput.Add(wx.Button(self, 101 , 'Browse'), 0, wx.CENTER)
+        
+        sizer = wx.BoxSizer(wx.VERTICAL)
+        sizer.Add(sizerinput, 0, wx.EXPAND|wx.ALL, 5)
+        sizer.Add(self.chkshowshortId, 0, wx.LEFT|wx.UP, 5)
+        sizer.Add(self.messageTravelPanel, 1, wx.EXPAND|wx.ALL, 5)
+        
+        self.Bind(wx.EVT_CHECKBOX, self.displayMessageInfo, id=100)
+        self.Bind(wx.EVT_BUTTON, self.displayMessageInfo, id=101)
+        
+        self.SetSizer(sizer)
+    
+    def displayMessageInfo(self, event):
+        """
+        Action to be executed when the 'Browse' button is pushed.
+        """
+        
+        self.messageTravelPanel.displayMessageInfo(self.textctrl1.GetValue(),
+                                                 self.textctrl2.GetValue(),
+                                                 self.rbshortId.GetValue())
+        
+    def logDataUpdated(self):
+        """
+        This method must be called to notify the panel that the parsed data has been updated.
+        It will in turn notify the message travel panel.
+        """
+        
+        self.messageTravelPanel.logDataUpdated()

Propchange: activemq/sandbox/activemq-log-analyzer/loganalyzergui/MessageTravelPanel.py
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/sandbox/activemq-log-analyzer/loganalyzergui/MessageTravelPanel.pyc
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-log-analyzer/loganalyzergui/MessageTravelPanel.pyc?rev=612559&view=auto
==============================================================================
Binary file - no diff available.

Propchange: activemq/sandbox/activemq-log-analyzer/loganalyzergui/MessageTravelPanel.pyc
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: activemq/sandbox/activemq-log-analyzer/loganalyzergui/MessageTravelText.py
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-log-analyzer/loganalyzergui/MessageTravelText.py?rev=612559&view=auto
==============================================================================
--- activemq/sandbox/activemq-log-analyzer/loganalyzergui/MessageTravelText.py (added)
+++ activemq/sandbox/activemq-log-analyzer/loganalyzergui/MessageTravelText.py Wed Jan 16 11:55:49 2008
@@ -0,0 +1,175 @@
+"""
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+"""
+
+"""
+Module MessageTravelText
+"""
+import wx
+from loganalyzerengine.Producer import Producer
+from loganalyzerengine.Message import Message
+
+class MessageTravelText(wx.TextCtrl):
+    """
+    Text box where the travel path of a message is displayed.
+    """
+    
+    def __init__(self, parent):
+        """
+        Constructor
+        """
+        
+        wx.TextCtrl.__init__(self, parent, -1, style=wx.TE_MULTILINE)#, style=wx.TE_CENTRE)
+        
+        self.parent = parent
+        self.datapresent = False
+        
+        self.SetEditable(False)
+        
+    def logDataUpdated(self):
+        """
+        Informs the text control that there is some parsed data.
+        """
+        
+        self.datapresent = True
+        
+    def displayMessageInfo(self, producerId, prodSeqId, isShortId):
+        """
+        Displays the travel information of a message as text.
+        connectionId must be a shortId if isShortId == True, and a longId if isShortId == False
+        """
+        
+        if self.datapresent:
+            
+            # we run some checks on the connection id and command id,
+            # and transform connectionId into a shortId
+            if isShortId:
+                if not producerId.isdigit():
+                    wx.MessageDialog(self, 'That short producer id is not an integer', style=wx.OK).ShowModal()
+                    return
+                producerId = int(producerId)
+                if producerId < 0 or producerId > Producer.nProducers - 1:
+                    wx.MessageDialog(self, 'That short producer id does not exist', style=wx.OK).ShowModal()
+                    return
+            else:
+                if Producer.exists(producerId):
+                    producerId = Producer.longIdToShortId(producerId)
+                else:
+                    wx.MessageDialog(self, 'That connection id does not exist', style=wx.OK).ShowModal()
+                    return
+                
+            if not prodSeqId.isdigit():
+                wx.MessageDialog(self, 'That command id is not an integer', style=wx.OK).ShowModal()
+                return
+            
+            # we ensure the shortId and the commandId are integers
+            producerId = int(producerId)
+            prodSeqId = int(prodSeqId)
+            
+            # we check that the message exists
+            if Message.exists(Producer.getProducerByShortId(producerId), prodSeqId):
+                message = Message.getMessage(Producer.getProducerByShortId(producerId), prodSeqId)
+                sendingFiles, receivingFiles = message.getFiles()
+                printShortIds = self.parent.chkshowshortId.GetValue()
+                
+                # we set the value of the text field
+                self.SetValue(
+                     "\n".join(['Message Id:', 
+                               '\tProducer Id: ' + str(producerId if printShortIds else Producer.shortIdToLongId(producerId)), 
+                               '\tProducer Sequence id: ' +  str(prodSeqId),
+                               'ADVISORY' if message.advisory else '(not advisory)',
+                               'Connections that sent this message:', 
+                               #one line for every connection that sent a message
+                               "\n".join([''.join([
+                                                    '\t',
+                                                    # if direction == True, message went from connection.fromFile to connection.toFile
+                                                    str(connection.shortId if printShortIds else connection.longId), 
+                                                    ''.join([
+                                                             ', from ', 
+                                                             str(connection.fromFile)
+                                                             if direction else
+                                                             str(connection.toFile)
+                                                             , 
+                                                             ' to ', 
+                                                             str(connection.toFile)
+                                                             if direction else
+                                                             str(connection.fromFile),
+                                                             ', ',
+                                                             ' | '.join([''.join([
+                                                                                 'ConID: ',
+                                                                                 str(connection.shortId if printShortIds else connection.longId),
+                                                                                 ', CommandID: ',
+                                                                                 str(commandid),
+                                                                                 ', ',
+                                                                                 timestamp
+                                                                                 ])
+                                                                         for (connection, commandid, timestamp) in values
+                                                                         ])
+                                                             ])
+                                                    ])
+                                                 for (connection, direction), values in message.sendingConnections.iteritems()
+                                                 ]), 
+                               'Connections that received this message:', 
+                               #one line for every connection that received a message
+                               "\n".join([''.join([
+                                                    '\t', 
+                                                    # if direction == True, message went from connection.fromFile to connection.toFile
+                                                    str(connection.shortId if printShortIds else connection.longId), 
+                                                    ''.join([
+                                                             ', from ', 
+                                                             str(connection.fromFile)
+                                                             if direction else
+                                                             str(connection.toFile)
+                                                             , 
+                                                             ' to ', 
+                                                             str(connection.toFile)
+                                                             if direction else
+                                                             str(connection.fromFile)
+                                                             ,
+                                                             ', ',
+                                                             ' | '.join([''.join([
+                                                                                 'ConID: ',
+                                                                                 str(connection.shortId if printShortIds else connection.longId),
+                                                                                 ', CommandID: ',
+                                                                                 str(commandid),
+                                                                                 ', ',
+                                                                                 timestamp
+                                                                                 ])
+                                                                         for (connection, commandid, timestamp) in values
+                                                                         ])
+                                                             ])
+                                                    ])
+                                                 for (connection, direction), values in message.receivingConnections.iteritems()
+                                                 ]), 
+                               'Log files where this message was sent:', 
+                               '\t' + ", ".join([str(f) for f in sendingFiles]), 
+                               'Log files where this message was received:', 
+                               '\t' + ", ".join([str(f) for f in receivingFiles])
+                               ])
+                     )
+                
+                
+                
+            else:
+                # the message doesn't exist
+                wx.MessageDialog(self, 'That message does not exist', style=wx.OK).ShowModal()
+                return
+        else:
+            # there is no data present
+            wx.MessageDialog(self, 'Please parse some files first', style=wx.OK).ShowModal()
+            return
+        
+        

Propchange: activemq/sandbox/activemq-log-analyzer/loganalyzergui/MessageTravelText.py
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/sandbox/activemq-log-analyzer/loganalyzergui/MessageTravelText.pyc
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-log-analyzer/loganalyzergui/MessageTravelText.pyc?rev=612559&view=auto
==============================================================================
Binary file - no diff available.

Propchange: activemq/sandbox/activemq-log-analyzer/loganalyzergui/MessageTravelText.pyc
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: activemq/sandbox/activemq-log-analyzer/loganalyzergui/TabbedPanel.py
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-log-analyzer/loganalyzergui/TabbedPanel.py?rev=612559&view=auto
==============================================================================
--- activemq/sandbox/activemq-log-analyzer/loganalyzergui/TabbedPanel.py (added)
+++ activemq/sandbox/activemq-log-analyzer/loganalyzergui/TabbedPanel.py Wed Jan 16 11:55:49 2008
@@ -0,0 +1,73 @@
+"""
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+"""
+
+"""
+Module TabbedPanel
+"""
+import wx
+from IncorrectSequencePanel import IncorrectSequencePanel
+from MessageTravelPanel import MessageTravelPanel
+from ViewClientsPanel import ViewClientsPanel
+from ViewConnectionsPanel import ViewConnectionsPanel
+from ViewFilesPanel import ViewFilesPanel
+
+class TabbedPanel(wx.Panel):
+    """
+    Panel with the tabs that will display the information once the log files are parsed.
+    It contains 4 tabs, via a wx.Notebook object:
+        -IncorrectSequencePanel.
+        -BrowsingMessagesPanel.
+        -ViewConnectionsPanel.
+        -ViewFilesPanel.
+    """
+    
+    def __init__(self, parent):
+        """
+        Constructor
+        """
+        
+        wx.Panel.__init__(self, parent, -1)
+        
+        notebook = wx.Notebook(self, -1)
+        
+        self.incorrectSequencePanel = IncorrectSequencePanel(notebook)
+        self.browsingMessagesPanel = MessageTravelPanel(notebook)
+        self.viewClientsPanel = ViewClientsPanel(notebook)
+        self.viewConnectionsPanel = ViewConnectionsPanel(notebook)
+        self.viewFilesPanel = ViewFilesPanel(notebook)
+        
+        notebook.AddPage(self.incorrectSequencePanel, 'Incorrect Sequences')
+        notebook.AddPage(self.browsingMessagesPanel, 'Message Browsing')
+        notebook.AddPage(self.viewClientsPanel, 'View clients')
+        notebook.AddPage(self.viewConnectionsPanel, 'View connections')
+        notebook.AddPage(self.viewFilesPanel, 'View files')
+        
+        sizer = wx.BoxSizer(wx.HORIZONTAL)
+        sizer.Add(notebook, 1, wx.EXPAND|wx.ALL, 5)
+        self.SetSizer(sizer)
+        
+    def logDataUpdated(self):
+        """
+        When this panel is notified that the parsed data has changed,
+        it notifies the 4 sub panels.
+        """
+        
+        self.incorrectSequencePanel.logDataUpdated()
+        self.browsingMessagesPanel.logDataUpdated()
+        self.viewClientsPanel.logDataUpdated()
+        self.viewConnectionsPanel.logDataUpdated()
+        self.viewFilesPanel.logDataUpdated()

Propchange: activemq/sandbox/activemq-log-analyzer/loganalyzergui/TabbedPanel.py
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/sandbox/activemq-log-analyzer/loganalyzergui/TabbedPanel.pyc
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-log-analyzer/loganalyzergui/TabbedPanel.pyc?rev=612559&view=auto
==============================================================================
Binary file - no diff available.

Propchange: activemq/sandbox/activemq-log-analyzer/loganalyzergui/TabbedPanel.pyc
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: activemq/sandbox/activemq-log-analyzer/loganalyzergui/ViewClientsPanel.py
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-log-analyzer/loganalyzergui/ViewClientsPanel.py?rev=612559&view=auto
==============================================================================
--- activemq/sandbox/activemq-log-analyzer/loganalyzergui/ViewClientsPanel.py (added)
+++ activemq/sandbox/activemq-log-analyzer/loganalyzergui/ViewClientsPanel.py Wed Jan 16 11:55:49 2008
@@ -0,0 +1,117 @@
+"""
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+"""
+
+"""
+Module ViewConnectionsPanel
+"""
+import wx
+
+from loganalyzerengine.Connection import Connection
+from loganalyzerengine.Producer import Producer
+from loganalyzerengine.Consumer import Consumer
+
+class ViewClientsPanel(wx.Panel):
+    """
+    This panel shows the list of connections that appear in the log files.
+    Also, it enables the user to copy the long id of a connection to the system clipboard,
+    and to 'jump' to the IncorrectSequencePanel, filtering the display so that only the
+    events of that connection are displayed.
+    """
+    
+    def __init__(self, parent):
+        """
+        Constructor
+        """
+        
+        wx.Panel.__init__(self, parent, -1)
+        
+        self.notebook = parent
+        
+        sizer = wx.BoxSizer(wx.VERTICAL)
+        
+        self.producerList = wx.ListCtrl(self, -1, 
+                             style=wx.LC_REPORT|wx.LC_SINGLE_SEL|wx.LC_HRULES|wx.LC_VRULES|wx.LC_EDIT_LABELS)
+        
+        self.producerList.InsertColumn(0, 'Short id')
+        self.producerList.InsertColumn(1, 'Short Connection id')
+        self.producerList.InsertColumn(2, 'Session Id')
+        self.producerList.InsertColumn(3, 'Value')
+        self.producerList.InsertColumn(4, 'Long Connection id')
+        
+        self.producerList.SetColumnWidth(0, 80)
+        self.producerList.SetColumnWidth(1, 120)
+        self.producerList.SetColumnWidth(2, 80)
+        self.producerList.SetColumnWidth(3, 80)
+        self.producerList.SetColumnWidth(4, 500)
+        
+        self.consumerList = wx.ListCtrl(self, -1, 
+                             style=wx.LC_REPORT|wx.LC_SINGLE_SEL|wx.LC_HRULES|wx.LC_VRULES|wx.LC_EDIT_LABELS)
+        
+        self.consumerList.InsertColumn(0, 'Short id')
+        self.consumerList.InsertColumn(1, 'Short Connection id')
+        self.consumerList.InsertColumn(2, 'Session Id')
+        self.consumerList.InsertColumn(3, 'Value')
+        self.consumerList.InsertColumn(4, 'Long Connection id')
+        
+        self.consumerList.SetColumnWidth(0, 80)
+        self.consumerList.SetColumnWidth(1, 120)
+        self.consumerList.SetColumnWidth(2, 80)
+        self.consumerList.SetColumnWidth(3, 80)
+        self.consumerList.SetColumnWidth(4, 500)
+        
+        sizer.Add(wx.StaticText(self, -1, 'Producers'), 0, wx.CENTER|wx.LEFT|wx.TOP|wx.RIGHT, 15)
+        sizer.Add(self.producerList, 1, wx.EXPAND|wx.ALL, 5)
+        sizer.Add(wx.StaticText(self, -1, 'Consumers'), 0, wx.CENTER|wx.LEFT|wx.TOP|wx.RIGHT, 15)
+        sizer.Add(self.consumerList, 1, wx.EXPAND|wx.ALL, 5)
+        
+        self.SetSizer(sizer)
+        
+    def logDataUpdated(self):
+        """
+        Informs this panel that new data has been parsed,
+        and that the list of connections should be updated.
+        """
+        
+        self.producerList.DeleteAllItems()
+        self.consumerList.DeleteAllItems()
+        
+        shortId = 0
+        for longId in Producer.producerIdList:
+            producer = Producer.getProducerByLongId(longId)
+            self.insertRow(self.producerList, shortId, Connection.longIdToShortId(producer.connectionId),
+                           producer.sessionId, producer.value,
+                           Connection.getConnectionByLongId(producer.connectionId))
+            shortId += 1
+            
+        shortId = 0
+        for longId in Consumer.consumerIdList:
+            consumer = Consumer.getConsumerByLongId(longId)
+            self.insertRow(self.consumerList, shortId, Connection.longIdToShortId(consumer.connectionId),
+                           consumer.sessionId, consumer.value,
+                           Connection.getConnectionByLongId(consumer.connectionId))
+            shortId += 1
+            
+    def insertRow(self, targetList, shortId, shortConnectionId, sessionId, value, longConnectionId):
+        """
+        Helper method to insert a new row in the list of connections.
+        """
+        
+        targetList.InsertStringItem(shortId, str(shortId))
+        targetList.SetStringItem(shortId, 1, str(shortConnectionId))
+        targetList.SetStringItem(shortId, 2, str(sessionId))
+        targetList.SetStringItem(shortId, 3, str(value))
+        targetList.SetStringItem(shortId, 4, str(longConnectionId))

Propchange: activemq/sandbox/activemq-log-analyzer/loganalyzergui/ViewClientsPanel.py
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/sandbox/activemq-log-analyzer/loganalyzergui/ViewClientsPanel.pyc
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-log-analyzer/loganalyzergui/ViewClientsPanel.pyc?rev=612559&view=auto
==============================================================================
Binary file - no diff available.

Propchange: activemq/sandbox/activemq-log-analyzer/loganalyzergui/ViewClientsPanel.pyc
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: activemq/sandbox/activemq-log-analyzer/loganalyzergui/ViewConnectionsPanel.py
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-log-analyzer/loganalyzergui/ViewConnectionsPanel.py?rev=612559&view=auto
==============================================================================
--- activemq/sandbox/activemq-log-analyzer/loganalyzergui/ViewConnectionsPanel.py (added)
+++ activemq/sandbox/activemq-log-analyzer/loganalyzergui/ViewConnectionsPanel.py Wed Jan 16 11:55:49 2008
@@ -0,0 +1,120 @@
+"""
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+"""
+
+"""
+Module ViewConnectionsPanel
+"""
+import wx
+from loganalyzerengine.Connection import Connection
+
+class ViewConnectionsPanel(wx.Panel):
+    """
+    This panel shows the list of connections that appear in the log files.
+    Also, it enables the user to copy the long id of a connection to the system clipboard,
+    and to 'jump' to the IncorrectSequencePanel, filtering the display so that only the
+    events of that connection are displayed.
+    """
+    
+    def __init__(self, parent):
+        """
+        Constructor
+        """
+        
+        wx.Panel.__init__(self, parent, -1)
+        
+        self.notebook = parent
+        
+        sizer = wx.BoxSizer(wx.VERTICAL)
+        
+        self.list = wx.ListCtrl(self, -1, 
+                             style=wx.LC_REPORT|wx.LC_SINGLE_SEL|wx.LC_HRULES|wx.LC_VRULES|wx.LC_EDIT_LABELS)
+        
+        self.list.InsertColumn(0, 'Short id')
+        self.list.InsertColumn(1, 'Long id')
+        self.list.InsertColumn(2, 'Connection established FROM file')
+        self.list.InsertColumn(3, 'Connection established TO file')
+        self.list.InsertColumn(4, 'Producers')
+        self.list.InsertColumn(5, 'Consumers')
+        
+        self.list.SetColumnWidth(0, 80)
+        self.list.SetColumnWidth(1, 250)
+        self.list.SetColumnWidth(2, 200)
+        self.list.SetColumnWidth(3, 200)
+        
+        sizer2 = wx.BoxSizer(wx.HORIZONTAL)
+        sizer2.Add(wx.Button(self, 100, 'Copy selected long id to clipboard'), 0, wx.RIGHT, 5)
+        sizer2.Add(wx.Button(self, 101, "Jump to this connection's problems"))
+        
+        sizer.Add(sizer2, 0, wx.ALL, 5)
+        sizer.Add(self.list, 1, wx.EXPAND|wx.LEFT|wx.BOTTOM|wx.RIGHT, 5)
+        
+        self.Bind(wx.EVT_BUTTON, self.OnCopy, id=100)
+        self.Bind(wx.EVT_BUTTON, self.OnJump, id=101)
+        
+        self.SetSizer(sizer)
+        
+    def logDataUpdated(self):
+        """
+        Informs this panel that new data has been parsed,
+        and that the list of connections should be updated.
+        """
+        
+        self.list.DeleteAllItems()
+        shortId = 0
+        for longId in Connection.connectionIdList:
+            connection = Connection.getConnectionByLongId(longId)
+            self.insertRow(shortId, longId, connection.fromFile, connection.toFile, connection.producers, connection.consumers)
+            shortId += 1
+            
+    def insertRow(self, shortId, longId, fromFile, to, producers, consumers):
+        """
+        Helper method to insert a new row in the list of connections.
+        """
+        
+        self.list.InsertStringItem(shortId, str(shortId))
+        self.list.SetStringItem(shortId, 1, str(longId))
+        self.list.SetStringItem(shortId, 2, str(fromFile))
+        self.list.SetStringItem(shortId, 3, str(to))
+        self.list.SetStringItem(shortId, 4, ", ".join(str(p.shortId) for p in producers))
+        self.list.SetStringItem(shortId, 5, ", ".join(str(c.shortId) for c in consumers))
+        
+    def OnCopy(self, event):
+        """
+        Action to be executed when pressing the 'Copy selected long id to clipboard' button.
+        The longId of the selected connection will be copied to the clipboard.
+        """
+        
+        shortId = self.list.GetFirstSelected()
+        if shortId != -1 and wx.TheClipboard.Open():
+            wx.TheClipboard.SetData(wx.TextDataObject(str(Connection.connectionIdList[shortId])))
+            wx.TheClipboard.Close()
+            
+    def OnJump(self, event):
+        """
+        Action to be executed when pressing the 'Jump to this connection's problems' button.
+        The tab with the 'IncorrectSequencePanel' will be selected and the list of incorrect
+        events will be automatically filtered by the selected connection.
+        """
+        
+        shortId = self.list.GetFirstSelected()
+        if shortId != -1:
+            incorrectSequencePanel = self.notebook.GetParent().incorrectSequencePanel
+            incorrectSequencePanel.connectionText.SetValue(str(shortId))
+            incorrectSequencePanel.rbshortId.SetValue(True)
+            incorrectSequencePanel.rblongId.SetValue(False)
+            incorrectSequencePanel.OnFilter(event)
+            self.notebook.SetSelection(0)

Propchange: activemq/sandbox/activemq-log-analyzer/loganalyzergui/ViewConnectionsPanel.py
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/sandbox/activemq-log-analyzer/loganalyzergui/ViewConnectionsPanel.pyc
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-log-analyzer/loganalyzergui/ViewConnectionsPanel.pyc?rev=612559&view=auto
==============================================================================
Binary file - no diff available.

Propchange: activemq/sandbox/activemq-log-analyzer/loganalyzergui/ViewConnectionsPanel.pyc
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: activemq/sandbox/activemq-log-analyzer/loganalyzergui/ViewFilesPanel.py
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-log-analyzer/loganalyzergui/ViewFilesPanel.py?rev=612559&view=auto
==============================================================================
--- activemq/sandbox/activemq-log-analyzer/loganalyzergui/ViewFilesPanel.py (added)
+++ activemq/sandbox/activemq-log-analyzer/loganalyzergui/ViewFilesPanel.py Wed Jan 16 11:55:49 2008
@@ -0,0 +1,62 @@
+"""
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+"""
+
+"""
+Module ViewFilesPanel
+"""
+import wx
+from loganalyzerengine.LogFile import LogFile
+
+class ViewFilesPanel(wx.Panel):
+    """
+    This panel shows the list of log files that have been read.
+    """
+    
+    def __init__(self, parent):
+        """
+        Constructor
+        """
+        
+        wx.Panel.__init__(self, parent, -1)
+        
+        sizer = wx.BoxSizer(wx.VERTICAL)
+        
+        self.text = wx.TextCtrl(self, -1, style=wx.TE_MULTILINE)
+        
+        sizer.Add(self.text, 1, wx.EXPAND|wx.ALL, 5)
+        
+        self.SetSizer(sizer)
+        
+    def logDataUpdated(self):
+        """
+        The panel is informed that new data has been parsed,
+        and the list of files should be updated.
+        """
+        
+        self.text.SetValue(
+            '\n'.join(
+                      '\n'.join([
+                                 str(file),
+                                 '\tConnections established from this file:',
+                                 '\n'.join(['\t\t' + str(con.shortId) + ' ' + str(con.longId) for con in file.outgoing]),
+                                 '\tConnections established to this file:',
+                                 '\n'.join(['\t\t' + str(con.shortId) + ' ' + str(con.longId) for con in file.incoming])
+                                ])
+                      for file in LogFile.logfiles)
+        )
+            
+        

Propchange: activemq/sandbox/activemq-log-analyzer/loganalyzergui/ViewFilesPanel.py
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/sandbox/activemq-log-analyzer/loganalyzergui/ViewFilesPanel.pyc
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-log-analyzer/loganalyzergui/ViewFilesPanel.pyc?rev=612559&view=auto
==============================================================================
Binary file - no diff available.

Propchange: activemq/sandbox/activemq-log-analyzer/loganalyzergui/ViewFilesPanel.pyc
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: activemq/sandbox/activemq-log-analyzer/loganalyzergui/__init__.py
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-log-analyzer/loganalyzergui/__init__.py?rev=612559&view=auto
==============================================================================
--- activemq/sandbox/activemq-log-analyzer/loganalyzergui/__init__.py (added)
+++ activemq/sandbox/activemq-log-analyzer/loganalyzergui/__init__.py Wed Jan 16 11:55:49 2008
@@ -0,0 +1,18 @@
+"""
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+"""
+
+

Propchange: activemq/sandbox/activemq-log-analyzer/loganalyzergui/__init__.py
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/sandbox/activemq-log-analyzer/loganalyzergui/__init__.pyc
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-log-analyzer/loganalyzergui/__init__.pyc?rev=612559&view=auto
==============================================================================
Binary file - no diff available.

Propchange: activemq/sandbox/activemq-log-analyzer/loganalyzergui/__init__.pyc
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: activemq/sandbox/activemq-log-analyzer/run.bat
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-log-analyzer/run.bat?rev=612559&view=auto
==============================================================================
--- activemq/sandbox/activemq-log-analyzer/run.bat (added)
+++ activemq/sandbox/activemq-log-analyzer/run.bat Wed Jan 16 11:55:49 2008
@@ -0,0 +1 @@
+python Main.py
\ No newline at end of file

Propchange: activemq/sandbox/activemq-log-analyzer/run.bat
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/sandbox/activemq-log-analyzer/run.sh
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-log-analyzer/run.sh?rev=612559&view=auto
==============================================================================
--- activemq/sandbox/activemq-log-analyzer/run.sh (added)
+++ activemq/sandbox/activemq-log-analyzer/run.sh Wed Jan 16 11:55:49 2008
@@ -0,0 +1,2 @@
+#/bin/sh
+python Main.py

Propchange: activemq/sandbox/activemq-log-analyzer/run.sh
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: activemq/sandbox/activemq-log-analyzer/run.sh
------------------------------------------------------------------------------
    svn:executable = *

Added: activemq/sandbox/activemq-log-analyzer/winxp_screenshots/1.png
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-log-analyzer/winxp_screenshots/1.png?rev=612559&view=auto
==============================================================================
Binary file - no diff available.

Propchange: activemq/sandbox/activemq-log-analyzer/winxp_screenshots/1.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Added: activemq/sandbox/activemq-log-analyzer/winxp_screenshots/2.png
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-log-analyzer/winxp_screenshots/2.png?rev=612559&view=auto
==============================================================================
Binary file - no diff available.

Propchange: activemq/sandbox/activemq-log-analyzer/winxp_screenshots/2.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Added: activemq/sandbox/activemq-log-analyzer/winxp_screenshots/3.png
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-log-analyzer/winxp_screenshots/3.png?rev=612559&view=auto
==============================================================================
Binary file - no diff available.

Propchange: activemq/sandbox/activemq-log-analyzer/winxp_screenshots/3.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Added: activemq/sandbox/activemq-log-analyzer/winxp_screenshots/4.png
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-log-analyzer/winxp_screenshots/4.png?rev=612559&view=auto
==============================================================================
Binary file - no diff available.

Propchange: activemq/sandbox/activemq-log-analyzer/winxp_screenshots/4.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Added: activemq/sandbox/activemq-log-analyzer/winxp_screenshots/5.png
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-log-analyzer/winxp_screenshots/5.png?rev=612559&view=auto
==============================================================================
Binary file - no diff available.

Propchange: activemq/sandbox/activemq-log-analyzer/winxp_screenshots/5.png
------------------------------------------------------------------------------
    svn:mime-type = image/png