[savara-commits] savara SVN: r98 - in trunk/org.pi4soa.monitor: META-INF and 9 other directories.
do-not-reply at jboss.org
do-not-reply at jboss.org
Sat Dec 5 05:50:51 EST 2009
Author: objectiser
Date: 2009-12-05 05:50:50 -0500 (Sat, 05 Dec 2009)
New Revision: 98
Added:
trunk/org.pi4soa.monitor/.classpath
trunk/org.pi4soa.monitor/.project
trunk/org.pi4soa.monitor/LICENSE.txt
trunk/org.pi4soa.monitor/META-INF/
trunk/org.pi4soa.monitor/META-INF/MANIFEST.MF
trunk/org.pi4soa.monitor/build.properties
trunk/org.pi4soa.monitor/plugin.xml
trunk/org.pi4soa.monitor/src/
trunk/org.pi4soa.monitor/src/java/
trunk/org.pi4soa.monitor/src/java/org/
trunk/org.pi4soa.monitor/src/java/org/pi4soa/
trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/
trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/CorrelationManagerListener.java
trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ExchangeEvent.java
trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/TxnMonitor.java
trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/eclipse/
trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/eclipse/Activator.java
trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/eclipse/MonitorAction.java
trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/eclipse/MonitorLaunchConfigurationConstants.java
trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/eclipse/MonitorLauncher.java
trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/eclipse/MonitorMainTab.java
trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/eclipse/MonitorTabGroup.java
trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/
trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/ChannelJPanel.java
trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/ExchangeEventWrapper.java
trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/ExchangeEventsData.java
trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/Monitor.java
trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/MonitorExchangeEvent.java
trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/MonitorFileFilter.java
trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/MonitorMainPanel.java
trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/MonitorMenuBar.java
trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/MonitorTreeModelListener.java
trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/SpringUtilities.java
trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/XmlPrettyPrinter.java
trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/icons/
trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/icons/channelclosed.png
trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/icons/channelempty.png
trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/icons/channelleaf.png
trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/icons/channelopen.png
trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/icons/errorsleaf.png
trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/icons/issuesclosed.png
trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/icons/issuesempty.png
trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/icons/issuesopen.png
trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/icons/monitor.png
trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/icons/txnclosed.png
trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/icons/txnempty.png
trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/icons/txnleaf.png
trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/icons/txnopen.png
trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/icons/unexpectedleaf.png
trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/icons/warningsleaf.png
trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/table/
trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/table/TableSorter.java
Log:
Temporary inclusion until SAM solution available.
Added: trunk/org.pi4soa.monitor/.classpath
===================================================================
--- trunk/org.pi4soa.monitor/.classpath (rev 0)
+++ trunk/org.pi4soa.monitor/.classpath 2009-12-05 10:50:50 UTC (rev 98)
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src/java"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="output" path="classes"/>
+</classpath>
Added: trunk/org.pi4soa.monitor/.project
===================================================================
--- trunk/org.pi4soa.monitor/.project (rev 0)
+++ trunk/org.pi4soa.monitor/.project 2009-12-05 10:50:50 UTC (rev 98)
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.pi4soa.monitor</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
Added: trunk/org.pi4soa.monitor/LICENSE.txt
===================================================================
--- trunk/org.pi4soa.monitor/LICENSE.txt (rev 0)
+++ trunk/org.pi4soa.monitor/LICENSE.txt 2009-12-05 10:50:50 UTC (rev 98)
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed 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.
Added: trunk/org.pi4soa.monitor/META-INF/MANIFEST.MF
===================================================================
--- trunk/org.pi4soa.monitor/META-INF/MANIFEST.MF (rev 0)
+++ trunk/org.pi4soa.monitor/META-INF/MANIFEST.MF 2009-12-05 10:50:50 UTC (rev 98)
@@ -0,0 +1,26 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: pi4soa Monitor Plug-in
+Bundle-SymbolicName: org.pi4soa.monitor;singleton:=true
+Bundle-Version: 2.1.0.qualifier
+Bundle-Activator: org.pi4soa.monitor.eclipse.Activator
+Bundle-Vendor: www.pi4soa.org
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.pi4soa.service,
+ org.pi4soa.cdl,
+ org.eclipse.core.resources,
+ org.eclipse.debug.core,
+ org.eclipse.jdt.launching,
+ org.eclipse.core.resources,
+ org.eclipse.ui.ide,
+ org.eclipse.jface,
+ org.eclipse.jdt.debug.ui,
+ org.eclipse.ui.console,
+ org.eclipse.debug.ui,
+ org.eclipse.ui,
+ org.eclipse.jdt.core,
+ org.eclipse.emf.ecore,
+ org.pi4soa.common
+Eclipse-LazyStart: true
+Bundle-ClassPath: .
Added: trunk/org.pi4soa.monitor/build.properties
===================================================================
--- trunk/org.pi4soa.monitor/build.properties (rev 0)
+++ trunk/org.pi4soa.monitor/build.properties 2009-12-05 10:50:50 UTC (rev 98)
@@ -0,0 +1,5 @@
+source.. = src/java/
+output.. = classes/
+bin.includes = META-INF/,\
+ .,\
+ plugin.xml
Added: trunk/org.pi4soa.monitor/plugin.xml
===================================================================
--- trunk/org.pi4soa.monitor/plugin.xml (rev 0)
+++ trunk/org.pi4soa.monitor/plugin.xml 2009-12-05 10:50:50 UTC (rev 98)
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.2"?>
+<plugin>
+ <extension point="org.eclipse.debug.core.launchConfigurationTypes">
+ <launchConfigurationType
+ id="org.pi4soa.monitor.eclipse.MonitorLauncher"
+ delegate="org.pi4soa.monitor.eclipse.MonitorLauncher"
+ modes="run"
+ name="Monitor">
+ <fileExtension extension="cdm" default="true"/>
+ </launchConfigurationType>
+ </extension>
+
+ <extension point="org.eclipse.debug.ui.launchConfigurationTabGroups">
+ <launchConfigurationTabGroup
+ type="org.pi4soa.monitor.eclipse.MonitorLauncher"
+ class="org.pi4soa.monitor.eclipse.MonitorTabGroup"
+ id="org.eclipse.jdt.debug.ui.launchConfigurationTabGroup.monitor">
+ </launchConfigurationTabGroup>
+ </extension>
+
+ <extension point="org.eclipse.ui.popupMenus">
+ <objectContribution
+ id="org.pi4soa.service.generation.contribution2"
+ objectClass="org.eclipse.core.resources.IFile"
+ nameFilter="*.cdm">
+ <menu
+ id="org.pi4soa.menu"
+ label="Choreography"
+ path="additions">
+ <separator name="group1"/>
+ </menu>
+ <action
+ label="Monitor"
+ class="org.pi4soa.monitor.eclipse.MonitorAction"
+ menubarPath="org.pi4soa.menu/group1"
+ enablesFor="1"
+ id="org.pi4soa.monitor.MonitorAction">
+ </action>
+ </objectContribution>
+ </extension>
+
+</plugin>
Added: trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/CorrelationManagerListener.java
===================================================================
--- trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/CorrelationManagerListener.java (rev 0)
+++ trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/CorrelationManagerListener.java 2009-12-05 10:50:50 UTC (rev 98)
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2005-8 Pi4 Technologies Ltd
+ *
+ * Licensed 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.
+ *
+ *
+ * Change History:
+ * 16 Jan, 2008 : Initial version created by martin
+ */
+package org.pi4soa.monitor;
+
+import org.pi4soa.service.correlator.CorrelationSession;
+
+/**
+ * This interface represents a listener interested in changes
+ * that occur within the correlation manager.
+ *
+ */
+public interface CorrelationManagerListener {
+
+ /**
+ * This method indicates that a correlation session has
+ * started.
+ *
+ * @param session The correlation session
+ */
+ public void correlationSessionStarted(CorrelationSession session);
+
+ /**
+ * This method indicates that a correlation session has
+ * finished.
+ *
+ * @param session The correlation session
+ */
+ public void correlationSessionFinished(CorrelationSession session);
+
+ /**
+ * A new exchange event has been added to a correlation session.
+ *
+ * @param exchangeEvent The exchange event.
+ */
+ public void exchangeEventAdded(ExchangeEvent exchangeEvent);
+
+
+ /**
+ * An exchange event has been updated.
+ *
+ * @param exchangeEvent The exchange event.
+ */
+ public void exchangeEventUpdated(ExchangeEvent exchangeEvent);
+
+ /**
+ * An unexpected event has occured
+ *
+ * @param exchangeEvent. The exchange event.
+ * @param serviceName The service reporting the error
+ */
+ public void unexpectedExchangeEventAdded(ExchangeEvent exchangeEvent,
+ String serviceName);
+
+ /**
+ * An error occurred related to the specified correlation
+ * session.
+ *
+ * @param session The correlation session
+ * @param mesg The error message
+ * @param exception The optional exception trace
+ * @param serviceName The service reporting the error
+ */
+ public void error(CorrelationSession session, String mesg,
+ String exception, String serviceName);
+
+ /**
+ * A warning occurred related to the specified correlation
+ * session.
+ *
+ * @param session The correlation session
+ * @param mesg The warning message
+ * @param exception The optional exception trace
+ * @param serviceName The service reporting the warning
+ */
+ public void warning(CorrelationSession session, String mesg,
+ String exception, String serviceName);
+
+ /**
+ * An information event occurred related to the specified correlation
+ * session.
+ *
+ * @param session The correlation session
+ * @param mesg The information message
+ * @param serviceName The service reporting the information
+ */
+ public void information(CorrelationSession session,
+ String mesg, String serviceName);
+
+}
\ No newline at end of file
Added: trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ExchangeEvent.java
===================================================================
--- trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ExchangeEvent.java (rev 0)
+++ trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ExchangeEvent.java 2009-12-05 10:50:50 UTC (rev 98)
@@ -0,0 +1,268 @@
+/*
+ * Copyright 2005-8 Pi4 Technologies Ltd
+ *
+ * Licensed 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.
+ *
+ *
+ * Change History:
+ * 16 Jan, 2008 : Initial version created by martin
+ */
+package org.pi4soa.monitor;
+
+import java.io.Serializable;
+import java.util.logging.Logger;
+import java.util.logging.Level;
+
+import org.pi4soa.cdl.ExchangeDetails;
+import org.pi4soa.service.Message;
+import org.pi4soa.service.Channel;
+import org.pi4soa.service.correlator.CorrelationSession;
+
+/**
+ * This class represents the 'exchange' correlation event.
+ *
+ */
+public class ExchangeEvent implements Serializable {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -1984285030410307153L;
+
+ Message m_message = null;
+
+ /**
+ * This class represents the 'exchange' correlation event.
+ *
+ * @param exchange The exchange details
+ * @param channel The channel
+ * @param session The session
+ * @param serviceDescriptionName The service description name
+ */
+ public ExchangeEvent(ExchangeDetails exchange,
+ Channel channel, CorrelationSession session,
+ String serviceDescriptionName, Message message) {
+ m_exchange = exchange;
+ m_channel = channel;
+ m_session = session;
+ m_serviceDescriptionName = serviceDescriptionName;
+ this.m_message = message;
+ }
+
+ /**
+ * This method returns the exchange details.
+ *
+ * @return The exchange details
+ */
+ public ExchangeDetails getExchange() {
+ return(m_exchange);
+ }
+
+ /**
+ * This method returns the channel.
+ *
+ * @return The channel
+ */
+ public Channel getChannel() {
+ return(m_channel);
+ }
+
+ /**
+ * This method returns the correlation session.
+ *
+ * @return The correlation session
+ */
+ public CorrelationSession getCorrelationSession() {
+ return(m_session);
+ }
+
+ /**
+ * This method returns the service description name.
+ *
+ * @return The service description name
+ */
+ public String getServiceDescriptionName() {
+ return(m_serviceDescriptionName);
+ }
+
+ /**
+ * This method returns the message.
+ *
+ * @return The service description name
+ */
+ public Message getMessage() {
+ return m_message;
+ }
+
+ /**
+ * This method returns whether the exchange has been
+ * initiated and completed.
+ *
+ * @return The 'complete' status of the exchange event
+ */
+ public boolean isExchangeComplete() {
+ return(m_initiated && m_completed);
+ }
+
+ /**
+ * This method determines whether the event has been
+ * initiated.
+ *
+ * @return Whether event has been initiated
+ */
+ public boolean getInitiated(){
+ return m_initiated;
+ }
+
+ /**
+ * This method determines whether the event has been
+ * completed.
+ *
+ * @return Whether event has been completed
+ */
+ public boolean getCompleted(){
+ return m_completed;
+ }
+
+ /**
+ * This method indicates that the exchange associated with
+ * the event has initiated.
+ *
+ */
+ public void initiated() {
+ m_initiated = true;
+ checkIfExchangeCorrelated();
+ }
+
+ /**
+ * This method indicates that the exchange associated with
+ * the event has completed.
+ *
+ */
+ public void completed() {
+ m_completed = true;
+ checkIfExchangeCorrelated();
+ }
+
+
+ protected void checkIfExchangeCorrelated() {
+ if (isExchangeComplete()) {
+ // logger.fine("EXCHANGE CORRELATED: "+this);
+ }
+ }
+
+ public int hashCode() {
+ return(m_message.getOperationName().hashCode());
+ }
+
+ public boolean equals(Object obj) {
+ boolean ret=false;
+ if (obj instanceof ExchangeEvent) {
+ ExchangeEvent other=(ExchangeEvent)obj;
+ if (m_exchange == null || other.getExchange() == null) {
+ // Compare on message basis
+ if (m_message.isRPCStyle() &&
+ other.getMessage().isRPCStyle()) {
+ if (m_message.getOperationName().equals(
+ other.getMessage().getOperationName()) &&
+ m_message.isRequest() == other.getMessage().isRequest() &&
+ m_message.getServiceType().equals(
+ other.getMessage().getServiceType())) {
+ ret = true;
+ }
+ } else if (m_message.isRPCStyle() == false &&
+ other.getMessage().isRPCStyle() == false) {
+ if (m_message.getType().equals(
+ other.getMessage().getType())) {
+ ret = true;
+ }
+ }
+ } else if (other.getExchange() == m_exchange &&
+ other.getChannel().getName().equals(m_channel.getName()) &&
+ other.getCorrelationSession() == m_session) {
+ ret = true;
+ }
+
+ if (ret) {
+
+ // Check identities
+ if (other.getMessage().getMessageIdentities().size()
+ == getMessage().getMessageIdentities().size()) {
+
+ for (int i=0; ret &&
+ i < getMessage().getMessageIdentities().size(); i++) {
+ ret = false;
+
+ org.pi4soa.service.Identity id=
+ getMessage().getMessageIdentities().get(i);
+
+ if (logger.isLoggable(Level.FINEST)) {
+ logger.finest("Checking message identity ("+i+
+ "): "+id);
+ }
+
+ for (int j=0; ret == false &&
+ j < other.getMessage().getMessageIdentities().size(); j++) {
+
+ if (id.equals(other.getMessage().getMessageIdentities().get(j))) {
+ ret = true;
+ }
+
+ if (logger.isLoggable(Level.FINEST)) {
+ logger.finest("Against message identity ("+j+
+ "): "+other.getMessage().getMessageIdentities().get(j)+
+ " = "+ret);
+ }
+ }
+ }
+ } else {
+ if (logger.isLoggable(Level.FINEST)) {
+ logger.finest("Message identity list length mismatch");
+ }
+
+ ret = false;
+ }
+ }
+ }
+ return(ret);
+ }
+
+ public String toString() {
+ StringBuffer ret=new StringBuffer();
+ ret.append("ExchangeEvent[");
+ if (m_exchange != null) {
+
+ // if (NamesUtil.isSet(m_exchange.getDescription())) {
+
+
+ if (m_exchange.getDescription() != null && "".equals(m_exchange.getDescription()) == false) {
+
+ ret.append(m_exchange.getDescription());
+ } else {
+ ret.append(m_exchange.getName());
+ }
+ ret.append(", ");
+ }
+ ret.append(m_message.toString()+"]");
+ return(ret.toString());
+ }
+
+ private static Logger logger = Logger.getLogger("org.pi4soa.monitor");
+
+ private ExchangeDetails m_exchange=null;
+ private Channel m_channel=null;
+ private CorrelationSession m_session;
+ private String m_serviceDescriptionName=null;
+ private boolean m_initiated=false;
+ private boolean m_completed=false;
+}
Added: trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/TxnMonitor.java
===================================================================
--- trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/TxnMonitor.java (rev 0)
+++ trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/TxnMonitor.java 2009-12-05 10:50:50 UTC (rev 98)
@@ -0,0 +1,593 @@
+/*
+ * Copyright 2005-8 Pi4 Technologies Ltd
+ *
+ * Licensed 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.
+ *
+ *
+ * Change History:
+ * 16 Jan, 2008 : Initial version created by martin
+ */
+package org.pi4soa.monitor;
+
+import java.util.logging.Logger;
+
+import org.pi4soa.cdl.ExchangeDetails;
+import org.pi4soa.service.Channel;
+import org.pi4soa.service.Message;
+import org.pi4soa.service.ServiceException;
+import org.pi4soa.service.correlator.CorrelationSession;
+import org.pi4soa.service.correlator.ServiceCorrelator;
+import org.pi4soa.service.correlator.ServiceCorrelatorFactory;
+import org.pi4soa.service.correlator.ServiceCorrelatorListener;
+import org.pi4soa.service.tracker.ServiceTrackerClient;
+import org.pi4soa.service.tracker.jms.JMSServiceTrackerClient;
+
+/**
+ * The TxnMonitor class is a generic transaction monitor class that
+ * takes in a CDL description and monitors the progress of transactions,
+ * which are long lived interactions, against the CDL description.
+ * A TxnMonitor MAY be used as a generic monitor for any CDL description.
+ *
+ */
+public class TxnMonitor {
+
+ public TxnMonitor(String fname)
+ {
+ m_cdlFile = fname;
+ }
+
+ public void initialize() throws ServiceException
+ {
+
+ m_correlator=ServiceCorrelatorFactory.getServiceCorrelator();
+ m_correlator.addServiceCorrelatorListener(new CorrelatorListener());
+
+ // Obtain service tracker client
+ m_trackerClient = new JMSServiceTrackerClient();
+
+ m_trackerClient.addServiceTrackerListener(m_correlator);
+
+ //System.err.println("");
+ //System.err.println("Staring to monitor events against " + m_cdlFile + " .... ");
+ //System.err.println("");
+ try {
+ monitor(m_cdlFile);
+ } catch(java.io.IOException ioe) {
+ throw new ServiceException("Failed to initialize monitor for '"+
+ m_cdlFile+"'", ioe);
+ }
+ }
+
+ /**
+ * This method returns the singleton for the TxnMonitor.
+ *
+ * @return The singleton
+ * @exception ServiceException Failed to obtain monitor
+ */
+ public static TxnMonitor getInstance(String fname) throws ServiceException {
+ // TODO: See if there is a better way to make an instance
+ // available to a view
+ if (m_instance == null) {
+ m_instance = new TxnMonitor(fname);
+ m_instance.initialize();
+ }
+
+ return(m_instance);
+ }
+
+ /**
+ * This method loads the choreography description associated
+ * with the supplied filename, and then monitors it, before
+ * returning it to the caller.
+ *
+ * @param filename The choreography description filename
+ * @return The choreography description being monitored
+ * @throws java.io.IOException Failed to load
+ * @throws ServiceException Failed to monitor
+ */
+ public org.pi4soa.cdl.Package monitor(String filename)
+ throws java.io.IOException, ServiceException {
+ org.pi4soa.cdl.Package ret=
+ org.pi4soa.cdl.CDLManager.load(filename);
+
+ monitor(ret);
+
+ return(ret);
+ }
+
+ /**
+ * This method initializes the correlator with the choreography
+ * description to be monitored.
+ *
+ * @param cdl The choreography description
+ * @exception ServiceException Failed to monitor choreography
+ * description
+ */
+ public void monitor(org.pi4soa.cdl.Package cdl)
+ throws ServiceException {
+ m_correlator.register(cdl);
+ }
+
+ /**
+ * This method disassociates the correlator from the choreography
+ * description being monitored.
+ *
+ * @param cdl The choreography description
+ * @exception ServiceException Failed to stop monitor choreography
+ * description
+ */
+ public void unmonitor(org.pi4soa.cdl.Package cdl)
+ throws ServiceException {
+ m_correlator.unregister(cdl);
+ }
+
+ /**
+ * @param args - the first argument in args is the location of the
+ * CDM file that will be used to drive the monitoring.
+ */
+ public static void main(String[] args)
+ {
+ // TODO Auto-generated method stub
+ String s = "Constructing a monitor for " + args[0];
+ logger.fine(s);
+
+ try {
+ TxnMonitor mon = TxnMonitor.getInstance(args[0]);
+ } catch(Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * This method will return an existing list, associated with the
+ * supplied session, or if not found, will create one - unless
+ * the session's event list has previously been removed and
+ * therefore a null will be returned (i.e. events to be
+ * ignored).
+ *
+ * @param session The session
+ * @return The list, or null if session to be ignored
+ */
+ protected java.util.List createEventList(CorrelationSession session) {
+ java.util.List ret=null;
+
+ logger.fine("createEventList for session - " + session);
+
+ synchronized(m_eventLists) {
+ ret = (java.util.List)m_eventLists.get(session);
+
+ if (ret == null) {
+ ret = new java.util.Vector();
+
+ logger.fine("Creating event list for session: "+session);
+
+ m_eventLists.put(session, ret);
+ }
+ }
+
+ logger.fine("createEventList returning - " + ret);
+
+ return(ret);
+ }
+
+ /**
+ * This method will remove the event list associated with
+ * the supplied session, and add the session to the list
+ * of sessions to be ignored from now on.
+ *
+ * @param session The session
+ */
+ protected void removeEventList(CorrelationSession session) {
+
+ synchronized(m_eventLists) {
+
+ logger.fine("Remove correlation session: "+session);
+
+ m_eventLists.remove(session);
+ }
+ }
+
+ protected void fireSessionStarted(CorrelationSession session) {
+ System.err.println(">>>> fireSessionStarted");
+ for (int i=0; i < m_listeners.size(); i++) {
+ CorrelationManagerListener l=
+ (CorrelationManagerListener)m_listeners.get(i);
+
+ l.correlationSessionStarted(session);
+ }
+ System.err.println(">>>> finished fireSessionStarted");
+ }
+
+ protected void fireSessionFinished(CorrelationSession session) {
+ System.err.println(">>>> fireSessionFinished");
+ for (int i=0; i < m_listeners.size(); i++) {
+ CorrelationManagerListener l=
+ (CorrelationManagerListener)m_listeners.get(i);
+
+ l.correlationSessionFinished(session);
+ }
+ logger.fine(">>>> finished fireSessionFinished");
+ }
+
+ protected void fireUpdatedSession(CorrelationSession session) {
+ logger.fine(">>>> fireSessionUpdated");
+ for (int i=0; i < m_listeners.size(); i++) {
+ CorrelationManagerListener l=
+ (CorrelationManagerListener)m_listeners.get(i);
+
+ // l.correlationSessionUpdated(session);
+ }
+ logger.fine(">>>> finished fireSessionUpdated");
+ }
+
+
+ protected void fireAddedExchangeEvent(ExchangeEvent exchangeEvent) {
+ for (int i=0; i < m_listeners.size(); i++) {
+ CorrelationManagerListener l=
+ (CorrelationManagerListener)m_listeners.get(i);
+
+ l.exchangeEventAdded(exchangeEvent);
+ }
+ }
+
+ protected void fireUpdatedExchangeEvent(ExchangeEvent exchangeEvent) {
+ for (int i=0; i < m_listeners.size(); i++) {
+ CorrelationManagerListener l=
+ (CorrelationManagerListener)m_listeners.get(i);
+
+ l.exchangeEventUpdated(exchangeEvent);
+ }
+ }
+
+ protected void fireAddedUnexpectedExchangeEvent(ExchangeEvent exchangeEvent,
+ String serviceName) {
+ logger.fine(">>>> fireAddedUnexpectedExchangeEvent");
+ for (int i=0; i < m_listeners.size(); i++) {
+ CorrelationManagerListener l=
+ (CorrelationManagerListener)m_listeners.get(i);
+
+ l.unexpectedExchangeEventAdded(exchangeEvent, serviceName);
+ }
+ logger.fine("<<<< fireAddedUnexpectedExchangeEvent");
+ }
+
+ protected void fireErrorEvent(CorrelationSession session,
+ String mesg, String exception, String serviceName) {
+ logger.fine(">>>> fireErrorEvent");
+ for (int i=0; i < m_listeners.size(); i++) {
+ CorrelationManagerListener l=
+ (CorrelationManagerListener)m_listeners.get(i);
+
+ l.error(session, mesg, exception, serviceName);
+ }
+ logger.fine("<<<< fireErrorEvent");
+ }
+
+ protected void fireWarningEvent(CorrelationSession session,
+ String mesg, String exception, String serviceName) {
+ logger.fine(">>>> fireWarningEvent");
+ for (int i=0; i < m_listeners.size(); i++) {
+ CorrelationManagerListener l=
+ (CorrelationManagerListener)m_listeners.get(i);
+
+ l.warning(session, mesg, exception, serviceName);
+ }
+ logger.fine("<<<< fireWarningEvent");
+ }
+
+ protected void fireInformationEvent(CorrelationSession session,
+ String mesg, String serviceName) {
+ logger.fine(">>>> fireInformationEvent");
+ for (int i=0; i < m_listeners.size(); i++) {
+ CorrelationManagerListener l=
+ (CorrelationManagerListener)m_listeners.get(i);
+
+ l.information(session, mesg, serviceName);
+ }
+ logger.fine("<<<< fireInformationEvent");
+ }
+
+ public void addCorrelationManagerListener(CorrelationManagerListener l) {
+ logger.fine(">>>> addCorrelationManagerListener");
+ m_listeners.add(l);
+ }
+
+ public void removeCorrelationManagerListener(CorrelationManagerListener l) {
+ logger.fine(">>>> removeCorrelationManagerListener");
+ m_listeners.remove(l);
+ }
+
+ private static Logger logger = Logger.getLogger("org.pi4soa.monitor");
+
+ private static TxnMonitor m_instance=null;
+ private ServiceCorrelator m_correlator=null;
+ private ServiceTrackerClient m_trackerClient=null;
+ private java.util.Hashtable m_eventLists=new java.util.Hashtable();
+ private java.util.Vector m_listeners=new java.util.Vector();
+ private String m_cdlFile = null;
+
+
+ public class CorrelatorListener implements ServiceCorrelatorListener {
+
+ /**
+ * This method indicates that the supplied choreography
+ * description has been registered with the service
+ * correlator.
+ *
+ * @param cdlpack The choreography description
+ */
+ public void choreographyDescriptionRegistered(org.pi4soa.cdl.Package cdlpack) {
+ logger.fine(">>>> choreographyDescriptionRegistered");
+ }
+
+ /**
+ * This method indicates that the supplied choreography
+ * description has been unregistered from the service
+ * correlator.
+ *
+ * @param cdlpack The choreography description
+ */
+ public void choreographyDescriptionUnregistered(org.pi4soa.cdl.Package cdlpack) {
+ logger.fine(">>>> choreographyDescriptionUnregistered");
+ }
+
+ /**
+ * This method indicates that a new correlated session has
+ * been started.
+ *
+ * @param session The session
+ */
+ public void sessionStarted(CorrelationSession session) {
+ logger.fine(">>>> sessionStarted");
+ fireSessionStarted(session);
+ }
+
+ /**
+ * This method indicates that a correlated session has
+ * been finished.
+ *
+ * @param session The session
+ */
+ public void sessionFinished(CorrelationSession session) {
+ logger.fine(">>>> sessionFinished");
+ fireSessionFinished(session);
+ }
+
+ /**
+ * This method is invoked to indicate that a choreography
+ * exchange has been initiated by one participant.
+ *
+ * @param exchange The exchange details
+ * @param channel The channel associated with the exchange
+ * @param session The session
+ * @param serviceDescriptionName The name of the service
+ * description that caused this exchange to
+ * be initiated
+ */
+ public synchronized void exchangeInitiated(ExchangeDetails exchange,
+ Channel channel, Message message, CorrelationSession session,
+ String serviceDescriptionName) {
+
+ logger.fine(">>>> exchangeInitiated");
+
+ java.util.List list = createEventList(session);
+
+ if(list != null){
+ ExchangeEvent event = new ExchangeEvent(exchange, channel, session, serviceDescriptionName, message);
+ int index = 0;
+ boolean f_updated=false;
+
+ if ((index=list.indexOf(event)) == -1) {
+ logger.fine("Add new event '"+event+ "' to correlation session "+session);
+ list.add(event);
+ }
+ else{
+ logger.fine("Retrieve existing event for index "+index);
+ ExchangeEvent existingEvent=
+ (ExchangeEvent)list.get(index);
+
+ if (existingEvent.getInitiated() == false) {
+ event = existingEvent;
+
+ // Remove event from list
+ list.remove(index);
+
+ if (list.size() == 0) {
+ // Remove list
+ removeEventList(session);
+ }
+
+ f_updated = true;
+ } else {
+ logger.fine("Add new event '"+event+ "' to correlation session "+session);
+ list.add(event);
+ }
+ }
+
+ event.initiated();
+ logger.fine("EXCHANGE INITIATED: ");
+ logger.fine(" CHANNEL DETAILS: " + channel + " (" + channel.getName() + ") session " + session);
+ logger.fine(" EXCHANGE DETAILS: " + exchange);
+
+ if(f_updated == false){
+ fireAddedExchangeEvent(event);
+ }
+ else{
+ fireUpdatedExchangeEvent(event);
+ }
+ // fireUpdatedSession(session);
+ }
+ }
+
+ /**
+ * This method is invoked to indicate that a choreography
+ * exchange has been completed by the target participant.
+ *
+ * @param exchange The exchange details
+ * @param channel The channel associated with the exchange
+ * @param session The session
+ * @param serviceDescriptionName The name of the service
+ * description that caused this exchange to
+ * be completed
+ */
+ public synchronized void exchangeCompleted(ExchangeDetails exchange,
+ Channel channel, Message message, CorrelationSession session,
+ String serviceDescriptionName) {
+
+ logger.fine(">>>> exchangeCompleted");
+
+ java.util.List list=createEventList(session);
+
+ if (list != null) {
+ ExchangeEvent event=new ExchangeEvent(exchange, channel, session, serviceDescriptionName, message);
+
+ int index = 0;
+
+ if ((index=list.indexOf(event)) == -1) {
+ logger.fine("Add new event '"+event+ "' to correlation session "+session);
+ list.add(event);
+ }
+ else{
+ logger.fine("Retrieve existing event for index "+index);
+ ExchangeEvent existingEvent=
+ (ExchangeEvent)list.get(index);
+
+ if (existingEvent.getCompleted() == false) {
+ event = existingEvent;
+
+ // Remove event from list
+ list.remove(index);
+
+ if (list.size() == 0) {
+ // Remove list
+ removeEventList(session);
+ }
+ } else {
+ logger.fine("Add new event '"+event+ "' to correlation session "+session);
+ list.add(event);
+ }
+ }
+
+ event.completed();
+ logger.fine("EXCHANGE COMPLETED: ");
+ // logger.fine(" CHANNEL DETAILS: " + channel);
+ logger.fine(" CHANNEL DETAILS: " + channel + " (" + channel.getName() + ") session " + session);
+ logger.fine(" EXCHANGE DETAILS: " + exchange);
+
+ if(index == -1){
+ fireAddedExchangeEvent(event);
+ }
+ else{
+ fireUpdatedExchangeEvent(event);
+ }
+ // fireUpdatedSession(session);
+ logger.fine("<<<< exchangeCompleted");
+ }
+ }
+
+ /**
+ * This method is invoked to indicate that a message
+ * was unexpected at a participant.
+ *
+ * @param message The message
+ * @param session The session
+ * @param serviceDescriptionName The name of the service
+ * description that caused this unexpected
+ * message error
+ */
+ public synchronized void unexpectedMessage(Message message,
+ CorrelationSession session, String serviceDescriptionName) {
+
+ logger.fine(">>>> unexpectedMessage");
+ logger.fine("MESSAGE: " + message + " SESSION: " + session + " SERVICE: " + serviceDescriptionName);
+ logger.fine("MESSAGE: " + message);
+ logger.fine("Identities: " + message.getChannelIdentity());
+ //java.util.List list = createEventList(session);
+
+ //if(list != null){
+ ExchangeDetails exchange = null;
+ Channel channel = null;
+
+ logger.fine(">>>> creating unexpected event");
+
+ ExchangeEvent event = new ExchangeEvent(exchange, channel, session, serviceDescriptionName, message);
+
+ logger.fine(">>>> created unexpected event");
+
+ logger.fine("Add unexpected new event '"+event+ "' to correlation session "+session);
+ //list.add(event);
+
+ logger.fine(">>>> UNEXPECTED EVENT for session: " + session);
+
+ fireAddedUnexpectedExchangeEvent(event, serviceDescriptionName);
+
+
+ logger.fine(">>>> HANDLED UNEXPECTED EVENT for session: " + session);
+ //}
+ logger.fine("<<<< unexpectedMessage");
+ }
+
+ /**
+ * An error occurred related to the specified correlation
+ * session.
+ *
+ * @param mesg The error message
+ * @param exception The optional exception details
+ * @param session The correlation session
+ * @param serviceDescriptionName The service name
+ */
+ public void error(String mesg, String exception,
+ CorrelationSession session, String serviceDescriptionName) {
+ logger.fine(">>>> error");
+
+ fireErrorEvent(session, mesg, exception, serviceDescriptionName);
+
+ logger.fine("<<<< error");
+ }
+
+ /**
+ * A warning occurred related to the specified correlation
+ * session.
+ *
+ * @param mesg The warning message
+ * @param exception The optional exception details
+ * @param session The correlation session
+ * @param serviceDescriptionName The service name
+ */
+ public void warning(String mesg, String exception,
+ CorrelationSession session, String serviceDescriptionName) {
+ logger.fine(">>>> warning");
+
+ fireWarningEvent(session, mesg, exception, serviceDescriptionName);
+
+ logger.fine("<<<< warning");
+ }
+
+ /**
+ * An information event occurred related to the specified correlation
+ * session.
+ *
+ * @param mesg The information message
+ * @param session The correlation session
+ * @param serviceDescriptionName The service name
+ */
+ public void information(String mesg, CorrelationSession session,
+ String serviceDescriptionName) {
+ logger.fine(">>>> information");
+
+ fireInformationEvent(session, mesg, serviceDescriptionName);
+
+ logger.fine("<<<< information");
+ }
+ }
+}
Added: trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/eclipse/Activator.java
===================================================================
--- trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/eclipse/Activator.java (rev 0)
+++ trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/eclipse/Activator.java 2009-12-05 10:50:50 UTC (rev 98)
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2005-8 Pi4 Technologies Ltd
+ *
+ * Licensed 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.
+ *
+ *
+ * Change History:
+ * 16 Jan, 2008 : Initial version created by gary
+ */
+package org.pi4soa.monitor.eclipse;
+
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+import org.pi4soa.common.eclipse.BundleUtil;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator extends AbstractUIPlugin {
+
+ // The plug-in ID
+ public static final String PLUGIN_ID = "org.pi4soa.monitor";
+
+ // The shared instance
+ private static Activator plugin;
+
+ /**
+ * The constructor
+ */
+ public Activator() {
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static Activator getDefault() {
+ return plugin;
+ }
+
+
+ static {
+ BundleUtil.registerClasspathEntries(PLUGIN_ID, false);
+ }
+}
Added: trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/eclipse/MonitorAction.java
===================================================================
--- trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/eclipse/MonitorAction.java (rev 0)
+++ trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/eclipse/MonitorAction.java 2009-12-05 10:50:50 UTC (rev 98)
@@ -0,0 +1,173 @@
+/*
+ * Copyright 2005-8 Pi4 Technologies Ltd
+ *
+ * Licensed 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.
+ *
+ *
+ * Change History:
+ * 17 Jan, 2008 : Initial version created by gary
+ */
+package org.pi4soa.monitor.eclipse;
+
+import java.util.logging.Logger;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.MessageBox;
+import org.eclipse.ui.IObjectActionDelegate;
+import org.eclipse.ui.IWorkbenchPart;
+import org.pi4soa.common.resource.eclipse.ResourceUtil;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationType;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.debug.core.ILaunchManager;
+import org.eclipse.debug.core.Launch;
+import org.eclipse.debug.core.DebugPlugin;
+
+/**
+ * This class invokes the monitor action on the selected
+ * choreography file.
+ *
+ */
+public class MonitorAction implements IObjectActionDelegate {
+
+ /**
+ * This method implements the action's run method.
+ *
+ * @param action The action
+ */
+ public void run(IAction action) {
+
+ if (m_selection instanceof StructuredSelection) {
+ StructuredSelection sel=(StructuredSelection)m_selection;
+
+ IResource res=(IResource)sel.getFirstElement();
+
+ // Make sure there are no markers associated
+ // with the resource
+ if (ResourceUtil.hasErrors(res) == false) {
+
+ launch(res.getProject().getName(),
+ res.getProjectRelativePath().toString());
+
+ } else {
+ error(ERRORS_NO_TEST);
+ }
+ }
+ }
+
+ /**
+ * This method invokes the launch action.
+ *
+ * @param project The project
+ * @param relativePath The relative path within the project
+ */
+ protected void launch(String project, String relativePath) {
+
+ MonitorLauncher launcher=new MonitorLauncher();
+
+ try {
+ ILaunchManager manager =
+ DebugPlugin.getDefault().getLaunchManager();
+
+ ILaunchConfigurationType type =
+ manager.getLaunchConfigurationType(
+ MonitorLaunchConfigurationConstants.LAUNCH_CONFIG_TYPE);
+ ILaunchConfiguration[] configurations =
+ manager.getLaunchConfigurations(type);
+
+ for (int i = 0; i < configurations.length; i++) {
+ ILaunchConfiguration configuration = configurations[i];
+ if (configuration.getName().equals(PI4SOA_MONITOR)) {
+ configuration.delete();
+ break;
+ }
+ }
+
+ ILaunchConfigurationWorkingCopy workingCopy =
+ type.newInstance(null, PI4SOA_MONITOR);
+
+ workingCopy.setAttribute(MonitorLaunchConfigurationConstants.ATTR_PROJECT_NAME,
+ project);
+ workingCopy.setAttribute(MonitorLaunchConfigurationConstants.ATTR_CHOREOGRAPHY_DESCRIPTION,
+ relativePath);
+
+ ILaunchConfiguration configuration=workingCopy.doSave();
+
+
+ Launch launch=new Launch(configuration, LAUNCH_MODE, null);
+
+ launcher.launch(configuration, LAUNCH_MODE, launch, null);
+
+ } catch(Exception e) {
+ logger.severe("Failed to launch monitor: "+e);
+
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * This method is used to report an error.
+ *
+ * @param mesg The error message
+ */
+ public void error(String mesg) {
+
+ logger.severe("Error occurred: "+mesg);
+
+ MessageBox mbox=new MessageBox(m_targetPart.getSite().getShell(),
+ SWT.ICON_ERROR|SWT.OK);
+
+ if (mesg == null) {
+ mesg = "Null pointer exception has occurred";
+ }
+
+ mbox.setMessage(mesg);
+ mbox.open();
+ }
+
+ /**
+ * This method indicates that the selection has changed.
+ *
+ * @param action The action
+ * @param selection The selection
+ */
+ public void selectionChanged(IAction action,
+ ISelection selection) {
+ m_selection = selection;
+ }
+
+ /**
+ * This method sets the currently active workbench part.
+ *
+ * @param action The action
+ * @param targetPart The active workbench part
+ */
+ public void setActivePart(IAction action,
+ IWorkbenchPart targetPart) {
+ m_targetPart = targetPart;
+ }
+
+ private static Logger logger = Logger.getLogger("org.pi4soa.monitor.eclipse");
+
+ private ISelection m_selection=null;
+ private IWorkbenchPart m_targetPart=null;
+
+ private static final String ERRORS_NO_TEST = "Choreography Description has errors, so cannot run monitor";
+
+ private static final String LAUNCH_MODE = "run";
+ private static final String PI4SOA_MONITOR = "Pi4SOA Monitor";
+}
Added: trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/eclipse/MonitorLaunchConfigurationConstants.java
===================================================================
--- trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/eclipse/MonitorLaunchConfigurationConstants.java (rev 0)
+++ trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/eclipse/MonitorLaunchConfigurationConstants.java 2009-12-05 10:50:50 UTC (rev 98)
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2005-8 Pi4 Technologies Ltd
+ *
+ * Licensed 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.
+ *
+ *
+ * Change History:
+ * 17 Jan, 2008 : Initial version created by gary
+ */
+package org.pi4soa.monitor.eclipse;
+
+/**
+ * This interface defines the constants for the monitor
+ * launch configuration.
+ */
+public interface MonitorLaunchConfigurationConstants {
+
+ public static final String ATTR_PROJECT_NAME="project";
+
+ public static final String ATTR_CHOREOGRAPHY_DESCRIPTION="choreography";
+
+ public static final String LAUNCH_CONFIG_TYPE=
+ "org.pi4soa.monitor.eclipse.MonitorLauncher";
+}
Added: trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/eclipse/MonitorLauncher.java
===================================================================
--- trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/eclipse/MonitorLauncher.java (rev 0)
+++ trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/eclipse/MonitorLauncher.java 2009-12-05 10:50:50 UTC (rev 98)
@@ -0,0 +1,282 @@
+/*
+ * Copyright 2005-8 Pi4 Technologies Ltd
+ *
+ * Licensed 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.
+ *
+ *
+ * Change History:
+ * 17 Jan, 2008 : Initial version created by gary
+ */
+package org.pi4soa.monitor.eclipse;
+
+import java.io.File;
+import java.text.MessageFormat;
+import java.util.Map;
+import java.util.Vector;
+import java.util.logging.Logger;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.ILaunch;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.IStreamListener;
+import org.eclipse.debug.core.model.IStreamMonitor;
+import org.eclipse.debug.core.model.IProcess;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.launching.AbstractJavaLaunchConfigurationDelegate;
+import org.eclipse.jdt.launching.ExecutionArguments;
+import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
+import org.eclipse.jdt.launching.IVMInstall;
+import org.eclipse.jdt.launching.IVMRunner;
+import org.eclipse.jdt.launching.VMRunnerConfiguration;
+import org.pi4soa.common.eclipse.BundleUtil;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.Path;
+
+/**
+ * This class is responsible for launching a monitor against
+ * a choreography description.
+ */
+public class MonitorLauncher
+ extends AbstractJavaLaunchConfigurationDelegate {
+
+ /**
+ * This is the default constructor.
+ *
+ */
+ public MonitorLauncher() {
+ }
+
+ /**
+ * This method launches the monitor.
+ *
+ * @param configuration The launch configuration
+ * @param mode The mode (run or debug)
+ * @param launch The launch object
+ * @param monitor The optional progress monitor
+ */
+ public void launch(ILaunchConfiguration configuration,
+ String mode, ILaunch launch, IProgressMonitor monitor)
+ throws CoreException {
+ if (monitor == null) {
+ monitor = new NullProgressMonitor();
+ }
+
+ monitor.beginTask(MessageFormat.format("{0}...", new String[]{configuration.getName()}), 3); //$NON-NLS-1$
+ // check for cancellation
+ if (monitor.isCanceled()) {
+ return;
+ }
+
+ monitor.subTask("Verifying launch configuration....");
+
+ String mainTypeName = org.pi4soa.monitor.ui.Monitor.class.getName();
+
+ IVMInstall vm = verifyVMInstall(configuration);
+
+ IVMRunner runner = vm.getVMRunner(mode);
+ if (runner == null) {
+ abort("VM runner does not exist",
+ null, IJavaLaunchConfigurationConstants.ERR_VM_RUNNER_DOES_NOT_EXIST); //$NON-NLS-1$
+ }
+
+ File workingDir = verifyWorkingDirectory(configuration);
+ String workingDirName = null;
+ if (workingDir != null) {
+ workingDirName = workingDir.getAbsolutePath();
+ }
+
+ // Environment variables
+ String[] envp= DebugPlugin.getDefault().getLaunchManager().getEnvironment(configuration);
+
+ // Program & VM args
+ String filename=configuration.getAttribute(
+ MonitorLaunchConfigurationConstants.ATTR_PROJECT_NAME, "")+
+ "/"+configuration.getAttribute(
+ MonitorLaunchConfigurationConstants.ATTR_CHOREOGRAPHY_DESCRIPTION, "");
+
+ String pgmArgs="\""+getPathForResource(filename);
+
+ logger.fine("Launching monitor with args: "+pgmArgs);
+
+ String vmArgs = getVMArguments(configuration);
+ ExecutionArguments execArgs = new ExecutionArguments(vmArgs, pgmArgs);
+
+ // VM-specific attributes
+ Map vmAttributesMap = getVMSpecificAttributesMap(configuration);
+
+ // Classpath
+ String[] classpath = getClasspath(configuration);
+
+ // Create VM config
+ VMRunnerConfiguration runConfig = new VMRunnerConfiguration(mainTypeName, classpath);
+ runConfig.setProgramArguments(execArgs.getProgramArgumentsArray());
+ runConfig.setEnvironment(envp);
+ runConfig.setVMArguments(execArgs.getVMArgumentsArray());
+ runConfig.setWorkingDirectory(workingDirName);
+ runConfig.setVMSpecificAttributesMap(vmAttributesMap);
+
+ // Bootpath
+ runConfig.setBootClassPath(getBootpath(configuration));
+
+ // check for cancellation
+ if (monitor.isCanceled()) {
+ return;
+ }
+
+ // stop in main
+ prepareStopInMain(configuration);
+
+ // done the verification phase
+ monitor.worked(1);
+
+ // Launch the configuration - 1 unit of work
+ runner.run(runConfig, launch, monitor);
+
+ IProcess[] processes=launch.getProcesses();
+ if (processes.length > 0) {
+ processes[0].getStreamsProxy().getOutputStreamMonitor().
+ addListener(new IStreamListener() {
+ public void streamAppended(String str, IStreamMonitor mon) {
+ handleResults(str, false);
+ }
+ });
+ processes[0].getStreamsProxy().getErrorStreamMonitor().
+ addListener(new IStreamListener() {
+ public void streamAppended(String str, IStreamMonitor mon) {
+ handleResults(str, true);
+ }
+ });
+ }
+
+ // check for cancellation
+ if (monitor.isCanceled()) {
+ return;
+ }
+
+ monitor.done();
+ }
+
+ /**
+ * This method handles the results produced by the launched
+ * monitor.
+ *
+ * @param results The results
+ * @param errorStream Whether the results are from the error
+ * stream
+ */
+ protected void handleResults(String results, boolean errorStream) {
+ //System.out.println(results);
+ }
+
+ /**
+ * This method returns the full path to the resource.
+ *
+ * @param relativePath The is the resource path beginning at
+ * the project
+ * @return The full path
+ */
+ protected String getPathForResource(String relativePath) {
+ String ret=null;
+
+ IFile file=ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(relativePath));
+ if (file != null && file.exists()) {
+ ret = file.getLocation().toString();
+ }
+
+ return(ret);
+ }
+
+ /**
+ * This method derives the classpath required to run the
+ * Monitor.
+ *
+ * @param configuration The launch configuation
+ * @return The list of classpath entries
+ */
+ public String[] getClasspath(ILaunchConfiguration configuration) {
+ String[] ret=null;
+ Vector classpathEntries=new Vector();
+
+ // Add classpath entry for current Java project
+ try {
+ String projname=configuration.getAttribute(
+ MonitorLaunchConfigurationConstants.ATTR_PROJECT_NAME, "");
+
+ IProject project=
+ ResourcesPlugin.getWorkspace().getRoot().getProject(projname);
+
+ IJavaProject jproject=JavaCore.create(project);
+
+ // Add output location
+ IPath outputLocation=jproject.getOutputLocation();
+
+ IFolder folder=
+ ResourcesPlugin.getWorkspace().getRoot().getFolder(outputLocation);
+
+ String path=folder.getLocation().toString();
+
+ classpathEntries.add(path);
+
+ // Add other libraries to the classpath
+ IClasspathEntry[] curclspath=jproject.getRawClasspath();
+ for (int i=0; curclspath != null &&
+ i < curclspath.length; i++) {
+
+ if (curclspath[i].getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
+ IFile file=
+ ResourcesPlugin.getWorkspace().
+ getRoot().getFile(curclspath[i].getPath());
+
+ if (file.exists()) {
+ // Library is within the workspace
+ classpathEntries.add(file.getLocation().toString());
+ } else {
+ // Assume library is external to workspace
+ classpathEntries.add(curclspath[i].getPath().toString());
+ }
+
+ } else if (curclspath[i].getEntryKind() ==
+ IClasspathEntry.CPE_CONTAINER) {
+ // Container's not currently handled - but
+ // problem need to retrieve from project and
+ // iterate over container entries
+ }
+ }
+
+ } catch(Exception e) {
+ // TODO: report error
+ }
+
+ String[] cpes=BundleUtil.getClasspathEntries();
+
+ for (int i=0; i < cpes.length; i++) {
+ classpathEntries.add(cpes[i]);
+ }
+
+ ret = new String[classpathEntries.size()];
+ classpathEntries.copyInto(ret);
+
+ return(ret);
+ }
+
+ private static Logger logger = Logger.getLogger("org.pi4soa.monitor.eclipse");
+}
\ No newline at end of file
Added: trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/eclipse/MonitorMainTab.java
===================================================================
--- trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/eclipse/MonitorMainTab.java (rev 0)
+++ trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/eclipse/MonitorMainTab.java 2009-12-05 10:50:50 UTC (rev 98)
@@ -0,0 +1,516 @@
+/*
+ * Copyright 2005-8 Pi4 Technologies Ltd
+ *
+ * Licensed 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.
+ *
+ *
+ * Change History:
+ * 17 Jan, 2008 : Initial version created by gary
+ */
+package org.pi4soa.monitor.eclipse;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.debug.ui.AbstractLaunchConfigurationTab;
+import org.eclipse.debug.ui.ILaunchConfigurationTab;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.dialogs.ElementListSelectionDialog;
+
+/**
+ * This class represents the first main tab within the tab group
+ * associated with the monitor launch configuration.
+ */
+public class MonitorMainTab extends AbstractLaunchConfigurationTab {
+
+ /**
+ * @see ILaunchConfigurationTab#createControl(org.eclipse.swt.widgets.Composite)
+ */
+ public void createControl(Composite parent) {
+ Composite comp = new Composite(parent, SWT.NONE);
+ setControl(comp);
+
+ GridLayout topLayout = new GridLayout();
+ topLayout.numColumns= 3;
+ comp.setLayout(topLayout);
+
+ Label label = new Label(comp, SWT.NONE);
+ GridData gd = new GridData();
+ gd.horizontalSpan = 3;
+ label.setLayoutData(gd);
+
+ createChoreographySection(comp);
+
+ label = new Label(comp, SWT.NONE);
+ gd = new GridData();
+ gd.horizontalSpan = 3;
+ label.setLayoutData(gd);
+
+ Dialog.applyDialogFont(comp);
+ validatePage();
+ }
+
+ /**
+ * This method creates the GUI components for the
+ * monitor tab.
+ *
+ * @param comp The composite
+ */
+ protected void createChoreographySection(Composite comp) {
+ GridData gd = new GridData();
+ gd.horizontalSpan = 3;
+
+ m_projectLabel = new Label(comp, SWT.NONE);
+ m_projectLabel.setText("Project");
+ gd= new GridData();
+ gd.horizontalIndent = 25;
+ m_projectLabel.setLayoutData(gd);
+
+ m_project= new Text(comp, SWT.SINGLE | SWT.BORDER);
+ m_project.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ m_project.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent evt) {
+ validatePage();
+ updateLaunchConfigurationDialog();
+ m_choreographySearch.setEnabled(m_project.getText().length() > 0);
+ }
+ });
+
+ m_projectButton = new Button(comp, SWT.PUSH);
+ m_projectButton.setText("Browse");
+ m_projectButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent evt) {
+ handleProjectButtonSelected();
+ }
+ });
+ setButtonGridData(m_projectButton);
+
+ m_choreographyLabel = new Label(comp, SWT.NONE);
+ gd = new GridData();
+ gd.horizontalIndent = 25;
+ m_choreographyLabel.setLayoutData(gd);
+ m_choreographyLabel.setText("Choreography");
+
+ m_choreography = new Text(comp, SWT.SINGLE | SWT.BORDER);
+ m_choreography.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ m_choreography.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent evt) {
+ validatePage();
+ updateLaunchConfigurationDialog();
+ }
+ });
+
+ m_choreographySearch = new Button(comp, SWT.PUSH);
+ m_choreographySearch.setEnabled(m_project.getText().length() > 0);
+ m_choreographySearch.setText("Search");
+ m_choreographySearch.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent evt) {
+ handleSearchButtonSelected();
+ }
+ });
+ setButtonGridData(m_choreographySearch);
+ }
+
+ protected static Image createImage(String path) {
+ return null;
+ }
+
+
+ /**
+ * @see ILaunchConfigurationTab#initializeFrom(ILaunchConfiguration)
+ */
+ public void initializeFrom(ILaunchConfiguration config) {
+ String projectName= "";
+ String choreography= "";
+
+ try {
+ projectName = config.getAttribute(MonitorLaunchConfigurationConstants.ATTR_PROJECT_NAME, ""); //$NON-NLS-1$
+ } catch (CoreException ce) {
+ }
+ m_project.setText(projectName);
+
+ try {
+ choreography = config.getAttribute(MonitorLaunchConfigurationConstants.ATTR_CHOREOGRAPHY_DESCRIPTION, ""); //$NON-NLS-1$
+ } catch (CoreException ce) {
+ }
+ m_choreography.setText(choreography);
+ }
+
+ /**
+ * @see ILaunchConfigurationTab#performApply(ILaunchConfigurationWorkingCopy)
+ */
+ public void performApply(ILaunchConfigurationWorkingCopy config) {
+ }
+
+ /**
+ * @see ILaunchConfigurationTab#dispose()
+ */
+ public void dispose() {
+ super.dispose();
+ }
+
+ /**
+ * @see AbstractLaunchConfigurationTab#getImage()
+ */
+ public Image getImage() {
+ return(null);
+ }
+
+ /**
+ * This method sets the grid data for the button.
+ *
+ * @param button The button
+ */
+ protected void setButtonGridData(Button button) {
+ GridData gridData= new GridData();
+ button.setLayoutData(gridData);
+ //SWTUtil.setButtonDimensionHint(button);
+ }
+
+ /**
+ * Show a dialog that lists all choreography files within the
+ * selected project
+ */
+ protected void handleSearchButtonSelected() {
+
+ IProject project = getProject();
+
+ ILabelProvider labelProvider=new LabelProvider() {
+ public String getText(Object obj) {
+ String ret="<unknown>";
+ if (obj instanceof IResource) {
+ String filename=((IResource)obj).getName();
+ if (filename.endsWith(org.pi4soa.cdl.CDLDefinitions.CDL_FILE_EXTENSION)) {
+ filename = filename.substring(0, filename.length()-
+ org.pi4soa.cdl.CDLDefinitions.CDL_FILE_EXTENSION.length()-1);
+ }
+ ret = filename+" ["+
+ ((IResource)obj).getParent().
+ getProjectRelativePath()+"]";
+ }
+ return(ret);
+ }
+ };
+
+ IResource[] choreos=null;
+
+ if (project.exists() == false) {
+ choreos = new IResource[0];
+ } else {
+ choreos = getChoreographies(project);
+ }
+
+ ElementListSelectionDialog dialog= new ElementListSelectionDialog(getShell(), labelProvider);
+ dialog.setTitle("Choreographies");
+ dialog.setMessage("Select the relevant choreography");
+ dialog.setElements(choreos);
+
+ if (dialog.open() == Window.OK) {
+ IResource file=(IResource)dialog.getFirstResult();
+ m_choreography.setText(file.getProjectRelativePath().toString());
+ }
+ }
+
+ /**
+ * This method returns the list of choreography resource files within
+ * the supplied project.
+ *
+ * @param project The project
+ * @return The list of choreography resource files
+ */
+ protected IResource[] getChoreographies(IProject project) {
+ IResource[] ret=null;
+ final java.util.Vector list=new java.util.Vector();
+
+ try {
+ project.accept(new org.eclipse.core.resources.IResourceVisitor() {
+ public boolean visit(IResource res) {
+
+ if (res.getFileExtension() != null &&
+ res.getFileExtension().equals(
+ org.pi4soa.cdl.CDLDefinitions.CDL_FILE_EXTENSION)) {
+ list.add(res);
+ }
+
+ return(true);
+ }
+ });
+
+ ret = new IResource[list.size()];
+ list.copyInto(ret);
+
+ } catch(Exception e) {
+ e.printStackTrace();
+ }
+
+ return(ret);
+ }
+
+ /**
+ * Show a dialog that lets the user select a project. This in turn provides
+ * context for the main type, allowing the user to key a main type name, or
+ * constraining the search for main types to the specified project.
+ */
+ protected void handleProjectButtonSelected() {
+ IProject project = chooseProject();
+ if (project == null) {
+ return;
+ }
+
+ String projectName = project.getName();
+ m_project.setText(projectName);
+ }
+
+ /**
+ * Realize a Java Project selection dialog and return the first selected project,
+ * or null if there was none.
+ */
+ protected IProject chooseProject() {
+ IProject[] projects;
+ try {
+ projects= getWorkspaceRoot().getProjects();
+ } catch (Exception e) {
+ projects= new IProject[0];
+ }
+
+ ILabelProvider labelProvider=new LabelProvider() {
+ public String getText(Object obj) {
+ String ret="<unknown>";
+ if (obj instanceof IResource) {
+ ret = ((IResource)obj).getName();
+ }
+ return(ret);
+ }
+ };
+
+ ElementListSelectionDialog dialog= new ElementListSelectionDialog(getShell(), labelProvider);
+ dialog.setTitle("Projects");
+ dialog.setMessage("Select the relevant project");
+ dialog.setElements(projects);
+
+ IProject project = getProject();
+ if (project != null) {
+ dialog.setInitialSelections(new Object[] { project });
+ }
+ if (dialog.open() == Window.OK) {
+ return (IProject) dialog.getFirstResult();
+ }
+ return null;
+ }
+
+ /**
+ * Return the IProject corresponding to the project name in the project name
+ * text field, or null if the text does not match a project name.
+ */
+ protected IProject getProject() {
+ String projectName = m_project.getText().trim();
+ if (projectName.length() < 1) {
+ return null;
+ }
+ return(getWorkspaceRoot().getProject(projectName));
+ }
+
+ /**
+ * Convenience method to get the workspace root.
+ */
+ private IWorkspaceRoot getWorkspaceRoot() {
+ return ResourcesPlugin.getWorkspace().getRoot();
+ }
+
+ /**
+ * @see ILaunchConfigurationTab#isValid(ILaunchConfiguration)
+ */
+ public boolean isValid(ILaunchConfiguration config) {
+ return getErrorMessage() == null;
+ }
+
+ /**
+ * This method validates the page.
+ *
+ */
+ private void validatePage() {
+ setErrorMessage(null);
+ setMessage(null);
+
+ String projectName = m_project.getText().trim();
+ if (projectName.length() == 0) {
+ setErrorMessage("Project name not specified");
+ return;
+ }
+
+ IProject project = getWorkspaceRoot().getProject(projectName);
+ if (!project.exists()) {
+ setErrorMessage("Project '"+projectName+"' does not exist");
+ return;
+ }
+
+ try {
+ String choreographyName = m_choreography.getText().trim();
+ if (choreographyName.length() == 0) {
+ setErrorMessage("Choreography has not been defined");
+ return;
+ }
+ IResource resource = project.findMember(choreographyName);
+ if (resource == null) {
+ setErrorMessage("Could not find choreography '"+choreographyName+"'");
+ } else {
+
+ // TODO: Check is valid choreography model
+ }
+ } catch (Exception e) {
+ }
+ }
+
+ /**
+ * @see ILaunchConfigurationTab#setDefaults(ILaunchConfigurationWorkingCopy)
+ */
+ public void setDefaults(ILaunchConfigurationWorkingCopy config) {
+
+ IResource resource = getContext();
+ if (resource != null) {
+ initializeProject(resource, config);
+ } else {
+ config.setAttribute(MonitorLaunchConfigurationConstants.ATTR_PROJECT_NAME, "");
+ config.setAttribute(MonitorLaunchConfigurationConstants.ATTR_CHOREOGRAPHY_DESCRIPTION, "");
+ }
+ initializeTestAttributes(resource, config);
+ }
+
+ /**
+ * This method identifies the context associated with the
+ * monitor.
+ *
+ * @return The context resource
+ */
+ protected IResource getContext() {
+ IResource ret=null;
+ IWorkbenchPage page =
+ org.eclipse.ui.PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+
+ if (page != null) {
+ ISelection selection = page.getSelection();
+ if (selection instanceof IStructuredSelection) {
+ IStructuredSelection ss = (IStructuredSelection)selection;
+ if (!ss.isEmpty()) {
+ Object obj = ss.getFirstElement();
+ if (obj instanceof IResource) {
+ ret = (IResource)obj;
+ }
+ }
+ }
+
+ if (ret == null) {
+ IEditorPart part = page.getActiveEditor();
+ if (part != null) {
+ IEditorInput input = part.getEditorInput();
+ ret =(IResource)input.getAdapter(IResource.class);
+ }
+ }
+ }
+
+ return(ret);
+ }
+
+ /**
+ * This method initializes the project details.
+ *
+ * @param resource The resource
+ * @param config The configuration
+ */
+ protected void initializeProject(IResource resource, ILaunchConfigurationWorkingCopy config) {
+ IProject project = resource.getProject();
+ String name = null;
+ if (project != null && project.exists()) {
+ name = project.getName();
+ }
+ config.setAttribute(MonitorLaunchConfigurationConstants.ATTR_PROJECT_NAME, name);
+ }
+
+ /**
+ * This method initializes the choreography details.
+ *
+ * @param resource The selected resource
+ * @param config The configuration
+ */
+ private void initializeTestAttributes(IResource resource, ILaunchConfigurationWorkingCopy config) {
+ if (resource != null && (resource.getType() == IResource.FOLDER ||
+ (resource.getType() == IResource.FILE &&
+ resource.getFileExtension().equals(
+ org.pi4soa.cdl.CDLDefinitions.CDL_FILE_EXTENSION)))) {
+
+ config.setAttribute(MonitorLaunchConfigurationConstants.ATTR_CHOREOGRAPHY_DESCRIPTION,
+ resource.getProjectRelativePath().toString());
+
+ initializeName(config, resource.getName());
+ }
+ }
+
+ /**
+ * This method initializes the launch configuration name.
+ *
+ * @param config The configuration
+ * @param name The name
+ */
+ private void initializeName(ILaunchConfigurationWorkingCopy config, String name) {
+ if (name == null) {
+ name= "";
+ }
+ if (name.length() > 0) {
+
+ int index = name.lastIndexOf('.');
+ if (index > 0) {
+ name = name.substring(0, index);
+ }
+ name= getLaunchConfigurationDialog().generateName(name);
+ config.rename(name);
+ }
+ }
+
+ /**
+ * @see ILaunchConfigurationTab#getName()
+ */
+ public String getName() {
+ return("Monitor");
+ }
+
+ private Label m_projectLabel=null;
+ private Text m_project=null;
+ private Button m_projectButton=null;
+ private Label m_choreographyLabel=null;
+ private Text m_choreography=null;
+ private Button m_choreographySearch=null;
+}
Added: trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/eclipse/MonitorTabGroup.java
===================================================================
--- trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/eclipse/MonitorTabGroup.java (rev 0)
+++ trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/eclipse/MonitorTabGroup.java 2009-12-05 10:50:50 UTC (rev 98)
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2005-8 Pi4 Technologies Ltd
+ *
+ * Licensed 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.
+ *
+ *
+ * Change History:
+ * 17 Jan, 2008 : Initial version created by gary
+ */
+package org.pi4soa.monitor.eclipse;
+
+import org.eclipse.debug.ui.AbstractLaunchConfigurationTabGroup;
+import org.eclipse.debug.ui.CommonTab;
+import org.eclipse.debug.ui.ILaunchConfigurationDialog;
+import org.eclipse.debug.ui.ILaunchConfigurationTab;
+import org.eclipse.jdt.debug.ui.launchConfigurations.JavaJRETab;
+
+/**
+ * This class represents the UI tab group for the Scenario Test
+ * launcher.
+ */
+public class MonitorTabGroup extends
+ AbstractLaunchConfigurationTabGroup {
+
+ /**
+ * The default constructor for the scenario type tab group.
+ */
+ public MonitorTabGroup() {
+ }
+
+ /**
+ * This method creates the tabs for the scenario test launch
+ * configuration.
+ *
+ * @param dialog The launch configuration dialog
+ * @param mode The mode
+ */
+ public void createTabs(ILaunchConfigurationDialog dialog, String mode) {
+ ILaunchConfigurationTab[] tabs = new ILaunchConfigurationTab[] {
+ new MonitorMainTab(),
+ new JavaJRETab(),
+ new CommonTab()
+ };
+ setTabs(tabs);
+ }
+}
Added: trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/ChannelJPanel.java
===================================================================
--- trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/ChannelJPanel.java (rev 0)
+++ trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/ChannelJPanel.java 2009-12-05 10:50:50 UTC (rev 98)
@@ -0,0 +1,556 @@
+/*
+ * Copyright 2005-8 Pi4 Technologies Ltd
+ *
+ * Licensed 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.
+ *
+ *
+ * Change History:
+ * 16 Jan, 2008 : Initial version created by martin
+ */
+package org.pi4soa.monitor.ui;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Component;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.logging.Logger;
+
+import javax.swing.Icon;
+import javax.swing.ImageIcon;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTree;
+import javax.swing.event.TreeSelectionListener;
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.DefaultTreeCellRenderer;
+import javax.swing.tree.DefaultTreeModel;
+import javax.swing.tree.TreePath;
+import javax.swing.tree.TreeSelectionModel;
+
+import org.pi4soa.service.Identity;
+import org.pi4soa.service.correlator.CorrelationSession;
+
+
+/**
+ * The left hand pane contains a tree whose root is the
+ * choreography, and whose leaves are channels and transactions.
+ *
+ * Selecting a channel filters the exchange events list (or should
+ * do).
+ */
+public class ChannelJPanel extends JPanel{
+
+ public final static String UNEXPECTED_MESSAGES_NAME = "Unexpected Messages";
+ public final static String ERROR_NAME="Errors";
+ public final static String WARNING_NAME="Warnings";
+ public final static String INFORMATION_NAME="Information";
+
+ private static Logger logger = Logger.getLogger("org.pi4soa.monitor.ui");
+
+ JTree tree = null;
+ TreeSelectionListener listener = null;
+ JScrollPane treeView = null;
+
+ ImageIcon channelLeafIcon = null;
+ ImageIcon channelOpenIcon = null;
+ ImageIcon channelClosedIcon = null;
+ ImageIcon channelEmptyIcon = null;
+ ImageIcon errorsLeafIcon = null;
+ ImageIcon unexpectedLeafIcon = null;
+ ImageIcon warningsLeafIcon = null;
+ ImageIcon issuesOpenIcon = null;
+ ImageIcon issuesClosedIcon = null;
+ ImageIcon issuesEmptyIcon = null;
+ ImageIcon txnLeafIcon = null;
+ ImageIcon txnOpenIcon = null;
+ ImageIcon txnClosedIcon = null;
+ ImageIcon txnEmptyIcon = null;
+
+ // Vector exchangeEvents = null;
+ ExchangeEventsData exchangeEventsData = null;
+
+ DefaultTreeModel treeModel = null;
+ DefaultMutableTreeNode rootNode = null;
+
+ DefaultMutableTreeNode channelRoot = null;
+ DefaultMutableTreeNode issuesRoot = null;
+ DefaultMutableTreeNode errorsRoot = null;
+ DefaultMutableTreeNode warningsRoot = null;
+ DefaultMutableTreeNode unexpectedMessagesRoot = null;
+ DefaultMutableTreeNode sessionRoot = null;
+
+ String sessionRootName = "Sessions";
+ String channelRootName = "Channels";
+ String unexpectedMessagesRootName = UNEXPECTED_MESSAGES_NAME;
+ String errorsRootName = ERROR_NAME;
+ String warningsRootName = WARNING_NAME;
+ String issuesRootName = "Issues";
+
+
+
+ /**
+ * Creates a new ChannelJPanel.
+ *
+ * @param listener The listener for tree selection changes.
+ */
+ public ChannelJPanel(TreeSelectionListener listener){
+
+ this.listener = listener;
+ this.setBackground(Color.white);
+ this.setLayout(new BorderLayout());
+ }
+
+ public ChannelJPanel(ExchangeEventsData eed, TreeSelectionListener listener){
+ this.listener = listener;
+ this.setBackground(Color.white);
+ this.setLayout(new BorderLayout());
+ exchangeEventsData = eed;
+ }
+
+ ////////////////////////////////////////////
+
+ static public String getUnexpectedMessagesName()
+ {
+ return UNEXPECTED_MESSAGES_NAME;
+ }
+
+ static public String getErrorName() {
+ return(ERROR_NAME);
+ }
+
+ static public String getWarningName() {
+ return(WARNING_NAME);
+ }
+
+ static public String getInformationName() {
+ return(INFORMATION_NAME);
+ }
+
+ public void addedSession(CorrelationSession s)
+ {
+ logger.fine("ADD SESSION TO PANEL " + s);
+ logger.fine("rootNote child count is: " + rootNode.getChildCount());
+ String name = ChannelJPanel.getSessionIdentity(s);
+ if (name == null)
+ {
+ name = "Session :" + s.toString().substring(s.getClass().getName().length());
+ }
+ logger.info("ADDING SESSION FOR TXN: " + name);
+
+ addObject(sessionRoot,new ProxyTreeNode(name, s),true);
+ }
+
+ static public String getSessionIdentity(CorrelationSession s)
+ {
+ String identityString = null;
+ java.util.List<Identity> messageIdentityArray = s.getIdentities();
+ if (messageIdentityArray != null)
+ logger.info("sessionIdentArray length is: " + messageIdentityArray.size());
+ else
+ logger.info("messageIdentityArray was null");
+ if(messageIdentityArray == null || messageIdentityArray.size() == 0)
+ {
+ return identityString;
+ } else {
+ Identity firstMessageIdentity = messageIdentityArray.get(0);
+ // messageIdentityString = firstMessageIdentity.toText();
+ String tokens[] = firstMessageIdentity.getTokens();
+ // value
+ Object values_obj[] = firstMessageIdentity.getValues();
+
+ String[] values = new String[values_obj.length];
+
+ for (int values_index=0; values_index < values_obj.length; values_index++)
+ {
+ values[values_index] = values_obj[values_index].toString();
+ if (values_obj[values_index] instanceof String)
+ {
+ values[values_index] = (String)values_obj[values_index];
+ }
+ else if (values_obj[values_index] instanceof java.util.List)
+ {
+ java.util.List list = (java.util.List)values_obj[values_index];
+ values[values_index] = "{";
+ for (int i=0; (i < list.size()); i++ )
+ {
+ values[values_index] += (String)list.get(i);
+ }
+ values[values_index] += "}";
+ } else {
+ logger.severe("Problem creating an identity string, values is of unknown type.");
+ }
+
+ }
+
+ if(tokens == null || values == null)
+ {
+ if(tokens == null)
+ {
+ logger.fine("identity.getTokens() returned null");
+ // messageIdentityString = "null tokens";
+ }
+
+ if(values == null)
+ {
+ logger.fine("identity.getValues() returned null");
+ // messageIdentityString = "null values";
+ }
+
+ identityString = firstMessageIdentity.toString();
+ } else {
+ if(tokens != null && values != null && tokens.length == values.length)
+ {
+ identityString = "";
+ for(int i = 0; i < tokens.length - 1; i++)
+ {
+ identityString += values[i] + " (" + tokens[i] + "), ";
+ }
+ identityString += values[tokens.length - 1] + " (" + tokens[tokens.length - 1]+")";
+ } else {
+ identityString = "tokens/values mismatch";
+ }
+ }
+ }
+
+ return identityString;
+ }
+
+ /**
+ * Adds the channel nodes to the tree, sorted in name order.
+ */
+ public void createAndAddTree(org.pi4soa.cdl.Package choreography){
+ if(tree != null){
+ // remove the current tree ...
+ this.remove(treeView);
+ treeView = null;
+ tree = null;
+ }
+
+ rootNode = new DefaultMutableTreeNode(choreography.getName());
+ if (treeModel == null){
+ treeModel = new DefaultTreeModel(rootNode);
+ treeModel.addTreeModelListener(new MonitorTreeModelListener());
+ }
+
+ createChannelNodes(treeModel, choreography);
+
+ tree = new JTree(treeModel); // instead of rootNode instead of treeModel
+ ChannelTreeCellRenderer renderer = new ChannelTreeCellRenderer();
+
+ if(txnLeafIcon == null) txnLeafIcon = MonitorMainPanel.createImageIcon("icons/txnleaf.png");
+ if(txnOpenIcon == null) txnOpenIcon = MonitorMainPanel.createImageIcon("icons/txnopen.png");
+ if(txnClosedIcon == null) txnClosedIcon = MonitorMainPanel.createImageIcon("icons/txnclosed.png");
+ if(txnEmptyIcon == null) txnEmptyIcon = MonitorMainPanel.createImageIcon("icons/txnempty.png");
+ if(channelLeafIcon == null) channelLeafIcon = MonitorMainPanel.createImageIcon("icons/channelleaf.png");
+ if(channelOpenIcon == null) channelOpenIcon = MonitorMainPanel.createImageIcon("icons/channelopen.png");
+ if(channelClosedIcon == null) channelClosedIcon = MonitorMainPanel.createImageIcon("icons/channelclosed.png");
+ if(channelEmptyIcon == null) channelEmptyIcon = MonitorMainPanel.createImageIcon("icons/channelempty.png");
+ if(errorsLeafIcon == null) errorsLeafIcon = MonitorMainPanel.createImageIcon("icons/errorsleaf.png");
+ if(warningsLeafIcon == null) warningsLeafIcon = MonitorMainPanel.createImageIcon("icons/warningsleaf.png");
+ if(unexpectedLeafIcon == null) unexpectedLeafIcon = MonitorMainPanel.createImageIcon("icons/unexpectedleaf.png");
+ if(issuesOpenIcon == null) issuesOpenIcon = MonitorMainPanel.createImageIcon("icons/issuesopen.png");
+ if(issuesClosedIcon == null) issuesClosedIcon = MonitorMainPanel.createImageIcon("icons/issuesclosed.png");
+ if(issuesEmptyIcon == null) issuesEmptyIcon = MonitorMainPanel.createImageIcon("icons/issuesempty.png");
+
+ tree.setCellRenderer(renderer);
+
+ tree.setRootVisible(false);
+
+ tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
+
+ // Listen for when the selection changes.
+ tree.addTreeSelectionListener(listener);
+
+ treeView = new JScrollPane(this.tree);
+ this.add(treeView, BorderLayout.CENTER);
+
+ // hack.
+ this.revalidate();
+ }
+
+ /**
+ * Adds the channel nodes to the tree, sorted in name order.
+ */
+ private void createChannelNodes(DefaultTreeModel t, org.pi4soa.cdl.Package choreography){
+
+ issuesRoot = addObject(null, issuesRootName);
+ unexpectedMessagesRoot = addObject(issuesRoot,unexpectedMessagesRootName); // was nullChannel
+ errorsRoot = addObject(issuesRoot,errorsRootName); // was nullChannel
+ warningsRoot = addObject(issuesRoot,warningsRootName); // was nullChannel
+
+ sessionRoot = addObject(null,sessionRootName); // was sessionRoot
+
+ logger.fine("createChannelNodes(new)");
+
+ channelRoot = addObject(null,channelRootName); // was channelRoot
+
+ org.pi4soa.cdl.TypeDefinitions typeDefinitions = choreography.getTypeDefinitions();
+ org.eclipse.emf.common.util.EList channelTypes = typeDefinitions.getChannelTypes();
+
+ // we would like to sort the list of channels first
+
+ org.eclipse.emf.common.util.ECollections.sort(channelTypes, new Comparator() {
+ public int compare(Object o1, Object o2) {
+ return ((org.pi4soa.cdl.ChannelType) o1).getName().compareTo(
+ ((org.pi4soa.cdl.ChannelType) o2).getName()
+ );
+ }
+ });
+
+ Iterator listIterator = channelTypes.iterator();
+ while(listIterator.hasNext()){
+ org.pi4soa.cdl.ChannelType channelType = (org.pi4soa.cdl.ChannelType) listIterator.next();
+ ProxyTreeNode node = new ProxyTreeNode(channelType.getName(),
+ channelType);
+ logger.fine("Adding channel type to tree: " + channelType.getName());
+ addObject(channelRoot,node);
+ }
+ }
+
+
+ /** Add child to the currently selected node. */
+ public DefaultMutableTreeNode addObject(Object child) {
+ logger.fine("addObject " + child.toString() + " to child");
+ DefaultMutableTreeNode parentNode = null;
+ TreePath parentPath = tree.getSelectionPath();
+
+ if (parentPath == null) {
+ parentNode = rootNode;
+ } else {
+ parentNode = (DefaultMutableTreeNode)
+ (parentPath.getLastPathComponent());
+ }
+
+ return addObject(parentNode, child, true);
+ }
+
+ public DefaultMutableTreeNode addObject(DefaultMutableTreeNode parent,
+ Object child) {
+ logger.fine("addObject " + child.toString() + " to parent");
+ return addObject(parent, child, false);
+ }
+
+ public DefaultMutableTreeNode addObject(DefaultMutableTreeNode parent,
+ Object child,
+ boolean shouldBeVisible) {
+ logger.fine("addObject " + child.toString() + " to parent with visibility " + shouldBeVisible);
+ DefaultMutableTreeNode childNode =
+ new DefaultMutableTreeNode(child);
+
+ if (parent == null) {
+ parent = rootNode;
+ }
+
+ treeModel.insertNodeInto(childNode, parent,
+ parent.getChildCount());
+
+ //Make sure the user can see the lovely new node.
+ if (shouldBeVisible) {
+ tree.scrollPathToVisible(new TreePath(childNode.getPath()));
+ }
+ return childNode;
+ }
+
+
+ /**
+ * Adds the channel nodes to the tree, sorted in name order.
+ */
+ public void setChannelSelectionOn(boolean channelSelection){
+ if(channelSelection == true){
+ tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
+ }
+ else{
+
+ }
+ }
+
+
+ /**
+ *
+ */
+ public JTree getTree(){
+ return tree;
+ }
+
+
+ /**
+ *
+ */
+ public void redraw(){
+ tree.setSelectionPaths(tree.getSelectionPaths());
+ tree.revalidate();
+ tree.repaint();
+ }
+
+ public class ProxyTreeNode {
+
+ public ProxyTreeNode(String label, Object obj) {
+ m_label = label;
+ m_object = obj;
+ }
+
+ public String getLabel() {
+ return(m_label);
+ }
+
+ public Object getObject() {
+ return(m_object);
+ }
+
+ public String toString() {
+ return(m_label);
+ }
+
+ private String m_label=null;
+ private Object m_object=null;
+ }
+
+ public class ChannelTreeCellRenderer extends DefaultTreeCellRenderer{
+
+ private Color originalTextNonSelectionColor = null;
+ private Color originalTextSelectionColor = null;
+
+ /**
+ *
+ */
+ public Component getTreeCellRendererComponent(JTree tree,
+ Object value,
+ boolean selected,
+ boolean expanded,
+ boolean leaf,
+ int row,
+ boolean hasFocus){
+
+ logger.fine("getTreeCellRendererComponent(" + value.toString() + ")");
+
+ if(originalTextNonSelectionColor == null) originalTextNonSelectionColor = this.getTextNonSelectionColor();
+ if(originalTextSelectionColor == null) originalTextSelectionColor = this.getTextSelectionColor();
+
+ boolean nodeHasErrors = false;
+ boolean nodeHasWarnings = false;
+ boolean nodeHasUnexpectedMessage = false;
+
+ if(leaf == true){
+ if(exchangeEventsData.getHasErrorsForChannel(value.toString()) == true ||
+ exchangeEventsData.getHasErrorsForSession(value.toString())) {
+ nodeHasErrors = true;
+ }
+ else if(exchangeEventsData.getHasWarningsForChannel(value.toString()) == true ||
+ exchangeEventsData.getHasWarningsForSession(value.toString())) {
+ nodeHasWarnings = true;
+ }
+ else if (exchangeEventsData.getHasUnexpectedExchangeEventsForChannel(value.toString()) == true ||
+ exchangeEventsData.getHasUnexpectedExchangeEventsForSession(value.toString())) {
+ nodeHasUnexpectedMessage = true;
+ }
+ }
+ else{
+ //nodeHasErrors = exchangeEventsData.getHasErrors();
+ //nodeHasWarnings = exchangeEventsData.getHasWarnings();
+ //nodeHasUnexpectedMessage = exchangeEventsData.getHasUnexpectedMessages();
+ }
+
+ //
+ // Sets the left panel colors
+ //
+ if(nodeHasErrors == true){
+ logger.fine("hasErrors - dark red");
+ this.setTextNonSelectionColor(Color.red.darker());
+ this.setTextSelectionColor(Color.red.darker());
+ }
+ else if(nodeHasWarnings == true){
+ logger.fine("hasWarnings - orange");
+ this.setTextNonSelectionColor(Color.orange);
+ this.setTextSelectionColor(Color.orange);
+ }
+ else if (nodeHasUnexpectedMessage == true) {
+ logger.fine("hasUnexpectedMessages - red");
+ this.setTextNonSelectionColor(Color.red);
+ this.setTextSelectionColor(Color.red);
+ }
+ else{
+ logger.fine("hasOkay");
+ this.setTextNonSelectionColor(originalTextNonSelectionColor);
+ this.setTextSelectionColor(originalTextSelectionColor);
+ }
+
+ if (value instanceof DefaultMutableTreeNode) {
+ m_lastValue = ((DefaultMutableTreeNode)value).getUserObject();
+ } else {
+ m_lastValue = value;
+ }
+
+ return super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
+ }
+
+ public Icon getOpenIcon() {
+ Icon ret=super.getOpenIcon();
+
+ if (m_lastValue.toString().equals(sessionRootName)) {
+ ret = txnOpenIcon;
+ } else if (m_lastValue.toString().equals(channelRootName)) {
+ ret = channelOpenIcon;
+ } else if (m_lastValue.toString().equals(issuesRootName)) {
+ ret = issuesOpenIcon;
+ }
+
+ logger.info("Returning open icon for "+m_lastValue);
+ return(ret);
+ }
+
+ public Icon getClosedIcon() {
+ Icon ret=super.getClosedIcon();
+
+ if (m_lastValue.toString().equals(sessionRootName)) {
+ ret = txnClosedIcon;
+ } else if (m_lastValue.toString().equals(channelRootName)) {
+ ret = channelClosedIcon;
+ } else if (m_lastValue.toString().equals(issuesRootName)) {
+ ret = issuesClosedIcon;
+ }
+
+ logger.info("Returning closed icon for "+m_lastValue);
+ return(ret);
+ }
+
+ public Icon getLeafIcon() {
+ Icon ret=super.getLeafIcon();
+
+ if (m_lastValue instanceof ProxyTreeNode) {
+ if (((ProxyTreeNode)m_lastValue).getObject() instanceof CorrelationSession) {
+ ret = txnLeafIcon;
+ } else if (((ProxyTreeNode)m_lastValue).getObject()
+ instanceof org.pi4soa.cdl.ChannelType) {
+ ret = channelLeafIcon;
+ }
+ } else if (m_lastValue.toString().equals(sessionRootName)) {
+ ret = txnEmptyIcon;
+ } else if (m_lastValue.toString().equals(channelRootName)) {
+ ret = channelEmptyIcon;
+ } else if (m_lastValue.toString().equals(unexpectedMessagesRootName)) {
+ ret = unexpectedLeafIcon;
+ } else if (m_lastValue.toString().equals(errorsRootName)) {
+ ret = errorsLeafIcon;
+ } else if (m_lastValue.toString().equals(warningsRootName)) {
+ ret = warningsLeafIcon;
+ }
+ logger.info("Returning leaf icon for "+m_lastValue+" of type "+m_lastValue.getClass());
+ return(ret);
+ }
+
+ private Object m_lastValue=null;
+ }
+
+}
+
Added: trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/ExchangeEventWrapper.java
===================================================================
--- trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/ExchangeEventWrapper.java (rev 0)
+++ trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/ExchangeEventWrapper.java 2009-12-05 10:50:50 UTC (rev 98)
@@ -0,0 +1,797 @@
+/*
+ * Copyright 2005-8 Pi4 Technologies Ltd
+ *
+ * Licensed 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.
+ *
+ *
+ * Change History:
+ * 16 Jan, 2008 : Initial version created by martin
+ */
+package org.pi4soa.monitor.ui;
+
+import org.pi4soa.monitor.ExchangeEvent;
+
+import org.pi4soa.cdl.Interaction;
+import org.pi4soa.cdl.RoleType;
+import org.pi4soa.cdl.Variable;
+
+import org.pi4soa.service.Message;
+import org.pi4soa.service.Identity;
+
+import org.pi4soa.service.correlator.CorrelationSession;
+
+import java.io.Serializable;
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+import java.io.ObjectInputStream;
+import java.util.logging.Logger;
+
+
+
+/**
+ *
+ */
+public class ExchangeEventWrapper implements Serializable{
+
+ Integer index = null;
+
+ String realSessionName = null;
+ String sessionName = null;
+ String description = null;
+ String toRoleTypeName = null;
+ String fromRoleTypeName = null;
+ String serviceName=null;
+ String sendVariableString = null;
+ String sendVariableTypeString = null;
+ String messageTypeString = "";
+ String messageTypeNoNamespaceString = "";
+ String operationString = null;
+ String messageValueString = null;
+ String exceptionValueString = null;
+ String messageIdentityString = null;
+ String channelType = null;
+ String correlationSessionString = null;
+
+ // don't serialize this one ...
+ transient private ExchangeEvent exchangeEvent = null;
+
+ String status = null;
+ boolean hasFrozenStatus = false;
+
+ boolean hasSetErrorsAndWarnings = false;
+ boolean isError = false;
+ boolean isWarning = false;
+
+ boolean isErrorMessage=false;
+ boolean isWarningMessage=false;
+ boolean isInformationMessage=false;
+
+ boolean isFault = false;
+ boolean hasSetIsFault = false;
+
+ boolean isRequest;
+
+ boolean isUnexpected = false;
+
+ private static Logger logger = Logger.getLogger("org.pi4soa.monitor.ui");
+
+ public ExchangeEventWrapper(CorrelationSession session,
+ Integer index, String mesgValue, String exception){
+ this.index = index;
+
+ correlationSessionString = (session == null?
+ "<unknown>":session.toString());
+
+ setMessageValue(mesgValue);
+
+ if (messageValueString == null) {
+ messageValueString = "";
+ }
+
+ exceptionValueString = exception;
+
+ messageIdentityString = "";
+ operationString = "";
+ description = "";
+ sendVariableString="";
+
+ setRealSessionName(session);
+ setSessionName(session);
+ }
+
+ /**
+ *
+ */
+ public ExchangeEventWrapper(ExchangeEvent event, Integer index){
+ this.index = index;
+ this.exchangeEvent = event;
+
+ correlationSessionString = (event.getCorrelationSession() == null?
+ "<unknown>":event.getCorrelationSession().toString());
+
+ Message message = exchangeEvent.getMessage();
+ if(message != null){
+
+ if (exchangeEvent.getExchange() != null) {
+ isRequest = (exchangeEvent.getExchange().getAction()
+ == org.pi4soa.cdl.ExchangeActionType.REQUEST);
+ } else {
+ isRequest = message.isRequest();
+ }
+
+ messageTypeString = message.getType();
+
+ messageTypeNoNamespaceString =
+ org.pi4soa.common.xml.NameSpaceUtil.getLocalPart(message.getType());
+
+ }
+ else{
+ logger.fine(">>>> Null message");
+ isRequest = true;
+ }
+
+ setRealSessionName(event.getCorrelationSession());
+ setSessionName(event.getCorrelationSession());
+ setDescription(event);
+ setFromRoleTypeName(event);
+ setToRoleTypeName(event);
+ setSendVariableName(event);
+ setSendVariableTypeName(event);
+ setOperationString(event);
+ setMessageValue(event);
+ setMessageIdentity(event);
+ setChannelType(event);
+ }
+
+ /**
+ *
+ */
+ public Integer getIndex(){ return index; }
+
+
+ /**
+ *
+ */
+ public String getRealSessionName() { return realSessionName; }
+ public String getSessionName() { return sessionName; }
+
+ /**
+ *
+ */
+ public void setRealSessionName(CorrelationSession s){
+
+ if (s == null) {
+ realSessionName = "Session:unknown";
+ } else {
+ realSessionName = "Session:" + s.toString().substring(s.getClass().getName().length());
+ }
+
+ logger.fine("Set real session name in wrapper: " + realSessionName);
+ }
+
+ public void setSessionName(CorrelationSession s){
+
+ if (s == null) {
+ sessionName = "unknown";
+ } else {
+ sessionName = ChannelJPanel.getSessionIdentity(s);
+ }
+
+ logger.fine("Set session name alias in wrapper: " + sessionName);
+ }
+ /**
+ *
+ */
+ public String getDescription(){ return description; }
+
+ /**
+ *
+ */
+ protected void setDescription(ExchangeEvent exchangeEvent){
+ if(exchangeEvent == null || exchangeEvent.getExchange() == null){
+ description = "null exchange";
+ }
+ else{
+ description = exchangeEvent.getExchange().getDescription();
+ if(description != null){
+ String newDescription = description.replaceAll("\\s+", " ");
+ description = newDescription;
+ }
+ else{
+ description = "";
+ }
+ }
+ }
+
+
+ /**
+ *
+ */
+ public String getStatus(){
+ String returnValue = null;
+ if(hasFrozenStatus == true){
+ returnValue = status;
+ } else {
+ if (exchangeEvent == null) {
+ returnValue = "";
+ } else if (exchangeEvent.getChannel() == null) {
+ returnValue = "Unexpected";
+ } else if(exchangeEvent.isExchangeComplete()) {
+ returnValue = "Completed";
+ } else{
+ returnValue = "Initiated";
+ }
+ }
+
+ return returnValue;
+ }
+
+
+ /**
+ *
+ */
+ public void freezeStatus(){
+ status = getStatus();
+ hasFrozenStatus = true;
+ }
+
+
+ /**
+ *
+ */
+ public boolean equals(Object object){
+ boolean result = false;
+
+ if (object != null && object instanceof ExchangeEventWrapper) {
+ ExchangeEventWrapper other = (ExchangeEventWrapper) object;
+ if(other.exchangeEvent != null && this.exchangeEvent != null){
+ if(other.exchangeEvent.equals(this.exchangeEvent)){
+ result = true;
+ }
+ }
+ else{
+ result = other.getDescription().equals(this.getDescription()) &&
+ other.getFromRoleTypeName().equals(this.getFromRoleTypeName()) &&
+ other.getToRoleTypeName().equals(this.getToRoleTypeName()) &&
+ other.getSendVariableName().equals(this.getSendVariableName()) &&
+ other.getOperationString().equals(this.getOperationString()) &&
+ other.getMessageValue().equals(this.getMessageValue()) &&
+ other.getMessageIdentity().equals(this.getMessageIdentity()) &&
+ other.getChannelType().equals(this.getChannelType());
+ }
+
+ }
+
+ return result;
+ }
+
+
+
+ /**
+ *
+ */
+ public String getFromRoleTypeName(){
+ if (exchangeEvent == null || exchangeEvent.getChannel() == null)
+ {
+ return(""); // "Unknown From Role";
+ }
+ if(isRequest){
+ return fromRoleTypeName;
+ }
+ else{
+ return toRoleTypeName;
+ }
+ }
+
+
+ /**
+ *
+ */
+ protected void setFromRoleTypeName(ExchangeEvent exchangeEvent){
+ if(exchangeEvent.getExchange() == null){
+ fromRoleTypeName = ""; //"Unknown From Role";
+ }
+ else{
+ Interaction interaction = exchangeEvent.getExchange().getInteraction();
+ if(interaction != null){
+ RoleType fromRoleType = interaction.getFromRoleType();
+ if(fromRoleType != null){
+ fromRoleTypeName = fromRoleType.getName() != null ? fromRoleType.getName() : "";
+ }
+ else{
+ fromRoleTypeName = ""; //"null fromRoleType";
+ }
+ }
+ else{
+ fromRoleTypeName = ""; //"null interaction";
+ }
+ }
+ }
+
+ protected void setServiceName(String name) {
+ serviceName = name;
+ }
+
+ public String getServiceName() { return serviceName; }
+
+ /**
+ *
+ */
+ public String getToRoleTypeName(){
+ if (exchangeEvent == null || exchangeEvent.getChannel() == null)
+ {
+ return(""); // "Unknown To Role";
+ }
+ if(isRequest){
+ return toRoleTypeName;
+ }
+ else{
+ return fromRoleTypeName;
+ }
+ }
+
+
+ /**
+ *
+ */
+ protected void setToRoleTypeName(ExchangeEvent exchangeEvent){
+ if(exchangeEvent == null || exchangeEvent.getExchange() == null){
+ toRoleTypeName = ""; //"Unknown To Role";
+ }
+ else{
+ Interaction interaction = exchangeEvent.getExchange().getInteraction();
+ if(interaction != null){
+ RoleType toRoleType = interaction.getToRoleType();
+ if(toRoleType != null){
+ toRoleTypeName = toRoleType.getName() != null ? toRoleType.getName() : "";
+ }
+ else{
+ toRoleTypeName = ""; //"null toRoleType";
+ }
+ }
+ else{
+ toRoleTypeName = ""; //"null interaction";
+ }
+ }
+ }
+
+
+ /**
+ *
+ */
+ public String getSendVariableName(){ return sendVariableString; }
+ public String getSendVariableTypeName() { return sendVariableTypeString; }
+
+ /**
+ *
+ */
+ protected void setSendVariableTypeName(ExchangeEvent exchangeEvent)
+ {
+ if(exchangeEvent.getExchange() == null){
+ if (exchangeEvent.getMessage().getType() != null) {
+ String tmp = exchangeEvent.getMessage().getType();
+ sendVariableTypeString = tmp.substring(tmp.indexOf("}")+1);
+ // Need to abberivate after the last "{"
+ } else {
+ sendVariableTypeString = "Unknown type";
+ }
+ }
+ else{
+ Variable sendVariable = exchangeEvent.getExchange().getSendVariable();
+ if(sendVariable != null){
+ //sendVariableString = sendVariable.getName() != null ? sendVariable.getName() : "Type: " + sendVariable.getType().getName();
+ sendVariableTypeString = sendVariable.getType().getName();
+ }
+ }
+ }
+ /**
+ *
+ */
+ protected void setSendVariableName(ExchangeEvent exchangeEvent){
+ if(exchangeEvent.getExchange() == null){
+ if (exchangeEvent.getMessage().getType() != null) {
+ String tmp = exchangeEvent.getMessage().getType();
+ sendVariableString = "None : " + tmp.substring(tmp.indexOf("}")+1);
+ // Need to abberivate after the last "{"
+ } else
+ sendVariableString = "null exchange";
+ }
+ else{
+ Variable sendVariable = exchangeEvent.getExchange().getSendVariable();
+ if(sendVariable != null){
+ //sendVariableString = sendVariable.getName() != null ? sendVariable.getName() : "Type: " + sendVariable.getType().getName();
+ sendVariableString = sendVariable.getName() != null ? sendVariable.getName() : " : " + sendVariable.getType().getName();
+ }
+ else{
+ sendVariableString = "None : " + exchangeEvent.getExchange().getType().getName();
+ //sendVariableString = "null sendVariable";
+ }
+ }
+ }
+
+
+ /**
+ *
+ */
+ public String getOperationString(){ return operationString; }
+
+
+
+ /**
+ *
+ */
+ protected void setOperationString(ExchangeEvent exchangeEvent){
+ if(exchangeEvent.getExchange() == null){
+ operationString = ""; //"Unknown Operation";
+ }
+ Message message = exchangeEvent.getMessage();
+ if(message == null){
+ operationString = ""; //"null message";
+ }
+ else{
+ operationString = message.getOperationName();
+ if(operationString == null){
+ operationString = ""; //"null operation";
+ }
+ }
+ }
+
+ public String getMessageSummary() {
+ String ret="";
+
+ if (exchangeEvent != null) {
+ String op=getOperationString();
+ if (op != null && op.trim().length() > 0) {
+ ret += op+"(";
+ }
+
+ ret += getMessageTypeNoNamespace();
+ if (op != null && op.trim().length() > 0) {
+ ret += ")";
+ }
+ } else {
+ ret = getMessageValue();
+ }
+
+ if (ret != null && ret.length() > 0 &&
+ ret.charAt(0) == '<') {
+ ret = getChannelType()+" ...";
+ }
+
+ return(ret);
+ }
+
+ /**
+ *
+ */
+ public String getMessageValue(){ return messageValueString; }
+
+ public String getExceptionValue() { return exceptionValueString; }
+
+ /**
+ *
+ */
+ protected void setMessageValue(ExchangeEvent exchangeEvent){
+ logger.fine("**** Setting message value");
+ messageValueString = "";
+ Message message = exchangeEvent.getMessage();
+ if(message == null){
+ logger.fine("**** null message");
+ messageValueString = "null message";
+ }
+ else{
+ Serializable messageValue = message.getValue();
+ if(messageValue == null){
+ messageValueString = "null message value";
+ logger.fine("**** null message value");
+ }
+ else{
+ setMessageValue(messageValue.toString());
+ }
+ }
+ }
+
+ protected void setMessageValue(String originalMessageValueString) {
+ logger.fine("**** original message = " + originalMessageValueString);
+
+ logger.fine("**** prettifying");
+
+ messageValueString = XmlPrettyPrinter.prettify(originalMessageValueString);
+
+ logger.fine("**** prettified");
+
+ logger.fine(messageValueString);
+
+ if(messageValueString == null) {
+
+ logger.fine("**** prettified string was null");
+
+ // messageValueString = originalMessageValueString;
+ // messageValueString = "prettyprinting failed";
+ messageValueString = originalMessageValueString.replaceAll("[ \\t]+", " ");
+
+ logger.fine("**** reprettified");
+ logger.fine(messageValueString);
+ }
+ }
+
+
+ /**
+ *
+ */
+ public String getMessageIdentity(){ return messageIdentityString; }
+
+ public String getMessageType() { return messageTypeString; }
+
+ public String getMessageTypeNoNamespace() { return messageTypeNoNamespaceString; }
+
+ /**
+ *
+ */
+ protected void setMessageIdentity(ExchangeEvent exchangeEvent){
+ Message message = exchangeEvent.getMessage();
+ if(message == null){
+ messageIdentityString = "null message";
+ }
+ else{
+ java.util.List<Identity> messageIdentityArray=message.getMessageIdentities();
+ if(messageIdentityArray == null || messageIdentityArray.size() == 0){
+ messageIdentityString = "no identities";
+ }
+ else{
+ Identity firstMessageIdentity = messageIdentityArray.get(0);
+ // messageIdentityString = firstMessageIdentity.toText();
+ String tokens[] = firstMessageIdentity.getTokens();
+ // valu
+ Object values_obj[] = firstMessageIdentity.getValues();
+
+ String[] values = new String[values_obj.length];
+
+ for (int values_index=0; values_index < values_obj.length; values_index++)
+ {
+ values[values_index] = values_obj[values_index].toString();
+ }
+
+ if(tokens == null || values == null){
+ if(tokens == null){
+ logger.fine("identity.getTokens() returned null");
+ // messageIdentityString = "null tokens";
+ }
+
+ if(values == null){
+ logger.fine("identity.getValues() returned null");
+ // messageIdentityString = "null values";
+ }
+
+ messageIdentityString = firstMessageIdentity.toString();
+ }
+ else{
+ if(tokens != null && values != null && tokens.length == values.length){
+ messageIdentityString = "";
+ for(int i = 0; i < tokens.length - 1; i++){
+ messageIdentityString += values[i] + " (" + tokens[i] + "), ";
+ }
+ messageIdentityString += values[tokens.length - 1] + " (" + tokens[tokens.length - 1]+")";
+ }
+ else{
+ messageIdentityString = "tokens/values mismatch";
+ }
+ }
+ }
+ }
+ }
+
+ public void setMessageIdentity(String ident)
+ {
+ messageIdentityString = ident;
+ }
+
+
+ /**
+ *
+ */
+ public boolean isFault(){
+ if(hasSetIsFault == false){
+ if(exchangeEvent != null && exchangeEvent.getExchange() != null){
+ isFault = exchangeEvent.getExchange().isFault();
+ }
+ //else{
+ // isFault = true;
+ //}
+ hasSetIsFault = true;
+ }
+ return isFault;
+ }
+
+
+ /**
+ *
+ */
+ private void setErrorsAndWarnings(){
+ if(hasSetErrorsAndWarnings == false){
+ if(getToRoleTypeName().toLowerCase().matches("exception")){
+ if(getOperationString().toLowerCase().matches("fatal")){
+ isError = true;
+ }
+ else{
+ isWarning = true;
+ }
+ }
+ else if(getFromRoleTypeName().toLowerCase().matches("exception")){
+ if(isFault()){
+ isError = true;
+ }
+ }
+ else{
+ if(exchangeEvent != null && exchangeEvent.getExchange() == null){
+ isUnexpected = true;
+ }
+ else if(isFault()){
+ isWarning = true;
+ }
+
+ // if the session was terminated early. color me red.
+ }
+ hasSetErrorsAndWarnings = true;
+ }
+ }
+
+ public void setErrorMessage(boolean b) {
+ isErrorMessage = b;
+
+ if (b) {
+ channelType = ChannelJPanel.getErrorName();
+ }
+ }
+
+ public boolean isErrorMessage() {
+ return(isErrorMessage);
+ }
+
+ public void setWarningMessage(boolean b) {
+ isWarningMessage = b;
+
+ if (b) {
+ channelType = ChannelJPanel.getWarningName();
+ }
+ }
+
+ public boolean isWarningMessage() {
+ return(isWarningMessage);
+ }
+
+ public void setInformationMessage(boolean b) {
+ isInformationMessage = b;
+
+ if (b) {
+ channelType = ChannelJPanel.getInformationName();
+ }
+ }
+
+ public boolean isInformationMessage() {
+ return(isInformationMessage);
+ }
+
+ /**
+ *
+ */
+ public boolean isError(){
+ if(hasSetErrorsAndWarnings == false){
+ setErrorsAndWarnings();
+ }
+ return(isError || isErrorMessage());
+ }
+
+ public boolean isUnexpected(){
+ return isUnexpected;
+ }
+
+ public void setUnexpected(boolean b){
+ isUnexpected = b;
+ }
+
+ /**
+ *
+ */
+ public boolean isWarning(){
+ if(hasSetErrorsAndWarnings == false){
+ setErrorsAndWarnings();
+ }
+ return(isWarning || isWarningMessage());
+ }
+
+
+ /**
+ *
+ */
+ public String getChannelType(){ return channelType; }
+
+ protected void setChannelType(String ctype) {
+ channelType = ctype;
+ }
+
+ /**
+ *
+ */
+ public String getCorrelationSession(){ return correlationSessionString; }
+
+ /**
+ *
+ */
+ public String toString()
+ {
+ String s = "EXCHANGE EVENT WRAPPER: " +
+ "<sessionName = " + sessionName + ">" +
+ "<realSessionName = " + realSessionName + ">" +
+ "<serviceName = " + serviceName + ">" +
+ "<description = " + description + ">" +
+ "<toRoleTypeName = " + toRoleTypeName + ">" +
+ "<fromRoleTypeName = " + fromRoleTypeName + ">" +
+ "<sendVariableString = " + sendVariableString + ">" +
+ "<operationString = " + operationString + ">" +
+ "<messageValueString = " + messageValueString + ">" +
+ "<messageIdentityString = " + messageIdentityString + ">" +
+ "<channelType = " + channelType + ">" +
+ "<correlationSessionString = " + correlationSessionString + ">" +
+ "<status = " + status + ">" +
+ "<hasFrozenStatus = " + hasFrozenStatus + ">" +
+ "<hasSetErrorsAndWarnings = " + hasSetErrorsAndWarnings + ">" +
+ "<isError = " + isError + ">" +
+ "<isWarning = " + isWarning + ">" +
+ "<isFault = " + isFault + ">" +
+ "<hasSetIsFault = " + hasSetIsFault + ">" +
+ "<isRequest = " + isRequest + ">" +
+ "<isUnexpected = " + isUnexpected + ">";
+
+ return s;
+ }
+ /**
+ *
+ */
+
+ protected void setChannelType(ExchangeEvent exchangeEvent){
+ if(exchangeEvent.getChannel() == null){
+ channelType = ChannelJPanel.getUnexpectedMessagesName();
+ }
+ else{
+ channelType = exchangeEvent.getExchange().getInteraction().getChannelVariable().getType().getName(); // Not getType
+ logger.fine("Channel type name: " + channelType);
+ logger.fine("Channel service type name: " + exchangeEvent.getChannel().getServiceType());
+ logger.fine("Channel instance name: " + exchangeEvent.getChannel().getName());
+ logger.fine("OR Channel instance name: " + exchangeEvent.getExchange().getInteraction().getChannelVariable().getType().getName());
+ }
+ }
+
+ // Serialization support
+
+
+ /**
+ *
+ */
+ private void writeObject(ObjectOutputStream out) throws IOException{
+ // to make sure that this has been set.
+ boolean myIsError = this.isError();
+ boolean myIsFault = this.isFault();
+ freezeStatus();
+ out.defaultWriteObject();
+ }
+
+
+ /**
+ *
+ */
+ private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException{
+ in.defaultReadObject();
+ }
+
+}
Added: trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/ExchangeEventsData.java
===================================================================
--- trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/ExchangeEventsData.java (rev 0)
+++ trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/ExchangeEventsData.java 2009-12-05 10:50:50 UTC (rev 98)
@@ -0,0 +1,449 @@
+/*
+ * Copyright 2005-8 Pi4 Technologies Ltd
+ *
+ * Licensed 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.
+ *
+ *
+ * Change History:
+ * 16 Jan, 2008 : Initial version created by martin
+ */
+package org.pi4soa.monitor.ui;
+
+import java.util.Vector;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.logging.Logger;
+
+import java.io.FileOutputStream;
+import java.io.ObjectOutputStream;
+
+import java.io.FileInputStream;
+import java.io.ObjectInputStream;
+
+
+import org.pi4soa.monitor.ExchangeEvent;
+import org.pi4soa.service.correlator.CorrelationSession;
+
+/**
+ *
+ */
+public class ExchangeEventsData{
+
+ private static Logger logger = Logger.getLogger("org.pi4soa.monitor.ui");
+
+ Vector exchangeEvents = null;
+
+ Vector warningAndErrorExchangeEvents = null;
+
+ Vector errorExchangeEvents = null;
+
+ Vector warningExchangeEvents = null;
+
+ Vector unexpectedExchangeEvents = null;
+
+ Hashtable exchangeEventsByChannelTable = null;
+
+ Hashtable exchangeEventsBySessionTable = null;
+
+ Hashtable sessionHasErrorsTable = null;
+ Hashtable sessionHasWarningsTable = null;
+ Hashtable sessionHasUnexpectedMessagesTable = null;
+ Hashtable channelHasErrorsTable = null;
+ Hashtable channelHasWarningsTable = null;
+ Hashtable channelHasUnexpectedMessagesTable = null;
+
+ Hashtable exchangeEventToWrapperMap = null;
+
+ boolean hasErrors = false;
+
+ boolean hasWarnings = false;
+
+ boolean hasUnexpectedMessages = false;
+
+ /**
+ *
+ */
+ public ExchangeEventsData(){
+ exchangeEvents = new Vector();
+ warningAndErrorExchangeEvents = new Vector();
+ errorExchangeEvents = new Vector();
+ warningExchangeEvents = new Vector();
+ unexpectedExchangeEvents = new Vector();
+ exchangeEventsByChannelTable = new Hashtable();
+ exchangeEventsBySessionTable = new Hashtable();
+ exchangeEventToWrapperMap = new Hashtable();
+ channelHasErrorsTable = new Hashtable();
+ channelHasUnexpectedMessagesTable = new Hashtable();
+ channelHasWarningsTable = new Hashtable();
+ sessionHasErrorsTable = new Hashtable();
+ sessionHasUnexpectedMessagesTable = new Hashtable();
+ sessionHasWarningsTable = new Hashtable();
+ }
+
+
+
+ /**
+ *
+ */
+ public void clear(){
+ exchangeEvents.clear();
+ exchangeEventsByChannelTable.clear();
+ exchangeEventsBySessionTable.clear();
+ exchangeEventToWrapperMap.clear();
+ warningAndErrorExchangeEvents.clear();
+ errorExchangeEvents.clear();
+ warningExchangeEvents.clear();
+ unexpectedExchangeEvents.clear();
+ channelHasErrorsTable.clear();
+ channelHasWarningsTable.clear();
+ channelHasUnexpectedMessagesTable.clear();
+ sessionHasErrorsTable.clear();
+ sessionHasWarningsTable.clear();
+ sessionHasUnexpectedMessagesTable.clear();
+ hasErrors = false;
+ hasWarnings = false;
+ }
+
+
+ /**
+ *
+ */
+ public boolean exportEvents(String path){
+ try{
+ FileOutputStream fileOutputStream = new FileOutputStream(path);
+ ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
+ objectOutputStream.writeObject(exchangeEvents);
+ objectOutputStream.close();
+ }
+ catch(Exception e){
+ logger.severe("Exception: " + e);
+ return false;
+ }
+
+ return true;
+ }
+
+
+
+ /**
+ *
+ */
+ public boolean importEvents(String path){
+ clear();
+
+ Vector v = null;
+
+ try{
+ FileInputStream fileInputStream = new FileInputStream(path);
+ ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
+ v = (Vector) objectInputStream.readObject();
+ objectInputStream.close();
+ }
+ catch(Exception e){
+ logger.severe("Exception: " + e);
+ return false;
+ }
+
+ Iterator iterator = v.iterator();
+ int i = 0;
+ while(iterator.hasNext()){
+ ExchangeEventWrapper wrapper = (ExchangeEventWrapper) iterator.next();
+
+ logger.fine("Getting wrapper message value");
+
+ String wrapperMessageValue = wrapper.getMessageValue();
+
+ logger.fine("Imported event wrapper message value = " + wrapperMessageValue);
+
+ Integer key = new Integer(i);
+ i++;
+ exchangeEventToWrapperMap.put(key, wrapper);
+ addExchangeEvent(wrapper);
+ }
+
+ return true;
+ }
+
+
+
+
+ /**
+ *
+ */
+ public ExchangeEventWrapper createExchangeEventWrapper(ExchangeEvent exchangeEvent){
+ ExchangeEventWrapper wrapper=null;
+
+ logger.fine(">>>> creating new wrapper");
+ wrapper = new ExchangeEventWrapper(exchangeEvent, new Integer(exchangeEvents.size()));
+ logger.fine(">>>> created new wrapper");
+
+ java.util.List list=(java.util.List)
+ exchangeEventToWrapperMap.get(exchangeEvent);
+
+ if (list == null) {
+ list = new java.util.Vector();
+ exchangeEventToWrapperMap.put(exchangeEvent, list);
+ logger.fine("Added new list for map entry: "+exchangeEvent);
+ }
+
+ list.add(wrapper);
+
+ return wrapper;
+ }
+
+ public ExchangeEventWrapper matchExchangeEventWrapper(ExchangeEvent exchangeEvent){
+ logger.info("getExchangeEventWrapper for " + exchangeEvent);
+ logger.fine(">>>> looking for pre-existing wrapper for " + exchangeEvent);
+
+ java.util.List list=
+ (java.util.List)exchangeEventToWrapperMap.get(exchangeEvent);
+
+ ExchangeEventWrapper wrapper=null;
+
+ if (list != null && list.size() > 0) {
+ wrapper = (ExchangeEventWrapper)list.remove(0);
+
+ if (list.size() == 0) {
+ exchangeEventToWrapperMap.remove(exchangeEvent);
+
+ logger.fine("Cleaned up map entry for: "+exchangeEvent);
+ }
+ }
+
+ if(wrapper == null){
+ logger.severe(">>>> Failed to find existing wrapper: "+exchangeEvent);
+ }
+ else{
+ logger.fine(">>>> found old wrapper");
+
+ // Remove from map
+ exchangeEventToWrapperMap.remove(exchangeEvent);
+ }
+
+ return wrapper;
+ }
+
+ public ExchangeEventWrapper errorExchangeEventWrapper(ExchangeEvent exchangeEvent){
+ ExchangeEventWrapper wrapper=null;
+
+ logger.fine(">>>> creating new error wrapper");
+ wrapper = new ExchangeEventWrapper(exchangeEvent, new Integer(exchangeEvents.size()));
+ logger.fine(">>>> created new error wrapper");
+
+ return wrapper;
+ }
+
+ public ExchangeEventWrapper simpleWrapper(CorrelationSession session,
+ String text, String exception) {
+ ExchangeEventWrapper wrapper=null;
+
+ logger.fine(">>>> creating new empty wrapper");
+ wrapper = new ExchangeEventWrapper(session,
+ new Integer(exchangeEvents.size()), text, exception);
+ logger.fine(">>>> created new empty wrapper");
+
+ return wrapper;
+ }
+
+ /**
+ *
+ */
+ public void addExchangeEvent(ExchangeEventWrapper wrapper){
+
+ String channelType = wrapper.getChannelType();
+ String sessionName = wrapper.getSessionName();
+
+ Vector exchangeEventsByChannel = (Vector) exchangeEventsByChannelTable.get(channelType);
+ Vector exchangeEventsBySession = (Vector) exchangeEventsBySessionTable.get(sessionName);
+
+
+ if(exchangeEventsByChannel == null){
+ exchangeEventsByChannel = new Vector();
+ }
+ logger.info("addExchangeEvent for CHANNEL TYPE: " + channelType);
+ exchangeEventsByChannel.add(wrapper);
+
+ if (exchangeEventsBySession == null){
+ exchangeEventsBySession = new Vector();
+ }
+ logger.info("addExchangeEvent for SESSION: " + sessionName);
+ exchangeEventsBySession.add(wrapper);
+
+ // is this necessary if we already had an entry?
+ exchangeEventsByChannelTable.put(channelType, exchangeEventsByChannel);
+ exchangeEventsBySessionTable.put(sessionName, exchangeEventsBySession);
+
+ exchangeEvents.add(wrapper);
+
+ logger.fine(">>>> added to exchange events list. size = " + exchangeEvents.size());
+
+ // OLD fault handling.
+ // if(wrapper.isFault() == true){
+ // channelHasErrorsTable.put(channelType, new Boolean(true));
+ // hasErrors = true;
+ // }
+
+ // NEW fault handling.
+logger.warning("Checking if error....");
+ if(wrapper.isWarning() == true || wrapper.isError() == true || wrapper.isUnexpected() == true){
+ // channelHasErrorsTable.put(channelType, new Boolean(true));
+ // hasErrors = true;
+
+ warningAndErrorExchangeEvents.add(wrapper);
+
+ if (wrapper.isError() == true) {
+ errorExchangeEvents.add(wrapper);
+logger.warning("RECORD ERROR channel="+channelType);
+ channelHasErrorsTable.put(channelType, new Boolean(true));
+ sessionHasErrorsTable.put(sessionName, new Boolean(true));
+ hasErrors = true;
+ } else if(wrapper.isWarning() == true){
+ warningExchangeEvents.add(wrapper);
+ channelHasWarningsTable.put(channelType, new Boolean(true));
+ sessionHasWarningsTable.put(sessionName, new Boolean(true));
+logger.warning("RECORD WARNING channel="+channelType);
+ hasWarnings = true;
+ } else if (wrapper.isUnexpected() == true) {
+ unexpectedExchangeEvents.add(wrapper);
+ channelHasUnexpectedMessagesTable.put(channelType, new Boolean(true));
+ sessionHasUnexpectedMessagesTable.put(sessionName, new Boolean(true));
+ hasUnexpectedMessages = true;
+ logger.info("ADDED UNEXPECTED WRAPPER TO ExchangeEventData for channelType " + channelType);
+ }
+logger.warning("Checked");
+ }
+ }
+
+
+ /**
+ *
+ */
+ public ExchangeEventWrapper getWrapper(int i){ return (ExchangeEventWrapper) exchangeEvents.elementAt(i); }
+
+
+
+ /**
+ *
+ */
+ public Vector getExchangeEventsForChannel(String channel){
+ return (Vector) exchangeEventsByChannelTable.get(channel);
+ }
+
+ public Vector getExchangeEventsForSession(String session) {
+ return (Vector)exchangeEventsBySessionTable.get(session);
+ }
+
+
+ /**
+ *
+ */
+ public Vector getExchangeEvents(){ return exchangeEvents; }
+
+ /**
+ *
+ */
+ public Vector getWarningAndErrorExchangeEvents(){ return warningAndErrorExchangeEvents; }
+
+ /**
+ *
+ */
+ public Vector getErrorExchangeEvents(){ return errorExchangeEvents; }
+
+ /**
+ *
+ */
+ public Vector getWarningExchangeEvents(){ return warningExchangeEvents; }
+
+ /**
+ *
+ */
+ public Vector getUnexpectedExchangeEvents() { return unexpectedExchangeEvents; }
+
+ /**
+ *
+ */
+ public boolean getHasUnexpectedExchangeEventsForChannel(String channel){
+ if(hasUnexpectedMessages == true){
+ Boolean hasUnexpectedMessagesForChannel = (Boolean) channelHasUnexpectedMessagesTable.get(channel);
+ if (hasUnexpectedMessagesForChannel != null) return true;
+ }
+ return false;
+ }
+
+ public boolean getHasUnexpectedExchangeEventsForSession(String session){
+ if(hasUnexpectedMessages == true){
+ Boolean hasUnexpectedMessagesForSession = (Boolean) sessionHasUnexpectedMessagesTable.get(session);
+ if (hasUnexpectedMessagesForSession != null) return true;
+ }
+ return false;
+ }
+
+ /**
+ *
+ */
+ public boolean getHasErrorsForChannel(String channel){
+ if(hasErrors == true){
+ Boolean hasErrorsForChannel = (Boolean) channelHasErrorsTable.get(channel);
+ if (hasErrorsForChannel != null) return true;
+ }
+ return false;
+ }
+
+ public boolean getHasErrorsForSession(String session){
+ if(hasErrors == true){
+ Boolean hasErrorsForSession = (Boolean) sessionHasErrorsTable.get(session);
+ if (hasErrorsForSession != null) return true;
+ }
+ return false;
+ }
+
+ /**
+ *
+ */
+ public boolean getHasWarningsForChannel(String channel){
+ if(hasWarnings == true){
+ Boolean hasWarningsForChannel = (Boolean) channelHasWarningsTable.get(channel);
+ if (hasWarningsForChannel != null) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public boolean getHasWarningsForSession(String session){
+ if(hasWarnings == true){
+ Boolean hasWarningsForSession = (Boolean) sessionHasWarningsTable.get(session);
+ if (hasWarningsForSession != null) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+
+ /**
+ *
+ */
+ public boolean getHasUnexpectedMessages(){ return hasUnexpectedMessages; }
+ /**
+ *
+ */
+ public boolean getHasErrors(){ return hasErrors; }
+
+
+ /**
+ *
+ */
+ public boolean getHasWarnings(){ return hasWarnings; }
+
+}
Added: trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/Monitor.java
===================================================================
--- trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/Monitor.java (rev 0)
+++ trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/Monitor.java 2009-12-05 10:50:50 UTC (rev 98)
@@ -0,0 +1,502 @@
+/*
+ * Copyright 2005-8 Pi4 Technologies Ltd
+ *
+ * Licensed 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.
+ *
+ *
+ * Change History:
+ * 16 Jan, 2008 : Initial version created by martin
+ */
+package org.pi4soa.monitor.ui;
+
+import javax.swing.*;
+
+import java.awt.BorderLayout;
+
+import java.io.IOException;
+import java.util.logging.Logger;
+
+import org.pi4soa.service.correlator.CorrelationSession;
+import org.pi4soa.monitor.CorrelationManagerListener;
+import org.pi4soa.monitor.TxnMonitor;
+import org.pi4soa.monitor.ExchangeEvent;
+
+/**
+ * Monitor user interface class.
+ */
+public class Monitor extends JApplet implements CorrelationManagerListener /* , TreeSelectionListener */{
+
+ private static final long serialVersionUID = -4323114698930604980L;
+
+ private static Logger logger = Logger.getLogger("org.pi4soa.monitor.ui");
+
+ static final int NEW_FRAME_WIDTH = 800;
+ static final int NEW_FRAME_HEIGHT = 600;
+
+ MonitorMainPanel smPanel = null;
+
+ String choreographyPath = null;
+
+ org.pi4soa.cdl.Package choreography = null;
+
+ TxnMonitor txnMonitor = null;
+
+ ExchangeEventsData exchangeEventsData = null;
+
+ boolean isMonitoring = false;
+ boolean choreographyProvided = false;
+
+ /**
+ * Initialisation.
+ */
+ public Monitor(boolean choreoProvided) {
+
+ exchangeEventsData = new ExchangeEventsData();
+
+ smPanel = new MonitorMainPanel(exchangeEventsData, choreoProvided);
+
+ this.getContentPane().setLayout(new BorderLayout());
+ this.getContentPane().add(smPanel, BorderLayout.CENTER);
+
+ smPanel.setApplet(this);
+ }
+
+
+ /**
+ * Initialisation.
+ */
+ public void init() {
+ // hack to get around system event queue check - which doesn't work, of course
+ this.getRootPane().putClientProperty("defeatSystemEventQueueCheck", Boolean.TRUE);
+ }
+
+
+ /**
+ * Returns info about the acceptable parameters
+ */
+ public String[][] getParameterInfo()
+ {
+ String pinfo[][] = {
+ // actual parameters might include
+ // ip address, directories, colors
+ // etc.
+
+ // properties should be used for
+ // most stuff
+
+ {"parameter1", "String", "A String."},
+ {"parameter2", "String", "Another String."},
+ {"parameter3", "integer", "An integer."},
+ };
+
+ return pinfo;
+ }
+
+ /**
+ *
+ */
+ public static void main(String args[]){
+ Monitor monitor = new Monitor(args.length > 0);
+ JFrame jFrame = new JFrame("Choreography Monitor");
+ jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ jFrame.getContentPane().setLayout(new BorderLayout());
+ jFrame.getContentPane().add(monitor, BorderLayout.CENTER);
+ monitor.init();
+
+ jFrame.setIconImage(MonitorMainPanel.createImageIcon("icons/monitor.png").getImage());
+
+ jFrame.setSize(NEW_FRAME_WIDTH, NEW_FRAME_HEIGHT);
+
+ java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
+ java.awt.Dimension frameSize = jFrame.getSize();
+ if (frameSize.height > screenSize.height) {
+ frameSize.height = screenSize.height;
+ }
+ if (frameSize.width > screenSize.width) {
+ frameSize.width = screenSize.width;
+ }
+ jFrame.setLocation( (screenSize.width - frameSize.width) / 2,
+ (screenSize.height - frameSize.height) / 2);
+ jFrame.setVisible(true);
+
+ if(args.length > 0){
+ if(monitor.loadChoreography(args[0])){
+ monitor.startMonitoring();
+ } else {
+ System.exit(1);
+ }
+ }
+ }
+
+ //////////////////////////
+
+
+ /**
+ *
+ */
+ public boolean isMonitoring(){ return isMonitoring; }
+
+ public boolean isChoreographyLoaded() { return choreography!=null; }
+
+ /**
+ *
+ */
+ public void setIsMonitoring(boolean isMonitoring){ this.isMonitoring = isMonitoring; }
+
+ public void close() {
+ this.destroy();
+ System.exit(0);
+ }
+
+ /**
+ *
+ */
+ public boolean loadChoreography(String choreographyPath){
+
+ logger.info("Loading " + choreographyPath);
+ smPanel.setStatus("Loading " + choreographyPath);
+
+ // try and read the new one ...
+ org.pi4soa.cdl.Package newChoreography = null;
+
+ try{
+ newChoreography = org.pi4soa.cdl.CDLManager.load(choreographyPath);
+ }
+ catch(IOException e){
+ logger.severe("Exception: " + e);
+ smPanel.setStatus("Failed to load " + choreographyPath);
+
+ JOptionPane.showMessageDialog(null,
+ "Failed to load "+choreographyPath,
+ "Error", JOptionPane.ERROR_MESSAGE);
+
+ return false;
+ }
+
+ // ok, we were successful ...
+ if(this.choreographyPath != null){
+ if(this.isMonitoring() == true){
+ // stop monitoring
+ }
+
+ exchangeEventsData.clear();
+ }
+
+ this.choreographyPath = choreographyPath;
+ this.choreography = newChoreography;
+
+ // tell the panel we loaded a new choreography ...
+ smPanel.loadedChoreography(choreography);
+
+ return true;
+ }
+
+
+ /**
+ *
+ */
+ public boolean startMonitoring(){
+
+ logger.info("Starting monitoring");
+
+ if(this.isMonitoring() == true){
+ logger.info("Already monitoring");
+ return false;
+ }
+
+ if(this.choreography == null){
+ logger.info("No choreography to monitor");
+ return false;
+ }
+
+ smPanel.setStatus("Trying to monitor " + choreography.getName());
+ logger.info("Trying to monitor " + choreography.getName());
+
+ try{
+ this.txnMonitor = TxnMonitor.getInstance(choreographyPath);
+ this.txnMonitor.addCorrelationManagerListener(this);
+ }
+ catch(Exception e){
+ // hack
+ logger.severe("Exception while trying to monitor choreography " + e);
+
+ JOptionPane.showMessageDialog(null,
+ "Failed to initialize monitor: "+e.getLocalizedMessage(),
+ "Error", JOptionPane.ERROR_MESSAGE);
+ }
+
+ logger.fine("Past txnMonitor calls");
+
+ this.setIsMonitoring(true);
+
+ // tell the panel
+ smPanel.startedMonitoring();
+
+ return true;
+ }
+
+
+ /**
+ *
+ */
+ public boolean stopMonitoring(){
+ if(this.isMonitoring() == false){
+ logger.info("Not monitoring");
+ return false;
+ }
+
+ this.txnMonitor.removeCorrelationManagerListener(this);
+
+ try{
+ this.txnMonitor.unmonitor(this.choreography);
+ }
+ catch(Exception e){
+ logger.severe("Exception: " + e);
+ return false;
+ }
+
+ this.setIsMonitoring(false);
+
+ // tell the panel
+ smPanel.stoppedMonitoring();
+
+ return true;
+ }
+
+
+ /**
+ *
+ */
+ public boolean importEvents(String path){
+ boolean result = exchangeEventsData.importEvents(path);
+ smPanel.importedEvents();
+ return result;
+ }
+
+
+ /**
+ *
+ */
+ public boolean exportEvents(String path){
+ return exchangeEventsData.exportEvents(path);
+ //
+ // try{
+ // FileOutputStream fileOutputStream = new FileOutputStream(path);
+ // ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
+ // objectOutputStream.writeObject(exchangeEvents);
+ // objectOutputStream.close();
+ // }
+ // catch(Exception e){
+ // System.err.println("Exception: " + e);
+ // return false;
+ // }
+ //
+ // return true;
+ }
+
+
+ // CorrelationManagerListener interface
+
+ /**
+ * This method indicates that a correlation session has
+ * started.
+ *
+ * @param session The correlation session
+ */
+ public void correlationSessionStarted(CorrelationSession session){
+ logger.info(">>>> CORRELATION SESSION STARTED: " + session );
+
+ // TO DO: Need to add something to the sessionPanel at this point.
+ ChannelJPanel cp = smPanel.getChannelPanel();
+ cp.addedSession(session);
+ }
+
+
+ /**
+ * This method indicates that a correlation session has
+ * finished.
+ *
+ * @param session The correlation session
+ */
+ public void correlationSessionFinished(CorrelationSession session){
+ logger.info(">>>> CORRELATION SESSION FINSIHED: " + session);
+ smPanel.getChannelPanel().addedSession(session);
+ // TO DO: Need to change colour for the same session item in the session Panel
+ }
+
+
+ /**
+ * A new exchange event has been added to a correlation session.
+ *
+ * @param exchangeEvent The exchange event.
+ */
+ public void exchangeEventAdded(ExchangeEvent exchangeEvent){
+ logger.fine(">>>> ADDING EXCHANGE EVENT" + exchangeEvent);
+ // System.err.println(">>>> Adding exchange event");
+ // System.err.println(">>>> Getting correlation session");
+ CorrelationSession session = exchangeEvent.getCorrelationSession();
+ logger.fine("Identity for new exchange is: " + ChannelJPanel.getSessionIdentity(exchangeEvent.getCorrelationSession()));
+ // System.err.println(">>>> Getting wrapper");
+ ExchangeEventWrapper wrapper = exchangeEventsData.createExchangeEventWrapper(exchangeEvent);
+ // System.err.println(">>>> Adding to data");
+ exchangeEventsData.addExchangeEvent(wrapper);
+ // System.err.println(">>>> updating smPanel");
+ smPanel.addedExchangeEvent(wrapper);
+ logger.fine(">>>> ADDED EXCHANGE EVENT FOR SESSION: " + session);
+ }
+
+
+ /**
+ * An exchange event has been updated.
+ *
+ * @param exchangeEvent The exchange event.
+ */
+ public void exchangeEventUpdated(ExchangeEvent exchangeEvent){
+ ExchangeEventWrapper wrapper = exchangeEventsData.matchExchangeEventWrapper(exchangeEvent);
+ logger.fine("Identity for updated exchange is: " + ChannelJPanel.getSessionIdentity(exchangeEvent.getCorrelationSession()));
+ smPanel.updatedExchangeEvent(wrapper);
+ }
+
+ /**
+ * An unexpcted exchange event has occured
+ *
+ * @param exchangeEvent. The exchange event.
+ * @param serviceName The service reporting the error
+ */
+ public void unexpectedExchangeEventAdded(ExchangeEvent exchangeEvent,
+ String serviceName)
+ {
+ logger.info(">>>> unexpectedExchangeEventAdded");
+
+ //CorrelationSession session = exchangeEvent.getCorrelationSession();
+ String ident = null;
+
+ if (exchangeEvent.getCorrelationSession() != null) {
+ ident = ChannelJPanel.getSessionIdentity(exchangeEvent.getCorrelationSession());
+ }
+
+ logger.info("Identity for unexpected is: " + ident);
+ ExchangeEventWrapper wrapper = exchangeEventsData.errorExchangeEventWrapper(exchangeEvent);
+ wrapper.setUnexpected(true);
+ wrapper.setMessageIdentity(ident);
+ wrapper.setServiceName(serviceName);
+ exchangeEventsData.addExchangeEvent(wrapper);
+ smPanel.addedUnexpectedExchangeEvent(wrapper);
+
+ logger.fine("<<<< unexpectedExchangeEventAdded");
+ }
+
+ /**
+ * An error occurred related to the specified correlation
+ * session.
+ *
+ * @param session The correlation session
+ * @param mesg The error message
+ * @param exception The optional exception
+ * @param serviceName The service reporting the error
+ */
+ public void error(CorrelationSession session, String mesg,
+ String exception, String serviceName) {
+ logger.info(">>>> error");
+
+ //CorrelationSession session = exchangeEvent.getCorrelationSession();
+ String ident = null;
+
+ if (session != null) {
+ ident = ChannelJPanel.getSessionIdentity(session);
+ }
+
+ logger.info("Identity for unexpected is: " + ident);
+ ExchangeEventWrapper wrapper =
+ exchangeEventsData.simpleWrapper(session, mesg,
+ exception);
+ wrapper.setErrorMessage(true);
+ wrapper.setMessageIdentity(ident);
+ wrapper.setChannelType(ChannelJPanel.getErrorName());
+ wrapper.setServiceName(serviceName);
+ exchangeEventsData.addExchangeEvent(wrapper);
+ smPanel.addedErrorEvent(wrapper);
+
+ logger.fine("<<<< error");
+ }
+
+ /**
+ * A warning occurred related to the specified correlation
+ * session.
+ *
+ * @param session The correlation session
+ * @param mesg The warning message
+ * @param exception The optional exception
+ * @param serviceName The service reporting the warning
+ */
+ public void warning(CorrelationSession session, String mesg,
+ String exception, String serviceName) {
+ logger.info(">>>> warning");
+
+ //CorrelationSession session = exchangeEvent.getCorrelationSession();
+ String ident = null;
+
+ if (session != null) {
+ ident = ChannelJPanel.getSessionIdentity(session);
+ }
+
+ logger.info("Identity for unexpected is: " + ident);
+ ExchangeEventWrapper wrapper =
+ exchangeEventsData.simpleWrapper(session, mesg,
+ exception);
+ wrapper.setWarningMessage(true);
+ wrapper.setMessageIdentity(ident);
+ wrapper.setChannelType(ChannelJPanel.getWarningName());
+ wrapper.setServiceName(serviceName);
+ exchangeEventsData.addExchangeEvent(wrapper);
+ smPanel.addedErrorEvent(wrapper);
+
+ logger.fine("<<<< warning");
+ }
+
+ /**
+ * An information event occurred related to the specified correlation
+ * session.
+ *
+ * @param session The correlation session
+ * @param mesg The information message
+ * @param serviceName The service reporting the information
+ */
+ public void information(CorrelationSession session, String mesg,
+ String serviceName) {
+ logger.info(">>>> information");
+
+ //CorrelationSession session = exchangeEvent.getCorrelationSession();
+ String ident = null;
+
+ if (session != null) {
+ ident = ChannelJPanel.getSessionIdentity(session);
+ }
+
+ logger.info("Identity for unexpected is: " + ident);
+ ExchangeEventWrapper wrapper =
+ exchangeEventsData.simpleWrapper(session, mesg, null);
+ wrapper.setInformationMessage(true);
+ wrapper.setMessageIdentity(ident);
+ wrapper.setChannelType(ChannelJPanel.getInformationName());
+ wrapper.setServiceName(serviceName);
+ exchangeEventsData.addExchangeEvent(wrapper);
+ smPanel.addedErrorEvent(wrapper);
+
+ logger.fine("<<<< information");
+ }
+
+
+} // End of Applet
+
+// EOF
Added: trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/MonitorExchangeEvent.java
===================================================================
--- trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/MonitorExchangeEvent.java (rev 0)
+++ trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/MonitorExchangeEvent.java 2009-12-05 10:50:50 UTC (rev 98)
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2005-8 Pi4 Technologies Ltd
+ *
+ * Licensed 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.
+ *
+ *
+ * Change History:
+ * 16 Jan, 2008 : Initial version created by martin
+ */
+package org.pi4soa.monitor.ui;
+
+
+import java.util.Date;
+
+import org.pi4soa.cdl.ExchangeDetails;
+import org.pi4soa.service.Channel;
+import org.pi4soa.cdl.ExchangeActionType;
+
+/**
+ * Convenience class for representing an exchange, and providing
+ * convenient access to data for display.
+ */
+public class MonitorExchangeEvent {
+
+ Date initiatedDate = null;
+ Date completedDate = null;
+
+ Channel channel = null;
+ ExchangeDetails exchangeDetails = null;
+
+ /**
+ *
+ */
+ public MonitorExchangeEvent(Channel channel, ExchangeDetails exchangeDetails){
+ this.channel = channel;
+ this.exchangeDetails = exchangeDetails;
+ }
+
+ /**
+ *
+ */
+ public String getChannelName(){
+ return channel.getName();
+ }
+
+ /**
+ *
+ */
+ public String getAction(){
+ if(exchangeDetails.getAction() == ExchangeActionType.REQUEST) return "Request";
+ else return "Response";
+ }
+
+
+ /**
+ *
+ */
+ public String getName(){
+ return exchangeDetails.getName();
+ }
+
+
+ /**
+ *
+ */
+ public String getDescription(){
+ return exchangeDetails.getDescription();
+ }
+
+
+ /**
+ *
+ */
+ public Date getInitiatedDate(){
+ return initiatedDate;
+ }
+
+
+ /**
+ *
+ */
+ public Date getCompletedDate(){
+ return completedDate;
+ }
+
+
+ /**
+ *
+ */
+ public String getStatus(){
+ if(completedDate != null) return "Completed";
+ else return "Initiated";
+ }
+
+
+ /**
+ *
+ */
+ public int hashCode(){
+ return exchangeDetails.hashCode();
+ }
+
+
+ /**
+ *
+ */
+ public boolean equals(Object object){
+ boolean result = false;
+
+ if(object instanceof MonitorExchangeEvent){
+ MonitorExchangeEvent other = (MonitorExchangeEvent) object;
+
+ if(other.exchangeDetails == this.exchangeDetails &&
+ other.getChannelName().equals(this.getChannelName())){
+ /* other.getCorrelationSession() == m_session) { */
+ result = true;
+ }
+ }
+
+ return result;
+ }
+
+
+} // End of class
Added: trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/MonitorFileFilter.java
===================================================================
--- trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/MonitorFileFilter.java (rev 0)
+++ trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/MonitorFileFilter.java 2009-12-05 10:50:50 UTC (rev 98)
@@ -0,0 +1,253 @@
+/*
+ * Copyright 2005-8 Pi4 Technologies Ltd
+ *
+ * Licensed 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.
+ *
+ *
+ * Change History:
+ * 16 Jan, 2008 : Initial version created by martin
+ */
+package org.pi4soa.monitor.ui;
+
+import java.io.File;
+import java.util.Hashtable;
+import java.util.Enumeration;
+import javax.swing.filechooser.*;
+
+/**
+ * A convenience implementation of FileFilter that filters out
+ * all files except for those type extensions that it knows about.
+ *
+ * Extensions are of the type ".foo", which is typically found on
+ * Windows and Unix boxes, but not on Macinthosh. Case is ignored.
+ *
+ * Example - create a new filter that filerts out all files
+ * but gif and jpg image files:
+ *
+ * JFileChooser chooser = new JFileChooser();
+ * ExampleFileFilter filter = new ExampleFileFilter(
+ * new String{"gif", "jpg"}, "JPEG & GIF Images")
+ * chooser.addChoosableFileFilter(filter);
+ * chooser.showOpenDialog(this);
+ *
+ * @version 1.9 04/23/99
+ * @author Jeff Dinkins
+ */
+public class MonitorFileFilter extends FileFilter {
+
+ //private static String TYPE_UNKNOWN = "Type Unknown";
+ //private static String HIDDEN_FILE = "Hidden File";
+
+ private Hashtable filters = null;
+ private String description = null;
+ private String fullDescription = null;
+ private boolean useExtensionsInDescription = true;
+
+ /**
+ * Creates a file filter. If no filters are added, then all
+ * files are accepted.
+ *
+ * @see #addExtension
+ */
+ public MonitorFileFilter() {
+ this.filters = new Hashtable();
+ }
+
+ /**
+ * Creates a file filter that accepts files with the given extension.
+ * Example: new ExampleFileFilter("jpg");
+ *
+ * @see #addExtension
+ */
+ public MonitorFileFilter(String extension) {
+ this(extension,null);
+ }
+
+ /**
+ * Creates a file filter that accepts the given file type.
+ * Example: new ExampleFileFilter("jpg", "JPEG Image Images");
+ *
+ * Note that the "." before the extension is not needed. If
+ * provided, it will be ignored.
+ *
+ * @see #addExtension
+ */
+ public MonitorFileFilter(String extension, String description) {
+ this();
+ if(extension!=null) addExtension(extension);
+ if(description!=null) setDescription(description);
+ }
+
+ /**
+ * Creates a file filter from the given string array.
+ * Example: new ExampleFileFilter(String {"gif", "jpg"});
+ *
+ * Note that the "." before the extension is not needed adn
+ * will be ignored.
+ *
+ * @see #addExtension
+ */
+ public MonitorFileFilter(String[] filters) {
+ this(filters, null);
+ }
+
+ /**
+ * Creates a file filter from the given string array and description.
+ * Example: new ExampleFileFilter(String {"gif", "jpg"}, "Gif and JPG Images");
+ *
+ * Note that the "." before the extension is not needed and will be ignored.
+ *
+ * @see #addExtension
+ */
+ public MonitorFileFilter(String[] filters, String description) {
+ this();
+ for (int i = 0; i < filters.length; i++) {
+ // add filters one by one
+ addExtension(filters[i]);
+ }
+ if(description!=null) setDescription(description);
+ }
+
+ /**
+ * Return true if this file should be shown in the directory pane,
+ * false if it shouldn't.
+ *
+ * Files that begin with "." are ignored.
+ *
+ * @see #getExtension
+ * @see FileFilter#accepts
+ */
+ public boolean accept(File f) {
+ if(f != null) {
+ if(f.isDirectory()) {
+ return true;
+ }
+ String extension = getExtension(f);
+ if(extension != null && filters.get(getExtension(f)) != null) {
+ return true;
+ };
+ }
+ return false;
+ }
+
+ /**
+ * Return the extension portion of the file's name .
+ *
+ * @see #getExtension
+ * @see FileFilter#accept
+ */
+ public String getExtension(File f) {
+ if(f != null) {
+ String filename = f.getName();
+ int i = filename.lastIndexOf('.');
+ if(i>0 && i<filename.length()-1) {
+ return filename.substring(i+1).toLowerCase();
+ };
+ }
+ return null;
+ }
+
+ /**
+ * Adds a filetype "dot" extension to filter against.
+ *
+ * For example: the following code will create a filter that filters
+ * out all files except those that end in ".jpg" and ".tif":
+ *
+ * ExampleFileFilter filter = new ExampleFileFilter();
+ * filter.addExtension("jpg");
+ * filter.addExtension("tif");
+ *
+ * Note that the "." before the extension is not needed and will be ignored.
+ */
+ public void addExtension(String extension) {
+ if(filters == null) {
+ filters = new Hashtable(5);
+ }
+ filters.put(extension.toLowerCase(), this);
+ fullDescription = null;
+ }
+
+
+ /**
+ * Returns the human readable description of this filter. For
+ * example: "JPEG and GIF Image Files (*.jpg, *.gif)"
+ *
+ * @see setDescription
+ * @see setExtensionListInDescription
+ * @see isExtensionListInDescription
+ * @see FileFilter#getDescription
+ */
+ public String getDescription() {
+ if(fullDescription == null) {
+ if(description == null || isExtensionListInDescription()) {
+ fullDescription = description==null ? "(" : description + " (";
+ // build the description from the extension list
+ Enumeration extensions = filters.keys();
+ if(extensions != null) {
+ fullDescription += "." + (String) extensions.nextElement();
+ while (extensions.hasMoreElements()) {
+ fullDescription += ", " + (String) extensions.nextElement();
+ }
+ }
+ fullDescription += ")";
+ } else {
+ fullDescription = description;
+ }
+ }
+ return fullDescription;
+ }
+
+ /**
+ * Sets the human readable description of this filter. For
+ * example: filter.setDescription("Gif and JPG Images");
+ *
+ * @see setDescription
+ * @see setExtensionListInDescription
+ * @see isExtensionListInDescription
+ */
+ public void setDescription(String description) {
+ this.description = description;
+ fullDescription = null;
+ }
+
+ /**
+ * Determines whether the extension list (.jpg, .gif, etc) should
+ * show up in the human readable description.
+ *
+ * Only relevent if a description was provided in the constructor
+ * or using setDescription();
+ *
+ * @see getDescription
+ * @see setDescription
+ * @see isExtensionListInDescription
+ */
+ public void setExtensionListInDescription(boolean b) {
+ useExtensionsInDescription = b;
+ fullDescription = null;
+ }
+
+ /**
+ * Returns whether the extension list (.jpg, .gif, etc) should
+ * show up in the human readable description.
+ *
+ * Only relevent if a description was provided in the constructor
+ * or using setDescription();
+ *
+ * @see getDescription
+ * @see setDescription
+ * @see setExtensionListInDescription
+ */
+ public boolean isExtensionListInDescription() {
+ return useExtensionsInDescription;
+ }
+}
Added: trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/MonitorMainPanel.java
===================================================================
--- trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/MonitorMainPanel.java (rev 0)
+++ trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/MonitorMainPanel.java 2009-12-05 10:50:50 UTC (rev 98)
@@ -0,0 +1,1038 @@
+/*
+ * Copyright 2005-8 Pi4 Technologies Ltd
+ *
+ * Licensed 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.
+ *
+ *
+ * Change History:
+ * 16 Jan, 2008 : Initial version created by martin
+ */
+package org.pi4soa.monitor.ui;
+
+import java.awt.Component;
+
+import java.util.Vector;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.Comparator;
+import java.util.Hashtable;
+import java.util.logging.Logger;
+
+import javax.swing.JTree;
+import javax.swing.JTable;
+import javax.swing.JScrollPane;
+import javax.swing.JLabel;
+import javax.swing.JSplitPane;
+import javax.swing.JPanel;
+import javax.swing.ImageIcon;
+import javax.swing.JTextArea;
+import javax.swing.JEditorPane;
+
+import javax.swing.ListSelectionModel;
+import javax.swing.SpringLayout;
+import javax.swing.JCheckBox;
+//import javax.swing.JPopupMenu;
+import javax.swing.JComboBox;
+
+import javax.swing.event.TreeSelectionEvent;
+import javax.swing.event.ListSelectionEvent;
+
+import javax.swing.event.ListSelectionListener;
+
+import javax.swing.tree.TreeSelectionModel;
+import javax.swing.event.TreeSelectionListener;
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.DefaultTreeCellRenderer;
+
+import javax.swing.table.AbstractTableModel;
+import javax.swing.table.TableCellRenderer;
+
+import java.awt.BorderLayout;
+import java.awt.FlowLayout;
+import java.awt.Dimension;
+import java.awt.Color;
+
+import java.awt.event.ItemListener;
+import java.awt.event.ItemEvent;
+
+import java.awt.event.ActionListener;
+import java.awt.event.ActionEvent;
+
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+
+import java.io.StringWriter;
+import java.io.StringReader;
+
+//import org.pi4soa.cdl.ExchangeDetails;
+import org.pi4soa.service.correlator.CorrelationSession;
+import org.pi4soa.cdl.ExchangeActionType;
+import org.pi4soa.monitor.ExchangeEvent;
+
+import org.pi4soa.monitor.ui.table.TableSorter;
+
+/**
+ * This is the main user interface for the swing monitor.
+ *
+ * It comprises a three-panel display, listing Channels, Exchange
+ * Events, and Exchange Event Details.
+ *
+ * @author Martin Redington
+ */
+public class MonitorMainPanel extends JPanel{
+
+ private static Logger logger = Logger.getLogger("org.pi4soa.monitor.ui");
+
+ // Vector exchangeEvents = null;
+ ExchangeEventsData exchangeEventsData = null;
+
+ MonitorMenuBar menuBar =null;
+
+ ControlPanel controlPanel = null;
+
+ ChannelJPanel channelPanel = null;
+ StatusPanel statusPanel = null;
+
+ ExchangeEventsTableModel exchangeEventsTableModel = null;
+ TableSorter sorter = null;
+
+ String choreographyName = null;
+
+ ExchangeJPanel exchangePanel = null;
+
+ public static final Comparator INTEGER_COMPARATOR = new Comparator() {
+ public int compare(Object o1, Object o2) {
+ return ((Integer) o1).intValue() - ((Integer) o2).intValue();
+ }
+ };
+
+ /**
+ * Constructor.
+ */
+ public MonitorMainPanel(ExchangeEventsData exchangeEventsData,
+ boolean choreoProvided){
+
+ this.menuBar = new MonitorMenuBar(choreoProvided);
+
+ this.exchangeEventsData = exchangeEventsData;
+
+ this.setLayout(new BorderLayout());
+ this.add(menuBar, BorderLayout.PAGE_START);
+
+ JPanel layoutPanel = new JPanel();
+ layoutPanel.setLayout(new BorderLayout());
+
+ controlPanel = new ControlPanel();
+ layoutPanel.add(controlPanel, BorderLayout.PAGE_START);
+
+ MessageJPanel exchangeDetailPanel = null;
+
+ if(true){
+ exchangeDetailPanel = new MessageJPanel(true);
+ }
+
+ exchangeDetailPanel.setPreferredSize(new Dimension(600, 100));
+ exchangeDetailPanel.setMinimumSize(new Dimension(400, 100));
+
+ exchangePanel = new ExchangeJPanel(exchangeDetailPanel);
+ exchangePanel.setPreferredSize(new Dimension(600, 350));
+ exchangePanel.setMinimumSize(new Dimension(400, 200));
+
+ channelPanel = new ChannelJPanel(this.exchangeEventsData,exchangeEventsTableModel);
+ channelPanel.setPreferredSize(new Dimension(200, 580));
+ channelPanel.setMinimumSize(new Dimension(180, 400));
+
+ statusPanel = new StatusPanel();
+
+
+ JSplitPane otherPanel = new JSplitPane(JSplitPane.VERTICAL_SPLIT, exchangePanel, exchangeDetailPanel);
+ JSplitPane mainPanel = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, channelPanel, otherPanel);
+ layoutPanel.add(mainPanel, BorderLayout.CENTER);
+ layoutPanel.add(statusPanel, BorderLayout.SOUTH);
+
+ this.add(layoutPanel, BorderLayout.CENTER);
+ }
+
+ ////////////////////////////////////////////////////////////
+
+ /** Returns the Channel Panel **/
+ public ChannelJPanel getChannelPanel()
+ {
+ return channelPanel;
+ }
+
+ /** Returns an ImageIcon, or null if the path was invalid. */
+ protected static ImageIcon createImageIcon(String path) {
+ java.net.URL imgURL = MonitorMainPanel.class.getResource(path);
+ if (imgURL != null) {
+ return new ImageIcon(imgURL);
+ } else {
+ System.err.println("Couldn't find file: " + path);
+ return null;
+ }
+ }
+
+ ////////////////////////////////////////////////////////////
+
+ /**
+ *
+ */
+ public void loadedChoreography(org.pi4soa.cdl.Package choreography){
+ channelPanel.createAndAddTree(choreography);
+ exchangeEventsTableModel.fireTableDataChanged();
+ menuBar.loadedChoreography();
+ choreographyName = choreography.getName();
+ setStatus("Loaded " + choreographyName);
+ }
+
+ ////////////////////////////////////////////////////////////
+
+ /**
+ *
+ */
+ public void startedMonitoring(){
+ menuBar.startedMonitoring();
+ setStatus("Monitoring " + choreographyName);
+ }
+
+ ////////////////////////////////////////////////////////////
+
+ /**
+ *
+ */
+ public void stoppedMonitoring(){
+ menuBar.stoppedMonitoring();
+ setStatus("Stopped monitoring " + choreographyName);
+ }
+
+ ////////////////////////////////////////////////////////////
+
+ /**
+ *
+ */
+ public void importedEvents(){
+ exchangeEventsTableModel.cancelFiltering();
+ exchangeEventsTableModel.fireTableDataChanged();
+ }
+
+ ////////////////////////////////////////////////////////////
+
+ /**
+ * Can't remember what this is for.
+ */
+ public void setApplet(Monitor applet) {
+ // ui.setApplet(applet);
+ menuBar.setMonitor(applet);
+ }
+
+
+
+ ////////////////////////////////////////////
+
+ /**
+ * Called by the SwingMonitor when a new exchange event occurs.
+ *
+ * The event will already have been added to the vector or
+ * exchange events.
+ */
+ public void addedExchangeEvent(ExchangeEventWrapper wrapper){
+ logger.fine(">>>> addedExchangeEvent");
+
+ String selectedChannelName = (String) exchangeEventsTableModel.getSelectedChannelName();
+ logger.fine("channel is: " + selectedChannelName);
+
+ // we are trying to fix the flickering updates here ...
+ if(selectedChannelName == null || wrapper.getChannelType().equals(selectedChannelName)){
+ logger.fine("fix flickering ...");
+ int index = -1;
+ if((index = exchangeEventsTableModel.indexOfExchangeEventWrapperInFilteredList(wrapper)) != -1){
+ logger.fine("inner ...");
+ // This might not work when we hack the table ...
+ // exchangeEventsTableModel.fireTableRowsInserted(index, index);
+ int newIndex = exchangeEventsTableModel.getRowCount() - 1 - index;
+ exchangeEventsTableModel.fireTableRowsInserted(newIndex, newIndex);
+ }
+ }
+
+ updateTreeIfEventIsFault(wrapper);
+ logger.fine("<<<< addedExchangeEvent");
+ }
+
+ ////////////////////////////////////////////
+
+ /**
+ * Called by the SwingMonitor when a new exchange event occurs.
+ *
+ * The event will already have been added to the vector or
+ * exchange events.
+ */
+ public void addedUnexpectedExchangeEvent(ExchangeEventWrapper wrapper){
+ logger.fine(">>>> addedUnexpectedExchangeEvent");
+ String selectedChannelName = ChannelJPanel.getUnexpectedMessagesName();
+ logger.fine("channel is: " + selectedChannelName);
+ // we are trying to fix the flickering updates here ...
+ if(selectedChannelName == null || wrapper.getChannelType().equals(selectedChannelName)){
+ logger.fine("fix flickering ...");
+ int index = -1;
+ if((index = exchangeEventsTableModel.indexOfExchangeEventWrapperInFilteredList(wrapper)) != -1){
+ // This might not work when we hack the table ...
+ // exchangeEventsTableModel.fireTableRowsInserted(index, index);
+ logger.fine("inner ...");
+ int newIndex = exchangeEventsTableModel.getRowCount() - 1 - index;
+ exchangeEventsTableModel.fireTableRowsInserted(newIndex, newIndex);
+ } else {
+ exchangeEventsTableModel.fireTableDataChanged();
+ }
+ }
+ exchangeEventsTableModel.fireTableDataChanged();
+ updateTreeIfEventIsFault(wrapper);
+
+ logger.fine("<<<< addedUnexpectedExchangeEvent");
+ }
+
+ public void addedErrorEvent(ExchangeEventWrapper wrapper){
+ logger.fine(">>>> addedErrorEvent");
+ String selectedChannelName = ChannelJPanel.getErrorName();
+ logger.fine("channel is: " + selectedChannelName);
+ // we are trying to fix the flickering updates here ...
+ if(selectedChannelName == null || wrapper.getChannelType().equals(selectedChannelName)){
+ logger.fine("fix flickering ...");
+ int index = -1;
+ if((index = exchangeEventsTableModel.indexOfExchangeEventWrapperInFilteredList(wrapper)) != -1){
+ // This might not work when we hack the table ...
+ // exchangeEventsTableModel.fireTableRowsInserted(index, index);
+ logger.fine("inner ...");
+ int newIndex = exchangeEventsTableModel.getRowCount() - 1 - index;
+ exchangeEventsTableModel.fireTableRowsInserted(newIndex, newIndex);
+ } else {
+ exchangeEventsTableModel.fireTableDataChanged();
+ }
+ }
+ exchangeEventsTableModel.fireTableDataChanged();
+ updateTreeIfEventIsFault(wrapper);
+
+ logger.fine("<<<< addedErrorEvent");
+ }
+
+ public void addedWarningEvent(ExchangeEventWrapper wrapper){
+ logger.fine(">>>> addedErrorEvent");
+ String selectedChannelName = ChannelJPanel.getWarningName();
+ logger.fine("channel is: " + selectedChannelName);
+ // we are trying to fix the flickering updates here ...
+ if(selectedChannelName == null || wrapper.getChannelType().equals(selectedChannelName)){
+ logger.fine("fix flickering ...");
+ int index = -1;
+ if((index = exchangeEventsTableModel.indexOfExchangeEventWrapperInFilteredList(wrapper)) != -1){
+ // This might not work when we hack the table ...
+ // exchangeEventsTableModel.fireTableRowsInserted(index, index);
+ logger.fine("inner ...");
+ int newIndex = exchangeEventsTableModel.getRowCount() - 1 - index;
+ exchangeEventsTableModel.fireTableRowsInserted(newIndex, newIndex);
+ } else {
+ exchangeEventsTableModel.fireTableDataChanged();
+ }
+ }
+ exchangeEventsTableModel.fireTableDataChanged();
+ updateTreeIfEventIsFault(wrapper);
+
+ logger.fine("<<<< addedErrorEvent");
+ }
+
+ public void addedInformationEvent(ExchangeEventWrapper wrapper){
+ logger.fine(">>>> addedErrorEvent");
+ String selectedChannelName = ChannelJPanel.getInformationName();
+ logger.fine("channel is: " + selectedChannelName);
+ // we are trying to fix the flickering updates here ...
+ if(selectedChannelName == null || wrapper.getChannelType().equals(selectedChannelName)){
+ logger.fine("fix flickering ...");
+ int index = -1;
+ if((index = exchangeEventsTableModel.indexOfExchangeEventWrapperInFilteredList(wrapper)) != -1){
+ // This might not work when we hack the table ...
+ // exchangeEventsTableModel.fireTableRowsInserted(index, index);
+ logger.fine("inner ...");
+ int newIndex = exchangeEventsTableModel.getRowCount() - 1 - index;
+ exchangeEventsTableModel.fireTableRowsInserted(newIndex, newIndex);
+ } else {
+ exchangeEventsTableModel.fireTableDataChanged();
+ }
+ }
+ exchangeEventsTableModel.fireTableDataChanged();
+ updateTreeIfEventIsFault(wrapper);
+
+ logger.fine("<<<< addedErrorEvent");
+ }
+
+ ////////////////////////////////////////////
+
+ /**
+ * Called by the SwingMonitor when an existing exchange event is updated.
+ *
+ */
+ public void updatedExchangeEvent(ExchangeEventWrapper wrapper){
+
+ String selectedChannelName = (String) exchangeEventsTableModel.getSelectedChannelName();
+
+ // we are trying to fix the flickering updates here ...
+ if(selectedChannelName == null || wrapper.getChannelType().equals(selectedChannelName)){
+ int index = -1;
+ if((index = exchangeEventsTableModel.indexOfExchangeEventWrapperInFilteredList(wrapper)) != -1){
+ int newIndex = exchangeEventsTableModel.getRowCount() - 1 - index;
+ exchangeEventsTableModel.fireTableRowsUpdated(newIndex, newIndex);
+ }
+ }
+
+ updateTreeIfEventIsFault(wrapper);
+ }
+
+ ////////////////////////////////////////////
+
+ /**
+ *
+ */
+ void updateTreeIfEventIsFault(ExchangeEventWrapper wrapper){
+ if(wrapper.isFault()){
+ channelPanel.revalidate();
+ channelPanel.redraw();
+ }
+ }
+
+ ////////////////////////////////////////////
+
+ /**
+ *
+ */
+ public void setStatus(String status){
+ statusPanel.setStatus(status);
+ }
+
+ ////////////////// Inner classes
+
+
+
+ ////////////////////////////////////////////
+
+ /**
+ *
+ */
+
+ ////////////////////////////////////////////
+
+ /**
+ * The upper pane contains a table listing the exchange events.
+ */
+ public class ExchangeJPanel extends JPanel{
+
+ /**
+ *
+ */
+ public ExchangeJPanel(ListSelectionListener listSelectionListener){
+
+ exchangeEventsTableModel = new ExchangeEventsTableModel();
+
+ final ExchangeEventRenderer exchangeEventRenderer = new ExchangeEventRenderer(true);
+
+ JTable table = new JTable() {
+ public TableCellRenderer getCellRenderer(int row, int column) {
+ return exchangeEventRenderer;
+ }
+ };
+ table.setModel(exchangeEventsTableModel);
+
+ table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ table.setColumnSelectionAllowed(false);
+ table.getTableHeader().setReorderingAllowed(false);
+
+ table.getColumnModel().getColumn(0).setPreferredWidth(40);
+ table.getColumnModel().getColumn(3).setPreferredWidth(200);
+ table.getColumnModel().getColumn(4).setPreferredWidth(40);
+
+ ListSelectionModel rowSM = table.getSelectionModel();
+ rowSM.addListSelectionListener(listSelectionListener);
+
+ JScrollPane scrollpane = new JScrollPane(table);
+ this.setLayout(new BorderLayout());
+ this.add(scrollpane, BorderLayout.CENTER);
+ }
+ }
+
+ ////////////////////////////////////////////
+
+ /**
+ *
+ */
+ public class ExchangeEventRenderer extends JLabel implements TableCellRenderer{
+
+ public ExchangeEventRenderer(boolean isBordered) {
+ // this.isBordered = isBordered;
+ setOpaque(true); //MUST do this for background to show up.
+ }
+
+ public Component getTableCellRendererComponent(JTable table, Object object,
+ boolean isSelected, boolean hasFocus,
+ int row, int column) {
+ Integer index = exchangeEventsTableModel.getEventIndexForRow(row);
+
+ ExchangeEventWrapper wrapper = exchangeEventsData.getWrapper(index.intValue());
+
+ logger.fine("RENDERING EXCHANGE:");
+ logger.fine("EXCHANGE IS: " + wrapper);
+
+ if(isSelected){
+ setForeground(table.getSelectionForeground());
+ setBackground(table.getSelectionBackground());
+ }
+ else{
+ setForeground(table.getForeground());
+ setBackground(table.getBackground());
+ }
+
+ if (object != null) {
+ setText(object.toString());
+ } else {
+ setText("");
+ }
+
+ //
+ // Sets the individual exchange color
+ //
+ if(wrapper.isError()){
+ logger.info("isError - setting color dark red");
+ setForeground(Color.red.darker());
+ }
+ else if (wrapper.isUnexpected()){
+ logger.info("isUnexpected - setting color red");
+ setForeground(Color.red);
+ }
+ else if(wrapper.isWarning()){
+ logger.info("isWarning - setting color orange");
+ setForeground(Color.orange);
+ }
+ else if(wrapper.isInformationMessage() && column == 3){
+ logger.info("isInformationMessage - setting color blue");
+ setForeground(Color.blue);
+ }
+ if (wrapper.isUnexpected())
+ setToolTipText("This message, '" + wrapper.getSendVariableTypeName()+ "' is invalid for this choreography.");
+ else
+ setToolTipText(wrapper.getDescription()); //Discussed in the following section
+
+ return this;
+ }
+ }
+
+ ////////////////////////////////////////////
+
+ /**
+ *
+ */
+ public class ExchangeEventsTableModel extends AbstractTableModel implements TreeSelectionListener{
+
+ String selectedChannelName = null;
+
+ Vector filteredExchangeEvents = null;
+
+ Vector emptyVector = new Vector();
+
+ boolean filterByChannel = true;
+
+ ////////////////////////////////////////////
+
+ /**
+ *
+ */
+ public ExchangeEventsTableModel(){
+ this.filteredExchangeEvents = exchangeEventsData.getExchangeEvents();
+ }
+
+ ////////////////////////////////////////////
+
+ public int getColumnCount() {
+ return 5;
+ }
+
+ ////////////////////////////////////////////
+
+ public int getRowCount() {
+ return filteredExchangeEvents.size();
+ }
+
+ ////////////////////////////////////////////
+
+ public String getColumnName(int col) {
+ return getColumnNameSTP(col);
+ }
+
+ ////////////////////////////////////////////
+
+ public String getColumnNameSTP(int col) {
+ if(col == 0){ return "Session Id"; }
+ else if(col == 1){ return "From"; }
+ else if(col == 2){ return "To"; }
+ else if(col == 3){ return "Msg"; }
+ else return "Status";
+ // else return "Priority";
+ }
+
+ ////////////////////////////////////////////
+
+ /**
+ *
+ */
+ public Object getValueAt(int row, int col) {
+ return getValueAtSTP(row, col);
+ }
+
+ ////////////////////////////////////////////
+
+ /**
+ *
+ */
+ public Class getColumnClass(int col) {
+ return Object.class;
+ }
+
+ ////////////////////////////////////////////
+
+ /**
+ *
+ */
+ protected ExchangeEventWrapper getWrapperForRow(int row) {
+ return (ExchangeEventWrapper) filteredExchangeEvents.elementAt(filteredExchangeEvents.size() - (row + 1));
+ }
+
+ ////////////////////////////////////////////
+
+
+ /**
+ *
+ */
+ public Integer getEventIndexForRow(int row) {
+ ExchangeEventWrapper wrapper = getWrapperForRow(row);
+ return wrapper.getIndex();
+ }
+
+ ////////////////////////////////////////////
+
+ /**
+ *
+ */
+ public Object getValueAtSTP(int row, int col) {
+ ExchangeEventWrapper wrapper = getWrapperForRow(row);
+ // ExchangeEvent exchangeEvent = wrapper.getExchangeEvent();
+
+ Object result = null;
+
+ switch(col){
+ case 0:
+ result = wrapper.getMessageIdentity();
+ break;
+ case 1:
+ result="";
+
+ if (wrapper.getFromRoleTypeName() != null &&
+ wrapper.getFromRoleTypeName().trim().length() > 0) {
+ result = wrapper.getFromRoleTypeName();
+ } else if (wrapper.getServiceName() != null) {
+ result = org.pi4soa.common.xml.NameSpaceUtil.getLocalPart(
+ wrapper.getServiceName());
+ }
+ break;
+ case 2:
+ result="";
+
+ if (wrapper.getToRoleTypeName() != null) {
+ result = wrapper.getToRoleTypeName();
+ }
+ break;
+ case 3:
+ result = wrapper.getMessageSummary();
+ break;
+ case 4:
+ result = wrapper.getStatus();
+ break;
+ default:
+ break;
+ }
+
+ return result;
+ }
+
+ ////////////////////////////////////////////
+
+
+ /**
+ *
+ */
+ public void cancelFiltering(){
+ JTree tree = channelPanel.getTree();
+
+ Vector exchangeEvents = exchangeEventsData.getExchangeEvents();
+ if(this.filteredExchangeEvents != exchangeEvents){
+ this.filteredExchangeEvents = exchangeEvents;
+ }
+ selectedChannelName = null;
+ fireTableDataChanged();
+ tree.clearSelection();
+ }
+
+ ////////////////////////////////////////////
+
+ /**
+ *
+ */
+ public void setFilterByChannel(boolean filterByChannel){
+ this.filterByChannel = filterByChannel;
+ JTree tree = channelPanel.getTree();
+
+ if(filterByChannel == true){
+ valueChangedForTree(tree);
+ }
+ else{
+ Vector exchangeEvents = exchangeEventsData.getExchangeEvents();
+ if(this.filteredExchangeEvents != exchangeEvents){
+ this.filteredExchangeEvents = exchangeEvents;
+ }
+ selectedChannelName = null;
+ fireTableDataChanged();
+
+ tree.clearSelection();
+ }
+ }
+
+ ////////////////////////////////////////////////////////////
+
+ /**
+ *
+ */
+ public void setFilterByEventType(int index, ControlPanel controlPanel){
+
+ Vector oldFilteredExchangeEvents = filteredExchangeEvents;
+ Vector newFilteredExchangeEvents = null;
+
+ switch(index){
+ case 0:
+ newFilteredExchangeEvents = exchangeEventsData.getExchangeEvents();
+ break;
+ case 1:
+ newFilteredExchangeEvents = exchangeEventsData.getWarningAndErrorExchangeEvents();
+ break;
+ case 2:
+ newFilteredExchangeEvents = exchangeEventsData.getErrorExchangeEvents();
+ break;
+ case 3:
+ newFilteredExchangeEvents = exchangeEventsData.getWarningExchangeEvents();
+ break;
+ default:
+ // this ain't gonna happen
+ return;
+ //break;
+ }
+ /*
+ if(oldFilteredExchangeEvents != newFilteredExchangeEvents){
+ // we should also reset the enablement of the channel filtering ...
+ if(index == 0){
+ controlPanel.setFilterEventsByChannelIsEnabled(true);
+ }
+ else{
+ controlPanel.setFilterEventsByChannelIsEnabled(false);
+ }
+
+ this.filteredExchangeEvents = newFilteredExchangeEvents;
+ fireTableDataChanged();
+ }
+ */
+ }
+
+ ////////////////////////////////////////////////////////////
+
+ /**
+ * When the channel panel selection changes, we (should) filter
+ * the exchange event list.
+ *
+ * Right now, we simply print the selection name to stderr.
+ */
+ public void valueChanged(TreeSelectionEvent e) {
+
+ logger.fine("valueChanged");
+ if(filterByChannel == false){
+ return;
+ }
+
+ JTree tree = (JTree) e.getSource();
+
+ valueChangedForTree(tree);
+ }
+
+
+ /**
+ *
+ */
+ public void valueChangedForTree(JTree tree) {
+ logger.fine("valueChangedForTree");
+ DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
+
+ if(node == null) {
+ selectedChannelName = null;
+ return;
+ }
+
+ Vector oldFilteredExchangeEvents = filteredExchangeEvents;
+
+ if (node.isLeaf()) {
+ logger.fine("Selected is: " + node.getUserObject().toString());
+ selectedChannelName = (String) node.getUserObject().toString();
+ logger.fine("SelectedChannelName is " + selectedChannelName);
+ Vector newVector = exchangeEventsData.getExchangeEventsForChannel(selectedChannelName);
+
+ // avoid npe's
+ if(newVector == null) {
+ newVector = exchangeEventsData.getExchangeEventsForSession(selectedChannelName);
+ if (newVector == null) {
+ this.filteredExchangeEvents = emptyVector;
+ logger.fine("emptyVector");
+ } else {
+ this.filteredExchangeEvents = newVector;
+ logger.fine("newVector (" + newVector.size() + ")");
+ }
+ } else {
+ this.filteredExchangeEvents = newVector;
+ logger.fine("newVector (" + newVector.size() + ")");
+ }
+
+
+
+ } else {
+ this.filteredExchangeEvents = exchangeEventsData.getExchangeEvents();
+ selectedChannelName = null;
+ }
+
+ if(oldFilteredExchangeEvents != filteredExchangeEvents) {
+ fireTableDataChanged();
+ }
+ }
+
+ ////////////////////////////////////////////////////////////
+
+ /**
+ *
+ */
+ public String getSelectedChannelName(){
+ return selectedChannelName;
+ }
+
+ ////////////////////////////////////////////////////////////
+
+ /**
+ *
+ */
+ public int indexOfExchangeEventWrapperInFilteredList(Object o){
+ return filteredExchangeEvents.indexOf(o);
+ }
+ }
+
+ ////////////////////////////////////////////
+
+ public class StatusPanel extends JPanel{
+ JLabel statusJLabel = new JLabel();
+
+ public StatusPanel(){
+ this.setLayout(new BorderLayout());
+ this.add(statusJLabel, BorderLayout.LINE_START);
+ setStatus("No choreography loaded");
+ }
+
+ public void setStatus(String status){
+ statusJLabel.setText(status);
+ }
+ }
+
+ ////////////////////////////////////////////
+
+ /**
+ *
+ */
+ public class ControlPanel extends JPanel implements ItemListener, ActionListener{
+ //JCheckBox filterEventsByChannelJCheckBox = new JCheckBox("Filter by channel", true);
+
+ Object sessionItems[] = { "All sessions" };
+ //JComboBox sessionPopupMenu = new JComboBox(sessionItems);
+
+ // add the sessions to the jpopup menu ...
+ // JComboBox sessionPopupMenu = new JComboBox(sessionItems);
+
+ //Object showItems[] = { "All Events", "Errors and Warnings", "Errors", "Warnings" };
+ //JComboBox showPopupMenu = new JComboBox(showItems);
+
+ // JComboBox showPopupMenu = new JComboBox("Show: ");
+
+
+
+ /**
+ *
+ */
+ public ControlPanel(){
+ this.setLayout(new BorderLayout());
+ //this.add(filterEventsByChannelJCheckBox, BorderLayout.WEST);
+
+ //filterEventsByChannelJCheckBox.addItemListener(this);
+
+ // this.add(sessionPopupMenu, BorderLayout.CENTER);
+ //JPanel layoutPanel = new JPanel();
+ // layoutPanel.setLayout(new FlowLayout());
+
+ //layoutPanel.add(new JLabel("Show: "));
+ //layoutPanel.add(showPopupMenu);
+ //showPopupMenu.addActionListener(this);
+
+ //this.add(layoutPanel, BorderLayout.EAST);
+ }
+
+
+ /**
+ *
+ *
+ public void itemStateChanged(ItemEvent e) {
+ Object source = e.getItemSelectable();
+ if(source == filterEventsByChannelJCheckBox){
+ boolean filterByChannel = filterEventsByChannelJCheckBox.isSelected();
+ exchangeEventsTableModel.setFilterByChannel(filterByChannel);
+ }
+ }
+ */
+ public void itemStateChanged(ItemEvent e) {}
+
+
+ /**
+ *
+ *
+ public void actionPerformed(ActionEvent e) {
+ Object source = e.getSource();
+ if(source == showPopupMenu){
+ int index = showPopupMenu.getSelectedIndex();
+ exchangeEventsTableModel.setFilterByEventType(index, this);
+ }
+ }
+ */
+ public void actionPerformed(ActionEvent e) {}
+
+
+
+ /**
+ *
+ *
+ public void setFilterEventsByChannelIsEnabled(boolean setFilterEventsByChannelIsEnabled){
+ if(setFilterEventsByChannelIsEnabled == false){
+ filterEventsByChannelJCheckBox.setSelected(false);
+ }
+ filterEventsByChannelJCheckBox.setEnabled(setFilterEventsByChannelIsEnabled);
+ }
+ */
+ public void setFilterEventsByChannelIsEnabled(boolean setFilterEventsByChannelIsEnabled){}
+
+ }
+
+ ////////////////////////////////////////////
+
+ /**
+ *
+ */
+ // public class MessageJPanel extends ExchangeDetailJPanel implements ListSelectionListener{
+ public class MessageJPanel extends JPanel implements ListSelectionListener{
+
+ JTextArea msgTextArea = null;
+
+ /**
+ *
+ */
+ public MessageJPanel(boolean dummy){
+ msgTextArea = new JTextArea();
+ msgTextArea.setEditable(false);
+ JScrollPane scrollpane = new JScrollPane(msgTextArea);
+ this.setLayout(new BorderLayout());
+ this.add(scrollpane, BorderLayout.CENTER);
+ }
+
+
+ public void valueChanged(ListSelectionEvent e) {
+
+ logger.fine(">>>> valueChanged - new message selected");
+
+ //Ignore extra messages.
+ if (e.getValueIsAdjusting()) {
+ logger.fine(">>>> just adjusting - returning early");
+ return;
+ }
+
+ ListSelectionModel lsm = (ListSelectionModel)e.getSource();
+
+ if (lsm.isSelectionEmpty()){
+ logger.fine(">>>> no rows selected");
+ // no rows are selected
+ }
+ else{
+ // selectedRow is selected
+ // harhar. grab the first value ...
+ int selectedRowIndex = lsm.getMinSelectionIndex();
+
+ logger.fine(">>>> selectedIndex = " + selectedRowIndex);
+
+ Integer index = (Integer) exchangeEventsTableModel.getEventIndexForRow(selectedRowIndex);
+
+ // ExchangeEventWrapper wrapper = (ExchangeEventWrapper) exchangeEvents.elementAt(index.intValue());
+ ExchangeEventWrapper wrapper = exchangeEventsData.getWrapper(index.intValue());
+
+
+ // avoid NPE's
+ if(wrapper != null){
+ this.updateDetails(wrapper);
+ }
+ else{
+ logger.fine(">>>> null exception wrapper");
+ }
+ }
+ }
+
+
+ /**
+ *
+ */
+ public void updateDetails(ExchangeEventWrapper exchangeEventWrapper){
+ String text = exchangeEventWrapper.getMessageValue();
+ logger.info("MESSAGE PAYLOAD: " + text);
+
+ try {
+ org.w3c.dom.Node node=org.pi4soa.common.xml.XMLUtils.getNode(text);
+
+ text = org.pi4soa.common.xml.XMLUtils.getText(node, true);
+
+ } catch (Exception e) {
+ //text = "Unable to display message\r\n\r\n"+e;
+ }
+
+ if (exchangeEventWrapper.getExceptionValue() != null) {
+ text += "\r\n\r\nException Trace:\r\n"+
+ exchangeEventWrapper.getExceptionValue();
+ }
+
+ msgTextArea.setText(text);
+ msgTextArea.setBackground(Color.lightGray);
+ msgTextArea.setCaretPosition(0);
+ }
+ }
+
+}
+
+
+// EOF
Added: trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/MonitorMenuBar.java
===================================================================
--- trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/MonitorMenuBar.java (rev 0)
+++ trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/MonitorMenuBar.java 2009-12-05 10:50:50 UTC (rev 98)
@@ -0,0 +1,318 @@
+/*
+ * Copyright 2005-8 Pi4 Technologies Ltd
+ *
+ * Licensed 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.
+ *
+ *
+ * Change History:
+ * 16 Jan, 2008 : Initial version created by martin
+ */
+package org.pi4soa.monitor.ui;
+
+import javax.swing.*;
+import java.awt.event.*;
+import java.io.*;
+
+/**
+ *
+ */
+public class MonitorMenuBar extends JMenuBar {
+
+ MonitorMenuBar menuBar = this;
+
+ static final int NEW_FRAME_WIDTH = 415;
+ static final int NEW_FRAME_HEIGHT = 330;
+
+ JMenu fileMenu = new JMenu("File");
+ JMenu editMenu = new JMenu("Edit");
+ JMenu monitorMenu = new JMenu("Monitor");
+ JMenu helpMenu = new JMenu("Help");
+
+ JMenuItem openItem = new JMenuItem("Open Choreography...");
+ JMenuItem importItem = new JMenuItem("Import Events...");
+ JMenuItem exportItem = new JMenuItem("Export Events...");
+ JMenuItem exitItem = new JMenuItem("Exit");
+
+ JMenuItem undoItem = new JMenuItem("Undo");
+ JMenuItem cutItem = new JMenuItem("Cut");
+ JMenuItem copyItem = new JMenuItem("Copy");
+ JMenuItem pasteItem = new JMenuItem("Paste");
+ JMenuItem selectAllItem = new JMenuItem("Select All");
+ JMenuItem clearItem = new JMenuItem("Clear");
+ JMenuItem preferencesItem = new JMenuItem("Preferences...");
+
+ JMenuItem startMonitoringItem = new JMenuItem("Start Monitoring");
+ JMenuItem stopMonitoringItem = new JMenuItem("Stop Monitoring");
+
+ JMenuItem helpItem = new JMenuItem("About Choreography Monitor");
+
+ Monitor monitor;
+
+ /**
+ *
+ */
+ public MonitorMenuBar(boolean choreoProvided){
+ setUpFileMenu(choreoProvided);
+ setUpEditMenu(choreoProvided);
+ setUpMonitorMenu(choreoProvided);
+ setUpHelpMenu(choreoProvided);
+ }
+
+
+ /**
+ *
+ */
+ private void setUpFileMenu(boolean choreoProvided){
+ openItem.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_O, java.awt.Event.META_MASK));
+ exitItem.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_X, java.awt.Event.META_MASK));
+
+ openItem.setEnabled(true);
+ importItem.setEnabled(true);
+ exportItem.setEnabled(false);
+ exitItem.setEnabled(true);
+
+ openItem.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ JFileChooser chooser = new JFileChooser();
+ chooser.setDialogTitle("Open Choreography");
+
+ // Note: source for ExampleFileFilter can be found in FileChooserDemo,
+ // under the demo/jfc directory in the Java 2 SDK, Standard Edition.
+ MonitorFileFilter filter = new MonitorFileFilter();
+ filter.addExtension("cdm");
+ filter.setDescription("CDM Files");
+ chooser.setFileFilter(filter);
+ int returnVal = chooser.showOpenDialog(menuBar);
+ if(returnVal == JFileChooser.APPROVE_OPTION) {
+ File directory = chooser.getCurrentDirectory();
+ String fileName = chooser.getSelectedFile().getName();
+ File path = new File(directory, fileName);
+ monitor.loadChoreography(path.getPath());
+
+ // now that we've opened, start monitoring should be enabled.
+ }
+ }
+ });
+
+
+ importItem.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ JFileChooser chooser = new JFileChooser();
+ chooser.setDialogTitle("Import Events");
+
+ // Note: source for ExampleFileFilter can be found in FileChooserDemo,
+ // under the demo/jfc directory in the Java 2 SDK, Standard Edition.
+ MonitorFileFilter filter = new MonitorFileFilter();
+ filter.addExtension("data");
+ filter.setDescription("Exchange Events");
+ chooser.setFileFilter(filter);
+ int returnVal = chooser.showOpenDialog(menuBar);
+ if(returnVal == JFileChooser.APPROVE_OPTION) {
+ File directory = chooser.getCurrentDirectory();
+ String fileName = chooser.getSelectedFile().getName();
+ File path = new File(directory, fileName);
+ monitor.importEvents(path.getPath());
+ }
+ }
+ });
+
+
+ exportItem.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ JFileChooser chooser = new JFileChooser();
+ chooser.setDialogTitle("Export Events");
+
+ // Note: source for ExampleFileFilter can be found in FileChooserDemo,
+ // under the demo/jfc directory in the Java 2 SDK, Standard Edition.
+ // ExampleFileFilter filter = new ExampleFileFilter();
+ // filter.addExtension("data");
+ // filter.setDescription("Exchange Events");
+ // chooser.setFileFilter(filter);
+ int returnVal = chooser.showSaveDialog(menuBar);
+ if(returnVal == JFileChooser.APPROVE_OPTION) {
+ File directory = chooser.getCurrentDirectory();
+ String fileName = chooser.getSelectedFile().getName();
+ File path = new File(directory, fileName);
+ monitor.exportEvents(path.getPath());
+ }
+ }
+ });
+
+ exitItem.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ monitor.close();
+ }
+ });
+
+ if (!choreoProvided) {
+ fileMenu.add(openItem);
+ fileMenu.add(new JSeparator());
+ }
+
+ // Disable import/export in this version
+ // If re-enabled, need to sort out message summary
+ // persistence, as it uses the exchange event which
+ // is transient
+ //fileMenu.add(importItem);
+ //fileMenu.add(exportItem);
+ //fileMenu.add(new JSeparator());
+
+ fileMenu.add(exitItem);
+
+ this.add(fileMenu);
+ }
+
+
+ /**
+ *
+ */
+ private void setUpEditMenu(boolean choreoProvided){
+
+ undoItem.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_Z, java.awt.Event.META_MASK));
+ cutItem.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_X, java.awt.Event.META_MASK));
+ copyItem.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_C, java.awt.Event.META_MASK));
+ pasteItem.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_V, java.awt.Event.META_MASK));
+ selectAllItem.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_A, java.awt.Event.META_MASK));
+ preferencesItem.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_P /* was VK_SEMICOLON */,
+ java.awt.Event.META_MASK));
+
+ undoItem.setEnabled(false);
+ cutItem.setEnabled(false);
+ copyItem.setEnabled(false);
+ pasteItem.setEnabled(false);
+ selectAllItem.setEnabled(false);
+ clearItem.setEnabled(false);
+
+ // preferences menu implementation
+ preferencesItem.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ // preferences.setVisible(true);
+ }
+ });
+
+ editMenu.add(undoItem);
+ editMenu.add(new JSeparator());
+ editMenu.add(cutItem);
+ editMenu.add(copyItem);
+ editMenu.add(pasteItem);
+ editMenu.add(selectAllItem);
+ editMenu.add(clearItem);
+ editMenu.add(new JSeparator());
+ editMenu.add(preferencesItem);
+
+ /*
+ this.add(editMenu);
+ */
+ }
+
+
+ /**
+ *
+ */
+ private void setUpMonitorMenu(boolean choreoProvided){
+ startMonitoringItem.setEnabled(false);
+ stopMonitoringItem.setEnabled(false);
+
+ startMonitoringItem.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ monitor.startMonitoring();
+ }
+ });
+
+ stopMonitoringItem.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ monitor.stopMonitoring();
+ }
+ });
+
+ monitorMenu.add(startMonitoringItem);
+ monitorMenu.add(stopMonitoringItem);
+
+ if (!choreoProvided) {
+ this.add(monitorMenu);
+ }
+ }
+
+
+ /**
+ *
+ */
+ private void setUpHelpMenu(boolean choreoProvided){
+ helpItem.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F1, 0));
+ helpMenu.add(helpItem);
+ helpItem.setEnabled(true);
+
+ helpItem.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ JOptionPane.showMessageDialog(null,
+ "pi4soa Choreography Monitor\r\n\r\n" +
+ "Version 1\r\n\r\n" +
+ "(c) Pi4 Technologies Ltd, 2005-8",
+ "About ...", JOptionPane.INFORMATION_MESSAGE);
+ }
+ });
+
+ this.add(helpMenu);
+ }
+
+
+ /**
+ *
+ */
+ public void setMonitor(Monitor monitor) {
+ this.monitor = monitor;
+ }
+
+
+ /**
+ *
+ */
+ public void loadedChoreography(){
+ startMonitoringItem.setEnabled(true);
+ }
+
+
+ /**
+ *
+ */
+ public void startedMonitoring(){
+ openItem.setEnabled(false);
+ importItem.setEnabled(false);
+ exportItem.setEnabled(true);
+ startMonitoringItem.setEnabled(false);
+ stopMonitoringItem.setEnabled(true);
+ }
+
+
+ /**
+ *
+ */
+ public void stoppedMonitoring(){
+ openItem.setEnabled(true);
+ importItem.setEnabled(true);
+ exportItem.setEnabled(true);
+ startMonitoringItem.setEnabled(true);
+ stopMonitoringItem.setEnabled(false);
+ }
+
+ /**
+ *
+ */
+ public void importedEvents(){
+ exportItem.setEnabled(true);
+ }
+
+} // End of class
+
+
+// EOF
Added: trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/MonitorTreeModelListener.java
===================================================================
--- trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/MonitorTreeModelListener.java (rev 0)
+++ trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/MonitorTreeModelListener.java 2009-12-05 10:50:50 UTC (rev 98)
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2005-8 Pi4 Technologies Ltd
+ *
+ * Licensed 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.
+ *
+ *
+ * Change History:
+ * 16 Jan, 2008 : Initial version created by martin
+ */
+package org.pi4soa.monitor.ui;
+
+import java.util.logging.Logger;
+
+import javax.swing.event.TreeModelEvent;
+import javax.swing.event.TreeModelListener;
+import javax.swing.event.TreeSelectionListener;
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.DefaultTreeCellRenderer;
+import javax.swing.tree.DefaultTreeModel;
+import javax.swing.tree.TreeSelectionModel;
+
+import org.pi4soa.service.correlator.CorrelationSession;
+
+
+/**
+ * The left hand pane contains a tree whose root is the
+ * choreography, and whose leaves are channels.
+ *
+ * Selecting a channel filters the exchange events list (or should
+ * do).
+ */
+class MonitorTreeModelListener implements TreeModelListener {
+
+ private static Logger logger = Logger.getLogger("org.pi4soa.monitor.ui");
+
+ public void treeNodesChanged(TreeModelEvent e) {
+ DefaultMutableTreeNode node;
+ node = (DefaultMutableTreeNode)
+ (e.getTreePath().getLastPathComponent());
+
+ /*
+ * If the event lists children, then the changed
+ * node is the child of the node we've already
+ * gotten. Otherwise, the changed node and the
+ * specified node are the same.
+ */
+ try {
+ int index = e.getChildIndices()[0];
+ node = (DefaultMutableTreeNode)
+ (node.getChildAt(index));
+ } catch (NullPointerException exc) {}
+
+ logger.fine(">>> CHANGED NODE");
+ logger.fine("The user has finished editing the node.");
+ logger.fine("New value: " + node.getUserObject());
+ }
+ public void treeNodesInserted(TreeModelEvent e) {
+ logger.fine(">>> INSERTED NODE");
+ }
+ public void treeNodesRemoved(TreeModelEvent e) {
+ logger.fine(">>> REMOVED NODE");
+ }
+ public void treeStructureChanged(TreeModelEvent e) {
+ logger.fine(">>> TREE STRUCTURE CHANGED");
+ }
+}
\ No newline at end of file
Added: trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/SpringUtilities.java
===================================================================
--- trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/SpringUtilities.java (rev 0)
+++ trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/SpringUtilities.java 2009-12-05 10:50:50 UTC (rev 98)
@@ -0,0 +1,213 @@
+/*
+ * Copyright 2005-8 Pi4 Technologies Ltd
+ *
+ * Licensed 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.
+ *
+ *
+ * Change History:
+ * 16 Jan, 2008 : Initial version created by martin
+ */
+package org.pi4soa.monitor.ui;
+
+import javax.swing.*;
+import javax.swing.SpringLayout;
+import java.awt.*;
+
+/**
+ * A 1.4 file that provides utility methods for
+ * creating form- or grid-style layouts with SpringLayout.
+ * These utilities are used by several programs, such as
+ * SpringBox and SpringCompactGrid.
+ */
+public class SpringUtilities {
+ /**
+ * A debugging utility that prints to stdout the component's
+ * minimum, preferred, and maximum sizes.
+ */
+ public static void printSizes(Component c) {
+ System.out.println("minimumSize = " + c.getMinimumSize());
+ System.out.println("preferredSize = " + c.getPreferredSize());
+ System.out.println("maximumSize = " + c.getMaximumSize());
+ }
+
+ /**
+ * Aligns the first <code>rows</code> * <code>cols</code>
+ * components of <code>parent</code> in
+ * a grid. Each component is as big as the maximum
+ * preferred width and height of the components.
+ * The parent is made just big enough to fit them all.
+ *
+ * @param rows number of rows
+ * @param cols number of columns
+ * @param initialX x location to start the grid at
+ * @param initialY y location to start the grid at
+ * @param xPad x padding between cells
+ * @param yPad y padding between cells
+ */
+ public static void makeGrid(Container parent,
+ int rows, int cols,
+ int initialX, int initialY,
+ int xPad, int yPad) {
+ SpringLayout layout;
+ try {
+ layout = (SpringLayout)parent.getLayout();
+ } catch (ClassCastException exc) {
+ System.err.println("The first argument to makeGrid must use SpringLayout.");
+ return;
+ }
+
+ Spring xPadSpring = Spring.constant(xPad);
+ Spring yPadSpring = Spring.constant(yPad);
+ Spring initialXSpring = Spring.constant(initialX);
+ Spring initialYSpring = Spring.constant(initialY);
+ int max = rows * cols;
+
+ //Calculate Springs that are the max of the width/height so that all
+ //cells have the same size.
+ Spring maxWidthSpring = layout.getConstraints(parent.getComponent(0)).
+ getWidth();
+ Spring maxHeightSpring = layout.getConstraints(parent.getComponent(0)).
+ getWidth();
+ for (int i = 1; i < max; i++) {
+ SpringLayout.Constraints cons = layout.getConstraints(
+ parent.getComponent(i));
+
+ maxWidthSpring = Spring.max(maxWidthSpring, cons.getWidth());
+ maxHeightSpring = Spring.max(maxHeightSpring, cons.getHeight());
+ }
+
+ //Apply the new width/height Spring. This forces all the
+ //components to have the same size.
+ for (int i = 0; i < max; i++) {
+ SpringLayout.Constraints cons = layout.getConstraints(
+ parent.getComponent(i));
+
+ cons.setWidth(maxWidthSpring);
+ cons.setHeight(maxHeightSpring);
+ }
+
+ //Then adjust the x/y constraints of all the cells so that they
+ //are aligned in a grid.
+ SpringLayout.Constraints lastCons = null;
+ SpringLayout.Constraints lastRowCons = null;
+ for (int i = 0; i < max; i++) {
+ SpringLayout.Constraints cons = layout.getConstraints(
+ parent.getComponent(i));
+ if (i % cols == 0) { //start of new row
+ lastRowCons = lastCons;
+ cons.setX(initialXSpring);
+ } else { //x position depends on previous component
+ cons.setX(Spring.sum(lastCons.getConstraint(SpringLayout.EAST),
+ xPadSpring));
+ }
+
+ if (i / cols == 0) { //first row
+ cons.setY(initialYSpring);
+ } else { //y position depends on previous row
+ cons.setY(Spring.sum(lastRowCons.getConstraint(SpringLayout.SOUTH),
+ yPadSpring));
+ }
+ lastCons = cons;
+ }
+
+ //Set the parent's size.
+ SpringLayout.Constraints pCons = layout.getConstraints(parent);
+ pCons.setConstraint(SpringLayout.SOUTH,
+ Spring.sum(
+ Spring.constant(yPad),
+ lastCons.getConstraint(SpringLayout.SOUTH)));
+ pCons.setConstraint(SpringLayout.EAST,
+ Spring.sum(
+ Spring.constant(xPad),
+ lastCons.getConstraint(SpringLayout.EAST)));
+ }
+
+ /* Used by makeCompactGrid. */
+ private static SpringLayout.Constraints getConstraintsForCell(
+ int row, int col,
+ Container parent,
+ int cols) {
+ SpringLayout layout = (SpringLayout) parent.getLayout();
+ Component c = parent.getComponent(row * cols + col);
+ return layout.getConstraints(c);
+ }
+
+ /**
+ * Aligns the first <code>rows</code> * <code>cols</code>
+ * components of <code>parent</code> in
+ * a grid. Each component in a column is as wide as the maximum
+ * preferred width of the components in that column;
+ * height is similarly determined for each row.
+ * The parent is made just big enough to fit them all.
+ *
+ * @param rows number of rows
+ * @param cols number of columns
+ * @param initialX x location to start the grid at
+ * @param initialY y location to start the grid at
+ * @param xPad x padding between cells
+ * @param yPad y padding between cells
+ */
+ public static void makeCompactGrid(Container parent,
+ int rows, int cols,
+ int initialX, int initialY,
+ int xPad, int yPad) {
+ SpringLayout layout;
+ try {
+ layout = (SpringLayout)parent.getLayout();
+ } catch (ClassCastException exc) {
+ System.err.println("The first argument to makeCompactGrid must use SpringLayout.");
+ return;
+ }
+
+ //Align all cells in each column and make them the same width.
+ Spring x = Spring.constant(initialX);
+ for (int c = 0; c < cols; c++) {
+ Spring width = Spring.constant(0);
+ for (int r = 0; r < rows; r++) {
+ width = Spring.max(width,
+ getConstraintsForCell(r, c, parent, cols).
+ getWidth());
+ }
+ for (int r = 0; r < rows; r++) {
+ SpringLayout.Constraints constraints =
+ getConstraintsForCell(r, c, parent, cols);
+ constraints.setX(x);
+ constraints.setWidth(width);
+ }
+ x = Spring.sum(x, Spring.sum(width, Spring.constant(xPad)));
+ }
+
+ //Align all cells in each row and make them the same height.
+ Spring y = Spring.constant(initialY);
+ for (int r = 0; r < rows; r++) {
+ Spring height = Spring.constant(0);
+ for (int c = 0; c < cols; c++) {
+ height = Spring.max(height,
+ getConstraintsForCell(r, c, parent, cols).
+ getHeight());
+ }
+ for (int c = 0; c < cols; c++) {
+ SpringLayout.Constraints constraints =
+ getConstraintsForCell(r, c, parent, cols);
+ constraints.setY(y);
+ constraints.setHeight(height);
+ }
+ y = Spring.sum(y, Spring.sum(height, Spring.constant(yPad)));
+ }
+
+ //Set the parent's size.
+ SpringLayout.Constraints pCons = layout.getConstraints(parent);
+ pCons.setConstraint(SpringLayout.SOUTH, y);
+ pCons.setConstraint(SpringLayout.EAST, x);
+ }
+}
Added: trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/XmlPrettyPrinter.java
===================================================================
--- trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/XmlPrettyPrinter.java (rev 0)
+++ trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/XmlPrettyPrinter.java 2009-12-05 10:50:50 UTC (rev 98)
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2005-8 Pi4 Technologies Ltd
+ *
+ * Licensed 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.
+ *
+ *
+ * Change History:
+ * 16 Jan, 2008 : Initial version created by martin
+ */
+package org.pi4soa.monitor.ui;
+
+
+import org.w3c.dom.Document;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.ParserConfigurationException;
+
+//import org.apache.xml.serialize.OutputFormat;
+//import org.apache.xml.serialize.XMLSerializer;
+
+import java.io.IOException;
+import java.io.StringBufferInputStream;
+import java.io.ByteArrayOutputStream;
+
+import org.xml.sax.SAXException;
+
+/**
+ *
+ */
+public class XmlPrettyPrinter{
+
+ /**
+ *
+ */
+ public static String prettify(String input){
+
+ // Find the implementation
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ DocumentBuilder builder = null;
+
+ try{
+ builder = factory.newDocumentBuilder();
+ }
+ catch(ParserConfigurationException pce){
+ System.err.println("Exception: " + pce);
+ return null;
+ }
+
+ StringBufferInputStream stringBufferInputStream = new StringBufferInputStream(input);
+
+ Document doc = null;
+
+ try{
+ doc = builder.parse(stringBufferInputStream);
+ }
+ catch(SAXException se){
+ System.err.println("Exception: " + se);
+ return null;
+ }
+ catch(IOException ioe){
+ System.err.println("Exception: " + ioe);
+ return null;
+ }
+
+ String text=null;
+
+ try {
+ text = org.pi4soa.common.xml.XMLUtils.getText(doc, true);
+ } catch(Exception e) {
+ System.err.println("Exception: " + e);
+ }
+
+ return(text);
+
+ /*
+ OutputFormat format = new OutputFormat(doc);
+ format.setLineWidth(65);
+ format.setIndenting(true);
+ format.setIndent(2);
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ XMLSerializer serializer = new XMLSerializer(byteArrayOutputStream, format);
+
+ try{
+ serializer.serialize(doc);
+ }
+ catch(IOException ioe){
+ System.err.println("Exception: " + ioe);
+ return null;
+ }
+
+ return byteArrayOutputStream.toString();
+ */
+ }
+
+}
Added: trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/icons/channelclosed.png
===================================================================
(Binary files differ)
Property changes on: trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/icons/channelclosed.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/icons/channelempty.png
===================================================================
(Binary files differ)
Property changes on: trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/icons/channelempty.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/icons/channelleaf.png
===================================================================
(Binary files differ)
Property changes on: trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/icons/channelleaf.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/icons/channelopen.png
===================================================================
(Binary files differ)
Property changes on: trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/icons/channelopen.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/icons/errorsleaf.png
===================================================================
(Binary files differ)
Property changes on: trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/icons/errorsleaf.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/icons/issuesclosed.png
===================================================================
(Binary files differ)
Property changes on: trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/icons/issuesclosed.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/icons/issuesempty.png
===================================================================
(Binary files differ)
Property changes on: trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/icons/issuesempty.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/icons/issuesopen.png
===================================================================
(Binary files differ)
Property changes on: trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/icons/issuesopen.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/icons/monitor.png
===================================================================
(Binary files differ)
Property changes on: trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/icons/monitor.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/icons/txnclosed.png
===================================================================
(Binary files differ)
Property changes on: trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/icons/txnclosed.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/icons/txnempty.png
===================================================================
(Binary files differ)
Property changes on: trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/icons/txnempty.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/icons/txnleaf.png
===================================================================
(Binary files differ)
Property changes on: trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/icons/txnleaf.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/icons/txnopen.png
===================================================================
(Binary files differ)
Property changes on: trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/icons/txnopen.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/icons/unexpectedleaf.png
===================================================================
(Binary files differ)
Property changes on: trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/icons/unexpectedleaf.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/icons/warningsleaf.png
===================================================================
(Binary files differ)
Property changes on: trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/icons/warningsleaf.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/table/TableSorter.java
===================================================================
--- trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/table/TableSorter.java (rev 0)
+++ trunk/org.pi4soa.monitor/src/java/org/pi4soa/monitor/ui/table/TableSorter.java 2009-12-05 10:50:50 UTC (rev 98)
@@ -0,0 +1,450 @@
+/*
+ * Copyright 2005-8 Pi4 Technologies Ltd
+ *
+ * Licensed 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.
+ *
+ *
+ * Change History:
+ * 16 Jan, 2008 : Initial version created by martin
+ */
+package org.pi4soa.monitor.ui.table;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import java.util.List;
+
+import javax.swing.*;
+import javax.swing.event.TableModelEvent;
+import javax.swing.event.TableModelListener;
+import javax.swing.table.*;
+
+public class TableSorter extends AbstractTableModel {
+ protected TableModel tableModel;
+
+ public static final int DESCENDING = -1;
+ public static final int NOT_SORTED = 0;
+ public static final int ASCENDING = 1;
+
+ private static Directive EMPTY_DIRECTIVE = new Directive(-1, NOT_SORTED);
+
+ public static final Comparator COMPARABLE_COMAPRATOR = new Comparator() {
+ public int compare(Object o1, Object o2) {
+ return ((Comparable) o1).compareTo(o2);
+ }
+ };
+ public static final Comparator LEXICAL_COMPARATOR = new Comparator() {
+ public int compare(Object o1, Object o2) {
+ return o1.toString().compareTo(o2.toString());
+ }
+ };
+
+ private Row[] viewToModel;
+ private int[] modelToView;
+
+ private JTableHeader tableHeader;
+ private MouseListener mouseListener;
+ private TableModelListener tableModelListener;
+ private Map columnComparators = new HashMap();
+ private List sortingColumns = new ArrayList();
+
+ public TableSorter() {
+ this.mouseListener = new MouseHandler();
+ this.tableModelListener = new TableModelHandler();
+ }
+
+ public TableSorter(TableModel tableModel) {
+ this();
+ setTableModel(tableModel);
+ }
+
+ public TableSorter(TableModel tableModel, JTableHeader tableHeader) {
+ this();
+ setTableHeader(tableHeader);
+ setTableModel(tableModel);
+ }
+
+ private void clearSortingState() {
+ viewToModel = null;
+ modelToView = null;
+ }
+
+ public TableModel getTableModel() {
+ return tableModel;
+ }
+
+ public void setTableModel(TableModel tableModel) {
+ if (this.tableModel != null) {
+ this.tableModel.removeTableModelListener(tableModelListener);
+ }
+
+ this.tableModel = tableModel;
+ if (this.tableModel != null) {
+ this.tableModel.addTableModelListener(tableModelListener);
+ }
+
+ clearSortingState();
+ fireTableStructureChanged();
+ }
+
+ public JTableHeader getTableHeader() {
+ return tableHeader;
+ }
+
+ public void setTableHeader(JTableHeader tableHeader) {
+ if (this.tableHeader != null) {
+ this.tableHeader.removeMouseListener(mouseListener);
+ TableCellRenderer defaultRenderer = this.tableHeader.getDefaultRenderer();
+ if (defaultRenderer instanceof SortableHeaderRenderer) {
+ this.tableHeader.setDefaultRenderer(((SortableHeaderRenderer) defaultRenderer).tableCellRenderer);
+ }
+ }
+ this.tableHeader = tableHeader;
+ if (this.tableHeader != null) {
+ this.tableHeader.addMouseListener(mouseListener);
+ this.tableHeader.setDefaultRenderer(
+ new SortableHeaderRenderer(this.tableHeader.getDefaultRenderer()));
+ }
+ }
+
+ public boolean isSorting() {
+ return sortingColumns.size() != 0;
+ }
+
+ private Directive getDirective(int column) {
+ for (int i = 0; i < sortingColumns.size(); i++) {
+ Directive directive = (Directive)sortingColumns.get(i);
+ if (directive.column == column) {
+ return directive;
+ }
+ }
+ return EMPTY_DIRECTIVE;
+ }
+
+ public int getSortingStatus(int column) {
+ return getDirective(column).direction;
+ }
+
+ private void sortingStatusChanged() {
+ clearSortingState();
+ fireTableDataChanged();
+ if (tableHeader != null) {
+ tableHeader.repaint();
+ }
+ }
+
+ public void setSortingStatus(int column, int status) {
+ Directive directive = getDirective(column);
+ if (directive != EMPTY_DIRECTIVE) {
+ sortingColumns.remove(directive);
+ }
+ if (status != NOT_SORTED) {
+ sortingColumns.add(new Directive(column, status));
+ }
+ sortingStatusChanged();
+ }
+
+ protected Icon getHeaderRendererIcon(int column, int size) {
+ Directive directive = getDirective(column);
+ if (directive == EMPTY_DIRECTIVE) {
+ return null;
+ }
+ return new Arrow(directive.direction == DESCENDING, size, sortingColumns.indexOf(directive));
+ }
+
+ private void cancelSorting() {
+ sortingColumns.clear();
+ sortingStatusChanged();
+ }
+
+ public void setColumnComparator(Class type, Comparator comparator) {
+ if (comparator == null) {
+ columnComparators.remove(type);
+ } else {
+ columnComparators.put(type, comparator);
+ }
+ }
+
+ protected Comparator getComparator(int column) {
+ Class columnType = tableModel.getColumnClass(column);
+ Comparator comparator = (Comparator) columnComparators.get(columnType);
+ if (comparator != null) {
+ return comparator;
+ }
+ if (Comparable.class.isAssignableFrom(columnType)) {
+ return COMPARABLE_COMAPRATOR;
+ }
+ return LEXICAL_COMPARATOR;
+ }
+
+ private Row[] getViewToModel() {
+ if (viewToModel == null) {
+ int tableModelRowCount = tableModel.getRowCount();
+ viewToModel = new Row[tableModelRowCount];
+ for (int row = 0; row < tableModelRowCount; row++) {
+ viewToModel[row] = new Row(row);
+ }
+
+ if (isSorting()) {
+ Arrays.sort(viewToModel);
+ }
+ }
+ return viewToModel;
+ }
+
+ public int modelIndex(int viewIndex) {
+ return getViewToModel()[viewIndex].modelIndex;
+ }
+
+ private int[] getModelToView() {
+ if (modelToView == null) {
+ int n = getViewToModel().length;
+ modelToView = new int[n];
+ for (int i = 0; i < n; i++) {
+ modelToView[modelIndex(i)] = i;
+ }
+ }
+ return modelToView;
+ }
+
+ // TableModel interface methods
+
+ public int getRowCount() {
+ return (tableModel == null) ? 0 : tableModel.getRowCount();
+ }
+
+ public int getColumnCount() {
+ return (tableModel == null) ? 0 : tableModel.getColumnCount();
+ }
+
+ public String getColumnName(int column) {
+ return tableModel.getColumnName(column);
+ }
+
+ public Class getColumnClass(int column) {
+ return tableModel.getColumnClass(column);
+ }
+
+ public boolean isCellEditable(int row, int column) {
+ return tableModel.isCellEditable(modelIndex(row), column);
+ }
+
+ public Object getValueAt(int row, int column) {
+ return tableModel.getValueAt(modelIndex(row), column);
+ }
+
+ public void setValueAt(Object aValue, int row, int column) {
+ tableModel.setValueAt(aValue, modelIndex(row), column);
+ }
+
+ // Helper classes
+
+ private class Row implements Comparable {
+ private int modelIndex;
+
+ public Row(int index) {
+ this.modelIndex = index;
+ }
+
+ public int compareTo(Object o) {
+ int row1 = modelIndex;
+ int row2 = ((Row) o).modelIndex;
+
+ for (Iterator it = sortingColumns.iterator(); it.hasNext();) {
+ Directive directive = (Directive) it.next();
+ int column = directive.column;
+ Object o1 = tableModel.getValueAt(row1, column);
+ Object o2 = tableModel.getValueAt(row2, column);
+
+ int comparison = 0;
+ // Define null less than everything, except null.
+ if (o1 == null && o2 == null) {
+ comparison = 0;
+ } else if (o1 == null) {
+ comparison = -1;
+ } else if (o2 == null) {
+ comparison = 1;
+ } else {
+ comparison = getComparator(column).compare(o1, o2);
+ }
+ if (comparison != 0) {
+ return directive.direction == DESCENDING ? -comparison : comparison;
+ }
+ }
+ return 0;
+ }
+ }
+
+ private class TableModelHandler implements TableModelListener {
+ public void tableChanged(TableModelEvent e) {
+ // If we're not sorting by anything, just pass the event along.
+ if (!isSorting()) {
+ clearSortingState();
+ fireTableChanged(e);
+ return;
+ }
+
+ // If the table structure has changed, cancel the sorting; the
+ // sorting columns may have been either moved or deleted from
+ // the model.
+ if (e.getFirstRow() == TableModelEvent.HEADER_ROW) {
+ cancelSorting();
+ fireTableChanged(e);
+ return;
+ }
+
+ // We can map a cell event through to the view without widening
+ // when the following conditions apply:
+ //
+ // a) all the changes are on one row (e.getFirstRow() == e.getLastRow()) and,
+ // b) all the changes are in one column (column != TableModelEvent.ALL_COLUMNS) and,
+ // c) we are not sorting on that column (getSortingStatus(column) == NOT_SORTED) and,
+ // d) a reverse lookup will not trigger a sort (modelToView != null)
+ //
+ // Note: INSERT and DELETE events fail this test as they have column == ALL_COLUMNS.
+ //
+ // The last check, for (modelToView != null) is to see if modelToView
+ // is already allocated. If we don't do this check; sorting can become
+ // a performance bottleneck for applications where cells
+ // change rapidly in different parts of the table. If cells
+ // change alternately in the sorting column and then outside of
+ // it this class can end up re-sorting on alternate cell updates -
+ // which can be a performance problem for large tables. The last
+ // clause avoids this problem.
+ int column = e.getColumn();
+ if (e.getFirstRow() == e.getLastRow()
+ && column != TableModelEvent.ALL_COLUMNS
+ && getSortingStatus(column) == NOT_SORTED
+ && modelToView != null) {
+ int viewIndex = getModelToView()[e.getFirstRow()];
+ fireTableChanged(new TableModelEvent(TableSorter.this,
+ viewIndex, viewIndex,
+ column, e.getType()));
+ return;
+ }
+
+ // Something has happened to the data that may have invalidated the row order.
+ clearSortingState();
+ fireTableDataChanged();
+ return;
+ }
+ }
+
+ private class MouseHandler extends MouseAdapter {
+ public void mouseClicked(MouseEvent e) {
+ JTableHeader h = (JTableHeader) e.getSource();
+ TableColumnModel columnModel = h.getColumnModel();
+ int viewColumn = columnModel.getColumnIndexAtX(e.getX());
+ int column = columnModel.getColumn(viewColumn).getModelIndex();
+ if (column != -1) {
+ int status = getSortingStatus(column);
+ if (!e.isControlDown()) {
+ cancelSorting();
+ }
+ // Cycle the sorting states through {NOT_SORTED, ASCENDING, DESCENDING} or
+ // {NOT_SORTED, DESCENDING, ASCENDING} depending on whether shift is pressed.
+ status = status + (e.isShiftDown() ? -1 : 1);
+ status = (status + 4) % 3 - 1; // signed mod, returning {-1, 0, 1}
+ setSortingStatus(column, status);
+ }
+ }
+ }
+
+ private static class Arrow implements Icon {
+ private boolean descending;
+ private int size;
+ private int priority;
+
+ public Arrow(boolean descending, int size, int priority) {
+ this.descending = descending;
+ this.size = size;
+ this.priority = priority;
+ }
+
+ public void paintIcon(Component c, Graphics g, int x, int y) {
+ Color color = c == null ? Color.GRAY : c.getBackground();
+ // In a compound sort, make each succesive triangle 20%
+ // smaller than the previous one.
+ int dx = (int)(size/2*Math.pow(0.8, priority));
+ int dy = descending ? dx : -dx;
+ // Align icon (roughly) with font baseline.
+ y = y + 5*size/6 + (descending ? -dy : 0);
+ int shift = descending ? 1 : -1;
+ g.translate(x, y);
+
+ // Right diagonal.
+ g.setColor(color.darker());
+ g.drawLine(dx / 2, dy, 0, 0);
+ g.drawLine(dx / 2, dy + shift, 0, shift);
+
+ // Left diagonal.
+ g.setColor(color.brighter());
+ g.drawLine(dx / 2, dy, dx, 0);
+ g.drawLine(dx / 2, dy + shift, dx, shift);
+
+ // Horizontal line.
+ if (descending) {
+ g.setColor(color.darker().darker());
+ } else {
+ g.setColor(color.brighter().brighter());
+ }
+ g.drawLine(dx, 0, 0, 0);
+
+ g.setColor(color);
+ g.translate(-x, -y);
+ }
+
+ public int getIconWidth() {
+ return size;
+ }
+
+ public int getIconHeight() {
+ return size;
+ }
+ }
+
+ private class SortableHeaderRenderer implements TableCellRenderer {
+ private TableCellRenderer tableCellRenderer;
+
+ public SortableHeaderRenderer(TableCellRenderer tableCellRenderer) {
+ this.tableCellRenderer = tableCellRenderer;
+ }
+
+ public Component getTableCellRendererComponent(JTable table,
+ Object value,
+ boolean isSelected,
+ boolean hasFocus,
+ int row,
+ int column) {
+ Component c = tableCellRenderer.getTableCellRendererComponent(table,
+ value, isSelected, hasFocus, row, column);
+ if (c instanceof JLabel) {
+ JLabel l = (JLabel) c;
+ l.setHorizontalTextPosition(JLabel.LEFT);
+ int modelColumn = table.convertColumnIndexToModel(column);
+ l.setIcon(getHeaderRendererIcon(modelColumn, l.getFont().getSize()));
+ }
+ return c;
+ }
+ }
+
+ private static class Directive {
+ private int column;
+ private int direction;
+
+ public Directive(int column, int direction) {
+ this.column = column;
+ this.direction = direction;
+ }
+ }
+}
More information about the savara-commits
mailing list