summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Greig <rgreig@apache.org>2006-12-18 09:10:59 +0000
committerRobert Greig <rgreig@apache.org>2006-12-18 09:10:59 +0000
commit55a17b9cb6c2cb3c3ebfddc65956a3f00c89ccb7 (patch)
treeb06421d8a95a462b9bb81fac33f324f247c2b59e
parent78c062d60e6e5bb193e86d79c592091cfd52688e (diff)
downloadqpid-python-55a17b9cb6c2cb3c3ebfddc65956a3f00c89ccb7.tar.gz
Merged up to rev 485730 from trunk
git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/branches/new_persistence@488163 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--java/broker/bin/qpid-server.bat47
-rw-r--r--java/broker/etc/qpid-server.conf2
-rw-r--r--java/broker/pom.xml7
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java3
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/Main.java112
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java16
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/DestNameExchange.java63
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/DestWildExchange.java71
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java61
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/ManagedExchange.java20
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/management/ManagedBroker.java27
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/protocol/AMQMinaProtocolSession.java115
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/protocol/ManagedConnection.java89
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java280
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/queue/ManagedQueue.java132
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/amqplain/AmqPlainSaslServer.java3
-rw-r--r--java/client/pom.xml11
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/AMQBrokerDetails.java53
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/AMQConnection.java22
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/AMQSession.java89
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer.java25
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer.java41
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/QueueReceiverAdaptor.java24
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/QueueSenderAdapter.java134
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/TopicPublisherAdapter.java138
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/TopicSubscriberAdaptor.java28
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/handler/ConnectionStartMethodHandler.java3
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/message/JMSBytesMessage.java1
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/message/JMSMapMessage.java19
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/message/JMSObjectMessage.java10
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/message/JMSTextMessage.java4
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/security/amqplain/AmqPlainSaslClient.java3
-rw-r--r--java/client/src/test/java/org/apache/qpid/client/message/TestMessageHelper.java2
-rw-r--r--java/client/src/test/java/org/apache/qpid/cts/src/providers/amqp/org/exolab/jmscts/amqp/AMQPAdministrator.java2
-rw-r--r--java/client/src/test/java/org/apache/qpid/cts/src/providers/amqp/org/exolab/jmscts/amqp/AMQPProvider.java2
-rw-r--r--java/client/src/test/java/org/apache/qpid/example/publisher/FileMessageDispatcher.java43
-rw-r--r--java/client/src/test/java/org/apache/qpid/example/publisher/FileMessageFactory.java (renamed from java/client/src/test/java/org/apache/qpid/example/publisher/MessageFactory.java)36
-rw-r--r--java/client/src/test/java/org/apache/qpid/example/publisher/MonitorMessageDispatcher.java33
-rw-r--r--java/client/src/test/java/org/apache/qpid/example/publisher/Publisher.java27
-rw-r--r--java/client/src/test/java/org/apache/qpid/example/subscriber/MonitoredSubscriber.java20
-rw-r--r--java/client/src/test/java/org/apache/qpid/example/subscriber/MonitoredSubscriptionWrapper.java16
-rw-r--r--java/client/src/test/java/org/apache/qpid/example/subscriber/Subscriber.java30
-rw-r--r--java/client/src/test/java/org/apache/qpid/example/subscriber/SubscriptionWrapper.java17
-rw-r--r--java/client/src/test/java/org/apache/qpid/example/test/TestAMSPubSub.java101
-rw-r--r--java/client/src/test/java/org/apache/qpid/example/test/TestMultSubscribers.java111
-rw-r--r--java/client/src/test/java/org/apache/qpid/example/test/TestPublisher.java85
-rw-r--r--java/client/src/test/java/org/apache/qpid/framing/FieldTableTest.java39
-rw-r--r--java/client/src/test/java/org/apache/qpid/headers/MessageFactory.java5
-rw-r--r--java/client/src/test/java/org/apache/qpid/requestreply1/ServiceRequestingClient.java1
-rw-r--r--java/client/src/test/java/org/apache/qpid/test/unit/basic/BytesMessageTest.java37
-rw-r--r--java/client/src/test/java/org/apache/qpid/test/unit/basic/FieldTableKeyEnumeratorTest.java25
-rw-r--r--java/client/src/test/java/org/apache/qpid/test/unit/basic/FieldTableMessageTest.java13
-rw-r--r--java/client/src/test/java/org/apache/qpid/test/unit/basic/FieldTablePropertyTest.java65
-rw-r--r--java/client/src/test/java/org/apache/qpid/test/unit/basic/MapMessageTest.java110
-rw-r--r--java/client/src/test/java/org/apache/qpid/test/unit/basic/ObjectMessageTest.java52
-rw-r--r--java/client/src/test/java/org/apache/qpid/test/unit/basic/PropertyValueTest.java264
-rw-r--r--java/client/src/test/java/org/apache/qpid/test/unit/basic/TextMessageTest.java61
-rw-r--r--java/client/src/test/java/org/apache/qpid/test/unit/client/BrokerDetails/BrokerDetailsTest.java93
-rw-r--r--java/client/src/test/java/org/apache/qpid/test/unit/client/connection/ConnectionTest.java38
-rw-r--r--java/client/src/test/java/org/apache/qpid/test/unit/client/connectionurl/ConnectionURLTest.java34
-rw-r--r--java/client/src/test/java/org/apache/qpid/test/unit/client/message/ObjectMessageTest.java79
-rw-r--r--java/cluster/pom.xml5
-rw-r--r--java/common/pom.xml7
-rw-r--r--java/common/protocol-version.xml16
-rw-r--r--java/common/src/main/java/org/apache/qpid/framing/BasicContentHeaderProperties.java11
-rw-r--r--java/common/src/main/java/org/apache/qpid/framing/Content.java (renamed from java/common/src/main/java/org/apache/qpid/framing/FieldTableKeyEnumeration.java)25
-rw-r--r--java/common/src/main/java/org/apache/qpid/framing/EncodingUtils.java284
-rw-r--r--java/common/src/main/java/org/apache/qpid/framing/FieldTable.java398
-rw-r--r--java/common/src/main/java/org/apache/qpid/framing/FieldTableFactory.java41
-rw-r--r--java/common/src/main/java/org/apache/qpid/framing/PropertyFieldTable.java888
-rw-r--r--java/common/src/test/java/org/apache/qpid/framing/BasicContentHeaderPropertiesTest.java192
-rw-r--r--java/common/src/test/java/org/apache/qpid/framing/PropertyFieldTableTest.java110
-rw-r--r--java/management/eclipse-plugin/META-INF/MANIFEST.MF12
-rw-r--r--java/management/eclipse-plugin/README.txt7
-rw-r--r--java/management/eclipse-plugin/bin/qpidmc.bat55
-rwxr-xr-xjava/management/eclipse-plugin/bin/qpidmc.sh21
-rw-r--r--java/management/eclipse-plugin/icons/Thumbs.dbbin0 -> 97280 bytes
-rw-r--r--java/management/eclipse-plugin/icons/add.gifbin0 -> 318 bytes
-rw-r--r--java/management/eclipse-plugin/icons/delete.gifbin0 -> 143 bytes
-rw-r--r--java/management/eclipse-plugin/icons/icon_ClosedFolder.gifbin0 -> 160 bytes
-rw-r--r--java/management/eclipse-plugin/icons/icon_OpenFolder.gifbin0 -> 152 bytes
-rw-r--r--java/management/eclipse-plugin/icons/mbean_view.pngbin0 -> 2046 bytes
-rw-r--r--java/management/eclipse-plugin/icons/notifications.gifbin0 -> 104 bytes
-rw-r--r--java/management/eclipse-plugin/icons/qpidConnections.gifbin0 -> 168 bytes
-rw-r--r--java/management/eclipse-plugin/icons/qpidmc.gifbin0 -> 1225 bytes
-rw-r--r--java/management/eclipse-plugin/icons/qpidmc16.gifbin0 -> 928 bytes
-rw-r--r--java/management/eclipse-plugin/icons/qpidmc32.bmpbin0 -> 1139 bytes
-rw-r--r--java/management/eclipse-plugin/icons/qpidmc32.gifbin0 -> 1139 bytes
-rw-r--r--java/management/eclipse-plugin/icons/reconnect.gifbin0 -> 327 bytes
-rw-r--r--java/management/eclipse-plugin/icons/refresh.gifbin0 -> 182 bytes
-rw-r--r--java/management/eclipse-plugin/icons/splash.bmpbin0 -> 207078 bytes
-rw-r--r--java/management/eclipse-plugin/icons/stop.gifbin0 -> 215 bytes
-rw-r--r--java/management/eclipse-plugin/plugin.properties20
-rw-r--r--java/management/eclipse-plugin/plugin.xml222
-rw-r--r--java/management/eclipse-plugin/plugins/com.ibm.icu_3.4.4.1.jarbin0 -> 3255246 bytes
-rw-r--r--java/management/eclipse-plugin/plugins/license.eclipse.txt88
-rw-r--r--java/management/eclipse-plugin/plugins/org.eclipse.core.commands_3.2.0.jarbin0 -> 89522 bytes
-rw-r--r--java/management/eclipse-plugin/plugins/org.eclipse.core.contenttype_3.2.0.jarbin0 -> 76141 bytes
-rw-r--r--java/management/eclipse-plugin/plugins/org.eclipse.core.expressions_3.2.0.jarbin0 -> 66037 bytes
-rw-r--r--java/management/eclipse-plugin/plugins/org.eclipse.core.jobs_3.2.0.jarbin0 -> 74797 bytes
-rw-r--r--java/management/eclipse-plugin/plugins/org.eclipse.core.runtime.compatibility.auth_3.2.0.jarbin0 -> 18733 bytes
-rw-r--r--java/management/eclipse-plugin/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.0/META-INF/MANIFEST.MF12
-rw-r--r--java/management/eclipse-plugin/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.0/runtime_registry_compatibility.jarbin0 -> 7584 bytes
-rw-r--r--java/management/eclipse-plugin/plugins/org.eclipse.core.runtime_3.2.0.jarbin0 -> 76627 bytes
-rw-r--r--java/management/eclipse-plugin/plugins/org.eclipse.equinox.common_3.2.0.jarbin0 -> 79780 bytes
-rw-r--r--java/management/eclipse-plugin/plugins/org.eclipse.equinox.preferences_3.2.0.jarbin0 -> 91661 bytes
-rw-r--r--java/management/eclipse-plugin/plugins/org.eclipse.equinox.registry_3.2.0.jarbin0 -> 143841 bytes
-rw-r--r--java/management/eclipse-plugin/plugins/org.eclipse.help_3.2.0.jarbin0 -> 115438 bytes
-rw-r--r--java/management/eclipse-plugin/plugins/org.eclipse.jface_3.2.0.jarbin0 -> 813596 bytes
-rw-r--r--java/management/eclipse-plugin/plugins/org.eclipse.osgi_3.2.0.jarbin0 -> 846716 bytes
-rw-r--r--java/management/eclipse-plugin/plugins/org.eclipse.swt.win32.win32.x86_3.2.0.jarbin0 -> 1553408 bytes
-rw-r--r--java/management/eclipse-plugin/plugins/org.eclipse.swt_3.2.0.jarbin0 -> 11003 bytes
-rw-r--r--java/management/eclipse-plugin/plugins/org.eclipse.ui.forms_3.2.0.jarbin0 -> 235371 bytes
-rw-r--r--java/management/eclipse-plugin/plugins/org.eclipse.ui.workbench.compatibility_3.2.0/META-INF/MANIFEST.MF12
-rw-r--r--java/management/eclipse-plugin/plugins/org.eclipse.ui.workbench.compatibility_3.2.0/compatibility.jarbin0 -> 4080 bytes
-rw-r--r--java/management/eclipse-plugin/plugins/org.eclipse.ui.workbench_3.2.0.jarbin0 -> 3070253 bytes
-rw-r--r--java/management/eclipse-plugin/plugins/org.eclipse.ui_3.2.0.jarbin0 -> 124307 bytes
-rw-r--r--java/management/eclipse-plugin/pom.xml216
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Activator.java84
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Application.java63
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationActionBarAdvisor.java96
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationRegistry.java129
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationWorkbenchAdvisor.java46
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationWorkbenchWindowAdvisor.java61
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Constants.java79
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ICommandIds.java36
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedBean.java80
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedObject.java36
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedServer.java75
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Perspective.java53
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ServerRegistry.java79
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/AddServer.java282
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/CloseConnection.java93
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/EditAttribute.java87
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/ReconnectServer.java92
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/Refresh.java77
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/RemoveServer.java92
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/exceptions/InfoRequiredException.java36
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientListener.java77
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientNotificationListener.java42
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXManagedObject.java50
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXServerRegistry.java336
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/MBeanUtility.java349
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/AttributeData.java95
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/ManagedAttributeModel.java113
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/NotificationInfoModel.java51
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/NotificationObject.java88
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/OperationData.java84
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/OperationDataModel.java73
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/ParameterData.java79
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/AttributesTabControl.java937
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/INotificationViewer.java32
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanView.java431
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NavigationView.java787
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NotificationsTabControl.java708
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/OperationTabControl.java718
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/TabControl.java57
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/TreeObject.java125
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/ViewUtility.java512
-rw-r--r--java/management/eclipse-plugin/src/main/resources/configuration/config.ini26
-rw-r--r--java/management/eclipse-plugin/src/main/resources/configuration/org.eclipse.osgi/bundles/16/1/.cp/swt-win32-3232.dllbin0 -> 323584 bytes
-rw-r--r--java/management/eclipse-plugin/src/main/resources/license.eclipse.txt88
-rw-r--r--java/management/eclipse-plugin/src/main/resources/qpidmc.exebin0 -> 180224 bytes
-rw-r--r--java/management/eclipse-plugin/src/main/resources/qpidmc.ini4
-rw-r--r--java/management/eclipse-plugin/src/main/resources/startup.jarbin0 -> 33049 bytes
-rw-r--r--java/pom.xml183
-rw-r--r--java/systests/pom.xml5
-rw-r--r--java/systests/src/test/java/org/apache/qpid/server/exchange/AbstractHeadersExchangeTest.java13
168 files changed, 11536 insertions, 1939 deletions
diff --git a/java/broker/bin/qpid-server.bat b/java/broker/bin/qpid-server.bat
index 1e2ca7c1ac..b839cc72d8 100644
--- a/java/broker/bin/qpid-server.bat
+++ b/java/broker/bin/qpid-server.bat
@@ -1,17 +1,20 @@
@REM
-@REM Copyright (c) 2006 The Apache Software Foundation
-@REM
-@REM Licensed under the Apache License, Version 2.0 (the "License");
-@REM you may not use this file except in compliance with the License.
-@REM You may obtain a copy of the License at
-@REM
-@REM http://www.apache.org/licenses/LICENSE-2.0
-@REM
-@REM Unless required by applicable law or agreed to in writing, software
-@REM distributed under the License is distributed on an "AS IS" BASIS,
-@REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-@REM See the License for the specific language governing permissions and
-@REM limitations under the License.
+@REM Licensed to the Apache Software Foundation (ASF) under one
+@REM or more contributor license agreements. See the NOTICE file
+@REM distributed with this work for additional information
+@REM regarding copyright ownership. The ASF licenses this file
+@REM to you under the Apache License, Version 2.0 (the
+@REM "License"); you may not use this file except in compliance
+@REM with the License. You may obtain a copy of the License at
+@REM
+@REM http://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing,
+@REM software distributed under the License is distributed on an
+@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@REM KIND, either express or implied. See the License for the
+@REM specific language governing permissions and limitations
+@REM under the License.
@REM
@echo off
@@ -46,8 +49,20 @@ echo This environment variable is needed to run this program.
goto exit
:okJavaHome
-set LAUNCH_JAR=%QPID_HOME%\lib\broker-launch.jar
-set MODULE_JARS=%QPID_HOME%\lib\bdbstore-launch.jar
-"%JAVA_HOME%"\bin\java -server -Xmx1024m -DQPID_HOME="%QPID_HOME%" -cp "%LAUNCH_JAR%;%MODULE_JARS%" org.apache.qpid.server.Main *
+rem Slurp the command line arguments. This loop allows for an unlimited number
+rem of agruments (up to the command line limit, anyway).
+set QPID_ARGS=%1
+if ""%1""=="""" goto runCommand
+shift
+:loop
+if ""%1""=="""" goto runCommand
+set QPID_ARGS=%QPID_ARGS% %1
+shift
+goto loop
+
+:runCommand
+set LAUNCH_JAR=%QPID_HOME%\lib\qpid-incubating.jar
+set MODULE_JARS=%QPID_MODULE_JARS%
+"%JAVA_HOME%\bin\java" -server -Xmx1024m -DQPID_HOME="%QPID_HOME%" -cp "%LAUNCH_JAR%;%MODULE_JARS%" org.apache.qpid.server.Main %QPID_ARGS%
:end
diff --git a/java/broker/etc/qpid-server.conf b/java/broker/etc/qpid-server.conf
index 494dae6534..95db730c3b 100644
--- a/java/broker/etc/qpid-server.conf
+++ b/java/broker/etc/qpid-server.conf
@@ -14,7 +14,7 @@
# limitations under the License.
#
-QPID_LIBS=$QPID_HOME/lib/broker-launch.jar:$QPID_HOME/lib/bdbstore-launch.jar
+QPID_LIBS=$QPID_HOME/lib/qpid-incubating.jar:$QPID_HOME/lib/bdbstore-launch.jar
export JAVA=java \
JAVA_VM=-server \
diff --git a/java/broker/pom.xml b/java/broker/pom.xml
index 4f23c6c63e..5a2c699cc1 100644
--- a/java/broker/pom.xml
+++ b/java/broker/pom.xml
@@ -41,7 +41,6 @@
<groupId>org.apache.qpid</groupId>
<artifactId>qpid-common</artifactId>
</dependency>
-
<dependency>
<groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId>
@@ -66,7 +65,6 @@
<groupId>backport-util-concurrent</groupId>
<artifactId>backport-util-concurrent</artifactId>
</dependency>
-
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
@@ -76,13 +74,8 @@
<artifactId>junit</artifactId>
</dependency>
<dependency>
- <groupId>ant</groupId>
- <artifactId>ant-junit</artifactId>
- </dependency>
- <dependency>
<groupId>org.easymock</groupId>
<artifactId>easymockclassextension</artifactId>
- <scope>test</scope>
</dependency>
</dependencies>
diff --git a/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java b/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java
index f725fe2871..cd5923751a 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java
@@ -89,8 +89,7 @@ public class AMQChannel
private final Map<String, AMQQueue> _consumerTag2QueueMap = new TreeMap<String, AMQQueue>();
private final MessageStore _messageStore;
-
- //private Map<Long, UnacknowledgedMessage> _unacknowledgedMessageMap = new LinkedHashMap<Long, UnacknowledgedMessage>(DEFAULT_PREFETCH);
+
private UnacknowledgedMessageMap _unacknowledgedMessageMap = new UnacknowledgedMessageMapImpl(DEFAULT_PREFETCH);
private final AtomicBoolean _suspended = new AtomicBoolean(false);
diff --git a/java/broker/src/main/java/org/apache/qpid/server/Main.java b/java/broker/src/main/java/org/apache/qpid/server/Main.java
index a1dabcd964..3470a5bb08 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/Main.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/Main.java
@@ -20,25 +20,13 @@
*/
package org.apache.qpid.server;
-import org.apache.qpid.framing.ProtocolVersionList;
-import org.apache.qpid.pool.ReadWriteThreadModel;
-import org.apache.qpid.server.protocol.AMQPFastProtocolHandler;
-import org.apache.qpid.server.protocol.AMQPProtocolProvider;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.registry.ConfigurationFileApplicationRegistry;
-import org.apache.qpid.server.registry.IApplicationRegistry;
-import org.apache.qpid.server.transport.ConnectorConfiguration;
-import org.apache.qpid.server.configuration.VirtualHostConfiguration;
-import org.apache.qpid.server.management.*;
-import org.apache.qpid.server.queue.QueueRegistry;
-import org.apache.qpid.server.queue.AMQQueue;
-import org.apache.qpid.server.exchange.ExchangeRegistry;
-import org.apache.qpid.server.exchange.ExchangeFactory;
-import org.apache.qpid.server.exchange.Exchange;
-import org.apache.qpid.server.store.MessageStore;
-import org.apache.qpid.AMQException;
-import org.apache.qpid.url.URLSyntaxException;
-import org.apache.commons.cli.*;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.HelpFormatter;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionBuilder;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+import org.apache.commons.cli.PosixParser;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Logger;
@@ -48,20 +36,40 @@ import org.apache.mina.common.IoAcceptor;
import org.apache.mina.common.SimpleByteBufferAllocator;
import org.apache.mina.transport.socket.nio.SocketAcceptorConfig;
import org.apache.mina.transport.socket.nio.SocketSessionConfig;
+import org.apache.qpid.AMQException;
+import org.apache.qpid.framing.ProtocolVersionList;
+import org.apache.qpid.pool.ReadWriteThreadModel;
+import org.apache.qpid.server.configuration.VirtualHostConfiguration;
+import org.apache.qpid.server.exchange.Exchange;
+import org.apache.qpid.server.exchange.ExchangeFactory;
+import org.apache.qpid.server.exchange.ExchangeRegistry;
+import org.apache.qpid.server.management.AMQManagedObject;
+import org.apache.qpid.server.management.MBeanConstructor;
+import org.apache.qpid.server.management.MBeanDescription;
+import org.apache.qpid.server.management.ManagedBroker;
+import org.apache.qpid.server.management.ManagedObject;
+import org.apache.qpid.server.protocol.AMQPFastProtocolHandler;
+import org.apache.qpid.server.protocol.AMQPProtocolProvider;
+import org.apache.qpid.server.queue.AMQQueue;
+import org.apache.qpid.server.queue.QueueRegistry;
+import org.apache.qpid.server.registry.ApplicationRegistry;
+import org.apache.qpid.server.registry.ConfigurationFileApplicationRegistry;
+import org.apache.qpid.server.registry.IApplicationRegistry;
+import org.apache.qpid.server.store.MessageStore;
+import org.apache.qpid.server.transport.ConnectorConfiguration;
+import org.apache.qpid.url.URLSyntaxException;
import javax.management.JMException;
import javax.management.MBeanException;
-import javax.management.NotCompliantMBeanException;
-import javax.management.ObjectName;
import javax.management.MalformedObjectNameException;
-
+import javax.management.ObjectName;
import java.io.File;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
-import java.util.StringTokenizer;
import java.util.Collection;
import java.util.List;
+import java.util.StringTokenizer;
/**
* Main entry point for AMQPD.
@@ -439,9 +447,9 @@ public class Main implements ProtocolVersionList
{
new AMQBrokerManager().register();
}
- catch (NotCompliantMBeanException ex)
+ catch (JMException ex)
{
- throw new AMQException("Exception occured in creating AMQBrokerManager MBean.");
+ throw new AMQException("Exception occured in creating AMQBrokerManager MBean");
}
}
@@ -450,8 +458,7 @@ public class Main implements ProtocolVersionList
* Broker level management features like creating and deleting exchanges and queue.
*/
@MBeanDescription("This MBean exposes the broker level management features")
- private final class AMQBrokerManager extends AMQManagedObject
- implements ManagedBroker
+ private final class AMQBrokerManager extends AMQManagedObject implements ManagedBroker
{
private final QueueRegistry _queueRegistry;
private final ExchangeRegistry _exchangeRegistry;
@@ -459,10 +466,9 @@ public class Main implements ProtocolVersionList
private final MessageStore _messageStore;
@MBeanConstructor("Creates the Broker Manager MBean")
- protected AMQBrokerManager() throws NotCompliantMBeanException
+ protected AMQBrokerManager() throws JMException
{
super(ManagedBroker.class, ManagedBroker.TYPE);
-
IApplicationRegistry appRegistry = ApplicationRegistry.getInstance();
_queueRegistry = appRegistry.getQueueRegistry();
_exchangeRegistry = appRegistry.getExchangeRegistry();
@@ -483,10 +489,7 @@ public class Main implements ProtocolVersionList
* @param autoDelete
* @throws JMException
*/
- public void createNewExchange(String exchangeName,
- String type,
- boolean durable,
- boolean autoDelete)
+ public void createNewExchange(String exchangeName, String type, boolean durable, boolean autoDelete)
throws JMException
{
try
@@ -494,14 +497,9 @@ public class Main implements ProtocolVersionList
synchronized(_exchangeRegistry)
{
Exchange exchange = _exchangeRegistry.getExchange(exchangeName);
-
if (exchange == null)
{
- exchange = _exchangeFactory.createExchange(exchangeName,
- type, //eg direct
- durable,
- autoDelete,
- 0); //ticket no
+ exchange = _exchangeFactory.createExchange(exchangeName, type, durable, autoDelete, 0);
_exchangeRegistry.registerExchange(exchange);
}
else
@@ -522,8 +520,7 @@ public class Main implements ProtocolVersionList
* @param exchangeName
* @throws JMException
*/
- public void unregisterExchange(String exchangeName)
- throws JMException
+ public void unregisterExchange(String exchangeName) throws JMException
{
boolean inUse = false;
// TODO
@@ -550,33 +547,28 @@ public class Main implements ProtocolVersionList
* @param autoDelete
* @throws JMException
*/
- public void createQueue(String queueName,
- boolean durable,
- String owner,
- boolean autoDelete)
+ public void createNewQueue(String queueName, boolean durable, String owner, boolean autoDelete)
throws JMException
{
AMQQueue queue = _queueRegistry.getQueue(queueName);
- if (queue == null)
+ if (queue != null)
{
- try
- {
- queue = new AMQQueue(queueName, durable, owner, autoDelete, _queueRegistry);
- if (queue.isDurable() && !queue.isAutoDelete())
- {
- _messageStore.createQueue(queue);
- }
- _queueRegistry.registerQueue(queue);
- }
- catch (AMQException ex)
+ throw new JMException("The queue \"" + queueName + "\" already exists.");
+ }
+
+ try
+ {
+ queue = new AMQQueue(queueName, durable, owner, autoDelete, _queueRegistry);
+ if (queue.isDurable() && !queue.isAutoDelete())
{
- _logger.error("Error in creating queue " + queueName, ex);
- throw new MBeanException(ex, ex.toString());
+ _messageStore.createQueue(queue);
}
+ _queueRegistry.registerQueue(queue);
}
- else
+ catch (AMQException ex)
{
- throw new JMException("The queue \"" + queueName + "\" already exists.");
+ _logger.error("Error in creating queue " + queueName, ex);
+ throw new MBeanException(ex, ex.toString());
}
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java
index 69f5e862d6..d5ca567308 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java
@@ -25,14 +25,16 @@ import org.apache.qpid.server.management.AMQManagedObject;
import org.apache.qpid.server.management.Managable;
import org.apache.qpid.server.management.ManagedObject;
+import javax.management.MalformedObjectNameException;
import javax.management.NotCompliantMBeanException;
+import javax.management.ObjectName;
public abstract class AbstractExchange implements Exchange, Managable
{
private String _name;
protected boolean _durable;
-
+ protected String _exchangeType;
protected int _ticket;
protected ExchangeMBean _exchangeMbean;
@@ -64,6 +66,11 @@ public abstract class AbstractExchange implements Exchange, Managable
return _name;
}
+ public String getExchangeType()
+ {
+ return _exchangeType;
+ }
+
public Integer getTicketNo()
{
return _ticket;
@@ -79,6 +86,13 @@ public abstract class AbstractExchange implements Exchange, Managable
return _autoDelete;
}
+ public ObjectName getObjectName() throws MalformedObjectNameException
+ {
+ String objNameString = super.getObjectName().toString();
+ objNameString = objNameString + ",ExchangeType=" + _exchangeType;
+ return new ObjectName(objNameString);
+ }
+
} // End of MBean class
public String getName()
diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/DestNameExchange.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/DestNameExchange.java
index bb5547be64..c7722d0e67 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/exchange/DestNameExchange.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/DestNameExchange.java
@@ -24,15 +24,14 @@ import org.apache.log4j.Logger;
import org.apache.qpid.AMQException;
import org.apache.qpid.framing.BasicPublishBody;
import org.apache.qpid.framing.FieldTable;
-import org.apache.qpid.server.management.MBeanDescription;
import org.apache.qpid.server.management.MBeanConstructor;
+import org.apache.qpid.server.management.MBeanDescription;
import org.apache.qpid.server.queue.AMQMessage;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.registry.ApplicationRegistry;
import javax.management.JMException;
import javax.management.MBeanException;
-import javax.management.NotCompliantMBeanException;
import javax.management.openmbean.*;
import java.util.ArrayList;
import java.util.List;
@@ -53,53 +52,36 @@ public class DestNameExchange extends AbstractExchange
@MBeanDescription("Management Bean for Direct Exchange")
private final class DestNameExchangeMBean extends ExchangeMBean
{
- private String[] _bindingItemNames = {"BindingKey", "QueueNames"};
- private String[] _bindingItemDescriptions = {"Binding key", "Queue Names"};
- private String[] _bindingItemIndexNames = {"BindingKey"};
+ // open mbean data types for representing exchange bindings
+ private String[] _bindingItemNames = {"Routing Key", "Queue Names"};
+ private String[] _bindingItemIndexNames = {_bindingItemNames[0]};
private OpenType[] _bindingItemTypes = new OpenType[2];
-
private CompositeType _bindingDataType = null;
private TabularType _bindinglistDataType = null;
private TabularDataSupport _bindingList = null;
@MBeanConstructor("Creates an MBean for AMQ direct exchange")
- public DestNameExchangeMBean() throws NotCompliantMBeanException
+ public DestNameExchangeMBean() throws JMException
{
super();
+ _exchangeType = "direct";
init();
}
/**
* initialises the OpenType objects.
*/
- private void init()
+ private void init() throws OpenDataException
{
- try
- {
- _bindingItemTypes[0] = SimpleType.STRING;
- //_bindingItemTypes[1] = ArrayType.getArrayType(SimpleType.STRING);
- _bindingItemTypes[1] = new ArrayType(1, SimpleType.STRING);
-
- _bindingDataType = new CompositeType("QueueBinding",
- "Queue and binding keye",
- _bindingItemNames,
- _bindingItemDescriptions,
- _bindingItemTypes);
- _bindinglistDataType = new TabularType("Bindings",
- "List of queues and binding keys",
- _bindingDataType,
- _bindingItemIndexNames);
- }
- catch(OpenDataException ex)
- {
- //It should never occur.
- _logger.error("OpenDataTypes could not be created.", ex);
- throw new RuntimeException(ex);
- }
+ _bindingItemTypes[0] = SimpleType.STRING;
+ _bindingItemTypes[1] = new ArrayType(1, SimpleType.STRING);
+ _bindingDataType = new CompositeType("Exchange Binding", "Routing key and Queue names",
+ _bindingItemNames, _bindingItemNames, _bindingItemTypes);
+ _bindinglistDataType = new TabularType("Exchange Bindings", "Exchange Bindings for " + getName(),
+ _bindingDataType, _bindingItemIndexNames);
}
- public TabularData viewBindings()
- throws OpenDataException
+ public TabularData bindings() throws OpenDataException
{
Map<String, List<AMQQueue>> bindings = _index.getBindingsMap();
_bindingList = new TabularDataSupport(_bindinglistDataType);
@@ -116,20 +98,16 @@ public class DestNameExchange extends AbstractExchange
}
Object[] bindingItemValues = {key, queueList.toArray(new String[0])};
- CompositeData bindingData = new CompositeDataSupport(_bindingDataType,
- _bindingItemNames,
- bindingItemValues);
+ CompositeData bindingData = new CompositeDataSupport(_bindingDataType, _bindingItemNames, bindingItemValues);
_bindingList.put(bindingData);
}
return _bindingList;
}
- public void createBinding(String queueName, String binding)
- throws JMException
+ public void createNewBinding(String queueName, String binding) throws JMException
{
AMQQueue queue = ApplicationRegistry.getInstance().getQueueRegistry().getQueue(queueName);
-
if (queue == null)
{
throw new JMException("Queue \"" + queueName + "\" is not registered with the exchange.");
@@ -155,10 +133,10 @@ public class DestNameExchange extends AbstractExchange
{
return new DestNameExchangeMBean();
}
- catch (NotCompliantMBeanException ex)
+ catch (JMException ex)
{
- _logger.error("Exception occured in creating the DestNameExchenge", ex);
- throw new AMQException("Exception occured in creating the DestNameExchenge", ex);
+ _logger.error("Exception occured in creating the direct exchange mbean", ex);
+ throw new AMQException("Exception occured in creating the direct exchange mbean", ex);
}
}
@@ -172,8 +150,7 @@ public class DestNameExchange extends AbstractExchange
}
else
{
- _logger.debug("Binding queue " + queue + " with routing key " + routingKey
- + " to exchange " + this);
+ _logger.debug("Binding queue " + queue + " with routing key " + routingKey + " to exchange " + this);
}
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/DestWildExchange.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/DestWildExchange.java
index 4258ce345e..6ac73c4484 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/exchange/DestWildExchange.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/DestWildExchange.java
@@ -22,18 +22,17 @@ package org.apache.qpid.server.exchange;
import org.apache.log4j.Logger;
import org.apache.qpid.AMQException;
-import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.framing.BasicPublishBody;
-import org.apache.qpid.server.queue.AMQQueue;
+import org.apache.qpid.framing.FieldTable;
+import org.apache.qpid.server.management.MBeanConstructor;
+import org.apache.qpid.server.management.MBeanDescription;
import org.apache.qpid.server.queue.AMQMessage;
+import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.management.MBeanDescription;
-import org.apache.qpid.server.management.MBeanConstructor;
-import javax.management.openmbean.*;
import javax.management.JMException;
import javax.management.MBeanException;
-import javax.management.NotCompliantMBeanException;
+import javax.management.openmbean.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -53,55 +52,41 @@ public class DestWildExchange extends AbstractExchange
@MBeanDescription("Management Bean for Topic Exchange")
private final class DestWildExchangeMBean extends ExchangeMBean
{
- private String[] _bindingItemNames = {"BindingKey", "QueueNames"};
- private String[] _bindingItemDescriptions = {"Binding key", "Queue Names"};
- private String[] _bindingItemIndexNames = {"BindingKey"};
+ // open mbean data types for representing exchange bindings
+ private String[] _bindingItemNames = {"Routing Key", "Queue Names"};
+ private String[] _bindingItemIndexNames = {_bindingItemNames[0]};
private OpenType[] _bindingItemTypes = new OpenType[2];
-
private CompositeType _bindingDataType = null;
private TabularType _bindinglistDataType = null;
private TabularDataSupport _bindingList = null;
@MBeanConstructor("Creates an MBean for AMQ topic exchange")
- public DestWildExchangeMBean() throws NotCompliantMBeanException
+ public DestWildExchangeMBean() throws JMException
{
super();
+ _exchangeType = "topic";
init();
}
/**
* initialises the OpenType objects.
*/
- private void init()
+ private void init() throws OpenDataException
{
- try
- {
- _bindingItemTypes[0] = SimpleType.STRING;
- _bindingItemTypes[1] = new ArrayType(1, SimpleType.STRING);
-
- _bindingDataType = new CompositeType("QueueBinding",
- "Queue and binding keye",
- _bindingItemNames,
- _bindingItemDescriptions,
- _bindingItemTypes);
- _bindinglistDataType = new TabularType("Bindings",
- "List of queues and binding keys",
- _bindingDataType,
- _bindingItemIndexNames);
- }
- catch(OpenDataException ex)
- {
- //It should never occur.
- _logger.error("OpenDataTypes could not be created.", ex);
- throw new RuntimeException(ex);
- }
+ _bindingItemTypes[0] = SimpleType.STRING;
+ _bindingItemTypes[1] = new ArrayType(1, SimpleType.STRING);
+ _bindingDataType = new CompositeType("Exchange Binding", "Routing key and Queue names",
+ _bindingItemNames, _bindingItemNames, _bindingItemTypes);
+ _bindinglistDataType = new TabularType("Exchange Bindings", "Exchange Bindings for " + getName(),
+ _bindingDataType, _bindingItemIndexNames);
}
- public TabularData viewBindings()
- throws OpenDataException
+ /**
+ * returns exchange bindings in tabular form
+ */
+ public TabularData bindings() throws OpenDataException
{
_bindingList = new TabularDataSupport(_bindinglistDataType);
-
for (Map.Entry<String, List<AMQQueue>> entry : _routingKey2queues.entrySet())
{
String key = entry.getKey();
@@ -114,20 +99,16 @@ public class DestWildExchange extends AbstractExchange
}
Object[] bindingItemValues = {key, queueList.toArray(new String[0])};
- CompositeData bindingData = new CompositeDataSupport(_bindingDataType,
- _bindingItemNames,
- bindingItemValues);
+ CompositeData bindingData = new CompositeDataSupport(_bindingDataType, _bindingItemNames, bindingItemValues);
_bindingList.put(bindingData);
}
return _bindingList;
}
- public void createBinding(String queueName, String binding)
- throws JMException
+ public void createNewBinding(String queueName, String binding) throws JMException
{
AMQQueue queue = ApplicationRegistry.getInstance().getQueueRegistry().getQueue(queueName);
-
if (queue == null)
throw new JMException("Queue \"" + queueName + "\" is not registered with the exchange.");
@@ -217,10 +198,10 @@ public class DestWildExchange extends AbstractExchange
{
return new DestWildExchangeMBean();
}
- catch (NotCompliantMBeanException ex)
+ catch (JMException ex)
{
- _logger.error("Exception occured in creating the DestWildExchenge", ex);
- throw new AMQException("Exception occured in creating the DestWildExchenge", ex);
+ _logger.error("Exception occured in creating the topic exchenge mbean", ex);
+ throw new AMQException("Exception occured in creating the topic exchenge mbean", ex);
}
}
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java
index 406bd392d3..818e5b04b2 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java
@@ -25,6 +25,7 @@ import org.apache.qpid.AMQException;
import org.apache.qpid.framing.BasicContentHeaderProperties;
import org.apache.qpid.framing.ContentHeaderBody;
import org.apache.qpid.framing.FieldTable;
+import org.apache.qpid.framing.FieldTableFactory;
import org.apache.qpid.server.management.MBeanConstructor;
import org.apache.qpid.server.management.MBeanDescription;
import org.apache.qpid.server.queue.AMQMessage;
@@ -32,7 +33,6 @@ import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.registry.ApplicationRegistry;
import javax.management.JMException;
-import javax.management.NotCompliantMBeanException;
import javax.management.openmbean.*;
import java.util.ArrayList;
import java.util.Iterator;
@@ -80,53 +80,39 @@ public class HeadersExchange extends AbstractExchange
@MBeanDescription("Management Bean for Headers Exchange")
private final class HeadersExchangeMBean extends ExchangeMBean
{
- private String[] _bindingItemNames = {"Queue", "HeaderBinding"};
- private String[] _bindingItemDescriptions = {"Queue Name", "Header attribute bindings"};
- private String[] _bindingItemIndexNames = {"HeaderBinding"};
- private OpenType[] _bindingItemTypes = new OpenType[2];
-
+ // open mbean data types for representing exchange bindings
+ private String[] _bindingItemNames = {"S.No.", "Queue Name", "Header Bindings"};
+ private String[] _bindingItemIndexNames = {_bindingItemNames[0]};
+ private OpenType[] _bindingItemTypes = new OpenType[3];
private CompositeType _bindingDataType = null;
private TabularType _bindinglistDataType = null;
private TabularDataSupport _bindingList = null;
@MBeanConstructor("Creates an MBean for AMQ Headers exchange")
- public HeadersExchangeMBean() throws NotCompliantMBeanException
+ public HeadersExchangeMBean() throws JMException
{
super();
+ _exchangeType = "headers";
init();
}
/**
* initialises the OpenType objects.
*/
- private void init()
+ private void init() throws OpenDataException
{
- try
- {
- _bindingItemTypes[0] = SimpleType.STRING;
- _bindingItemTypes[1] = new ArrayType(1, SimpleType.STRING);
-
- _bindingDataType = new CompositeType("QueueAndHeaderAttributesBinding",
- "Queue name and header bindings",
- _bindingItemNames,
- _bindingItemDescriptions,
- _bindingItemTypes);
- _bindinglistDataType = new TabularType("HeaderBindings",
- "List of queue bindings for " + getName(),
- _bindingDataType,
- _bindingItemIndexNames);
- }
- catch(OpenDataException ex)
- {
- //It should never occur.
- _logger.error("OpenDataTypes could not be created.", ex);
- throw new RuntimeException(ex);
- }
+ _bindingItemTypes[0] = SimpleType.INTEGER;
+ _bindingItemTypes[1] = SimpleType.STRING;
+ _bindingItemTypes[2] = new ArrayType(1, SimpleType.STRING);
+ _bindingDataType = new CompositeType("Exchange Binding", "Queue name and header bindings",
+ _bindingItemNames, _bindingItemNames, _bindingItemTypes);
+ _bindinglistDataType = new TabularType("Exchange Bindings", "List of exchange bindings for " + getName(),
+ _bindingDataType, _bindingItemIndexNames);
}
- public TabularData viewBindings()
- throws OpenDataException
+ public TabularData bindings() throws OpenDataException
{
_bindingList = new TabularDataSupport(_bindinglistDataType);
+ int count = 1;
for (Iterator<Registration> itr = _bindings.iterator(); itr.hasNext();)
{
Registration registration = itr.next();
@@ -144,10 +130,8 @@ public class HeadersExchange extends AbstractExchange
mappingList.add(key + "=" + value);
}
- Object[] bindingItemValues = {queueName, mappingList.toArray(new String[0])};
- CompositeData bindingData = new CompositeDataSupport(_bindingDataType,
- _bindingItemNames,
- bindingItemValues);
+ Object[] bindingItemValues = {count++, queueName, mappingList.toArray(new String[0])};
+ CompositeData bindingData = new CompositeDataSupport(_bindingDataType, _bindingItemNames, bindingItemValues);
_bindingList.put(bindingData);
}
@@ -161,8 +145,7 @@ public class HeadersExchange extends AbstractExchange
* @param binding
* @throws javax.management.JMException
*/
- public void createBinding(String queueName, String binding)
- throws JMException
+ public void createNewBinding(String queueName, String binding) throws JMException
{
AMQQueue queue = ApplicationRegistry.getInstance().getQueueRegistry().getQueue(queueName);
@@ -172,7 +155,7 @@ public class HeadersExchange extends AbstractExchange
}
String[] bindings = binding.split(",");
- FieldTable fieldTable = new FieldTable();
+ FieldTable fieldTable = FieldTableFactory.newFieldTable();
for (int i = 0; i < bindings.length; i++)
{
String[] keyAndValue = bindings[i].split("=");
@@ -240,7 +223,7 @@ public class HeadersExchange extends AbstractExchange
{
return new HeadersExchangeMBean();
}
- catch (NotCompliantMBeanException ex)
+ catch (JMException ex)
{
_logger.error("Exception occured in creating the HeadersExchangeMBean", ex);
throw new AMQException("Exception occured in creating the HeadersExchangeMBean", ex);
diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/ManagedExchange.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/ManagedExchange.java
index 3c2c105186..b61aa233f8 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/exchange/ManagedExchange.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/ManagedExchange.java
@@ -23,6 +23,7 @@ package org.apache.qpid.server.exchange;
import org.apache.qpid.server.management.MBeanAttribute;
import org.apache.qpid.server.management.MBeanOperation;
import org.apache.qpid.server.management.MBeanOperationParameter;
+import org.apache.qpid.server.queue.ManagedQueue;
import javax.management.openmbean.TabularData;
import javax.management.JMException;
@@ -44,9 +45,12 @@ public interface ManagedExchange
* @return the name of the exchange.
* @throws IOException
*/
- @MBeanAttribute(name="Name", description="Name of exchange")
+ @MBeanAttribute(name="Name", description=TYPE + " Name")
String getName() throws IOException;
+ @MBeanAttribute(name="ExchangeType", description="Exchange Type")
+ String getExchangeType() throws IOException;
+
@MBeanAttribute(name="TicketNo", description="Exchange Ticket No")
Integer getTicketNo() throws IOException;
@@ -74,8 +78,8 @@ public interface ManagedExchange
* @throws IOException
* @throws JMException
*/
- @MBeanOperation(name="viewBindings", description="view the queue bindings for this exchange")
- TabularData viewBindings() throws IOException, JMException;
+ @MBeanOperation(name="bindings", description="view the queue bindings for this exchange")
+ TabularData bindings() throws IOException, JMException;
/**
* Creates new binding with the given queue and binding.
@@ -83,11 +87,11 @@ public interface ManagedExchange
* @param binding
* @throws JMException
*/
- @MBeanOperation(name="createBinding",
- description="create a new binding with this exchange",
- impact= MBeanOperationInfo.ACTION)
- void createBinding(@MBeanOperationParameter(name="queue name", description="queue name") String queueName,
- @MBeanOperationParameter(name="binding", description="queue binding")String binding)
+ @MBeanOperation(name="createNewBinding",
+ description="create a new binding with this exchange",
+ impact= MBeanOperationInfo.ACTION)
+ void createNewBinding(@MBeanOperationParameter(name= ManagedQueue.TYPE, description="Queue name") String queueName,
+ @MBeanOperationParameter(name="Binding", description="New binding")String binding)
throws JMException;
} \ No newline at end of file
diff --git a/java/broker/src/main/java/org/apache/qpid/server/management/ManagedBroker.java b/java/broker/src/main/java/org/apache/qpid/server/management/ManagedBroker.java
index 266fb62fd8..aec7d6cb73 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/management/ManagedBroker.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/management/ManagedBroker.java
@@ -21,6 +21,9 @@
package org.apache.qpid.server.management;
+import org.apache.qpid.server.exchange.ManagedExchange;
+import org.apache.qpid.server.queue.ManagedQueue;
+
import javax.management.JMException;
import javax.management.MBeanOperationInfo;
import java.io.IOException;
@@ -45,10 +48,9 @@ public interface ManagedBroker
* @throws IOException
* @throws JMException
*/
- @MBeanOperation(name="createNewExchange", description="Creates a new Exchange",
- impact= MBeanOperationInfo.ACTION)
+ @MBeanOperation(name="createNewExchange", description="Creates a new Exchange", impact= MBeanOperationInfo.ACTION)
void createNewExchange(@MBeanOperationParameter(name="name", description="Name of the new exchange")String name,
- @MBeanOperationParameter(name="excahnge type", description="Type of the exchange")String type,
+ @MBeanOperationParameter(name="ExchangeType", description="Type of the exchange")String type,
@MBeanOperationParameter(name="durable", description="true if the Exchang should be durable")boolean durable,
@MBeanOperationParameter(name="passive", description="true of the Exchange should be passive")boolean passive)
throws IOException, JMException;
@@ -61,9 +63,9 @@ public interface ManagedBroker
* @throws JMException
*/
@MBeanOperation(name="unregisterExchange",
- description="Unregisters all the related channels and queuebindings of this exchange",
- impact= MBeanOperationInfo.ACTION)
- void unregisterExchange(@MBeanOperationParameter(name="exchange name", description="Name of the exchange")String exchange)
+ description="Unregisters all the related channels and queuebindings of this exchange",
+ impact= MBeanOperationInfo.ACTION)
+ void unregisterExchange(@MBeanOperationParameter(name= ManagedExchange.TYPE, description="Exchange Name")String exchange)
throws IOException, JMException;
/**
@@ -75,12 +77,11 @@ public interface ManagedBroker
* @throws IOException
* @throws JMException
*/
- @MBeanOperation(name="createQueue", description="Create a new Queue on the Broker server",
- impact= MBeanOperationInfo.ACTION)
- void createQueue(@MBeanOperationParameter(name="queue name", description="Name of the new queue")String queueName,
- @MBeanOperationParameter(name="durable", description="true if the queue should be durable")boolean durable,
- @MBeanOperationParameter(name="owner", description="Owner name")String owner,
- @MBeanOperationParameter(name="autoDelete", description="true if the queue should be auto delete") boolean autoDelete)
+ @MBeanOperation(name="createNewQueue", description="Create a new Queue on the Broker server", impact= MBeanOperationInfo.ACTION)
+ void createNewQueue(@MBeanOperationParameter(name="queue name", description="Name of the new queue")String queueName,
+ @MBeanOperationParameter(name="durable", description="true if the queue should be durable")boolean durable,
+ @MBeanOperationParameter(name="owner", description="Owner name")String owner,
+ @MBeanOperationParameter(name="autoDelete", description="true if the queue should be auto delete") boolean autoDelete)
throws IOException, JMException;
/**
@@ -93,6 +94,6 @@ public interface ManagedBroker
@MBeanOperation(name="deleteQueue",
description="Unregisters the Queue bindings, removes the subscriptions and deletes the queue",
impact= MBeanOperationInfo.ACTION)
- void deleteQueue(@MBeanOperationParameter(name="queue name", description="Name of the queue")String queueName)
+ void deleteQueue(@MBeanOperationParameter(name= ManagedQueue.TYPE, description="Queue Name")String queueName)
throws IOException, JMException;
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQMinaProtocolSession.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQMinaProtocolSession.java
index 46289ecab8..fd97bf0d96 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQMinaProtocolSession.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQMinaProtocolSession.java
@@ -36,7 +36,10 @@ import org.apache.qpid.server.queue.QueueRegistry;
import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.state.AMQStateManager;
-import javax.management.*;
+import javax.management.JMException;
+import javax.management.MBeanException;
+import javax.management.MBeanNotificationInfo;
+import javax.management.Notification;
import javax.management.monitor.MonitorNotification;
import javax.management.openmbean.*;
import javax.security.sasl.SaslServer;
@@ -97,66 +100,35 @@ public class AMQMinaProtocolSession implements AMQProtocolSession,
* augment the ManagedConnection interface and add the appropriate implementation here.
*/
@MBeanDescription("Management Bean for an AMQ Broker Connection")
- private final class ManagedAMQProtocolSession extends AMQManagedObject
- implements ManagedConnection
+ private final class ManagedAMQProtocolSession extends AMQManagedObject implements ManagedConnection
{
private String _name = null;
- /**
- * Represents the channel attributes sent with channel data.
- */
- private String[] _channelAtttibuteNames = { "ChannelId",
- "Transactional",
- "DefaultQueue",
- "UnacknowledgedMessageCount"};
- private String[] _channelAttributeDescriptions = { "Channel Identifier",
- "is Channel Transactional?",
- "Default Queue Name",
- "Unacknowledged Message Count"};
- private OpenType[] _channelAttributeTypes = { SimpleType.INTEGER,
- SimpleType.BOOLEAN,
- SimpleType.STRING,
- SimpleType.INTEGER};
-
- private String[] _indexNames = { "ChannelId" }; //Channels in the list will be indexed according to channelId.
- private CompositeType _channelType = null; // represents the data type for channel data
- private TabularType _channelsType = null; // Datatype for list of channelsType
+ //openmbean data types for representing the channel attributes
+ private String[] _channelAtttibuteNames = { "Channel Id", "Transactional", "Default Queue", "Unacknowledged Message Count"};
+ private String[] _indexNames = {_channelAtttibuteNames[0]};
+ private OpenType[] _channelAttributeTypes = {SimpleType.INTEGER, SimpleType.BOOLEAN, SimpleType.STRING, SimpleType.INTEGER};
+ private CompositeType _channelType = null; // represents the data type for channel data
+ private TabularType _channelsType = null; // Data type for list of channels type
private TabularDataSupport _channelsList = null;
@MBeanConstructor("Creates an MBean exposing an AMQ Broker Connection")
- public ManagedAMQProtocolSession() throws NotCompliantMBeanException
+ public ManagedAMQProtocolSession() throws JMException
{
super(ManagedConnection.class, ManagedConnection.TYPE);
init();
}
/**
- * initialises the CompositeTypes and TabularType attributes.
+ * initialises the openmbean data types
*/
- private void init()
+ private void init() throws OpenDataException
{
String remote = getRemoteAddress();
remote = "anonymous".equals(remote) ? remote + hashCode() : remote;
_name = jmxEncode(new StringBuffer(remote), 0).toString();
-
- try
- {
- _channelType = new CompositeType("channel",
- "Channel Details",
- _channelAtttibuteNames,
- _channelAttributeDescriptions,
- _channelAttributeTypes);
-
- _channelsType = new TabularType("channelsType",
- "List of available channels",
- _channelType,
- _indexNames);
- }
- catch(OpenDataException ex)
- {
- // It should never occur.
- _logger.error("OpenDataTypes could not be created.", ex);
- throw new RuntimeException(ex);
- }
+ _channelType = new CompositeType("Channel", "Channel Details", _channelAtttibuteNames,
+ _channelAtttibuteNames, _channelAttributeTypes);
+ _channelsType = new TabularType("Channels", "Channels", _channelType, _indexNames);
}
public Date getLastIoTime()
@@ -179,12 +151,12 @@ public class AMQMinaProtocolSession implements AMQProtocolSession,
return _minaProtocolSession.getReadBytes();
}
- public Long getMaximumNumberOfAllowedChannels()
+ public Long getMaximumNumberOfChannels()
{
return _maxNoOfChannels;
}
- public void setMaximumNumberOfAllowedChannels(Long value)
+ public void setMaximumNumberOfChannels(Long value)
{
_maxNoOfChannels = value;
}
@@ -239,30 +211,25 @@ public class AMQMinaProtocolSession implements AMQProtocolSession,
* @return list of channels in tabular form.
* @throws OpenDataException
*/
- public TabularData getChannels() throws OpenDataException
+ public TabularData channels() throws OpenDataException
{
_channelsList = new TabularDataSupport(_channelsType);
for (Map.Entry<Integer, AMQChannel> entry : _channelMap.entrySet())
{
AMQChannel channel = entry.getValue();
- Object[] itemValues = {channel.getChannelId(),
- channel.isTransactional(),
+ Object[] itemValues = {channel.getChannelId(), channel.isTransactional(),
(channel.getDefaultQueue() != null) ? channel.getDefaultQueue().getName() : null,
channel.getUnacknowledgedMessageMap().size()};
- CompositeData channelData = new CompositeDataSupport(_channelType,
- _channelAtttibuteNames,
- itemValues);
-
+ CompositeData channelData = new CompositeDataSupport(_channelType, _channelAtttibuteNames, itemValues);
_channelsList.put(channelData);
}
return _channelsList;
}
-
- public void closeChannel(int id)
- throws Exception
+
+ public void closeChannel(int id) throws Exception
{
try
{
@@ -274,8 +241,7 @@ public class AMQMinaProtocolSession implements AMQProtocolSession,
}
}
- public void closeConnection()
- throws Exception
+ public void closeConnection() throws Exception
{
try
{
@@ -290,13 +256,10 @@ public class AMQMinaProtocolSession implements AMQProtocolSession,
@Override
public MBeanNotificationInfo[] getNotificationInfo()
{
- String[] notificationTypes = new String[]
- {MonitorNotification.THRESHOLD_VALUE_EXCEEDED};
+ String[] notificationTypes = new String[] {MonitorNotification.THRESHOLD_VALUE_EXCEEDED};
String name = MonitorNotification.class.getName();
- String description = "An attribute of this MBean has reached threshold value";
- MBeanNotificationInfo info1 = new MBeanNotificationInfo(notificationTypes,
- name,
- description);
+ String description = "Channel count has reached threshold value";
+ MBeanNotificationInfo info1 = new MBeanNotificationInfo(notificationTypes, name, description);
return new MBeanNotificationInfo[] {info1};
}
@@ -304,14 +267,11 @@ public class AMQMinaProtocolSession implements AMQProtocolSession,
private void checkForNotification()
{
int channelsCount = _channelMap.size();
- if (channelsCount >= getMaximumNumberOfAllowedChannels())
+ if (channelsCount >= getMaximumNumberOfChannels())
{
- Notification n = new Notification(
- MonitorNotification.THRESHOLD_VALUE_EXCEEDED,
- this,
- ++_notificationSequenceNumber,
- System.currentTimeMillis(),
- "ChannelsCount = " + channelsCount + ", ChannelsCount has reached the threshold value");
+ Notification n = new Notification(MonitorNotification.THRESHOLD_VALUE_EXCEEDED, this,
+ ++_notificationSequenceNumber, System.currentTimeMillis(),
+ "Channel count (" + channelsCount + ") has reached the threshold value");
_broadcaster.sendNotification(n);
}
@@ -347,10 +307,10 @@ public class AMQMinaProtocolSession implements AMQProtocolSession,
{
return new ManagedAMQProtocolSession();
}
- catch(NotCompliantMBeanException ex)
+ catch(JMException ex)
{
- _logger.error("AMQProtocolSession MBean creation has failed.", ex);
- throw new AMQException("AMQProtocolSession MBean creation has failed.", ex);
+ _logger.error("AMQProtocolSession MBean creation has failed ", ex);
+ throw new AMQException("AMQProtocolSession MBean creation has failed ", ex);
}
}
@@ -389,6 +349,11 @@ public class AMQMinaProtocolSession implements AMQProtocolSession,
int i = pv.length - 1;
_minaProtocolSession.write(new ProtocolInitiation(pv[i][PROTOCOL_MAJOR], pv[i][PROTOCOL_MINOR]));
// TODO: Close connection (but how to wait until message is sent?)
+ // ritchiem 2006-12-04 will this not do?
+// WriteFuture future = _minaProtocolSession.write(new ProtocolInitiation(pv[i][PROTOCOL_MAJOR], pv[i][PROTOCOL_MINOR]));
+// future.join();
+// close connection
+
}
}
else
diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/ManagedConnection.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/ManagedConnection.java
index 889acd0142..2f3102b048 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/protocol/ManagedConnection.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/ManagedConnection.java
@@ -41,83 +41,57 @@ public interface ManagedConnection
static final String TYPE = "Connection";
/**
- * channel details of all the channels opened for this connection.
- * @return general channel details
- * @throws IOException
- * @throws JMException
+ * Tells the remote address of this connection.
+ * @return remote address
*/
- @MBeanAttribute(name="Channels",
- description="channel details of all the channels opened for this connection")
- TabularData getChannels() throws IOException, JMException;
+ @MBeanAttribute(name="RemoteAddress", description=TYPE + " Address")
+ String getRemoteAddress();
/**
* Tells the last time, the IO operation was done.
* @return last IO time.
*/
- @MBeanAttribute(name="LastIOTime",
- description="The last time, the IO operation was done")
+ @MBeanAttribute(name="LastIOTime", description="The last time, the IO operation was done")
Date getLastIoTime();
/**
- * Tells the remote address of this connection.
- * @return remote address
- */
- @MBeanAttribute(name="RemoteAddress",
- description="The remote address of this connection")
- String getRemoteAddress();
-
- /**
* Tells the total number of bytes written till now.
* @return number of bytes written.
*/
- @MBeanAttribute(name="WrittenBytes",
- description="The total number of bytes written till now")
+ @MBeanAttribute(name="WrittenBytes", description="The total number of bytes written till now")
Long getWrittenBytes();
/**
* Tells the total number of bytes read till now.
* @return number of bytes read.
*/
- @MBeanAttribute(name="ReadBytes",
- description="The total number of bytes read till now")
+ @MBeanAttribute(name="ReadBytes", description="The total number of bytes read till now")
Long getReadBytes();
/**
- * Tells the maximum number of channels that can be opened using
- * this connection. This is useful in setting notifications or
+ * Threshold high value for no of channels. This is useful in setting notifications or
* taking required action is there are more channels being created.
- * @return maximum number of channels allowed to be created.
+ * @return threshold limit for no of channels
*/
- Long getMaximumNumberOfAllowedChannels();
+ Long getMaximumNumberOfChannels();
/**
- * Sets the maximum number of channels allowed to be created using
- * this connection.
+ * Sets the threshold high value for number of channels for a connection
* @param value
*/
- @MBeanAttribute(name="MaximumNumberOfAllowedChannels",
- description="The maximum number of channels that can be opened using this connection")
- void setMaximumNumberOfAllowedChannels(Long value);
+ @MBeanAttribute(name="MaximumNumberOfChannels", description="The threshold high value for number of channels for this connection")
+ void setMaximumNumberOfChannels(Long value);
//********** Operations *****************//
/**
- * Closes all the related channels and unregisters this connection from managed objects.
- */
- @MBeanOperation(name="closeConnection",
- description="Closes this connection and all related channels",
- impact= MBeanOperationInfo.ACTION)
- void closeConnection() throws Exception;
-
- /**
- * Unsubscribes the consumers and unregisters the channel from managed objects.
+ * channel details of all the channels opened for this connection.
+ * @return general channel details
+ * @throws IOException
+ * @throws JMException
*/
- @MBeanOperation(name="closeChannel",
- description="Closes the channel with given channeld and" +
- "connected consumers will be unsubscribed",
- impact= MBeanOperationInfo.ACTION)
- void closeChannel(@MBeanOperationParameter(name="channel Id", description="channel Id")int channelId)
- throws Exception;
+ @MBeanOperation(name="channels", description="Channel details for this connection")
+ TabularData channels() throws IOException, JMException;
/**
* Commits the transactions if the channel is transactional.
@@ -125,8 +99,8 @@ public interface ManagedConnection
* @throws JMException
*/
@MBeanOperation(name="commitTransaction",
- description="Commits the transactions for given channelID, if the channel is transactional",
- impact= MBeanOperationInfo.ACTION)
+ description="Commits the transactions for given channel Id, if the channel is transactional",
+ impact= MBeanOperationInfo.ACTION)
void commitTransactions(@MBeanOperationParameter(name="channel Id", description="channel Id")int channelId) throws JMException;
/**
@@ -135,7 +109,24 @@ public interface ManagedConnection
* @throws JMException
*/
@MBeanOperation(name="rollbackTransactions",
- description="Rollsback the transactions for given channelId, if the channel is transactional",
- impact= MBeanOperationInfo.ACTION)
+ description="Rollsback the transactions for given channel Id, if the channel is transactional",
+ impact= MBeanOperationInfo.ACTION)
void rollbackTransactions(@MBeanOperationParameter(name="channel Id", description="channel Id")int channelId) throws JMException;
+
+ /**
+ * Unsubscribes the consumers and unregisters the channel from managed objects.
+ */
+ @MBeanOperation(name="closeChannel",
+ description="Closes the channel with given channel Id and connected consumers will be unsubscribed",
+ impact= MBeanOperationInfo.ACTION)
+ void closeChannel(@MBeanOperationParameter(name="channel Id", description="channel Id")int channelId)
+ throws Exception;
+
+ /**
+ * Closes all the related channels and unregisters this connection from managed objects.
+ */
+ @MBeanOperation(name="closeConnection",
+ description="Closes this connection and all related channels",
+ impact= MBeanOperationInfo.ACTION)
+ void closeConnection() throws Exception;
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java b/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java
index 8cc358f243..7f3d772e47 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java
@@ -23,6 +23,7 @@ package org.apache.qpid.server.queue;
import org.apache.log4j.Logger;
import org.apache.qpid.AMQException;
import org.apache.qpid.framing.ContentBody;
+import org.apache.qpid.framing.ContentHeaderBody;
import org.apache.qpid.framing.BasicContentHeaderProperties;
import org.apache.qpid.server.exchange.Exchange;
import org.apache.qpid.server.management.*;
@@ -91,19 +92,19 @@ public class AMQQueue implements Managable, Comparable
private final AMQQueueMBean _managedObject;
/**
- * max allowed size of a single message(in KBytes).
+ * max allowed size(KB) of a single message
*/
- private long _maxAllowedMessageSize = 10000; // 10 MB
+ private long _maxMessageSize = 10000;
/**
* max allowed number of messages on a queue.
*/
- private Integer _maxAllowedMessageCount = 10000;
+ private Integer _maxMessageCount = 10000;
/**
- * max allowed size in KBytes for all the messages combined together in a queue.
+ * max queue depth(KB) for the queue
*/
- private long _queueDepth = 10000000; // 10 GB
+ private long _maxQueueDepth = 10000000;
/**
* total messages received by the queue since startup.
@@ -123,83 +124,45 @@ public class AMQQueue implements Managable, Comparable
private final class AMQQueueMBean extends AMQManagedObject implements ManagedQueue
{
private String _queueName = null;
+ // OpenMBean data types for viewMessages method
+ private String[] _msgAttributeNames = {"Message Id", "Header", "Size(bytes)", "Redelivered"};
+ private String[] _msgAttributeIndex = {_msgAttributeNames[0]};
+ private OpenType[] _msgAttributeTypes = new OpenType[4]; // AMQ message attribute types.
+ private CompositeType _messageDataType = null; // Composite type for representing AMQ Message data.
+ private TabularType _messagelistDataType = null; // Datatype for representing AMQ messages list.
- // AMQ message attribute names
- private String[] _msgAttributeNames = {"MessageId",
- "Header",
- "Size",
- "Redelivered"
- };
- // AMQ Message attribute descriptions.
- private String[] _msgAttributeDescriptions = {"Message Id",
- "Header",
- "Message size in bytes",
- "Redelivered"
- };
-
- private OpenType[] _msgAttributeTypes = new OpenType[4]; // AMQ message attribute types.
- private String[] _msgAttributeIndex = {"MessageId"}; // Messages will be indexed according to the messageId.
- private CompositeType _messageDataType = null; // Composite type for representing AMQ Message data.
- private TabularType _messagelistDataType = null; // Datatype for representing AMQ messages list.
-
-
- private CompositeType _msgContentType = null; // For message content
- private String[] _msgContentAttributes = {"MessageId",
- "MimeType",
- "Encoding",
- "Content"
- };
- private String[] _msgContentDescriptions = {"Message Id",
- "MimeType",
- "Encoding",
- "Message content"
- };
- private OpenType[] _msgContentAttributeTypes = new OpenType[4];
-
-
- @MBeanConstructor("Creates an MBean exposing an AMQQueue.")
- public AMQQueueMBean() throws NotCompliantMBeanException
+ // OpenMBean data types for viewMessageContent method
+ private CompositeType _msgContentType = null;
+ private String[] _msgContentAttributes = {"Message Id", "MimeType", "Encoding", "Content"};
+ private OpenType[] _msgContentAttributeTypes = new OpenType[4];
+
+ @MBeanConstructor("Creates an MBean exposing an AMQQueue")
+ public AMQQueueMBean() throws JMException
{
super(ManagedQueue.class, ManagedQueue.TYPE);
init();
}
- private void init()
+ /**
+ * initialises the openmbean data types
+ */
+ private void init() throws OpenDataException
{
_queueName = jmxEncode(new StringBuffer(_name), 0).toString();
- try
- {
- _msgContentAttributeTypes[0] = SimpleType.LONG; // For message id
- _msgContentAttributeTypes[1] = SimpleType.STRING; // For MimeType
- _msgContentAttributeTypes[2] = SimpleType.STRING; // For Encoding
- _msgContentAttributeTypes[3] = new ArrayType(1, SimpleType.BYTE); // For message content
- _msgContentType = new CompositeType("MessageContent",
- "AMQ Message Content",
- _msgContentAttributes,
- _msgContentDescriptions,
- _msgContentAttributeTypes);
-
-
- _msgAttributeTypes[0] = SimpleType.LONG; // For message id
- _msgAttributeTypes[1] = new ArrayType(1, SimpleType.STRING); // For header attributes
- _msgAttributeTypes[2] = SimpleType.LONG; // For size
- _msgAttributeTypes[3] = SimpleType.BOOLEAN; // For redelivered
-
- _messageDataType = new CompositeType("Message",
- "AMQ Message",
- _msgAttributeNames,
- _msgAttributeDescriptions,
- _msgAttributeTypes);
- _messagelistDataType = new TabularType("Messages",
- "List of messages",
- _messageDataType,
- _msgAttributeIndex);
- }
- catch (OpenDataException ex)
- {
- _logger.error("OpenDataTypes could not be created.", ex);
- throw new RuntimeException(ex);
- }
+ _msgContentAttributeTypes[0] = SimpleType.LONG; // For message id
+ _msgContentAttributeTypes[1] = SimpleType.STRING; // For MimeType
+ _msgContentAttributeTypes[2] = SimpleType.STRING; // For Encoding
+ _msgContentAttributeTypes[3] = new ArrayType(1, SimpleType.BYTE); // For message content
+ _msgContentType = new CompositeType("Message Content", "AMQ Message Content", _msgContentAttributes,
+ _msgContentAttributes, _msgContentAttributeTypes);
+
+ _msgAttributeTypes[0] = SimpleType.LONG; // For message id
+ _msgAttributeTypes[1] = new ArrayType(1, SimpleType.STRING); // For header attributes
+ _msgAttributeTypes[2] = SimpleType.LONG; // For size
+ _msgAttributeTypes[3] = SimpleType.BOOLEAN; // For redelivered
+
+ _messageDataType = new CompositeType("Message","AMQ Message", _msgAttributeNames, _msgAttributeNames, _msgAttributeTypes);
+ _messagelistDataType = new TabularType("Messages", "List of messages", _messageDataType, _msgAttributeIndex);
}
public String getObjectInstanceName()
@@ -234,12 +197,12 @@ public class AMQQueue implements Managable, Comparable
public Long getMaximumMessageSize()
{
- return _maxAllowedMessageSize;
+ return _maxMessageSize;
}
public void setMaximumMessageSize(Long value)
{
- _maxAllowedMessageSize = value;
+ _maxMessageSize = value;
}
public Integer getConsumerCount()
@@ -259,27 +222,29 @@ public class AMQQueue implements Managable, Comparable
public Integer getMaximumMessageCount()
{
- return _maxAllowedMessageCount;
+ return _maxMessageCount;
}
public void setMaximumMessageCount(Integer value)
{
- _maxAllowedMessageCount = value;
+ _maxMessageCount = value;
}
- public Long getQueueDepth()
+ public Long getMaximumQueueDepth()
{
- return _queueDepth;
+ return _maxQueueDepth;
}
// Sets the queue depth, the max queue size
- public void setQueueDepth(Long value)
+ public void setMaximumQueueDepth(Long value)
{
- _queueDepth = value;
+ _maxQueueDepth = value;
}
- // Returns the size of messages in the queue
- public Long getQueueSize() throws AMQException
+ /**
+ * returns the size of messages(KB) in the queue.
+ */
+ public Long getQueueDepth()
{
/* TODO: this must return a maintained count not
* iterate through all messages
@@ -291,17 +256,19 @@ public class AMQQueue implements Managable, Comparable
return 0l;
}
- long queueSize = 0;
+ long queueDepth = 0;
for (AMQMessage message : list)
{
- queueSize = queueSize + getMessageSize(message);
+ queueDepth = queueDepth + getMessageSize(message);
}
- return new Long(Math.round(queueSize / 100));
+ return (long)Math.round(queueDepth / 1000);
*/
}
// Operations
- // calculates the size of an AMQMessage
+ /**
+ * returns size of message in bytes
+ */
private long getMessageSize(AMQMessage msg) throws AMQException
{
if (msg == null)
@@ -312,41 +279,40 @@ public class AMQQueue implements Managable, Comparable
return msg.getContentHeaderBody().bodySize;
}
- // Checks if there is any notification to be send to the listeners
+ /**
+ * Checks if there is any notification to be send to the listeners
+ */
private void checkForNotification(AMQMessage msg) throws AMQException
{
- // Check for message count
+ // Check for threshold message count
Integer msgCount = getMessageCount();
if (msgCount >= getMaximumMessageCount())
{
- notifyClients("MessageCount = " + msgCount + ", Queue has reached its size limit and is now full.");
+ notifyClients("Message count(" + msgCount + ") has reached or exceeded the threshold high value");
}
- // Check for received message size
+ // Check for threshold message size
long messageSize = getMessageSize(msg);
- if (messageSize >= getMaximumMessageSize())
+ if (messageSize >= _maxMessageSize)
{
- notifyClients("MessageSize = " + messageSize + ", Message size (MessageID=" + msg.getMessageId() +
- ")is higher than the threshold value");
+ notifyClients("Message size(ID=" + msg.getMessageId() + ", size=" + messageSize + " bytes) is higher than the threshold value");
}
- // Check for queue size in bytes
- long queueSize = getQueueSize();
- if (queueSize >= getQueueDepth())
+ // Check for threshold queue depth in bytes
+ long queueDepth = getQueueDepth();
+ if (queueDepth >= _maxQueueDepth)
{
- notifyClients("QueueSize = " + queueSize + ", Queue size has reached the threshold value");
+ notifyClients("Queue depth(" + queueDepth + "), Queue size has reached the threshold high value");
}
}
- // Send the notification to the listeners
+ /**
+ * Sends the notification to the listeners
+ */
private void notifyClients(String notificationMsg)
{
- Notification n = new Notification(
- MonitorNotification.THRESHOLD_VALUE_EXCEEDED,
- this,
- ++_notificationSequenceNumber,
- System.currentTimeMillis(),
- notificationMsg);
+ Notification n = new Notification(MonitorNotification.THRESHOLD_VALUE_EXCEEDED, this,
+ ++_notificationSequenceNumber, System.currentTimeMillis(), notificationMsg);
_broadcaster.sendNotification(n);
}
@@ -375,10 +341,12 @@ public class AMQQueue implements Managable, Comparable
}
}
- public CompositeData viewMessageContent(long msgId) throws JMException, AMQException
+ /**
+ * returns message content as byte array and related attributes for the given message id.
+ */
+ public CompositeData viewMessageContent(long msgId) throws JMException
{
List<AMQMessage> list = _deliveryMgr.getMessages();
- CompositeData messageContent = null;
AMQMessage msg = null;
for (AMQMessage message : list)
{
@@ -391,70 +359,65 @@ public class AMQQueue implements Managable, Comparable
if (msg != null)
{
- // get message content
- Iterator<ContentBody> cBodies = msg.getContentBodyIterator();
- List<Byte> msgContent = new ArrayList<Byte>();
- while (cBodies.hasNext())
+ try
{
- ContentBody body = cBodies.next();
- if (body.getSize() != 0)
+ // get message content
+ Iterator<ContentBody> cBodies = msg.getContentBodyIterator();
+ List<Byte> msgContent = new ArrayList<Byte>();
+ while (cBodies.hasNext())
{
- ByteBuffer slice = body.payload.slice();
- for (int j = 0; j < slice.limit(); j++)
+ ContentBody body = cBodies.next();
+ if (body.getSize() != 0)
{
- msgContent.add(slice.get());
+ ByteBuffer slice = body.payload.slice();
+ for (int j = 0; j < slice.limit(); j++)
+ {
+ msgContent.add(slice.get());
+ }
}
}
- }
- // Create header attributes list
- BasicContentHeaderProperties headerProperties = (BasicContentHeaderProperties) msg.getContentHeaderBody().properties;
- String mimeType = headerProperties.getContentType();
- String encoding = headerProperties.getEncoding() == null ? "" : headerProperties.getEncoding();
+ // Create header attributes list
+ BasicContentHeaderProperties headerProperties = (BasicContentHeaderProperties)msg.getContentHeaderBody().properties;
+ String mimeType = headerProperties.getContentType();
+ String encoding = headerProperties.getEncoding() == null ? "" : headerProperties.getEncoding();
+ Object[] itemValues = {msgId, mimeType, encoding, msgContent.toArray(new Byte[0])};
- Object[] itemValues = {msgId, mimeType, encoding, msgContent.toArray(new Byte[0])};
- messageContent = new CompositeDataSupport(_msgContentType, _msgContentAttributes, itemValues);
+ return new CompositeDataSupport(_msgContentType, _msgContentAttributes, itemValues);
+ }
+ catch (AMQException e)
+ {
+ throw new JMException(e.getMessage());
+ }
}
else
{
- throw new JMException("AMQMessage with message id = " + msgId + " is not in the " + _queueName);
+ throw new OperationsException("AMQMessage with message id = " + msgId + " is not in the " + _queueName);
}
-
- return messageContent;
}
/**
- * Returns the messages stored in this queue in tabular form.
- *
- * @param beginIndex
- * @param endIndex
- * @return AMQ messages in tabular form.
- * @throws JMException
+ * Returns the header contents of the messages stored in this queue in tabular form.
*/
public TabularData viewMessages(int beginIndex, int endIndex) throws JMException, AMQException
{
if ((beginIndex > endIndex) || (beginIndex < 1))
{
- throw new JMException("FromIndex = " + beginIndex + ", ToIndex = " + endIndex +
- "\nFromIndex should be greater than 0 and less than ToIndex");
+ throw new JMException("From Index = " + beginIndex + ", To Index = " + endIndex +
+ "\nFrom Index should be greater than 0 and less than To Index");
}
List<AMQMessage> list = _deliveryMgr.getMessages();
TabularDataSupport _messageList = new TabularDataSupport(_messagelistDataType);
- if (beginIndex > list.size())
- {
- return _messageList;
- }
- endIndex = endIndex < list.size() ? endIndex : list.size();
-
- for (int i = beginIndex; i <= endIndex; i++)
+ // Create the tabular list of message header contents
+ for (int i = beginIndex; i <= endIndex && i <= list.size(); i++)
{
AMQMessage msg = list.get(i - 1);
- long size = msg.getContentHeaderBody().bodySize;
-
+ ContentHeaderBody headerBody = msg.getContentHeaderBody();
+ long size = headerBody.bodySize;
// Create header attributes list
- BasicContentHeaderProperties headerProperties = (BasicContentHeaderProperties) msg.getContentHeaderBody().properties;
+ BasicContentHeaderProperties headerProperties = (BasicContentHeaderProperties)headerBody.properties;
List<String> headerAttribsList = new ArrayList<String>();
headerAttribsList.add("App Id=" + headerProperties.getAppId());
headerAttribsList.add("MimeType=" + headerProperties.getContentType());
@@ -462,13 +425,9 @@ public class AMQQueue implements Managable, Comparable
headerAttribsList.add("Encoding=" + headerProperties.getEncoding());
headerAttribsList.add(headerProperties.toString());
- Object[] itemValues = {msg.getMessageId(),
- headerAttribsList.toArray(new String[0]),
- size, msg.isRedelivered()};
-
- CompositeData messageData = new CompositeDataSupport(_messageDataType,
- _msgAttributeNames,
- itemValues);
+ Object[] itemValues = {msg.getMessageId(), headerAttribsList.toArray(new String[0]),
+ headerBody.bodySize, msg.isRedelivered()};
+ CompositeData messageData = new CompositeDataSupport(_messageDataType, _msgAttributeNames, itemValues);
_messageList.put(messageData);
}
@@ -476,20 +435,15 @@ public class AMQQueue implements Managable, Comparable
}
/**
- * Creates all the notifications this MBean can send.
- *
- * @return Notifications broadcasted by this MBean.
+ * returns Notifications sent by this MBean.
*/
@Override
public MBeanNotificationInfo[] getNotificationInfo()
{
- String[] notificationTypes = new String[]
- {MonitorNotification.THRESHOLD_VALUE_EXCEEDED};
+ String[] notificationTypes = new String[] {MonitorNotification.THRESHOLD_VALUE_EXCEEDED};
String name = MonitorNotification.class.getName();
- String description = "An attribute of this MBean has reached threshold value";
- MBeanNotificationInfo info1 = new MBeanNotificationInfo(notificationTypes,
- name,
- description);
+ String description = "Either Message count or Queue depth or Message size has reached threshold high value";
+ MBeanNotificationInfo info1 = new MBeanNotificationInfo(notificationTypes, name, description);
return new MBeanNotificationInfo[]{info1};
}
@@ -591,9 +545,9 @@ public class AMQQueue implements Managable, Comparable
{
return new AMQQueueMBean();
}
- catch (NotCompliantMBeanException ex)
+ catch (JMException ex)
{
- throw new AMQException("AMQQueue MBean creation has failed.", ex);
+ throw new AMQException("AMQQueue MBean creation has failed ", ex);
}
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/ManagedQueue.java b/java/broker/src/main/java/org/apache/qpid/server/queue/ManagedQueue.java
index 47b109994c..8925ed9450 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/queue/ManagedQueue.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/queue/ManagedQueue.java
@@ -46,16 +46,48 @@ public interface ManagedQueue
* @return the name of the managedQueue.
* @throws IOException
*/
- @MBeanAttribute(name="Name", description = "Name of the " + TYPE)
+ @MBeanAttribute(name="Name", description = TYPE + " Name")
String getName() throws IOException;
/**
- * Tells whether this ManagedQueue is durable or not.
- * @return true if this ManagedQueue is a durable queue.
+ * Total number of messages on the queue, which are yet to be delivered to the consumer(s).
+ * @return number of undelivered message in the Queue.
* @throws IOException
*/
- @MBeanAttribute(name="Durable", description = "true if the AMQQueue is durable")
- boolean isDurable() throws IOException;
+ @MBeanAttribute(name="MessageCount", description = "Total number of undelivered messages on the queue")
+ Integer getMessageCount() throws IOException;
+
+ /**
+ * Tells the total number of messages receieved by the queue since startup.
+ * @return total number of messages received.
+ * @throws IOException
+ */
+ @MBeanAttribute(name="ReceivedMessageCount", description="The total number of messages receieved by the queue since startup")
+ Long getReceivedMessageCount() throws IOException;
+
+ /**
+ * Size of messages in the queue
+ * @return
+ * @throws IOException
+ */
+ @MBeanAttribute(name="QueueDepth", description="Size of messages(KB) in the queue")
+ Long getQueueDepth() throws IOException;
+
+ /**
+ * Returns the total number of active subscribers to the queue.
+ * @return the number of active subscribers
+ * @throws IOException
+ */
+ @MBeanAttribute(name="ActiveConsumerCount", description="The total number of active subscribers to the queue")
+ Integer getActiveConsumerCount() throws IOException;
+
+ /**
+ * Returns the total number of subscribers to the queue.
+ * @return the number of subscribers.
+ * @throws IOException
+ */
+ @MBeanAttribute(name="ConsumerCount", description="The total number of subscribers to the queue")
+ Integer getConsumerCount() throws IOException;
/**
* Tells the Owner of the ManagedQueue.
@@ -66,21 +98,20 @@ public interface ManagedQueue
String getOwner() throws IOException;
/**
- * Tells if the ManagedQueue is set to AutoDelete.
- * @return true if the ManagedQueue is set to AutoDelete.
+ * Tells whether this ManagedQueue is durable or not.
+ * @return true if this ManagedQueue is a durable queue.
* @throws IOException
*/
- @MBeanAttribute(name="AutoDelete", description = "true if the AMQQueue is AutoDelete")
- boolean isAutoDelete() throws IOException;
+ @MBeanAttribute(name="Durable", description = "true if the AMQQueue is durable")
+ boolean isDurable() throws IOException;
/**
- * Total number of messages on the queue, which are yet to be delivered to the consumer(s).
- * @return number of undelivered message in the Queue.
+ * Tells if the ManagedQueue is set to AutoDelete.
+ * @return true if the ManagedQueue is set to AutoDelete.
* @throws IOException
*/
- @MBeanAttribute(name="MessageCount",
- description = "Total number of undelivered messages on the queue")
- Integer getMessageCount() throws IOException;
+ @MBeanAttribute(name="AutoDelete", description = "true if the AMQQueue is AutoDelete")
+ boolean isAutoDelete() throws IOException;
/**
* Returns the maximum size of a message (in kbytes) allowed to be accepted by the
@@ -99,36 +130,10 @@ public interface ManagedQueue
* @param size maximum size of message.
* @throws IOException
*/
- @MBeanAttribute(name="MaximumMessageSize",
- description="Maximum size(KB) of a message allowed for this Queue")
+ @MBeanAttribute(name="MaximumMessageSize", description="Threshold high value(KB) for a message size")
void setMaximumMessageSize(Long size) throws IOException;
/**
- * Returns the total number of subscribers to the queue.
- * @return the number of subscribers.
- * @throws IOException
- */
- @MBeanAttribute(name="ConsumerCount", description="The total number of subscribers to the queue")
- Integer getConsumerCount() throws IOException;
-
- /**
- * Returns the total number of active subscribers to the queue.
- * @return the number of active subscribers
- * @throws IOException
- */
- @MBeanAttribute(name="ActiveConsumerCount", description="The total number of active subscribers to the queue")
- Integer getActiveConsumerCount() throws IOException;
-
- /**
- * Tells the total number of messages receieved by the queue since startup.
- * @return total number of messages received.
- * @throws IOException
- */
- @MBeanAttribute(name="ReceivedMessageCount",
- description="The total number of messages receieved by the queue since startup")
- Long getReceivedMessageCount() throws IOException;
-
- /**
* Tells the maximum number of messages that can be stored in the queue.
* This is useful in setting the notifications or taking required
* action is the number of message increase this limit.
@@ -142,27 +147,16 @@ public interface ManagedQueue
* @param value the maximum number of messages allowed to be stored in the queue.
* @throws IOException
*/
- @MBeanAttribute(name="MaximumMessageCount",
- description="The maximum number of messages allowed to be stored in the queue")
+ @MBeanAttribute(name="MaximumMessageCount", description="Threshold high value for number of undelivered messages in the queue")
void setMaximumMessageCount(Integer value) throws IOException;
/**
- * Size of messages in the queue
- * @return
- * @throws IOException
- */
- @MBeanAttribute(name="QueueSize", description="Size of messages(KB) in the queue")
- Long getQueueSize() throws IOException, AMQException;
-
- /**
- * Tells the maximum size of all the messages combined together,
- * that can be stored in the queue. This is useful for setting notifications
- * or taking required action if the size of messages stored in the queue
- * increases over this limit.
- * @return maximum size of the all the messages allowed for the queue.
+ * This is useful for setting notifications or taking required action if the size of messages
+ * stored in the queue increases over this limit.
+ * @return threshold high value for Queue Depth
* @throws IOException
*/
- Long getQueueDepth() throws IOException;
+ Long getMaximumQueueDepth() throws IOException;
/**
* Sets the maximum size of all the messages together, that can be stored
@@ -170,9 +164,8 @@ public interface ManagedQueue
* @param value
* @throws IOException
*/
- @MBeanAttribute(name="QueueDepth",
- description="The size(KB) of all the messages together, that can be stored in the queue")
- void setQueueDepth(Long value) throws IOException;
+ @MBeanAttribute(name="MaximumQueueDepth", description="The threshold high value(KB) for Queue Depth")
+ void setMaximumQueueDepth(Long value) throws IOException;
@@ -189,19 +182,22 @@ public interface ManagedQueue
* @throws JMException
*/
@MBeanOperation(name="viewMessages",
- description="shows messages in this queue with given indexes. eg. from index 1 - 100")
+ description="Message headers for messages in this queue within given index range. eg. from index 1 - 100")
TabularData viewMessages(@MBeanOperationParameter(name="from index", description="from index")int fromIndex,
@MBeanOperationParameter(name="to index", description="to index")int toIndex)
throws IOException, JMException, AMQException;
+ @MBeanOperation(name="viewMessageContent", description="The message content for given Message Id")
+ CompositeData viewMessageContent(@MBeanOperationParameter(name="Message Id", description="Message Id")long messageId)
+ throws IOException, JMException;
+
/**
* Deletes the first message from top.
* @throws IOException
* @throws JMException
*/
- @MBeanOperation(name="deleteMessageFromTop",
- description="Deletes the first message from top",
- impact= MBeanOperationInfo.ACTION)
+ @MBeanOperation(name="deleteMessageFromTop", description="Deletes the first message from top",
+ impact= MBeanOperationInfo.ACTION)
void deleteMessageFromTop() throws IOException, JMException;
/**
@@ -210,12 +206,8 @@ public interface ManagedQueue
* @throws JMException
*/
@MBeanOperation(name="clearQueue",
- description="Clears the queue by deleting all the undelivered messages from the queue",
- impact= MBeanOperationInfo.ACTION)
+ description="Clears the queue by deleting all the undelivered messages from the queue",
+ impact= MBeanOperationInfo.ACTION)
void clearQueue() throws IOException, JMException;
- @MBeanOperation(name="viewMessageContent",
- description="Returns the message content along with MimeType and Encoding")
- CompositeData viewMessageContent(@MBeanOperationParameter(name="Message Id", description="Message Id")long messageId)
- throws IOException, JMException, AMQException;
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/amqplain/AmqPlainSaslServer.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/amqplain/AmqPlainSaslServer.java
index 3ad74ce180..c364ca1d8d 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/amqplain/AmqPlainSaslServer.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/amqplain/AmqPlainSaslServer.java
@@ -22,6 +22,7 @@ package org.apache.qpid.server.security.auth.amqplain;
import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.framing.AMQFrameDecodingException;
+import org.apache.qpid.framing.FieldTableFactory;
import org.apache.mina.common.ByteBuffer;
import javax.security.sasl.SaslServer;
@@ -54,7 +55,7 @@ public class AmqPlainSaslServer implements SaslServer
{
try
{
- final FieldTable ft = new FieldTable(ByteBuffer.wrap(response), response.length);
+ final FieldTable ft = FieldTableFactory.newFieldTable(ByteBuffer.wrap(response), response.length);
String username = (String) ft.get("LOGIN");
// we do not care about the prompt but it throws if null
NameCallback nameCb = new NameCallback("prompt", username);
diff --git a/java/client/pom.xml b/java/client/pom.xml
index 915f51245c..2e53b1a965 100644
--- a/java/client/pom.xml
+++ b/java/client/pom.xml
@@ -38,7 +38,6 @@
<amqj.logging.level>warn</amqj.logging.level>
</properties>
-
<dependencies>
<dependency>
<groupId>org.apache.qpid</groupId>
@@ -49,7 +48,6 @@
<artifactId>qpid-broker</artifactId>
</dependency>
-
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
@@ -72,11 +70,11 @@
<artifactId>mina-filter-ssl</artifactId>
</dependency>
-
<dependency>
<groupId>jmscts</groupId>
<artifactId>jmscts</artifactId>
<version>0.5-b2</version>
+ <scope>test</scope>
<exclusions>
<exclusion>
<groupId>jms</groupId>
@@ -86,9 +84,12 @@
</dependency>
<dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </dependency>
+ <dependency>
<groupId>org.easymock</groupId>
<artifactId>easymockclassextension</artifactId>
- <scope>test</scope>
</dependency>
</dependencies>
@@ -106,7 +107,7 @@
</property>
<property>
<name>amqj.logging.level</name>
- <value>WARN</value>
+ <value>${amqj.logging.level}</value>
</property>
<property>
<name>log4j.configuration</name>
diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQBrokerDetails.java b/java/client/src/main/java/org/apache/qpid/client/AMQBrokerDetails.java
index 7cabc667c1..6da0da9f6f 100644
--- a/java/client/src/main/java/org/apache/qpid/client/AMQBrokerDetails.java
+++ b/java/client/src/main/java/org/apache/qpid/client/AMQBrokerDetails.java
@@ -56,7 +56,7 @@ public class AMQBrokerDetails implements BrokerDetails
{
//todo this list of valid transports should be enumerated somewhere
if ((!(transport.equalsIgnoreCase("vm") ||
- transport.equalsIgnoreCase("tcp"))))
+ transport.equalsIgnoreCase("tcp"))))
{
if (transport.equalsIgnoreCase("localhost"))
{
@@ -65,7 +65,7 @@ public class AMQBrokerDetails implements BrokerDetails
}
else
{
- if (url.charAt(transport.length()) == ':' && url.charAt(transport.length()+1) != '/' )
+ if (url.charAt(transport.length()) == ':' && url.charAt(transport.length() + 1) != '/')
{
//Then most likely we have a host:port value
connection = new URI(DEFAULT_TRANSPORT + "://" + url);
@@ -88,7 +88,7 @@ public class AMQBrokerDetails implements BrokerDetails
if (transport == null)
{
URLHelper.parseError(-1, "Unknown transport:'" + transport + "'" +
- " In broker URL:'" + url + "' Format: " + URL_FORMAT_EXAMPLE, "");
+ " In broker URL:'" + url + "' Format: " + URL_FORMAT_EXAMPLE, "");
}
setTransport(transport);
@@ -107,12 +107,45 @@ public class AMQBrokerDetails implements BrokerDetails
if (port == -1)
{
- // Another fix for Java 1.5 URI handling
+ // Fix for when there is port data but it is not automatically parseable by getPort().
String auth = connection.getAuthority();
- if (auth != null && auth.startsWith(":"))
+ if (auth != null && auth.contains(":"))
{
- setPort(Integer.parseInt(auth.substring(1)));
+ int start = auth.indexOf(":") + 1;
+ int end = start;
+ boolean looking = true;
+ boolean found = false;
+ //Walk the authority looking for a port value.
+ while (looking)
+ {
+ try
+ {
+ end++;
+ Integer.parseInt(auth.substring(start, end));
+
+ if (end >= auth.length())
+ {
+ looking = false;
+ found = true;
+ }
+ }
+ catch (NumberFormatException nfe)
+ {
+ looking = false;
+ }
+
+ }
+ if (found)
+ {
+ setPort(Integer.parseInt(auth.substring(start, end)));
+ }
+ else
+ {
+ URLHelper.parseError(connection.toString().indexOf(connection.getAuthority()) + end - 1,
+ "Illegal character in port number", connection.toString());
+ }
+
}
else
{
@@ -134,7 +167,7 @@ public class AMQBrokerDetails implements BrokerDetails
{
if (uris instanceof URLSyntaxException)
{
- throw (URLSyntaxException) uris;
+ throw(URLSyntaxException) uris;
}
URLHelper.parseError(uris.getIndex(), uris.getReason(), uris.getInput());
@@ -245,9 +278,9 @@ public class AMQBrokerDetails implements BrokerDetails
BrokerDetails bd = (BrokerDetails) o;
return _host.equalsIgnoreCase(bd.getHost()) &&
- (_port == bd.getPort()) &&
- _transport.equalsIgnoreCase(bd.getTransport()) &&
- (useSSL() == bd.useSSL());
+ (_port == bd.getPort()) &&
+ _transport.equalsIgnoreCase(bd.getTransport()) &&
+ (useSSL() == bd.useSSL());
//todo do we need to compare all the options as well?
}
diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java b/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java
index 98db26d0c4..0bb8736227 100644
--- a/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java
+++ b/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java
@@ -44,6 +44,7 @@ import org.apache.qpid.jms.FailoverPolicy;
import org.apache.qpid.url.URLSyntaxException;
import javax.jms.*;
+import javax.jms.IllegalStateException;
import javax.naming.NamingException;
import javax.naming.Reference;
import javax.naming.Referenceable;
@@ -92,7 +93,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
/**
* Maps from session id (Integer) to AMQSession instance
*/
- private final Map _sessions = new LinkedHashMap(); //fixme this is map is replicated in amqprotocolsession as _channelId2SessionMap
+ private final Map _sessions = new LinkedHashMap(); //fixme this is map is replicated in amqprotocolsession as _channelId2SessionMap
private String _clientName;
@@ -142,7 +143,8 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
String clientName, String virtualHost) throws AMQException, URLSyntaxException
{
this(new AMQConnectionURL(ConnectionURL.AMQ_PROTOCOL + "://" +
- username + ":" + password + "@" + clientName +
+ username + ":" + password + "@" +
+ (clientName==null?"":clientName) +
virtualHost + "?brokerlist='" + broker + "'"));
}
@@ -157,11 +159,13 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
{
this(new AMQConnectionURL(useSSL ?
ConnectionURL.AMQ_PROTOCOL + "://" +
- username + ":" + password + "@" + clientName +
+ username + ":" + password + "@" +
+ (clientName==null?"":clientName) +
virtualHost + "?brokerlist='tcp://" + host + ":" + port + "'"
+ "," + ConnectionURL.OPTIONS_SSL + "='true'" :
ConnectionURL.AMQ_PROTOCOL + "://" +
- username + ":" + password + "@" + clientName +
+ username + ":" + password + "@" +
+ (clientName==null?"":clientName) +
virtualHost + "?brokerlist='tcp://" + host + ":" + port + "'"
+ "," + ConnectionURL.OPTIONS_SSL + "='false'"
));
@@ -537,7 +541,10 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
public void setClientID(String clientID) throws JMSException
{
checkNotClosed();
- _clientName = clientID;
+ // in AMQP it is not possible to change the client ID. If one is not specified
+ // upon connection construction, an id is generated automatically. Therefore
+ // we can always throw an exception.
+ throw new IllegalStateException("Client name cannot be changed after being set");
}
public ConnectionMetaData getMetaData() throws JMSException
@@ -583,7 +590,6 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
public void stop() throws JMSException
{
checkNotClosed();
-
if (_started)
{
for (Iterator i = _sessions.values().iterator(); i.hasNext();)
@@ -920,8 +926,8 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
void deregisterSession(int channelId)
{
_sessions.remove(channelId);
- }
-
+ }
+
/**
* For all sessions, and for all consumers in those sessions, resubscribe. This is called during failover handling.
* The caller must hold the failover mutex before calling this method.
diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQSession.java b/java/client/src/main/java/org/apache/qpid/client/AMQSession.java
index a847658846..8f90913e5c 100644
--- a/java/client/src/main/java/org/apache/qpid/client/AMQSession.java
+++ b/java/client/src/main/java/org/apache/qpid/client/AMQSession.java
@@ -27,6 +27,7 @@ import org.apache.qpid.client.failover.FailoverSupport;
import org.apache.qpid.client.message.AbstractJMSMessage;
import org.apache.qpid.client.message.MessageFactoryRegistry;
import org.apache.qpid.client.message.UnprocessedMessage;
+import org.apache.qpid.client.message.JMSStreamMessage;
import org.apache.qpid.client.protocol.AMQProtocolHandler;
import org.apache.qpid.client.util.FlowControllingBlockingQueue;
import org.apache.qpid.framing.*;
@@ -367,13 +368,24 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi
public StreamMessage createStreamMessage() throws JMSException
{
- checkNotClosed();
- throw new UnsupportedOperationException("Stream messages not supported");
+ synchronized (_connection.getFailoverMutex())
+ {
+ checkNotClosed();
+
+ try
+ {
+ return (StreamMessage) _messageFactoryRegistry.createMessage(JMSStreamMessage.MIME_TYPE);
+ }
+ catch (AMQException e)
+ {
+ throw new JMSException("Unable to create text message: " + e);
+ }
+ }
}
public TextMessage createTextMessage() throws JMSException
{
- synchronized(_connection.getFailoverMutex())
+ synchronized (_connection.getFailoverMutex())
{
checkNotClosed();
@@ -462,28 +474,30 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi
// that can be called from a different thread of control from the one controlling the session
synchronized(_connection.getFailoverMutex())
{
- _closed.set(true);
-
- // we pass null since this is not an error case
- closeProducersAndConsumers(null);
-
- try
+ //Ensure we only try and close an open session.
+ if (!_closed.getAndSet(true))
{
- _connection.getProtocolHandler().closeSession(this);
- final AMQFrame frame = ChannelCloseBody.createAMQFrame(
- getChannelId(), AMQConstant.REPLY_SUCCESS.getCode(), "JMS client closing channel", 0, 0);
- _connection.getProtocolHandler().syncWrite(frame, ChannelCloseOkBody.class);
- // When control resumes at this point, a reply will have been received that
- // indicates the broker has closed the channel successfully
+ // we pass null since this is not an error case
+ closeProducersAndConsumers(null);
- }
- catch (AMQException e)
- {
- throw new JMSException("Error closing session: " + e);
- }
- finally
- {
- _connection.deregisterSession(_channelId);
+ try
+ {
+ _connection.getProtocolHandler().closeSession(this);
+ final AMQFrame frame = ChannelCloseBody.createAMQFrame(
+ getChannelId(), AMQConstant.REPLY_SUCCESS.getCode(), "JMS client closing channel", 0, 0);
+ _connection.getProtocolHandler().syncWrite(frame, ChannelCloseOkBody.class);
+ // When control resumes at this point, a reply will have been received that
+ // indicates the broker has closed the channel successfully
+
+ }
+ catch (AMQException e)
+ {
+ throw new JMSException("Error closing session: " + e);
+ }
+ finally
+ {
+ _connection.deregisterSession(_channelId);
+ }
}
}
}
@@ -723,6 +737,7 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi
/**
* Creates a QueueReceiver
+ *
* @param destination
* @return QueueReceiver - a wrapper around our MessageConsumer
* @throws JMSException
@@ -736,6 +751,7 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi
/**
* Creates a QueueReceiver using a message selector
+ *
* @param destination
* @param messageSelector
* @return QueueReceiver - a wrapper around our MessageConsumer
@@ -826,7 +842,7 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi
final AMQProtocolHandler protocolHandler = _connection.getProtocolHandler();
// TODO: construct the rawSelector from the selector string if rawSelector == null
- final FieldTable ft = new FieldTable();
+ final FieldTable ft = FieldTableFactory.newFieldTable();
//if (rawSelector != null)
// ft.put("headers", rawSelector.getDataAsBytes());
if (rawSelector != null)
@@ -935,6 +951,7 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi
public Queue createQueue(String queueName) throws JMSException
{
+ checkNotClosed();
if (queueName.indexOf('/') == -1)
{
return new AMQQueue(queueName);
@@ -957,12 +974,14 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi
/**
* Creates a QueueReceiver wrapping a MessageConsumer
+ *
* @param queue
* @return QueueReceiver
* @throws JMSException
*/
public QueueReceiver createReceiver(Queue queue) throws JMSException
{
+ checkNotClosed();
AMQQueue dest = (AMQQueue) queue;
BasicMessageConsumer consumer = (BasicMessageConsumer) createConsumer(dest);
return new QueueReceiverAdaptor(dest, consumer);
@@ -970,6 +989,7 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi
/**
* Creates a QueueReceiver wrapping a MessageConsumer using a message selector
+ *
* @param queue
* @param messageSelector
* @return QueueReceiver
@@ -977,6 +997,7 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi
*/
public QueueReceiver createReceiver(Queue queue, String messageSelector) throws JMSException
{
+ checkNotClosed();
AMQQueue dest = (AMQQueue) queue;
BasicMessageConsumer consumer = (BasicMessageConsumer)
createConsumer(dest, messageSelector);
@@ -985,11 +1006,15 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi
public QueueSender createSender(Queue queue) throws JMSException
{
- return (QueueSender) createProducer(queue);
+ checkNotClosed();
+ //return (QueueSender) createProducer(queue);
+ return new QueueSenderAdapter(createProducer(queue), queue);
}
public Topic createTopic(String topicName) throws JMSException
{
+ checkNotClosed();
+
if (topicName.indexOf('/') == -1)
{
return new AMQTopic(topicName);
@@ -1012,18 +1037,21 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi
/**
* Creates a non-durable subscriber
+ *
* @param topic
* @return TopicSubscriber - a wrapper round our MessageConsumer
* @throws JMSException
*/
public TopicSubscriber createSubscriber(Topic topic) throws JMSException
{
+ checkNotClosed();
AMQTopic dest = new AMQTopic(topic.getTopicName());
return new TopicSubscriberAdaptor(dest, (BasicMessageConsumer) createConsumer(dest));
}
/**
* Creates a non-durable subscriber with a message selector
+ *
* @param topic
* @param messageSelector
* @param noLocal
@@ -1032,6 +1060,7 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi
*/
public TopicSubscriber createSubscriber(Topic topic, String messageSelector, boolean noLocal) throws JMSException
{
+ checkNotClosed();
AMQTopic dest = new AMQTopic(topic.getTopicName());
return new TopicSubscriberAdaptor(dest, (BasicMessageConsumer) createConsumer(dest, messageSelector, noLocal));
}
@@ -1045,6 +1074,7 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi
*/
public TopicSubscriber createDurableSubscriber(Topic topic, String name) throws JMSException
{
+ checkNotClosed();
AMQTopic dest = new AMQTopic((AMQTopic) topic, _connection.getClientID(), name);
return new TopicSubscriberAdaptor(dest, (BasicMessageConsumer) createConsumer(dest));
}
@@ -1055,6 +1085,7 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi
public TopicSubscriber createDurableSubscriber(Topic topic, String name, String messageSelector, boolean noLocal)
throws JMSException
{
+ checkNotClosed();
AMQTopic dest = new AMQTopic((AMQTopic) topic, _connection.getClientID(), name);
BasicMessageConsumer consumer = (BasicMessageConsumer) createConsumer(dest, messageSelector, noLocal);
return new TopicSubscriberAdaptor(dest, consumer);
@@ -1062,26 +1093,32 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi
public TopicPublisher createPublisher(Topic topic) throws JMSException
{
- return (TopicPublisher) createProducer(topic);
+ checkNotClosed();
+ //return (TopicPublisher) createProducer(topic);
+ return new TopicPublisherAdapter(createProducer(topic), topic);
}
public QueueBrowser createBrowser(Queue queue) throws JMSException
{
+ checkNotClosed();
throw new UnsupportedOperationException("Queue browsing not supported");
}
public QueueBrowser createBrowser(Queue queue, String messageSelector) throws JMSException
{
+ checkNotClosed();
throw new UnsupportedOperationException("Queue browsing not supported");
}
public TemporaryQueue createTemporaryQueue() throws JMSException
{
+ checkNotClosed();
return new AMQTemporaryQueue();
}
public TemporaryTopic createTemporaryTopic() throws JMSException
{
+ checkNotClosed();
return new AMQTemporaryTopic();
}
diff --git a/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer.java b/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer.java
index f97ea6bf1e..ded2152bf8 100644
--- a/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer.java
+++ b/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer.java
@@ -159,11 +159,13 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer
public String getMessageSelector() throws JMSException
{
+ checkPreConditions();
return _messageSelector;
}
public MessageListener getMessageListener() throws JMSException
{
+ checkPreConditions();
return (MessageListener) _messageListener.get();
}
@@ -179,7 +181,7 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer
public void setMessageListener(MessageListener messageListener) throws JMSException
{
- checkNotClosed();
+ checkPreConditions();
//if the current listener is non-null and the session is not stopped, then
//it is an error to call this method.
@@ -277,7 +279,7 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer
public Message receive(long l) throws JMSException
{
- checkNotClosed();
+ checkPreConditions();
acquireReceiving();
@@ -311,7 +313,7 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer
public Message receiveNoWait() throws JMSException
{
- checkNotClosed();
+ checkPreConditions();
acquireReceiving();
@@ -520,7 +522,7 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer
*/
private void deregisterConsumer()
{
- _session.deregisterConsumer(_consumerTag);
+ _session.deregisterConsumer(_consumerTag);
}
public String getConsumerTag()
@@ -529,7 +531,20 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer
}
public void setConsumerTag(String consumerTag)
- {
+ {
_consumerTag = consumerTag;
}
+
+ public AMQSession getSession() {
+ return _session;
+ }
+
+ private void checkPreConditions() throws JMSException{
+
+ this.checkNotClosed();
+
+ if(_session == null || _session.isClosed()){
+ throw new UnsupportedOperationException("Invalid Session");
+ }
+ }
}
diff --git a/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer.java b/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer.java
index 14cafc3558..8d6287eca3 100644
--- a/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer.java
+++ b/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer.java
@@ -143,6 +143,7 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j
public void setDisableMessageID(boolean b) throws JMSException
{
+ checkPreConditions();
checkNotClosed();
// IGNORED
}
@@ -156,7 +157,7 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j
public void setDisableMessageTimestamp(boolean b) throws JMSException
{
- checkNotClosed();
+ checkPreConditions();
_disableTimestamps = b;
}
@@ -168,7 +169,7 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j
public void setDeliveryMode(int i) throws JMSException
{
- checkNotClosed();
+ checkPreConditions();
if (i != DeliveryMode.NON_PERSISTENT && i != DeliveryMode.PERSISTENT)
{
throw new JMSException("DeliveryMode must be either NON_PERSISTENT or PERSISTENT. Value of " + i +
@@ -185,7 +186,7 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j
public void setPriority(int i) throws JMSException
{
- checkNotClosed();
+ checkPreConditions();
if (i < 0 || i > 9)
{
throw new IllegalArgumentException("Priority of " + i + " is illegal. Value must be in range 0 to 9");
@@ -201,7 +202,7 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j
public void setTimeToLive(long l) throws JMSException
{
- checkNotClosed();
+ checkPreConditions();
if (l < 0)
{
throw new IllegalArgumentException("Time to live must be non-negative - supplied value was " + l);
@@ -229,6 +230,7 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j
public void send(Message message) throws JMSException
{
+ checkPreConditions();
synchronized (_connection.getFailoverMutex())
{
sendImpl(_destination, (AbstractJMSMessage) message, _deliveryMode, _messagePriority, _timeToLive,
@@ -238,6 +240,7 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j
public void send(Message message, int deliveryMode) throws JMSException
{
+ checkPreConditions();
synchronized (_connection.getFailoverMutex())
{
sendImpl(_destination, (AbstractJMSMessage) message, deliveryMode, _messagePriority, _timeToLive,
@@ -247,6 +250,7 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j
public void send(Message message, int deliveryMode, boolean immediate) throws JMSException
{
+ checkPreConditions();
synchronized (_connection.getFailoverMutex())
{
sendImpl(_destination, (AbstractJMSMessage) message, deliveryMode, _messagePriority, _timeToLive,
@@ -257,6 +261,7 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j
public void send(Message message, int deliveryMode, int priority,
long timeToLive) throws JMSException
{
+ checkPreConditions();
synchronized (_connection.getFailoverMutex())
{
sendImpl(_destination, (AbstractJMSMessage)message, deliveryMode, priority, timeToLive, _mandatory,
@@ -266,7 +271,7 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j
public void send(Destination destination, Message message) throws JMSException
{
- checkNotClosed();
+ checkPreConditions();
synchronized (_connection.getFailoverMutex())
{
validateDestination(destination);
@@ -279,7 +284,7 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j
int priority, long timeToLive)
throws JMSException
{
- checkNotClosed();
+ checkPreConditions();
synchronized (_connection.getFailoverMutex())
{
validateDestination(destination);
@@ -292,7 +297,7 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j
int priority, long timeToLive, boolean mandatory)
throws JMSException
{
- checkNotClosed();
+ checkPreConditions();
synchronized (_connection.getFailoverMutex())
{
validateDestination(destination);
@@ -305,7 +310,7 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j
int priority, long timeToLive, boolean mandatory, boolean immediate)
throws JMSException
{
- checkNotClosed();
+ checkPreConditions();
synchronized (_connection.getFailoverMutex())
{
validateDestination(destination);
@@ -319,7 +324,7 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j
boolean immediate, boolean waitUntilSent)
throws JMSException
{
- checkNotClosed();
+ checkPreConditions();
synchronized (_connection.getFailoverMutex())
{
validateDestination(destination);
@@ -334,7 +339,7 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j
{
throw new JMSException("Unsupported destination class: " +
(destination != null ? destination.getClass() : null));
- }
+ }
declareDestination((AMQDestination)destination);
}
@@ -481,4 +486,20 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j
checkNotClosed();
_encoding = encoding;
}
+
+ private void checkPreConditions() throws IllegalStateException, JMSException {
+ checkNotClosed();
+
+ if(_destination == null){
+ throw new UnsupportedOperationException("Destination is null");
+ }
+
+ if(_session == null || _session.isClosed()){
+ throw new UnsupportedOperationException("Invalid Session");
+ }
+ }
+
+ public AMQSession getSession() {
+ return _session;
+ }
}
diff --git a/java/client/src/main/java/org/apache/qpid/client/QueueReceiverAdaptor.java b/java/client/src/main/java/org/apache/qpid/client/QueueReceiverAdaptor.java
index 57e458d833..21ec50c046 100644
--- a/java/client/src/main/java/org/apache/qpid/client/QueueReceiverAdaptor.java
+++ b/java/client/src/main/java/org/apache/qpid/client/QueueReceiverAdaptor.java
@@ -39,31 +39,37 @@ public class QueueReceiverAdaptor implements QueueReceiver {
public String getMessageSelector() throws JMSException
{
+ checkPreConditions();
return _consumer.getMessageSelector();
}
public MessageListener getMessageListener() throws JMSException
{
+ checkPreConditions();
return _consumer.getMessageListener();
}
public void setMessageListener(MessageListener messageListener) throws JMSException
{
+ checkPreConditions();
_consumer.setMessageListener(messageListener);
}
public Message receive() throws JMSException
{
+ checkPreConditions();
return _consumer.receive();
}
public Message receive(long l) throws JMSException
{
+ checkPreConditions();
return _consumer.receive(l);
}
public Message receiveNoWait() throws JMSException
{
+ checkPreConditions();
return _consumer.receiveNoWait();
}
@@ -79,8 +85,26 @@ public class QueueReceiverAdaptor implements QueueReceiver {
*/
public Queue getQueue() throws JMSException
{
+ checkPreConditions();
return _queue;
}
+ private void checkPreConditions() throws javax.jms.IllegalStateException {
+ BasicMessageConsumer msgConsumer = (BasicMessageConsumer)_consumer;
+
+ if (msgConsumer.isClosed() ){
+ throw new javax.jms.IllegalStateException("Consumer is closed");
+ }
+
+ if(_queue == null){
+ throw new UnsupportedOperationException("Queue is null");
+ }
+
+ AMQSession session = msgConsumer.getSession();
+
+ if(session == null || session.isClosed()){
+ throw new UnsupportedOperationException("Invalid Session");
+ }
+ }
}
diff --git a/java/client/src/main/java/org/apache/qpid/client/QueueSenderAdapter.java b/java/client/src/main/java/org/apache/qpid/client/QueueSenderAdapter.java
new file mode 100644
index 0000000000..15bf4a125f
--- /dev/null
+++ b/java/client/src/main/java/org/apache/qpid/client/QueueSenderAdapter.java
@@ -0,0 +1,134 @@
+package org.apache.qpid.client;
+
+import javax.jms.Destination;
+import javax.jms.IllegalStateException;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageProducer;
+import javax.jms.Queue;
+import javax.jms.QueueSender;
+
+public class QueueSenderAdapter implements QueueSender {
+
+ private MessageProducer delegate;
+ private Queue queue;
+ private boolean closed = false;
+
+ public QueueSenderAdapter(MessageProducer msgProducer, Queue queue){
+ delegate = msgProducer;
+ this.queue = queue;
+ }
+
+ public Queue getQueue() throws JMSException {
+ checkPreConditions();
+ return queue;
+ }
+
+ public void send(Message msg) throws JMSException {
+ checkPreConditions();
+ delegate.send(msg);
+ }
+
+ public void send(Queue queue, Message msg) throws JMSException {
+ checkPreConditions();
+ delegate.send(queue, msg);
+ }
+
+ public void publish(Message msg, int deliveryMode, int priority, long timeToLive)
+ throws JMSException {
+ checkPreConditions();
+ delegate.send(msg, deliveryMode,priority,timeToLive);
+ }
+
+ public void send(Queue queue,Message msg, int deliveryMode, int priority, long timeToLive)
+ throws JMSException {
+ checkPreConditions();
+ delegate.send(queue,msg, deliveryMode,priority,timeToLive);
+ }
+
+ public void close() throws JMSException {
+ delegate.close();
+ closed = true;
+ }
+
+ public int getDeliveryMode() throws JMSException {
+ return delegate.getDeliveryMode();
+ }
+
+ public Destination getDestination() throws JMSException {
+ return delegate.getDestination();
+ }
+
+ public boolean getDisableMessageID() throws JMSException {
+ return delegate.getDisableMessageID();
+ }
+
+ public boolean getDisableMessageTimestamp() throws JMSException {
+ return delegate.getDisableMessageTimestamp();
+ }
+
+ public int getPriority() throws JMSException {
+ return delegate.getPriority();
+ }
+
+ public long getTimeToLive() throws JMSException {
+ return delegate.getTimeToLive();
+ }
+
+ public void send(Destination dest, Message msg) throws JMSException {
+ checkPreConditions();
+ delegate.send(dest,msg);
+ }
+
+ public void send(Message msg, int deliveryMode, int priority, long timeToLive)
+ throws JMSException {
+ checkPreConditions();
+ delegate.send(msg, deliveryMode,priority,timeToLive);
+ }
+
+ public void send(Destination dest, Message msg, int deliveryMode, int priority, long timeToLive) throws JMSException {
+ checkPreConditions();
+ delegate.send(dest,msg, deliveryMode,priority,timeToLive);
+ }
+
+ public void setDeliveryMode(int deliveryMode) throws JMSException {
+ checkPreConditions();
+ delegate.setDeliveryMode(deliveryMode);
+ }
+
+ public void setDisableMessageID(boolean disableMessageID) throws JMSException {
+ checkPreConditions();
+ delegate.setDisableMessageID(disableMessageID);
+ }
+
+ public void setDisableMessageTimestamp(boolean disableMessageTimestamp) throws JMSException {
+ checkPreConditions();
+ delegate.setDisableMessageTimestamp(disableMessageTimestamp);
+ }
+
+ public void setPriority(int priority) throws JMSException {
+ checkPreConditions();
+ delegate.setPriority(priority);
+ }
+
+ public void setTimeToLive(long timeToLive) throws JMSException {
+ checkPreConditions();
+ delegate.setTimeToLive(timeToLive);
+ }
+
+ private void checkPreConditions() throws IllegalStateException, IllegalStateException {
+ if (closed){
+ throw new javax.jms.IllegalStateException("Publisher is closed");
+ }
+
+ if(queue == null){
+ throw new UnsupportedOperationException("Queue is null");
+ }
+
+ AMQSession session = ((BasicMessageProducer)delegate).getSession();
+
+ if(session == null || session.isClosed()){
+ throw new UnsupportedOperationException("Invalid Session");
+ }
+ }
+}
diff --git a/java/client/src/main/java/org/apache/qpid/client/TopicPublisherAdapter.java b/java/client/src/main/java/org/apache/qpid/client/TopicPublisherAdapter.java
new file mode 100644
index 0000000000..0702202c2a
--- /dev/null
+++ b/java/client/src/main/java/org/apache/qpid/client/TopicPublisherAdapter.java
@@ -0,0 +1,138 @@
+package org.apache.qpid.client;
+
+import javax.jms.Destination;
+import javax.jms.IllegalStateException;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageProducer;
+import javax.jms.Topic;
+import javax.jms.TopicPublisher;
+
+public class TopicPublisherAdapter implements TopicPublisher {
+
+ private MessageProducer delegate;
+ private Topic topic;
+ private boolean closed = false;
+
+ public TopicPublisherAdapter(MessageProducer msgProducer, Topic topic){
+ delegate = msgProducer;
+ this.topic = topic;
+ }
+
+ public Topic getTopic() throws JMSException {
+ checkPreConditions();
+ return topic;
+ }
+
+ public void publish(Message msg) throws JMSException {
+ checkPreConditions();
+ delegate.send(msg);
+ }
+
+ public void publish(Topic topic, Message msg) throws JMSException {
+ checkPreConditions();
+ delegate.send(topic,msg);
+ }
+
+ public void publish(Message msg, int deliveryMode, int priority, long timeToLive)
+ throws JMSException {
+ checkPreConditions();
+ delegate.send(msg, deliveryMode,priority,timeToLive);
+ }
+
+ public void publish(Topic topic, Message msg, int deliveryMode, int priority, long timeToLive)
+ throws JMSException {
+ checkPreConditions();
+ delegate.send(topic,msg, deliveryMode,priority,timeToLive);
+ }
+
+ public void close() throws JMSException {
+ delegate.close();
+ closed = true;
+ }
+
+ public int getDeliveryMode() throws JMSException {
+ return delegate.getDeliveryMode();
+ }
+
+ public Destination getDestination() throws JMSException {
+ return delegate.getDestination();
+ }
+
+ public boolean getDisableMessageID() throws JMSException {
+ return delegate.getDisableMessageID();
+ }
+
+ public boolean getDisableMessageTimestamp() throws JMSException {
+ return delegate.getDisableMessageTimestamp();
+ }
+
+ public int getPriority() throws JMSException {
+ return delegate.getPriority();
+ }
+
+ public long getTimeToLive() throws JMSException {
+ return delegate.getTimeToLive();
+ }
+
+ public void send(Message msg) throws JMSException {
+ checkPreConditions();
+ delegate.send(msg);
+ }
+
+ public void send(Destination dest, Message msg) throws JMSException {
+ checkPreConditions();
+ delegate.send(dest,msg);
+ }
+
+ public void send(Message msg, int deliveryMode, int priority, long timeToLive)
+ throws JMSException {
+ checkPreConditions();
+ delegate.send(msg, deliveryMode,priority,timeToLive);
+ }
+
+ public void send(Destination dest, Message msg, int deliveryMode, int priority, long timeToLive) throws JMSException {
+ checkPreConditions();
+ delegate.send(dest,msg, deliveryMode,priority,timeToLive);
+ }
+
+ public void setDeliveryMode(int deliveryMode) throws JMSException {
+ checkPreConditions();
+ delegate.setDeliveryMode(deliveryMode);
+ }
+
+ public void setDisableMessageID(boolean disableMessageID) throws JMSException {
+ checkPreConditions();
+ delegate.setDisableMessageID(disableMessageID);
+ }
+
+ public void setDisableMessageTimestamp(boolean disableMessageTimestamp) throws JMSException {
+ checkPreConditions();
+ delegate.setDisableMessageTimestamp(disableMessageTimestamp);
+ }
+
+ public void setPriority(int priority) throws JMSException {
+ checkPreConditions();
+ delegate.setPriority(priority);
+ }
+
+ public void setTimeToLive(long timeToLive) throws JMSException {
+ checkPreConditions();
+ delegate.setTimeToLive(timeToLive);
+ }
+
+ private void checkPreConditions() throws IllegalStateException, IllegalStateException {
+ if (closed){
+ throw new javax.jms.IllegalStateException("Publisher is closed");
+ }
+
+ if(topic == null){
+ throw new UnsupportedOperationException("Topic is null");
+ }
+
+ AMQSession session = ((BasicMessageProducer)delegate).getSession();
+ if(session == null || session.isClosed()){
+ throw new UnsupportedOperationException("Invalid Session");
+ }
+ }
+}
diff --git a/java/client/src/main/java/org/apache/qpid/client/TopicSubscriberAdaptor.java b/java/client/src/main/java/org/apache/qpid/client/TopicSubscriberAdaptor.java
index c776a9943e..06e353e271 100644
--- a/java/client/src/main/java/org/apache/qpid/client/TopicSubscriberAdaptor.java
+++ b/java/client/src/main/java/org/apache/qpid/client/TopicSubscriberAdaptor.java
@@ -20,6 +20,7 @@
*/
package org.apache.qpid.client;
+import javax.jms.IllegalStateException;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
@@ -43,37 +44,45 @@ class TopicSubscriberAdaptor implements TopicSubscriber
_consumer = consumer;
_noLocal = noLocal;
}
+
TopicSubscriberAdaptor(Topic topic, BasicMessageConsumer consumer)
{
this(topic, consumer, consumer.isNoLocal());
}
+
public Topic getTopic() throws JMSException
{
+ checkPreConditions();
return _topic;
}
public boolean getNoLocal() throws JMSException
{
+ checkPreConditions();
return _noLocal;
}
public String getMessageSelector() throws JMSException
{
+ checkPreConditions();
return _consumer.getMessageSelector();
}
public MessageListener getMessageListener() throws JMSException
{
+ checkPreConditions();
return _consumer.getMessageListener();
}
public void setMessageListener(MessageListener messageListener) throws JMSException
{
+ checkPreConditions();
_consumer.setMessageListener(messageListener);
}
public Message receive() throws JMSException
{
+ checkPreConditions();
return _consumer.receive();
}
@@ -84,6 +93,7 @@ class TopicSubscriberAdaptor implements TopicSubscriber
public Message receiveNoWait() throws JMSException
{
+ checkPreConditions();
return _consumer.receiveNoWait();
}
@@ -91,4 +101,22 @@ class TopicSubscriberAdaptor implements TopicSubscriber
{
_consumer.close();
}
+
+ private void checkPreConditions() throws javax.jms.IllegalStateException{
+ BasicMessageConsumer msgConsumer = (BasicMessageConsumer)_consumer;
+
+ if (msgConsumer.isClosed() ){
+ throw new javax.jms.IllegalStateException("Consumer is closed");
+ }
+
+ if(_topic == null){
+ throw new UnsupportedOperationException("Topic is null");
+ }
+
+ AMQSession session = msgConsumer.getSession();
+
+ if(session == null || session.isClosed()){
+ throw new UnsupportedOperationException("Invalid Session");
+ }
+ }
}
diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionStartMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionStartMethodHandler.java
index caef9a3f44..9333df3fe4 100644
--- a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionStartMethodHandler.java
+++ b/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionStartMethodHandler.java
@@ -32,6 +32,7 @@ import org.apache.qpid.client.state.StateAwareMethodListener;
import org.apache.qpid.framing.ConnectionStartBody;
import org.apache.qpid.framing.ConnectionStartOkBody;
import org.apache.qpid.framing.FieldTable;
+import org.apache.qpid.framing.FieldTableFactory;
import javax.security.sasl.Sasl;
import javax.security.sasl.SaslClient;
@@ -117,7 +118,7 @@ public class ConnectionStartMethodHandler implements StateAwareMethodListener
}
stateManager.changeState(AMQState.CONNECTION_NOT_TUNED);
- FieldTable clientProperties = new FieldTable();
+ FieldTable clientProperties = FieldTableFactory.newFieldTable();
clientProperties.put("instance", ps.getClientID());
clientProperties.put("product", "Qpid");
clientProperties.put("version", "1.0");
diff --git a/java/client/src/main/java/org/apache/qpid/client/message/JMSBytesMessage.java b/java/client/src/main/java/org/apache/qpid/client/message/JMSBytesMessage.java
index 6745052a5d..456d4d520c 100644
--- a/java/client/src/main/java/org/apache/qpid/client/message/JMSBytesMessage.java
+++ b/java/client/src/main/java/org/apache/qpid/client/message/JMSBytesMessage.java
@@ -27,6 +27,7 @@ import org.apache.qpid.framing.ContentHeaderBody;
import javax.jms.BytesMessage;
import javax.jms.JMSException;
import javax.jms.MessageFormatException;
+import javax.jms.MessageEOFException;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
diff --git a/java/client/src/main/java/org/apache/qpid/client/message/JMSMapMessage.java b/java/client/src/main/java/org/apache/qpid/client/message/JMSMapMessage.java
index 2001573ef9..5282dce4c9 100644
--- a/java/client/src/main/java/org/apache/qpid/client/message/JMSMapMessage.java
+++ b/java/client/src/main/java/org/apache/qpid/client/message/JMSMapMessage.java
@@ -23,10 +23,10 @@ package org.apache.qpid.client.message;
import org.apache.mina.common.ByteBuffer;
import org.apache.qpid.framing.BasicContentHeaderProperties;
import org.apache.qpid.framing.PropertyFieldTable;
+import org.apache.qpid.framing.FieldTableFactory;
import org.apache.qpid.AMQException;
import javax.jms.JMSException;
-import javax.jms.MessageFormatException;
import java.util.Enumeration;
public class JMSMapMessage extends JMSTextMessage implements javax.jms.MapMessage
@@ -58,7 +58,7 @@ public class JMSMapMessage extends JMSTextMessage implements javax.jms.MapMessag
try
{
- _map = new PropertyFieldTable(getText());
+ _map = FieldTableFactory.newFieldTable(getText());
}
catch (JMSException e)
{
@@ -68,7 +68,7 @@ public class JMSMapMessage extends JMSTextMessage implements javax.jms.MapMessag
// AbstractJMSMessage Interface
- public void clearBody() throws JMSException
+ public void clearBodyImpl() throws JMSException
{
if (_data != null)
{
@@ -206,48 +206,55 @@ public class JMSMapMessage extends JMSTextMessage implements javax.jms.MapMessag
public void setBoolean(String string, boolean b) throws JMSException
{
+ checkWritable();
_map.setBoolean(string, b);
}
public void setByte(String string, byte b) throws JMSException
{
+ checkWritable();
_map.setByte(string, b);
}
public void setShort(String string, short i) throws JMSException
{
+ checkWritable();
_map.setShort(string, i);
}
public void setChar(String string, char c) throws JMSException
{
+ checkWritable();
_map.setChar(string, c);
}
public void setInt(String string, int i) throws JMSException
{
+ checkWritable();
_map.setInteger(string, i);
}
public void setLong(String string, long l) throws JMSException
{
+ checkWritable();
_map.setLong(string, l);
}
public void setFloat(String string, float v) throws JMSException
{
-
+ checkWritable();
_map.setFloat(string, v);
}
public void setDouble(String string, double v) throws JMSException
{
-
+ checkWritable();
_map.setDouble(string, v);
}
public void setString(String string, String string1) throws JMSException
{
+ checkWritable();
_map.setString(string, string1);
}
@@ -258,11 +265,13 @@ public class JMSMapMessage extends JMSTextMessage implements javax.jms.MapMessag
public void setBytes(String string, byte[] bytes, int i, int i1) throws JMSException
{
+ checkWritable();
_map.setBytes(string, bytes, i, i1);
}
public void setObject(String string, Object object) throws JMSException
{
+ checkWritable();
_map.setObject(string, object);
}
diff --git a/java/client/src/main/java/org/apache/qpid/client/message/JMSObjectMessage.java b/java/client/src/main/java/org/apache/qpid/client/message/JMSObjectMessage.java
index 34dd7e9ec1..61f326d52b 100644
--- a/java/client/src/main/java/org/apache/qpid/client/message/JMSObjectMessage.java
+++ b/java/client/src/main/java/org/apache/qpid/client/message/JMSObjectMessage.java
@@ -36,7 +36,6 @@ import java.nio.charset.CharacterCodingException;
public class JMSObjectMessage extends AbstractJMSMessage implements ObjectMessage
{
static final String MIME_TYPE = "application/java-object-stream";
- private final boolean _readonly;
private static final int DEFAULT_BUFFER_SIZE = 1024;
@@ -56,7 +55,6 @@ public class JMSObjectMessage extends AbstractJMSMessage implements ObjectMessag
_data = ByteBuffer.allocate(DEFAULT_BUFFER_SIZE);
_data.setAutoExpand(true);
}
- _readonly = (data != null);
getJmsContentHeaderProperties().setContentType(MIME_TYPE);
}
@@ -66,10 +64,9 @@ public class JMSObjectMessage extends AbstractJMSMessage implements ObjectMessag
JMSObjectMessage(long messageNbr, ContentHeaderBody contentHeader, ByteBuffer data) throws AMQException
{
super(messageNbr, (BasicContentHeaderProperties) contentHeader.properties, data);
- _readonly = data != null;
}
- public void clearBody() throws JMSException
+ public void clearBodyImpl() throws JMSException
{
if (_data != null)
{
@@ -90,10 +87,7 @@ public class JMSObjectMessage extends AbstractJMSMessage implements ObjectMessag
public void setObject(Serializable serializable) throws JMSException
{
- if (_readonly)
- {
- throw new MessageNotWriteableException("Message is not writable.");
- }
+ checkWritable();
if (_data == null)
{
diff --git a/java/client/src/main/java/org/apache/qpid/client/message/JMSTextMessage.java b/java/client/src/main/java/org/apache/qpid/client/message/JMSTextMessage.java
index 2624c20105..3061d5a59c 100644
--- a/java/client/src/main/java/org/apache/qpid/client/message/JMSTextMessage.java
+++ b/java/client/src/main/java/org/apache/qpid/client/message/JMSTextMessage.java
@@ -66,7 +66,7 @@ public class JMSTextMessage extends AbstractJMSMessage implements javax.jms.Text
setText(text);
}
- public void clearBody() throws JMSException
+ public void clearBodyImpl() throws JMSException
{
if (_data != null)
{
@@ -93,6 +93,8 @@ public class JMSTextMessage extends AbstractJMSMessage implements javax.jms.Text
public void setText(String string) throws JMSException
{
+ checkWritable();
+
clearBody();
try
{
diff --git a/java/client/src/main/java/org/apache/qpid/client/security/amqplain/AmqPlainSaslClient.java b/java/client/src/main/java/org/apache/qpid/client/security/amqplain/AmqPlainSaslClient.java
index 81d3fb76d5..4291cb3259 100644
--- a/java/client/src/main/java/org/apache/qpid/client/security/amqplain/AmqPlainSaslClient.java
+++ b/java/client/src/main/java/org/apache/qpid/client/security/amqplain/AmqPlainSaslClient.java
@@ -21,6 +21,7 @@
package org.apache.qpid.client.security.amqplain;
import org.apache.qpid.framing.FieldTable;
+import org.apache.qpid.framing.FieldTableFactory;
import javax.security.sasl.SaslClient;
import javax.security.sasl.SaslException;
@@ -71,7 +72,7 @@ public class AmqPlainSaslClient implements SaslClient
{
throw new SaslException("Error handling SASL callbacks: " + e, e);
}
- FieldTable table = new FieldTable();
+ FieldTable table = FieldTableFactory.newFieldTable();
table.put("LOGIN", nameCallback.getName());
table.put("PASSWORD", pwdCallback.getPassword());
return table.getDataAsBytes();
diff --git a/java/client/src/test/java/org/apache/qpid/client/message/TestMessageHelper.java b/java/client/src/test/java/org/apache/qpid/client/message/TestMessageHelper.java
index 02fe103c6a..c26f67bf10 100644
--- a/java/client/src/test/java/org/apache/qpid/client/message/TestMessageHelper.java
+++ b/java/client/src/test/java/org/apache/qpid/client/message/TestMessageHelper.java
@@ -39,7 +39,7 @@ public class TestMessageHelper
return new JMSMapMessage();
}
- public static JMSStreamMessage newJMSStreamMessage() throws JMSException
+ public static JMSStreamMessage newJMSStreamMessage()
{
return new JMSStreamMessage();
}
diff --git a/java/client/src/test/java/org/apache/qpid/cts/src/providers/amqp/org/exolab/jmscts/amqp/AMQPAdministrator.java b/java/client/src/test/java/org/apache/qpid/cts/src/providers/amqp/org/exolab/jmscts/amqp/AMQPAdministrator.java
index 21a6816af7..006bda7e2e 100644
--- a/java/client/src/test/java/org/apache/qpid/cts/src/providers/amqp/org/exolab/jmscts/amqp/AMQPAdministrator.java
+++ b/java/client/src/test/java/org/apache/qpid/cts/src/providers/amqp/org/exolab/jmscts/amqp/AMQPAdministrator.java
@@ -41,7 +41,7 @@
* Copyright 2001, 2003 (C) Exoffice Technologies Inc. All Rights Reserved.
*
*/
-package org.exolab.jmscts.amqp;
+package org.apache.qpid.cts.src.providers.amqp.org.exolab.jmscts.amqp;
import org.apache.qpid.client.*;
import org.exolab.jmscts.provider.Administrator;
diff --git a/java/client/src/test/java/org/apache/qpid/cts/src/providers/amqp/org/exolab/jmscts/amqp/AMQPProvider.java b/java/client/src/test/java/org/apache/qpid/cts/src/providers/amqp/org/exolab/jmscts/amqp/AMQPProvider.java
index 21610d39b2..aafa415d1e 100644
--- a/java/client/src/test/java/org/apache/qpid/cts/src/providers/amqp/org/exolab/jmscts/amqp/AMQPProvider.java
+++ b/java/client/src/test/java/org/apache/qpid/cts/src/providers/amqp/org/exolab/jmscts/amqp/AMQPProvider.java
@@ -41,7 +41,7 @@
* Copyright 2001, 2003 (C) Exoffice Technologies Inc. All Rights Reserved.
*
*/
-package org.exolab.jmscts.amqp;
+package org.apache.qpid.cts.src.providers.amqp.org.exolab.jmscts.amqp;
import javax.jms.JMSException;
diff --git a/java/client/src/test/java/org/apache/qpid/example/publisher/FileMessageDispatcher.java b/java/client/src/test/java/org/apache/qpid/example/publisher/FileMessageDispatcher.java
index ca3e5ce3f5..b199d41432 100644
--- a/java/client/src/test/java/org/apache/qpid/example/publisher/FileMessageDispatcher.java
+++ b/java/client/src/test/java/org/apache/qpid/example/publisher/FileMessageDispatcher.java
@@ -19,7 +19,7 @@
package org.apache.qpid.example.publisher;
import org.apache.log4j.Logger;
-import java.util.Properties;
+
import java.io.File;
import org.apache.qpid.example.shared.FileUtils;
@@ -34,12 +34,17 @@ import javax.jms.JMSException;
*/
public class FileMessageDispatcher {
- private static final Logger _logger = Logger.getLogger(FileMessageDispatcher.class);
-
- private static Publisher _publisher = null;
+ protected static final Logger _logger = Logger.getLogger(FileMessageDispatcher.class);
- private static final String DEFAULT_PUB_NAME = "Publisher";
+ protected static Publisher _publisher = null;
+ /**
+ * To use this main method you need to specify a path or file to use for input
+ * This class then uses file contents from the dir/file specified to generate
+ * messages to publish
+ * Intended to be a very simple way to get going with publishing using the broker
+ * @param args - must specify one value, the path to file(s) for publisher
+ */
public static void main(String[] args)
{
@@ -52,7 +57,7 @@ public class FileMessageDispatcher {
{
try
{
- //publish message(s) from file(s) and send message to monitor queue
+ //publish message(s) from file(s) to configured queue
publish(args[0]);
//Move payload file(s) to archive location as no error
@@ -60,7 +65,8 @@ public class FileMessageDispatcher {
}
catch(Exception e)
{
- System.err.println("Error trying to dispatch message: " + e);
+ //log error and exit
+ _logger.error("Error trying to dispatch message: " + e);
System.exit(1);
}
finally
@@ -81,8 +87,12 @@ public class FileMessageDispatcher {
System.exit(0);
}
-
- //Publish files or file as message
+ /**
+ * Publish the content of a file or files from a directory as messages
+ * @param path - from main args
+ * @throws JMSException
+ * @throws MessageFactoryException - if cannot create message from file content
+ */
public static void publish(String path) throws JMSException, MessageFactoryException
{
File tempFile = new File(path);
@@ -100,7 +110,7 @@ public class FileMessageDispatcher {
for (File file : files)
{
//Create message factory passing in payload path
- MessageFactory factory = new MessageFactory(getPublisher().getSession(), file.toString());
+ FileMessageFactory factory = new FileMessageFactory(getPublisher().getSession(), file.toString());
//Send the message generated from the payload using the _publisher
getPublisher().sendMessage(factory.createEventMessage());
@@ -110,16 +120,18 @@ public class FileMessageDispatcher {
}
else
{
- //handle as single file
+ //handle a single file
//Create message factory passing in payload path
- MessageFactory factory = new MessageFactory(getPublisher().getSession(),tempFile.toString());
+ FileMessageFactory factory = new FileMessageFactory(getPublisher().getSession(),tempFile.toString());
//Send the message generated from the payload using the _publisher
getPublisher().sendMessage(factory.createEventMessage());
}
}
- //cleanup publishers
+ /**
+ * Cleanup before exit
+ */
public static void cleanup()
{
if (getPublisher() != null)
@@ -128,8 +140,8 @@ public class FileMessageDispatcher {
}
}
- /*
- * Returns a _publisher for a queue
+ /**
+ * @return A Publisher instance
*/
private static Publisher getPublisher()
{
@@ -141,7 +153,6 @@ public class FileMessageDispatcher {
//Create a _publisher
_publisher = new Publisher();
- _publisher.setName(DEFAULT_PUB_NAME);
return _publisher;
}
diff --git a/java/client/src/test/java/org/apache/qpid/example/publisher/MessageFactory.java b/java/client/src/test/java/org/apache/qpid/example/publisher/FileMessageFactory.java
index f9944284c8..88bcbbbccb 100644
--- a/java/client/src/test/java/org/apache/qpid/example/publisher/MessageFactory.java
+++ b/java/client/src/test/java/org/apache/qpid/example/publisher/FileMessageFactory.java
@@ -25,13 +25,19 @@ import org.apache.qpid.example.shared.Statics;
import java.io.*;
import javax.jms.*;
-public class MessageFactory
+public class FileMessageFactory
{
- private final Session _session;
- private final String _payload;
- private final String _filename;
+ protected final Session _session;
+ protected final String _payload;
+ protected final String _filename;
- public MessageFactory(Session session, String filename) throws MessageFactoryException
+ /**
+ * Contructs and instance using a filename from which content will be used to create message
+ * @param session
+ * @param filename
+ * @throws MessageFactoryException
+ */
+ public FileMessageFactory(Session session, String filename) throws MessageFactoryException
{
try
{
@@ -45,9 +51,13 @@ public class MessageFactory
}
}
- /*
- * Creates message and sets filename property on it
- */
+ /**
+ * Creates a text message and sets filename property on it
+ * The filename property is purely intended to provide visibility
+ * of file content passing trhough the broker using example classes
+ * @return Message - a TextMessage with content from file
+ * @throws JMSException
+ */
public Message createEventMessage() throws JMSException
{
TextMessage msg = _session.createTextMessage();
@@ -56,9 +66,13 @@ public class MessageFactory
return msg;
}
- /*
- * Creates message from a string for use by the monitor
- */
+ /**
+ * Creates message from a string for use by the monitor
+ * @param session
+ * @param textMsg - message content
+ * @return Message - TextMessage with content from String
+ * @throws JMSException
+ */
public static Message createSimpleEventMessage(Session session, String textMsg) throws JMSException
{
TextMessage msg = session.createTextMessage();
diff --git a/java/client/src/test/java/org/apache/qpid/example/publisher/MonitorMessageDispatcher.java b/java/client/src/test/java/org/apache/qpid/example/publisher/MonitorMessageDispatcher.java
index 16b32da22a..8784d340da 100644
--- a/java/client/src/test/java/org/apache/qpid/example/publisher/MonitorMessageDispatcher.java
+++ b/java/client/src/test/java/org/apache/qpid/example/publisher/MonitorMessageDispatcher.java
@@ -20,8 +20,9 @@ package org.apache.qpid.example.publisher;
import org.apache.log4j.Logger;
import org.apache.log4j.BasicConfigurator;
-import org.apache.qpid.example.shared.Statics;
+
import javax.jms.*;
+
import java.util.Properties;
/**
@@ -32,14 +33,18 @@ public class MonitorMessageDispatcher {
private static final Logger _logger = Logger.getLogger(MonitorMessageDispatcher.class);
- private static MonitorPublisher _monitorPublisher = null;
+ protected static MonitorPublisher _monitorPublisher = null;
- private static final String DEFAULT_MONITOR_PUB_NAME = "MonitorPublisher";
+ protected static final String DEFAULT_MONITOR_PUB_NAME = "MonitorPublisher";
+ /**
+ * Easy entry point for running a message dispatcher for monitoring consumption
+ * @param args
+ */
public static void main(String[] args)
{
- //@TODO switch on logging appropriately at your app level
+ //Switch on logging appropriately for your app
BasicConfigurator.configure();
try
@@ -61,7 +66,7 @@ public class MonitorMessageDispatcher {
}
catch(UndeliveredMessageException a)
{
- //@TODO trigger application specific failure handling here
+ //trigger application specific failure handling here
_logger.error("Problem delivering monitor message");
break;
}
@@ -69,8 +74,7 @@ public class MonitorMessageDispatcher {
}
catch(Exception e)
{
-
- System.err.println("Error trying to dispatch AMS monitor message: " + e);
+ _logger.error("Error trying to dispatch AMS monitor message: " + e);
System.exit(1);
}
finally
@@ -84,15 +88,21 @@ public class MonitorMessageDispatcher {
System.exit(1);
}
- //Publish heartbeat message
+ /**
+ * Publish heartbeat message
+ * @throws JMSException
+ * @throws UndeliveredMessageException
+ */
public static void publish() throws JMSException, UndeliveredMessageException
{
//Send the message generated from the payload using the _publisher
getMonitorPublisher().sendImmediateMessage
- (MessageFactory.createSimpleEventMessage(getMonitorPublisher().getSession(),"monitor:" +System.currentTimeMillis()));
+ (FileMessageFactory.createSimpleEventMessage(getMonitorPublisher().getSession(),"monitor:" +System.currentTimeMillis()));
}
- //cleanup publishers
+ /**
+ * Cleanup publishers
+ */
public static void cleanup()
{
if (getMonitorPublisher() != null)
@@ -114,9 +124,6 @@ public class MonitorMessageDispatcher {
return _monitorPublisher;
}
- //Create _publisher using system properties
- Properties props = System.getProperties();
-
//Create a _publisher using failover details and constant for monitor queue
_monitorPublisher = new MonitorPublisher();
diff --git a/java/client/src/test/java/org/apache/qpid/example/publisher/Publisher.java b/java/client/src/test/java/org/apache/qpid/example/publisher/Publisher.java
index d64fd9b142..be42e0e413 100644
--- a/java/client/src/test/java/org/apache/qpid/example/publisher/Publisher.java
+++ b/java/client/src/test/java/org/apache/qpid/example/publisher/Publisher.java
@@ -22,14 +22,14 @@ import org.apache.log4j.Logger;
import org.apache.qpid.client.AMQConnectionFactory;
-import org.apache.qpid.jms.Session;
-
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.DeliveryMode;
import javax.jms.Queue;
import javax.jms.MessageProducer;
import javax.jms.Connection;
+import javax.jms.Session;
+
import javax.naming.InitialContext;
import org.apache.qpid.example.shared.InitialContextHelper;
@@ -44,7 +44,7 @@ public class Publisher
protected Session _session;
- private MessageProducer _producer;
+ protected MessageProducer _producer;
protected String _destinationDir;
@@ -54,7 +54,10 @@ public class Publisher
protected static final String _defaultDestinationDir = "/tmp";
- //constructor for use with a single host
+ /**
+ * Creates a Publisher instance using properties from example.properties
+ * See InitialContextHelper for details of how context etc created
+ */
public Publisher()
{
try
@@ -68,7 +71,7 @@ public class Publisher
_connection = cf.createConnection();
//create a transactional session
- _session = (Session) _connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
+ _session = _connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
//lookup the example queue and use it
//Queue is non-exclusive and not deleted when last consumer detaches
@@ -90,8 +93,9 @@ public class Publisher
}
/**
- * Publishes a non-persistent message using transacted session
- **/
+ * Publishes a non-persistent message using transacted session
+ * Note that persistent is the default mode for send - so need to specify for transient
+ */
public boolean sendMessage(Message message)
{
try
@@ -124,6 +128,9 @@ public class Publisher
return true;
}
+ /**
+ * Cleanup resources before exit
+ */
public void cleanup()
{
try
@@ -138,11 +145,15 @@ public class Publisher
}
catch(Exception e)
{
- System.err.println("Error trying to cleanup publisher " + e);
+ _log.error("Error trying to cleanup publisher " + e);
System.exit(1);
}
}
+ /**
+ * Exposes session
+ * @return Session
+ */
public Session getSession()
{
return _session;
diff --git a/java/client/src/test/java/org/apache/qpid/example/subscriber/MonitoredSubscriber.java b/java/client/src/test/java/org/apache/qpid/example/subscriber/MonitoredSubscriber.java
index d6e020bf43..9c195aef40 100644
--- a/java/client/src/test/java/org/apache/qpid/example/subscriber/MonitoredSubscriber.java
+++ b/java/client/src/test/java/org/apache/qpid/example/subscriber/MonitoredSubscriber.java
@@ -42,6 +42,9 @@ public class MonitoredSubscriber extends Subscriber
_monitorDestinationName = _destinationName + Statics.MONITOR_QUEUE_SUFFIX;
}
+ /**
+ * MessageListener implementation for this subscriber
+ */
public static class MonitorMessageListener implements MessageListener
{
private String _name;
@@ -52,9 +55,10 @@ public class MonitoredSubscriber extends Subscriber
}
- /*
- * Listens for heartbeat messages and acknowledges them
- */
+ /**
+ * Listens for heartbeat messages and acknowledges them
+ * @param message
+ */
public void onMessage(javax.jms.Message message)
{
_logger.info(_name + " monitor got message '" + message + "'");
@@ -79,9 +83,9 @@ public class MonitoredSubscriber extends Subscriber
}
}
- /*
- * Subscribes to Queue and attaches additional monitor listener
- */
+ /**
+ * Subscribes to Queue and attaches additional monitor listener
+ */
public void subscribeAndMonitor()
{
try
@@ -115,7 +119,9 @@ public class MonitoredSubscriber extends Subscriber
}
}
- //stop consuming
+ /**
+ * Stop consuming
+ */
public void stopMonitor()
{
try
diff --git a/java/client/src/test/java/org/apache/qpid/example/subscriber/MonitoredSubscriptionWrapper.java b/java/client/src/test/java/org/apache/qpid/example/subscriber/MonitoredSubscriptionWrapper.java
index d6ec8bd5de..d2f27da052 100644
--- a/java/client/src/test/java/org/apache/qpid/example/subscriber/MonitoredSubscriptionWrapper.java
+++ b/java/client/src/test/java/org/apache/qpid/example/subscriber/MonitoredSubscriptionWrapper.java
@@ -19,9 +19,6 @@
package org.apache.qpid.example.subscriber;
import org.apache.log4j.BasicConfigurator;
-import org.apache.qpid.example.shared.Statics;
-
-import java.util.Properties;
/**
* Allows you to simply start a monitored subscriber
@@ -30,6 +27,10 @@ public class MonitoredSubscriptionWrapper {
private static MonitoredSubscriber _subscriber;
+ /**
+ * Create a monitored subscriber and start it
+ * @param args - no params required
+ */
public static void main(String args[])
{
//switch on logging
@@ -37,15 +38,12 @@ public class MonitoredSubscriptionWrapper {
_subscriber = new MonitoredSubscriber();
- //using system props but can replace with app appropriate config here
- Properties props = System.getProperties();
-
- //note that for failover should set -Dhost=host1:port1;host2:port2
- //Client will then failover in order i.e. connect to first host and failover to second and so on
_subscriber.subscribe();
}
- //Stop subscribing now ...
+ /**
+ * Stop subscribing now ...
+ */
public static void stop()
{
_subscriber.stop();
diff --git a/java/client/src/test/java/org/apache/qpid/example/subscriber/Subscriber.java b/java/client/src/test/java/org/apache/qpid/example/subscriber/Subscriber.java
index 6b89567b83..34c7d6c7bb 100644
--- a/java/client/src/test/java/org/apache/qpid/example/subscriber/Subscriber.java
+++ b/java/client/src/test/java/org/apache/qpid/example/subscriber/Subscriber.java
@@ -69,9 +69,9 @@ public class Subscriber
}
}
- /*
- * Listener class that handles messages
- */
+ /**
+ * Listener class that handles messages
+ */
public static class ExampleMessageListener implements MessageListener
{
private String _name;
@@ -82,10 +82,10 @@ public class Subscriber
}
- /*
- * Listens for message callbacks, handles and then acknowledges them
- * @param message - the message received
- */
+ /**
+ * Listens for message callbacks, handles and then acknowledges them
+ * @param message - the message received
+ */
public void onMessage(javax.jms.Message message)
{
_log.info(_name + " got message '" + message + "'");
@@ -113,9 +113,9 @@ public class Subscriber
}
}
- /*
- * Subscribes to example Queue and attaches listener
- */
+ /**
+ * Subscribes to example Queue and attaches listener
+ */
public void subscribe()
{
_log.info("Starting subscription ...");
@@ -160,14 +160,18 @@ public class Subscriber
}
}
+ /**
+ * Set destination (queue or topic) name
+ * @param name
+ */
public void setDestinationName(String name)
{
_destinationName = name;
}
- /*
- * stop consuming and close connection
- */
+ /**
+ * Stop consuming and close connection
+ */
public void stop()
{
try
diff --git a/java/client/src/test/java/org/apache/qpid/example/subscriber/SubscriptionWrapper.java b/java/client/src/test/java/org/apache/qpid/example/subscriber/SubscriptionWrapper.java
index 4e755e858f..32a0ef685c 100644
--- a/java/client/src/test/java/org/apache/qpid/example/subscriber/SubscriptionWrapper.java
+++ b/java/client/src/test/java/org/apache/qpid/example/subscriber/SubscriptionWrapper.java
@@ -18,10 +18,6 @@
*/
package org.apache.qpid.example.subscriber;
-import org.apache.qpid.example.shared.Statics;
-
-import java.util.Properties;
-
import org.apache.log4j.BasicConfigurator;
/**
@@ -31,6 +27,10 @@ public class SubscriptionWrapper {
private static Subscriber _subscriber;
+ /**
+ * Create a subscriber and start it
+ * @param args
+ */
public static void main(String args[])
{
//switch on logging
@@ -38,15 +38,12 @@ public class SubscriptionWrapper {
_subscriber = new Subscriber();
- //using system props but can replace with app appropriate config here
- Properties props = System.getProperties();
-
- //note that for failover should set -Dhost=host1:port1;host2:port2
- //Client will then failover in order i.e. connect to first host and failover to second and so on
_subscriber.subscribe();
}
- //Stop subscribing now ...
+ /**
+ * Stop subscribing now ...
+ */
public static void stop()
{
_subscriber.stop();
diff --git a/java/client/src/test/java/org/apache/qpid/example/test/TestAMSPubSub.java b/java/client/src/test/java/org/apache/qpid/example/test/TestAMSPubSub.java
deleted file mode 100644
index 3a81a0224b..0000000000
--- a/java/client/src/test/java/org/apache/qpid/example/test/TestAMSPubSub.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.qpid.example.test;
-
-import org.apache.qpid.example.subscriber.Subscriber;
-import org.apache.qpid.example.publisher.FileMessageDispatcher;
-import org.apache.qpid.example.shared.Statics;
-
-import java.net.InetAddress;
-import java.util.Properties;
-
-import org.apache.log4j.Logger;
-import org.apache.log4j.BasicConfigurator;
-
-
-public class TestAMSPubSub {
-
- private static final Logger _logger = Logger.getLogger(TestAMSPubSub.class);
- private static final String _defaultPayloadPath = "/tmp";
-
- private static Subscriber subscriber;
-
-
- /**
- * Test main for class using default of local file for message payload
- */
- public static void main(String[] args)
- {
-
- //switch on logging
- BasicConfigurator.configure();
-
- InetAddress _address;
- TestAMSPubSub testPubSub = new TestAMSPubSub();
-
- //create publisher and subscriber
- subscriber = new Subscriber();
-
- //subscribe
- testPubSub.subscribe();
-
- //publish a message
- if (args.length == 1)
- {
- testPubSub.publish(args[0]);
- }
- else
- {
- testPubSub.publish(null);
- }
-
- //Should be able to see message publication and receipt in logs now
-
- //Disconnect and end test run
- FileMessageDispatcher.cleanup();
-
- //and exit as we're all done
- System.exit(0);
-
- }
-
- private void subscribe()
- {
- subscriber.subscribe();
- }
-
- private void publish(String payloadPath)
- {
-
- try
- {
- if (payloadPath == null|| payloadPath.length() == 0)
- {
- payloadPath = _defaultPayloadPath;
- }
-
- FileMessageDispatcher.publish(payloadPath);
-
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- }
-}
diff --git a/java/client/src/test/java/org/apache/qpid/example/test/TestMultSubscribers.java b/java/client/src/test/java/org/apache/qpid/example/test/TestMultSubscribers.java
deleted file mode 100644
index f1a921e106..0000000000
--- a/java/client/src/test/java/org/apache/qpid/example/test/TestMultSubscribers.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.qpid.example.test;
-
-import org.apache.qpid.example.subscriber.Subscriber;
-import org.apache.qpid.example.publisher.FileMessageDispatcher;
-import org.apache.qpid.example.shared.Statics;
-
-import java.net.InetAddress;
-import java.util.Properties;
-
-import org.apache.log4j.Logger;
-import org.apache.log4j.BasicConfigurator;
-
-
-public class TestMultSubscribers {
-
- private static final Logger _logger = Logger.getLogger(TestMultSubscribers.class);
- private static final String _defaultPayloadPath = "/tmp";
-
- private static Subscriber subscriber1;
- private static Subscriber subscriber2;
-
- private static final String DEFAULT_LOG_CONFIG_FILENAME = "log4j.xml";
-
- /**
- * Test main for class using default of local file for message payload
- */
- public static void main(String[] args)
- {
-
- //switch on logging
- BasicConfigurator.configure();
-
- InetAddress _address;
- TestMultSubscribers testMultSub = new TestMultSubscribers();
-
- //create publisher and subscriber
- subscriber1 = new Subscriber();
- subscriber2 = new Subscriber();
-
- //subscribe to the topic
- testMultSub.subscribe(args);
-
- //publish a message
- if (args.length == 1)
- {
- testMultSub.publish(args[0]);
- }
- else
- {
- testMultSub.publish(null);
- }
-
- //Should be able to see message publication and receipt in logs now
-
- //Disconnect and end test run
- FileMessageDispatcher.cleanup();
-
- //and exit as we're all done
- System.exit(0);
-
- }
-
- /*
- * Point both of our subscribers at one queue
- */
- private void subscribe(String[] args)
- {
- Properties props = System.getProperties();
- subscriber1.subscribe();
- subscriber2.subscribe();
-
- }
-
- private void publish(String payloadPath)
- {
-
- try
- {
- if (payloadPath == null|| payloadPath.length() == 0)
- {
- payloadPath = _defaultPayloadPath;
- }
-
- FileMessageDispatcher.publish(payloadPath);
-
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- }
-}
-
diff --git a/java/client/src/test/java/org/apache/qpid/example/test/TestPublisher.java b/java/client/src/test/java/org/apache/qpid/example/test/TestPublisher.java
deleted file mode 100644
index 6ff6028ccd..0000000000
--- a/java/client/src/test/java/org/apache/qpid/example/test/TestPublisher.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.qpid.example.test;
-
-import org.apache.qpid.example.publisher.FileMessageDispatcher;
-
-import java.net.InetAddress;
-
-import org.apache.log4j.Logger;
-import org.apache.log4j.BasicConfigurator;
-
-
-public class TestPublisher {
-
- private static final Logger _logger = Logger.getLogger(TestAMSPubSub.class);
- private static final String _defaultPayloadPath = "/tmp";
-
- /**
- * Test main for class using default of local file for message payload
- */
- public static void main(String[] args)
- {
-
- //switch on logging
- BasicConfigurator.configure();
-
- InetAddress _address;
- TestPublisher testPub = new TestPublisher();
-
- //publish a message
- if (args.length == 1)
- {
- testPub.publish(args[0]);
- }
- else
- {
- testPub.publish(null);
- }
-
- //Should be able to see message publication and receipt in logs now
-
- //Disconnect and end test run
- FileMessageDispatcher.cleanup();
-
- //and exit as we're all done
- System.exit(0);
-
- }
-
- private void publish(String payloadPath)
- {
-
- try
- {
- if (payloadPath == null|| payloadPath.length() == 0)
- {
- payloadPath = _defaultPayloadPath;
- }
-
- FileMessageDispatcher.publish(payloadPath);
-
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- }
-}
-
diff --git a/java/client/src/test/java/org/apache/qpid/framing/FieldTableTest.java b/java/client/src/test/java/org/apache/qpid/framing/FieldTableTest.java
index 49e1630f15..2a7cb8be30 100644
--- a/java/client/src/test/java/org/apache/qpid/framing/FieldTableTest.java
+++ b/java/client/src/test/java/org/apache/qpid/framing/FieldTableTest.java
@@ -33,6 +33,33 @@ import junit.framework.TestCase;
public class FieldTableTest extends TestCase
{
+
+ public void testEncoding()
+ {
+ FieldTable table = FieldTableFactory.newFieldTable();
+
+ String key = "String";
+ String value = "Hello";
+ table.put(key, value);
+
+ //Add one for the type encoding
+ int size = EncodingUtils.encodedShortStringLength(key) + 1 +
+ EncodingUtils.encodedLongStringLength(value);
+
+ assertEquals(table.getEncodedSize(), size);
+
+ key = "Integer";
+ Integer number = new Integer(60);
+ table.put(key, number);
+
+ //Add one for the type encoding
+ size += EncodingUtils.encodedShortStringLength(key) + 1 + 4;
+
+
+ assertEquals(table.getEncodedSize(), size);
+ }
+
+
public void testDataDump() throws IOException, AMQFrameDecodingException
{
byte[] data = readBase64("content.txt");
@@ -46,7 +73,7 @@ public class FieldTableTest extends TestCase
ByteBuffer buffer = ByteBuffer.allocate(data.length);
buffer.put(data);
buffer.flip();
- FieldTable table = new FieldTable(buffer, size);
+ FieldTable table = FieldTableFactory.newFieldTable(buffer, size);
}
/*
@@ -107,7 +134,7 @@ public class FieldTableTest extends TestCase
FieldTable load(String name) throws IOException
{
- return populate(new FieldTable(), read(name));
+ return populate(FieldTableFactory.newFieldTable(), read(name));
}
Properties read(String name) throws IOException
@@ -123,11 +150,12 @@ public class FieldTableTest extends TestCase
{
String key = (String) i.nextElement();
String value = properties.getProperty(key);
- try{
+ try
+ {
int ival = Integer.parseInt(value);
table.put(key, (long) ival);
}
- catch(NumberFormatException e)
+ catch (NumberFormatException e)
{
table.put(key, value);
}
@@ -144,7 +172,8 @@ public class FieldTableTest extends TestCase
{
StringBuffer buffer = new StringBuffer();
String line = in.readLine();
- while (line != null){
+ while (line != null)
+ {
buffer.append(line).append(" ");
line = in.readLine();
}
diff --git a/java/client/src/test/java/org/apache/qpid/headers/MessageFactory.java b/java/client/src/test/java/org/apache/qpid/headers/MessageFactory.java
index f1f310c6e5..6f538d068c 100644
--- a/java/client/src/test/java/org/apache/qpid/headers/MessageFactory.java
+++ b/java/client/src/test/java/org/apache/qpid/headers/MessageFactory.java
@@ -22,6 +22,7 @@ package org.apache.qpid.headers;
import org.apache.qpid.client.AMQSession;
import org.apache.qpid.framing.FieldTable;
+import org.apache.qpid.framing.FieldTableFactory;
import javax.jms.BytesMessage;
import javax.jms.Destination;
@@ -127,14 +128,14 @@ class MessageFactory
FieldTable getConsumerBinding()
{
- FieldTable binding = new FieldTable();
+ FieldTable binding = FieldTableFactory.newFieldTable();
binding.put("SF0000", "value");
return binding;
}
FieldTable getControllerBinding()
{
- FieldTable binding = new FieldTable();
+ FieldTable binding = FieldTableFactory.newFieldTable();
binding.put("SCONTROL", "value");
return binding;
}
diff --git a/java/client/src/test/java/org/apache/qpid/requestreply1/ServiceRequestingClient.java b/java/client/src/test/java/org/apache/qpid/requestreply1/ServiceRequestingClient.java
index 5dc57364b3..74becfd9bb 100644
--- a/java/client/src/test/java/org/apache/qpid/requestreply1/ServiceRequestingClient.java
+++ b/java/client/src/test/java/org/apache/qpid/requestreply1/ServiceRequestingClient.java
@@ -107,6 +107,7 @@ public class ServiceRequestingClient implements ExceptionListener
}
try
{
+ m.getPropertyNames();
if (m.propertyExists("timeSent"))
{
long timeSent = Long.parseLong(m.getStringProperty("timeSent"));
diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/basic/BytesMessageTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/basic/BytesMessageTest.java
index 4d37c5d2a6..2983a16e6d 100644
--- a/java/client/src/test/java/org/apache/qpid/test/unit/basic/BytesMessageTest.java
+++ b/java/client/src/test/java/org/apache/qpid/test/unit/basic/BytesMessageTest.java
@@ -135,6 +135,8 @@ public class BytesMessageTest extends TestCase implements MessageListener
buffer.get(data);
actual.add(data);
+
+ //Check Body Write Status
try
{
m.writeBoolean(true);
@@ -144,6 +146,41 @@ public class BytesMessageTest extends TestCase implements MessageListener
{
//normal execution
}
+
+ m.clearBody();
+
+ try
+ {
+ m.writeBoolean(true);
+ }
+ catch (MessageNotWriteableException mnwe)
+ {
+ Assert.fail("Message should be writeable");
+ }
+
+
+ //Check property write status
+ try
+ {
+ m.setStringProperty("test", "test");
+ Assert.fail("Message should not be writeable");
+ }
+ catch (MessageNotWriteableException mnwe)
+ {
+ //normal execution
+ }
+
+ m.clearProperties();
+
+ try
+ {
+ m.setStringProperty("test", "test");
+ }
+ catch (MessageNotWriteableException mnwe)
+ {
+ Assert.fail("Message should be writeable");
+ }
+
}
assertEqual(messages.iterator(), actual.iterator());
diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/basic/FieldTableKeyEnumeratorTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/basic/FieldTableKeyEnumeratorTest.java
index 079def81d0..ad180e3a89 100644
--- a/java/client/src/test/java/org/apache/qpid/test/unit/basic/FieldTableKeyEnumeratorTest.java
+++ b/java/client/src/test/java/org/apache/qpid/test/unit/basic/FieldTableKeyEnumeratorTest.java
@@ -21,10 +21,13 @@
package org.apache.qpid.test.unit.basic;
import org.apache.qpid.framing.FieldTable;
+import org.apache.qpid.framing.FieldTableFactory;
import org.apache.qpid.client.message.JMSTextMessage;
import org.apache.qpid.client.message.TestMessageHelper;
import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
import javax.jms.JMSException;
@@ -34,20 +37,28 @@ public class FieldTableKeyEnumeratorTest extends TestCase
{
public void testKeyEnumeration()
{
- FieldTable result = new FieldTable();
+ FieldTable result = FieldTableFactory.newFieldTable();
result.put("one", 1L);
result.put("two", 2L);
result.put("three", 3L);
result.put("four", 4L);
result.put("five", 5L);
- Enumeration e = result.keys();
+ Iterator iterator = result.keySet().iterator();
+
+ try
+ {
+ assertTrue("one".equals(iterator.next()));
+ assertTrue("two".equals(iterator.next()));
+ assertTrue("three".equals(iterator.next()));
+ assertTrue("four".equals(iterator.next()));
+ assertTrue("five".equals(iterator.next()));
+ }
+ catch (NoSuchElementException e)
+ {
+ fail("All elements should be found.");
+ }
- assertTrue("one".equals(e.nextElement()));
- assertTrue("two".equals(e.nextElement()));
- assertTrue("three".equals(e.nextElement()));
- assertTrue("four".equals(e.nextElement()));
- assertTrue("five".equals(e.nextElement()));
}
public void testPropertEnu()
diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/basic/FieldTableMessageTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/basic/FieldTableMessageTest.java
index 67b7f49565..c1ecef6b57 100644
--- a/java/client/src/test/java/org/apache/qpid/test/unit/basic/FieldTableMessageTest.java
+++ b/java/client/src/test/java/org/apache/qpid/test/unit/basic/FieldTableMessageTest.java
@@ -26,10 +26,12 @@ import org.apache.qpid.client.AMQQueue;
import org.apache.qpid.client.AMQSession;
import org.apache.qpid.client.message.JMSBytesMessage;
import org.apache.qpid.framing.AMQFrameDecodingException;
-import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.framing.FieldTableTest;
+import org.apache.qpid.framing.FieldTable;
+import org.apache.qpid.framing.FieldTableFactory;
import org.apache.qpid.test.VMBrokerSetup;
import org.apache.mina.common.ByteBuffer;
+import org.apache.log4j.Logger;
import java.io.IOException;
import java.util.ArrayList;
@@ -39,6 +41,9 @@ import junit.framework.TestCase;
public class FieldTableMessageTest extends TestCase implements MessageListener
{
+
+ private static final Logger _logger = Logger.getLogger(FieldTableMessageTest.class);
+
private AMQConnection _connection;
private AMQDestination _destination;
private AMQSession _session;
@@ -50,7 +55,7 @@ public class FieldTableMessageTest extends TestCase implements MessageListener
protected void setUp() throws Exception
{
super.setUp();
- init(new AMQConnection(_connectionString, "guest", "guest", randomize("Client"), "/test_path"));
+ init(new AMQConnection(_connectionString, "guest", "guest", randomize("Client"), "/test_path"));
}
protected void tearDown() throws Exception
@@ -80,7 +85,7 @@ public class FieldTableMessageTest extends TestCase implements MessageListener
private FieldTable load() throws IOException
{
- FieldTable result = new FieldTable();
+ FieldTable result = FieldTableFactory.newFieldTable();
result.put("one", 1L);
result.put("two", 2L);
result.put("three", 3L);
@@ -128,7 +133,7 @@ public class FieldTableMessageTest extends TestCase implements MessageListener
for (Object m : received)
{
ByteBuffer buffer = ((JMSBytesMessage) m).getData();
- FieldTable actual = new FieldTable(buffer, buffer.remaining());
+ FieldTable actual = FieldTableFactory.newFieldTable(buffer, buffer.remaining());
new FieldTableTest().assertEquivalent(_expected, actual);
}
}
diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/basic/FieldTablePropertyTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/basic/FieldTablePropertyTest.java
new file mode 100644
index 0000000000..92b4831d93
--- /dev/null
+++ b/java/client/src/test/java/org/apache/qpid/test/unit/basic/FieldTablePropertyTest.java
@@ -0,0 +1,65 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.test.unit.basic;
+
+import org.apache.qpid.framing.PropertyFieldTable;
+import org.apache.qpid.framing.FieldTable;
+import org.apache.qpid.client.message.JMSTextMessage;
+import org.apache.qpid.client.message.TestMessageHelper;
+
+import java.util.Enumeration;
+import java.util.NoSuchElementException;
+
+import javax.jms.JMSException;
+
+import junit.framework.TestCase;
+
+public class FieldTablePropertyTest extends TestCase
+{
+ public void testPropertyNames()
+ {
+ try
+ {
+ JMSTextMessage text = TestMessageHelper.newJMSTextMessage();
+
+ text.setBooleanProperty("Boolean1", true);
+ text.setBooleanProperty("Boolean2", true);
+ text.setIntProperty("Int", 2);
+ text.setLongProperty("Long", 2);
+
+ Enumeration e = text.getPropertyNames();
+
+ assertEquals("Boolean1", e.nextElement());
+ assertTrue("Boolean2".equals(e.nextElement()));
+ assertTrue("Int".equals(e.nextElement()));
+ assertTrue("Long".equals(e.nextElement()));
+ }
+ catch (JMSException e)
+ {
+
+ }
+ }
+
+ public static junit.framework.Test suite()
+ {
+ return new junit.framework.TestSuite(FieldTablePropertyTest.class);
+ }
+}
diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/basic/MapMessageTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/basic/MapMessageTest.java
index f25d2887ae..5353a19d13 100644
--- a/java/client/src/test/java/org/apache/qpid/test/unit/basic/MapMessageTest.java
+++ b/java/client/src/test/java/org/apache/qpid/test/unit/basic/MapMessageTest.java
@@ -47,6 +47,7 @@ public class MapMessageTest extends TestCase implements MessageListener
private final List<String> messages = new ArrayList<String>();
private int _count = 100;
public String _connectionString = "vm://:1";
+ private byte[] _bytes = {99, 98, 97, 96, 95};
protected void setUp() throws Exception
{
@@ -104,9 +105,31 @@ public class MapMessageTest extends TestCase implements MessageListener
MapMessage message = _session.createMapMessage();
message.setBoolean("odd", i / 2 == 0);
+ message.setByte("byte", (byte) Byte.MAX_VALUE);
+
+ message.setBytes("bytes", _bytes);
+ message.setChar("char", (char) 'c');
+ message.setDouble("double", (double) Double.MAX_VALUE);
+ message.setFloat("float", (float) Float.MAX_VALUE);
+
message.setInt("messageNumber", i);
+ message.setInt("int", (int) Integer.MAX_VALUE);
+
+ message.setLong("long", (long) Long.MAX_VALUE);
+ message.setShort("short", (short) Short.MAX_VALUE);
message.setString("message", text);
+
+ message.setObject("object-bool", true);
+ message.setObject("object-byte", Byte.MAX_VALUE);
+ message.setObject("object-bytes", _bytes);
+ message.setObject("object-char", 'c');
+ message.setObject("object-double", Double.MAX_VALUE);
+ message.setObject("object-float", Float.MAX_VALUE);
+ message.setObject("object-int", Integer.MAX_VALUE);
+ message.setObject("object-long", Long.MAX_VALUE);
+ message.setObject("object-short", Short.MAX_VALUE);
+
producer.send(message);
}
}
@@ -130,18 +153,74 @@ public class MapMessageTest extends TestCase implements MessageListener
{
actual.add(m.getString("message"));
assertEqual(m.getInt("messageNumber"), count);
- assertEqual(m.getBoolean("odd"), count / 2 == 0);
-// try
-// {
-// m.setInt("testint", 3);
-// fail("Message should not be writeable");
-// }
-// catch (MessageNotWriteableException mnwe)
-// {
-// //normal execution
-// }
+ assertEqual(count / 2 == 0, m.getBoolean("odd"));
+ assertEqual((byte) Byte.MAX_VALUE, m.getByte("byte"));
+
+ assertBytesEqual(_bytes, m.getBytes("bytes"));
+ assertEqual((char) 'c', m.getChar("char"));
+ assertEqual((double) Double.MAX_VALUE, m.getDouble("double"));
+ assertEqual((float) Float.MAX_VALUE, m.getFloat("float"));
+
+ assertEqual(count, m.getInt("messageNumber"));
+ assertEqual((int) Integer.MAX_VALUE, m.getInt("int"));
+ assertEqual((long) Long.MAX_VALUE, m.getLong("long"));
+ assertEqual((short) Short.MAX_VALUE, m.getShort("short"));
+
+ assertEqual(true, m.getObject("object-bool"));
+ assertEqual(Byte.MAX_VALUE, m.getObject("object-byte"));
+ assertBytesEqual(_bytes, (byte[]) m.getObject("object-bytes"));
+ assertEqual('c', m.getObject("object-char"));
+ assertEqual(Double.MAX_VALUE, m.getObject("object-double"));
+ assertEqual(Float.MAX_VALUE, m.getObject("object-float"));
+ assertEqual(Integer.MAX_VALUE, m.getObject("object-int"));
+ assertEqual(Long.MAX_VALUE, m.getObject("object-long"));
+ assertEqual(Short.MAX_VALUE, m.getObject("object-short"));
+
+
+ try
+ {
+ m.setInt("testint", 3);
+ fail("Message should not be writeable");
+ }
+ catch (MessageNotWriteableException mnwe)
+ {
+ //normal execution
+ }
+
+ m.clearBody();
+
+ try
+ {
+ m.setInt("testint", 3);
+ }
+ catch (MessageNotWriteableException mnwe)
+ {
+ Assert.fail("Message should be writeable");
+ }
+
+ //Check property write status
+ try
+ {
+ m.setStringProperty("test", "test");
+ Assert.fail("Message should not be writeable");
+ }
+ catch (MessageNotWriteableException mnwe)
+ {
+ //normal execution
+ }
+
+ m.clearProperties();
+
+ try
+ {
+ m.setStringProperty("test", "test");
+ }
+ catch (MessageNotWriteableException mnwe)
+ {
+ Assert.fail("Message should be writeable");
+ }
count++;
}
@@ -149,6 +228,17 @@ public class MapMessageTest extends TestCase implements MessageListener
assertEqual(messages.iterator(), actual.iterator());
}
+ private void assertBytesEqual(byte[] expected, byte[] actual)
+ {
+ Assert.assertEquals(expected.length, actual.length);
+
+ for (int index = 0; index < expected.length; index++)
+ {
+ Assert.assertEquals(expected[index], actual[index]);
+ }
+ }
+
+
private static void assertEqual(Iterator expected, Iterator actual)
{
List<String> errors = new ArrayList<String>();
diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/basic/ObjectMessageTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/basic/ObjectMessageTest.java
index dfb1b26454..e7d7159bd8 100644
--- a/java/client/src/test/java/org/apache/qpid/test/unit/basic/ObjectMessageTest.java
+++ b/java/client/src/test/java/org/apache/qpid/test/unit/basic/ObjectMessageTest.java
@@ -125,19 +125,53 @@ public class ObjectMessageTest extends TestCase implements MessageListener
{
actual.add(m.getObject());
-// try
-// {
-// m.setObject("Test text");
-// Assert.fail("Message should not be writeable");
-// }
-// catch (MessageNotWriteableException mnwe)
-// {
-// //normal execution
-// }
+ try
+ {
+ m.setObject("Test text");
+ Assert.fail("Message should not be writeable");
+ }
+ catch (MessageNotWriteableException mnwe)
+ {
+ //normal execution
+ }
+
+ m.clearBody();
+
+ try
+ {
+ m.setObject("Test text");
+ }
+ catch (MessageNotWriteableException mnwe)
+ {
+ Assert.fail("Message should be writeable");
+ }
+
+ //Check property write status
+ try
+ {
+ m.setStringProperty("test", "test");
+ Assert.fail("Message should not be writeable");
+ }
+ catch (MessageNotWriteableException mnwe)
+ {
+ //normal execution
+ }
+
+ m.clearProperties();
+
+ try
+ {
+ m.setStringProperty("test", "test");
+ }
+ catch (MessageNotWriteableException mnwe)
+ {
+ Assert.fail("Message should be writeable");
+ }
}
assertEqual(messages.iterator(), actual.iterator());
+
}
private static void assertEqual(Iterator expected, Iterator actual)
diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/basic/PropertyValueTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/basic/PropertyValueTest.java
new file mode 100644
index 0000000000..02f371e81b
--- /dev/null
+++ b/java/client/src/test/java/org/apache/qpid/test/unit/basic/PropertyValueTest.java
@@ -0,0 +1,264 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.test.unit.basic;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+import org.apache.log4j.Logger;
+import org.apache.qpid.client.AMQConnection;
+import org.apache.qpid.client.AMQQueue;
+import org.apache.qpid.client.AMQSession;
+import org.apache.qpid.client.message.JMSTextMessage;
+import org.apache.qpid.test.VMBrokerSetup;
+
+import javax.jms.Destination;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageListener;
+import javax.jms.MessageProducer;
+import javax.jms.Queue;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class PropertyValueTest extends TestCase implements MessageListener
+{
+
+ private static final Logger _logger = Logger.getLogger(PropertyValueTest.class);
+
+ private int count = 0;
+ private AMQConnection _connection;
+ private Destination _destination;
+ private AMQSession _session;
+ private final List<JMSTextMessage> received = new ArrayList<JMSTextMessage>();
+ private final List<String> messages = new ArrayList<String>();
+ private int _count = 100;
+ public String _connectionString = "vm://:1";
+
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+ try
+ {
+ init(new AMQConnection(_connectionString, "guest", "guest", randomize("Client"), "/test_path"));
+ }
+ catch (Exception e)
+ {
+ fail("Unable to initialilse connection: " + e);
+ }
+ }
+
+ protected void tearDown() throws Exception
+ {
+ super.tearDown();
+ }
+
+ private void init(AMQConnection connection) throws Exception
+ {
+ Destination destination = new AMQQueue(randomize("PropertyValueTest"), true);
+ init(connection, destination);
+ }
+
+ private void init(AMQConnection connection, Destination destination) throws Exception
+ {
+ _connection = connection;
+ _destination = destination;
+ _session = (AMQSession) connection.createSession(false, AMQSession.AUTO_ACKNOWLEDGE);
+
+ //set up a slow consumer
+ _session.createConsumer(destination).setMessageListener(this);
+ connection.start();
+ }
+
+ public void test() throws Exception
+ {
+ int count = _count;
+ send(count);
+ waitFor(count);
+ check();
+ System.out.println("Completed without failure");
+ _connection.close();
+ }
+
+ void send(int count) throws JMSException
+ {
+ //create a publisher
+ MessageProducer producer = _session.createProducer(_destination);
+ for (int i = 0; i < count; i++)
+ {
+ String text = "Message " + i;
+ messages.add(text);
+ Message m = _session.createTextMessage(text);
+
+ m.setBooleanProperty("Bool", true);
+
+ m.setByteProperty("Byte", (byte) Byte.MAX_VALUE);
+ m.setDoubleProperty("Double", (double) Double.MAX_VALUE);
+ m.setFloatProperty("Float", (float) Float.MAX_VALUE);
+ m.setIntProperty("Int", (int) Integer.MAX_VALUE);
+
+ m.setJMSCorrelationID("Correlation");
+ m.setJMSPriority(100);
+
+ // Queue
+ Queue q = //_session.createTemporaryQueue();
+ q = new AMQQueue("TestReply");
+ m.setJMSReplyTo(q);
+ m.setStringProperty("TempQueue", q.toString());
+
+ _logger.info("Message:" + m);
+
+ Assert.assertEquals("Check temp queue has been set correctly",
+ m.getJMSReplyTo().toString(), m.getStringProperty("TempQueue"));
+
+ m.setJMSType("Test");
+ m.setLongProperty("UnsignedInt", (long) 4294967295L);
+ m.setLongProperty("Long", (long) Long.MAX_VALUE);
+
+ m.setShortProperty("Short", (short) Short.MAX_VALUE);
+ m.setStringProperty("String", "Test");
+
+ _logger.info("Sending Msg:" + m);
+ producer.send(m);
+ }
+ }
+
+ void waitFor(int count) throws InterruptedException
+ {
+ synchronized(received)
+ {
+ while (received.size() < count)
+ {
+ received.wait();
+ }
+ }
+ }
+
+ void check() throws JMSException
+ {
+ List<String> actual = new ArrayList<String>();
+ for (JMSTextMessage m : received)
+ {
+ actual.add(m.getText());
+
+ //Check Properties
+
+ Assert.assertEquals("Check Boolean properties are correctly transported",
+ true, m.getBooleanProperty("Bool"));
+ Assert.assertEquals("Check Byte properties are correctly transported",
+ (byte) Byte.MAX_VALUE, m.getByteProperty("Byte"));
+ Assert.assertEquals("Check Double properties are correctly transported",
+ (double) Double.MAX_VALUE, m.getDoubleProperty("Double"));
+ Assert.assertEquals("Check Float properties are correctly transported",
+ (float) Float.MAX_VALUE, m.getFloatProperty("Float"));
+ Assert.assertEquals("Check Int properties are correctly transported",
+ (int) Integer.MAX_VALUE, m.getIntProperty("Int"));
+ Assert.assertEquals("Check CorrelationID properties are correctly transported",
+ "Correlation", m.getJMSCorrelationID());
+// Assert.assertEquals("Check Priority properties are correctly transported",
+// 100, m.getJMSPriority());
+
+ // Queue
+ Assert.assertEquals("Check ReplyTo properties are correctly transported",
+ m.getStringProperty("TempQueue"), m.getJMSReplyTo().toString());
+
+// Assert.assertEquals("Check Type properties are correctly transported",
+// "Test", m.getJMSType());
+ Assert.assertEquals("Check Short properties are correctly transported",
+ (short) Short.MAX_VALUE, m.getShortProperty("Short"));
+ Assert.assertEquals("Check UnsignedInt properties are correctly transported",
+ (long) 4294967295L, m.getLongProperty("UnsignedInt"));
+ Assert.assertEquals("Check Long properties are correctly transported",
+ (long) Long.MAX_VALUE, m.getLongProperty("Long"));
+ Assert.assertEquals("Check String properties are correctly transported",
+ "Test", m.getStringProperty("String"));
+ }
+
+ assertEqual(messages.iterator(), actual.iterator());
+ }
+
+ private static void assertEqual(Iterator expected, Iterator actual)
+ {
+ List<String> errors = new ArrayList<String>();
+ while (expected.hasNext() && actual.hasNext())
+ {
+ try
+ {
+ assertEqual(expected.next(), actual.next());
+ }
+ catch (Exception e)
+ {
+ errors.add(e.getMessage());
+ }
+ }
+ while (expected.hasNext())
+ {
+ errors.add("Expected " + expected.next() + " but no more actual values.");
+ }
+ while (actual.hasNext())
+ {
+ errors.add("Found " + actual.next() + " but no more expected values.");
+ }
+ if (!errors.isEmpty())
+ {
+ throw new RuntimeException(errors.toString());
+ }
+ }
+
+ private static void assertEqual(Object expected, Object actual)
+ {
+ if (!expected.equals(actual))
+ {
+ throw new RuntimeException("Expected '" + expected + "' found '" + actual + "'");
+ }
+ }
+
+ public void onMessage(Message message)
+ {
+ synchronized(received)
+ {
+ received.add((JMSTextMessage) message);
+ received.notify();
+ }
+ }
+
+ private static String randomize(String in)
+ {
+ return in + System.currentTimeMillis();
+ }
+
+ public static void main(String[] argv) throws Exception
+ {
+ PropertyValueTest test = new PropertyValueTest();
+ test._connectionString = argv.length == 0 ? "vm://:1" : argv[0];
+ test.setUp();
+ if (argv.length > 1)
+ {
+ test._count = Integer.parseInt(argv[1]);
+ }
+ test.test();
+ }
+
+ public static junit.framework.Test suite()
+ {
+ return new VMBrokerSetup(new junit.framework.TestSuite(PropertyValueTest.class));
+ }
+}
diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/basic/TextMessageTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/basic/TextMessageTest.java
index 04a9185fa6..cd3954fbcb 100644
--- a/java/client/src/test/java/org/apache/qpid/test/unit/basic/TextMessageTest.java
+++ b/java/client/src/test/java/org/apache/qpid/test/unit/basic/TextMessageTest.java
@@ -28,6 +28,7 @@ import org.apache.qpid.client.vmbroker.AMQVMBrokerCreationException;
import org.apache.qpid.client.transport.TransportConnection;
import org.apache.qpid.client.message.JMSTextMessage;
import org.apache.qpid.test.VMBrokerSetup;
+import org.apache.log4j.Logger;
import java.util.ArrayList;
import java.util.Iterator;
@@ -39,6 +40,8 @@ import junit.framework.Assert;
public class TextMessageTest extends TestCase implements MessageListener
{
+ private static final Logger _logger = Logger.getLogger(TextMessageTest.class);
+
private AMQConnection _connection;
private Destination _destination;
private AMQSession _session;
@@ -100,7 +103,11 @@ public class TextMessageTest extends TestCase implements MessageListener
{
String text = "Message " + i;
messages.add(text);
- producer.send(_session.createTextMessage(text));
+ Message m = _session.createTextMessage(text);
+ m.setStringProperty("String", "hello");
+
+ _logger.info("Sending Msg:" + m);
+ producer.send(m);
}
}
@@ -122,15 +129,49 @@ public class TextMessageTest extends TestCase implements MessageListener
{
actual.add(m.getText());
-// try
-// {
-// m.setText("Test text");
-// Assert.fail("Message should not be writeable");
-// }
-// catch (MessageNotWriteableException mnwe)
-// {
-// //normal execution
-// }
+ //Check body write status
+ try
+ {
+ m.setText("Test text");
+ Assert.fail("Message should not be writeable");
+ }
+ catch (MessageNotWriteableException mnwe)
+ {
+ //normal execution
+ }
+
+ m.clearBody();
+
+ try
+ {
+ m.setText("Test text");
+ }
+ catch (MessageNotWriteableException mnwe)
+ {
+ Assert.fail("Message should be writeable");
+ }
+
+ //Check property write status
+ try
+ {
+ m.setStringProperty("test", "test");
+ Assert.fail("Message should not be writeable");
+ }
+ catch (MessageNotWriteableException mnwe)
+ {
+ //normal execution
+ }
+
+ m.clearProperties();
+
+ try
+ {
+ m.setStringProperty("test", "test");
+ }
+ catch (MessageNotWriteableException mnwe)
+ {
+ Assert.fail("Message should be writeable");
+ }
}
diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/BrokerDetails/BrokerDetailsTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/BrokerDetails/BrokerDetailsTest.java
new file mode 100644
index 0000000000..84e9026a6a
--- /dev/null
+++ b/java/client/src/test/java/org/apache/qpid/test/unit/client/BrokerDetails/BrokerDetailsTest.java
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *
+ */
+package org.apache.qpid.test.unit.client.BrokerDetails;
+
+import junit.framework.TestCase;
+import org.apache.qpid.client.AMQBrokerDetails;
+import org.apache.qpid.url.URLSyntaxException;
+
+public class BrokerDetailsTest extends TestCase
+{
+
+ public void testMultiParameters() throws URLSyntaxException
+ {
+ String url = "tcp://localhost:5672?timeout='200',immediatedelivery='true'";
+
+ AMQBrokerDetails broker = new AMQBrokerDetails(url);
+
+ assertTrue(broker.getOption("timeout").equals("200"));
+ assertTrue(broker.getOption("immediatedelivery").equals("true"));
+ }
+
+ public void testVMBroker() throws URLSyntaxException
+ {
+ String url = "vm://:2";
+
+ AMQBrokerDetails broker = new AMQBrokerDetails(url);
+ assertTrue(broker.getTransport().equals("vm"));
+ assertEquals(broker.getPort(), 2);
+ }
+
+ public void testTransportsDefaultToTCP() throws URLSyntaxException
+ {
+ String url = "localhost:5672";
+
+ AMQBrokerDetails broker = new AMQBrokerDetails(url);
+ assertTrue(broker.getTransport().equals("tcp"));
+ }
+
+ public void testCheckDefaultPort() throws URLSyntaxException
+ {
+ String url = "tcp://localhost";
+
+ AMQBrokerDetails broker = new AMQBrokerDetails(url);
+ assertTrue(broker.getPort() == AMQBrokerDetails.DEFAULT_PORT);
+ }
+
+ public void testBothDefaults() throws URLSyntaxException
+ {
+ String url = "localhost";
+
+ AMQBrokerDetails broker = new AMQBrokerDetails(url);
+
+ assertTrue(broker.getTransport().equals("tcp"));
+ assertTrue(broker.getPort() == AMQBrokerDetails.DEFAULT_PORT);
+ }
+
+ public void testWrongOptionSeparatorInBroker()
+ {
+ String url = "tcp://localhost:5672+option='value'";
+ try
+ {
+ new AMQBrokerDetails(url);
+ }
+ catch (URLSyntaxException urise)
+ {
+ assertTrue(urise.getReason().equals("Illegal character in port number"));
+ }
+
+ }
+
+ public static junit.framework.Test suite()
+ {
+ return new junit.framework.TestSuite(BrokerDetailsTest.class);
+ }
+}
diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/connection/ConnectionTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/connection/ConnectionTest.java
index d7862d047f..0da4147351 100644
--- a/java/client/src/test/java/org/apache/qpid/test/unit/client/connection/ConnectionTest.java
+++ b/java/client/src/test/java/org/apache/qpid/test/unit/client/connection/ConnectionTest.java
@@ -22,12 +22,10 @@ package org.apache.qpid.test.unit.client.connection;
import org.apache.qpid.client.AMQConnection;
import org.apache.qpid.client.AMQAuthenticationException;
-import org.apache.qpid.client.vmbroker.AMQVMBrokerCreationException;
import org.apache.qpid.client.transport.TransportConnection;
import org.apache.qpid.AMQException;
import org.apache.qpid.AMQConnectionException;
import org.apache.qpid.AMQUnresolvedAddressException;
-import org.apache.qpid.test.VMBrokerSetup;
import javax.jms.Connection;
@@ -40,6 +38,18 @@ public class ConnectionTest extends TestCase
String _broker_NotRunning = "vm://:2";
String _broker_BadDNS = "tcp://hg3sgaaw4lgihjs";
+
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+ TransportConnection.createVMBroker(1);
+ }
+
+ protected void tearDown() throws Exception
+ {
+ TransportConnection.killAllVMBrokers();
+ }
+
public void testSimpleConnection()
{
try
@@ -102,8 +112,30 @@ public class ConnectionTest extends TestCase
}
}
+ public void testClientIdCannotBeChanged() throws Exception
+ {
+ Connection connection = new AMQConnection(_broker, "guest", "guest",
+ "fred", "/test");
+ try
+ {
+ connection.setClientID("someClientId");
+ fail("No IllegalStateException thrown when resetting clientid");
+ }
+ catch (javax.jms.IllegalStateException e)
+ {
+ // PASS
+ }
+ }
+
+ public void testClientIdIsPopulatedAutomatically() throws Exception
+ {
+ Connection connection = new AMQConnection(_broker, "guest", "guest",
+ null, "/test");
+ assertNotNull(connection.getClientID());
+ }
+
public static junit.framework.Test suite()
{
- return new VMBrokerSetup(new junit.framework.TestSuite(ConnectionTest.class));
+ return new junit.framework.TestSuite(ConnectionTest.class);
}
}
diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/connectionurl/ConnectionURLTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/connectionurl/ConnectionURLTest.java
index 13a6d214ba..64adcb13e4 100644
--- a/java/client/src/test/java/org/apache/qpid/test/unit/client/connectionurl/ConnectionURLTest.java
+++ b/java/client/src/test/java/org/apache/qpid/test/unit/client/connectionurl/ConnectionURLTest.java
@@ -310,29 +310,7 @@ public class ConnectionURLTest extends TestCase
assertTrue(connectionurl.getBrokerCount() == 1);
}
- // FIXME Connection now parses but result is wrong QPID-71
- /*
- public void testWrongOptionSeparatorInBroker()
- {
- String url = "amqp://user:@/test?brokerlist='tcp://localhost:5672+option='value''";
- try
- {
- AMQConnectionURL connection = new AMQConnectionURL(url);
-
- Float version = Float.parseFloat(System.getProperty("java.specification.version"));
- if (version > 1.5)
- {
- fail("URL Should not parse on Java " + version + " Connection is:" + connection);
- }
- }
- catch (URLSyntaxException urise)
- {
- assertTrue(urise.getReason().equals("Illegal character in port number"));
- }
-
- }
- */
public void testWrongOptionSeparatorInOptions()
{
@@ -349,18 +327,6 @@ public class ConnectionURLTest extends TestCase
}
- public void testTransportsDefaultToTCP() throws URLSyntaxException
- {
- String url = "amqp://guest:guest@/test?brokerlist='localhost:5672;myhost:5673'&failover='roundrobin'";
-
- AMQConnectionURL connection = new AMQConnectionURL(url);
-
- BrokerDetails broker = connection.getBrokerDetails(0);
- assertTrue(broker.getTransport().equals("tcp"));
-
- broker = connection.getBrokerDetails(1);
- assertTrue(broker.getTransport().equals("tcp"));
- }
public void testNoUserDetailsProvidedWithClientID()
diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/message/ObjectMessageTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/message/ObjectMessageTest.java
index 9425b7c304..9bb2fcc59b 100644
--- a/java/client/src/test/java/org/apache/qpid/test/unit/client/message/ObjectMessageTest.java
+++ b/java/client/src/test/java/org/apache/qpid/test/unit/client/message/ObjectMessageTest.java
@@ -24,8 +24,6 @@ import org.apache.qpid.client.AMQConnection;
import org.apache.qpid.client.AMQQueue;
import org.apache.qpid.client.AMQDestination;
import org.apache.qpid.client.AMQSession;
-import org.apache.qpid.client.vmbroker.AMQVMBrokerCreationException;
-import org.apache.qpid.client.transport.TransportConnection;
import org.apache.qpid.test.VMBrokerSetup;
import javax.jms.MessageListener;
@@ -36,6 +34,7 @@ import javax.jms.ObjectMessage;
import java.io.Serializable;
import java.util.HashMap;
import java.util.ArrayList;
+import java.util.Arrays;
import junit.framework.TestCase;
@@ -44,6 +43,7 @@ public class ObjectMessageTest extends TestCase implements MessageListener
private AMQConnection connection;
private AMQDestination destination;
private AMQSession session;
+ private MessageProducer producer;
private Serializable[] data;
private volatile boolean waiting;
private int received;
@@ -57,6 +57,13 @@ public class ObjectMessageTest extends TestCase implements MessageListener
connection = new AMQConnection(_broker, "guest", "guest", randomize("Client"), "/test_path");
destination = new AMQQueue(randomize("LatencyTest"), true);
session = (AMQSession) connection.createSession(false, AMQSession.NO_ACKNOWLEDGE);
+
+ //set up a consumer
+ session.createConsumer(destination).setMessageListener(this);
+ connection.start();
+
+ //create a publisher
+ producer = session.createProducer(destination, false, false, true);
A a1 = new A(1, "A");
A a2 = new A(2, "a");
B b = new B(1, "B");
@@ -83,7 +90,7 @@ public class ObjectMessageTest extends TestCase implements MessageListener
_broker = broker;
}
- public void test() throws Exception
+ public void testSendAndReceive() throws Exception
{
try
{
@@ -102,16 +109,68 @@ public class ObjectMessageTest extends TestCase implements MessageListener
}
}
- private void send() throws Exception
+ public void testSetObjectPropertyForString() throws Exception
{
- //set up a consumer
- session.createConsumer(destination).setMessageListener(this);
- connection.start();
+ String testStringProperty = "TestStringProperty";
+ ObjectMessage msg = session.createObjectMessage(data[0]);
+ msg.setObjectProperty("TestStringProperty",testStringProperty);
+ assertEquals(testStringProperty, msg.getObjectProperty("TestStringProperty"));
+ }
- //create a publisher
- MessageProducer producer = session.createProducer(destination, false, false, true);
+ public void testSetObjectPropertyForBoolean() throws Exception
+ {
+ ObjectMessage msg = session.createObjectMessage(data[0]);
+ msg.setObjectProperty("TestBooleanProperty",Boolean.TRUE);
+ assertEquals(Boolean.TRUE, msg.getObjectProperty("TestBooleanProperty"));
+ }
+ public void testSetObjectPropertyForByte() throws Exception
+ {
+ ObjectMessage msg = session.createObjectMessage(data[0]);
+ msg.setObjectProperty("TestByteProperty",Byte.MAX_VALUE);
+ assertEquals(Byte.MAX_VALUE, msg.getObjectProperty("TestByteProperty"));
+ }
+ public void testSetObjectPropertyForShort() throws Exception
+ {
+ ObjectMessage msg = session.createObjectMessage(data[0]);
+ msg.setObjectProperty("TestShortProperty",Short.MAX_VALUE);
+ assertEquals(Short.MAX_VALUE, msg.getObjectProperty("TestShortProperty"));
+ }
+ public void testSetObjectPropertyForInteger() throws Exception
+ {
+ ObjectMessage msg = session.createObjectMessage(data[0]);
+ msg.setObjectProperty("TestIntegerProperty",Integer.MAX_VALUE);
+ assertEquals(Integer.MAX_VALUE, msg.getObjectProperty("TestIntegerProperty"));
+ }
+
+ public void testSetObjectPropertyForDouble() throws Exception
+ {
+ ObjectMessage msg = session.createObjectMessage(data[0]);
+ msg.setObjectProperty("TestDoubleProperty",Double.MAX_VALUE);
+ assertEquals(Double.MAX_VALUE, msg.getObjectProperty("TestDoubleProperty"));
+ }
+
+ public void testSetObjectPropertyForFloat() throws Exception
+ {
+ ObjectMessage msg = session.createObjectMessage(data[0]);
+ msg.setObjectProperty("TestFloatProperty",Float.MAX_VALUE);
+ assertEquals(Float.MAX_VALUE, msg.getObjectProperty("TestFloatProperty"));
+ }
+
+ public void testSetObjectPropertyForByteArray() throws Exception
+ {
+ byte[] array = {1,2,3,4,5};
+ ObjectMessage msg = session.createObjectMessage(data[0]);
+ msg.setObjectProperty("TestByteArrayProperty",array);
+ assertTrue(Arrays.equals(array,(byte[])msg.getObjectProperty("TestByteArrayProperty")));
+ }
+
+
+
+
+ private void send() throws Exception
+ {
for (int i = 0; i < data.length; i++)
{
ObjectMessage msg;
@@ -207,7 +266,7 @@ public class ObjectMessageTest extends TestCase implements MessageListener
{
System.out.println("Usage: <broker>");
}
- new ObjectMessageTest(broker).test();
+ new ObjectMessageTest(broker).testSendAndReceive();
}
private static class A implements Serializable
diff --git a/java/cluster/pom.xml b/java/cluster/pom.xml
index 7b198a70d3..93fe4a7517 100644
--- a/java/cluster/pom.xml
+++ b/java/cluster/pom.xml
@@ -53,11 +53,6 @@
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
- <dependency>
- <groupId>ant</groupId>
- <artifactId>ant-junit</artifactId>
- <scope>test</scope>
- </dependency>
</dependencies>
<build>
diff --git a/java/common/pom.xml b/java/common/pom.xml
index b0d68a3559..bbc70bf7f6 100644
--- a/java/common/pom.xml
+++ b/java/common/pom.xml
@@ -39,7 +39,7 @@
<spec.stylesheet>${basedir}/src/main/xsl/framing.xsl</spec.stylesheet>
<registry.stylesheet>${basedir}/src/main/xsl/registry.xsl</registry.stylesheet>
<registry.template>${basedir}/src/main/xsl/registry.template</registry.template>
- <generated.path>${project.build.directory}/generated/xsl</generated.path>
+ <generated.path>${project.build.directory}/generated-sources/xsl</generated.path>
<generated.package>org/apache/qpid/framing</generated.package>
<generated.dir>${generated.path}/${generated.package}</generated.dir>
<specs.dir>${topDirectoryLocation}/../specs</specs.dir>
@@ -47,7 +47,6 @@
<build>
<plugins>
-
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
@@ -91,9 +90,5 @@
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
- <dependency>
- <groupId>ant</groupId>
- <artifactId>ant-junit</artifactId>
- </dependency>
</dependencies>
</project>
diff --git a/java/common/protocol-version.xml b/java/common/protocol-version.xml
index 59e83d7f8f..96ce348523 100644
--- a/java/common/protocol-version.xml
+++ b/java/common/protocol-version.xml
@@ -21,6 +21,8 @@
<project name="Qpid Common Protocol Versions" default="generate">
<property name="saxon.jar" value="lib/saxon/saxon8.jar"/>
+ <!-- temporarily hard-wired XML spec version for build avoidance -->
+ <property name="amqp.xml" value="${specs.dir}/amqp-8.0.xml"/>
<macrodef name="saxon">
<attribute name="out"/>
@@ -61,8 +63,7 @@
flags="s" byline="true"/>
<!-- Create directory; generate from specification file -->
- <mkdir dir="${generated.dir}_${@{ver}.amqp(major)}_${@{ver}.amqp(minor)}"/>
- <saxon out="${generated.dir}_${@{ver}.amqp(major)}_${@{ver}.amqp(minor)}/results.out"
+ <saxon out="${generated.dir}/results.out"
src="${specs.dir}/amqp-@{ver}.xml"
xsl="${spec.stylesheet}">
<arg value="major=${@{ver}.amqp(major)}"/>
@@ -70,14 +71,14 @@
<arg value="registry_name=MainRegistry"/>
</saxon>
<!-- -->
- <saxon out="${generated.dir}_${@{ver}.amqp(major)}_${@{ver}.amqp(minor)}/cluster.out"
+ <saxon out="${generated.dir}/cluster.out"
src="${cluster.asl}"
xsl="${spec.stylesheet}">
<arg value="major=${@{ver}.amqp(major)}"/>
<arg value="minor=${@{ver}.amqp(minor)}"/>
<arg value="registry_name=ClusterRegistry"/>
</saxon>
- <saxon out="${generated.dir}_${@{ver}.amqp(major)}_${@{ver}.amqp(minor)}/registry.out"
+ <saxon out="${generated.dir}/registry.out"
src="${registry.template}"
xsl="${registry.stylesheet}">
<arg value="major=${@{ver}.amqp(major)}"/>
@@ -86,11 +87,10 @@
</sequential>
</macrodef>
-<!-- <uptodate property="generated" targetfile="${generated.dir}/results.out"
- srcfile="${amqp.xml}"/> -->
+ <uptodate property="generated" targetfile="${generated.dir}/results.out"
+ srcfile="${amqp.xml}"/>
-<!-- <target name="generate" unless="generated"> -->
- <target name="generate">
+ <target name="generate" unless="generated">
<mkdir dir="${generated.dir}"/>
<copy file="src/main/versions/ProtocolVersionList.java.tmpl" tofile="${proto_version}"
overwrite="true"/>
diff --git a/java/common/src/main/java/org/apache/qpid/framing/BasicContentHeaderProperties.java b/java/common/src/main/java/org/apache/qpid/framing/BasicContentHeaderProperties.java
index 3c7e656053..a908c76286 100644
--- a/java/common/src/main/java/org/apache/qpid/framing/BasicContentHeaderProperties.java
+++ b/java/common/src/main/java/org/apache/qpid/framing/BasicContentHeaderProperties.java
@@ -241,7 +241,7 @@ public class BasicContentHeaderProperties implements ContentHeaderProperties
}
}
}
-
+
public void populatePropertiesFromBuffer(ByteBuffer buffer, int propertyFlags, int size)
throws AMQFrameDecodingException
{
@@ -402,6 +402,7 @@ public class BasicContentHeaderProperties implements ContentHeaderProperties
decodeUpToContentType();
}
}
+
public String getContentType()
{
decodeContentTypeIfNecessary();
@@ -431,6 +432,12 @@ public class BasicContentHeaderProperties implements ContentHeaderProperties
public FieldTable getHeaders()
{
decodeHeadersIfNecessary();
+
+ if (_headers == null)
+ {
+ setHeaders(FieldTableFactory.newFieldTable());
+ }
+
return _headers;
}
@@ -587,6 +594,6 @@ public class BasicContentHeaderProperties implements ContentHeaderProperties
public String toString()
{
- return "reply-to = " + _replyTo + " propertyFlags = " + _propertyFlags;
+ return "reply-to = " + _replyTo + " propertyFlags = " + _propertyFlags;
}
}
diff --git a/java/common/src/main/java/org/apache/qpid/framing/FieldTableKeyEnumeration.java b/java/common/src/main/java/org/apache/qpid/framing/Content.java
index e3ba9080c7..e5feeec2a4 100644
--- a/java/common/src/main/java/org/apache/qpid/framing/FieldTableKeyEnumeration.java
+++ b/java/common/src/main/java/org/apache/qpid/framing/Content.java
@@ -20,28 +20,7 @@
*/
package org.apache.qpid.framing;
-import java.util.Enumeration;
-import java.util.Iterator;
-
-
-public class FieldTableKeyEnumeration implements Enumeration
+public interface Content
{
- protected FieldTable _table;
- protected Iterator _iterator;
-
- public FieldTableKeyEnumeration(FieldTable ft)
- {
- _table = ft;
- _iterator = ft.keySet().iterator();
- }
-
- public boolean hasMoreElements()
- {
- return _iterator.hasNext();
- }
-
- public Object nextElement()
- {
- return _iterator.next();
- }
+ // TODO: New Content class required for AMQP 0-9.
}
diff --git a/java/common/src/main/java/org/apache/qpid/framing/EncodingUtils.java b/java/common/src/main/java/org/apache/qpid/framing/EncodingUtils.java
index 3a683b8e90..2f791ea541 100644
--- a/java/common/src/main/java/org/apache/qpid/framing/EncodingUtils.java
+++ b/java/common/src/main/java/org/apache/qpid/framing/EncodingUtils.java
@@ -98,6 +98,12 @@ public class EncodingUtils
}
}
+ public static int encodedContentLength(Content table)
+ {
+ // TODO: New Content class required for AMQP 0-9.
+ return 0;
+ }
+
public static void writeShortStringBytes(ByteBuffer buffer, String s)
{
if (s != null)
@@ -108,9 +114,7 @@ public class EncodingUtils
{
encodedString[i] = (byte) cha[i];
}
- // TODO: check length fits in an unsigned byte
- writeUnsignedByte(buffer, (short) encodedString.length);
- buffer.put(encodedString);
+ writeBytes(buffer,encodedString);
}
else
{
@@ -227,6 +231,11 @@ public class EncodingUtils
}
}
+ public static void writeContentBytes(ByteBuffer buffer, Content content)
+ {
+ // TODO: New Content class required for AMQP 0-9.
+ }
+
public static void writeBooleans(ByteBuffer buffer, boolean[] values)
{
byte packedValue = 0;
@@ -243,6 +252,7 @@ public class EncodingUtils
/**
* This is used for writing longstrs.
+ *
* @param buffer
* @param data
*/
@@ -286,10 +296,16 @@ public class EncodingUtils
}
else
{
- return new FieldTable(buffer, length);
+ return FieldTableFactory.newFieldTable(buffer, length);
}
}
+ public static Content readContent(ByteBuffer buffer) throws AMQFrameDecodingException
+ {
+ // TODO: New Content class required for AMQP 0-9.
+ return null;
+ }
+
public static String readShortString(ByteBuffer buffer)
{
short length = buffer.getUnsigned();
@@ -330,9 +346,9 @@ public class EncodingUtils
// than constructing one from a char array.
// this approach here is valid since we know that all the chars are
// ASCII (0-127)
- byte[] stringBytes = new byte[(int)length];
- buffer.get(stringBytes, 0, (int)length);
- char[] stringChars = new char[(int)length];
+ byte[] stringBytes = new byte[(int) length];
+ buffer.get(stringBytes, 0, (int) length);
+ char[] stringChars = new char[(int) length];
for (int i = 0; i < stringChars.length; i++)
{
stringChars[i] = (char) stringBytes[i];
@@ -350,7 +366,7 @@ public class EncodingUtils
}
else
{
- byte[] result = new byte[(int)length];
+ byte[] result = new byte[(int) length];
buffer.get(result);
return result;
}
@@ -363,97 +379,6 @@ public class EncodingUtils
return buffer.getUnsignedInt();
}
- // Will barf with a NPE on a null input. Not sure whether it should return null or
- // an empty field-table (which would be slower - perhaps unnecessarily).
- //
- // Some sample input and the result output:
- //
- // Input: "a=1" "a=2 c=3" "a=3 c=4 d" "a='four' b='five'" "a=bad"
- //
- // Parsing <a=1>...
- // {a=1}
- // Parsing <a=2 c=3>...
- // {a=2, c=3}
- // Parsing <a=3 c=4 d>...
- // {a=3, c=4, d=null}
- // Parsing <a='four' b='five'>...
- // {a=four, b=five}
- // Parsing <a=bad>...
- // java.lang.IllegalArgumentException: a: Invalid integer in <bad> from <a=bad>.
- //
- public static FieldTable createFieldTableFromMessageSelector(String selector)
- {
- boolean debug = _logger.isDebugEnabled();
-
- // TODO: Doesn't support embedded quotes properly.
- String[] expressions = selector.split(" +");
-
- FieldTable result = new FieldTable();
-
- for (int i = 0; i < expressions.length; i++)
- {
- String expr = expressions[i];
-
- if (debug)
- {
- _logger.debug("Expression = <" + expr + ">");
- }
-
- int equals = expr.indexOf('=');
-
- if (equals < 0)
- {
- // Existence check
- result.put("S" + expr.trim(), null);
- }
- else
- {
- String key = expr.substring(0, equals).trim();
- String value = expr.substring(equals + 1).trim();
-
- if (debug)
- {
- _logger.debug("Key = <" + key + ">, Value = <" + value + ">");
- }
-
- if (value.charAt(0) == '\'')
- {
- if (value.charAt(value.length() - 1) != '\'')
- {
- throw new IllegalArgumentException(key + ": Missing quote in <" + value + "> from <" + selector + ">.");
- }
- else
- {
- value = value.substring(1, value.length() - 1);
-
- result.put("S" + key, value);
- }
- }
- else
- {
- try
- {
- int intValue = Integer.parseInt(value);
-
- result.put("i" + key, value);
- }
- catch (NumberFormatException e)
- {
- throw new IllegalArgumentException(key + ": Invalid integer in <" + value + "> from <" + selector + ">.");
-
- }
- }
- }
- }
-
- if (debug)
- {
- _logger.debug("Field-table created from <" + selector + "> is <" + result + ">");
- }
-
- return (result);
-
- }
static byte[] hexToByteArray(String id)
{
@@ -481,7 +406,7 @@ public class EncodingUtils
public static char[] convertToHexCharArray(byte[] from)
{
int length = from.length;
- char[] result_buff = new char[length * 2 + 2];
+ char[] result_buff = new char[length * 2 + 2];
result_buff[0] = '0';
result_buff[1] = 'x';
@@ -526,24 +451,155 @@ public class EncodingUtils
return (new String(convertToHexCharArray(from)));
}
- public static void main(String[] args)
+ private static char hex_chars[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
+
+ //**** new methods
+
+ // BOOLEAN_PROPERTY_PREFIX
+
+ public static void writeBoolean(ByteBuffer buffer, Boolean aBoolean)
{
- for (int i = 0; i < args.length; i++)
- {
- String selector = args[i];
+ buffer.put((byte) (aBoolean ? 1 : 0));
+ }
+
+ public static Boolean readBoolean(ByteBuffer buffer)
+ {
+ byte packedValue = buffer.get();
+ return (packedValue == 1);
+ }
- System.err.println("Parsing <" + selector + ">...");
+ public static int encodedBooleanLength()
+ {
+ return 1;
+ }
- try
- {
- System.err.println(createFieldTableFromMessageSelector(selector));
- }
- catch (IllegalArgumentException e)
- {
- System.err.println(e);
- }
+ // BYTE_PROPERTY_PREFIX
+ public static void writeByte(ByteBuffer buffer, Byte aByte)
+ {
+ buffer.put(aByte);
+ }
+
+ public static Byte readByte(ByteBuffer buffer)
+ {
+ return buffer.get();
+ }
+
+ public static int encodedByteLength()
+ {
+ return 1;
+ }
+
+
+ // SHORT_PROPERTY_PREFIX
+ public static void writeShort(ByteBuffer buffer, Short aShort)
+ {
+ buffer.putShort(aShort);
+ }
+
+ public static Short readShort(ByteBuffer buffer)
+ {
+ return buffer.getShort();
+ }
+
+ public static int encodedShortLength()
+ {
+ return 2;
+ }
+
+ // INTEGER_PROPERTY_PREFIX
+ public static void writeInteger(ByteBuffer buffer, Integer aInteger)
+ {
+ buffer.putInt(aInteger);
+ }
+
+ public static Integer readInteger(ByteBuffer buffer)
+ {
+ return buffer.getInt();
+ }
+
+ public static int encodedIntegerLength()
+ {
+ return 4;
+ }
+
+ // LONG_PROPERTY_PREFIX
+ public static void writeLong(ByteBuffer buffer, Long aLong)
+ {
+ buffer.putLong(aLong);
+ }
+
+ public static Long readLong(ByteBuffer buffer)
+ {
+ return buffer.getLong();
+ }
+
+ public static int encodedLongLength()
+ {
+ return 8;
+ }
+
+ // Float_PROPERTY_PREFIX
+ public static void writeFloat(ByteBuffer buffer, Float aFloat)
+ {
+ buffer.putFloat(aFloat);
+ }
+
+ public static Float readFloat(ByteBuffer buffer)
+ {
+ return buffer.getFloat();
+ }
+
+ public static int encodedFloatLength()
+ {
+ return 4;
+ }
+
+
+ // Double_PROPERTY_PREFIX
+ public static void writeDouble(ByteBuffer buffer, Double aDouble)
+ {
+ buffer.putDouble(aDouble);
+ }
+
+ public static Double readDouble(ByteBuffer buffer)
+ {
+ return buffer.getDouble();
+ }
+
+ public static int encodedDoubleLength()
+ {
+ return 8;
+ }
+
+
+ public static byte[] readBytes(ByteBuffer buffer)
+ {
+ short length = buffer.getUnsigned();
+ if (length == 0)
+ {
+ return null;
+ }
+ else
+ {
+ byte[] dataBytes = new byte[length];
+ buffer.get(dataBytes, 0, length);
+
+ return dataBytes;
}
}
- private static char hex_chars[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
+ public static void writeBytes(ByteBuffer buffer, byte[] data)
+ {
+ if (data != null)
+ {
+ // TODO: check length fits in an unsigned byte
+ writeUnsignedByte(buffer, (short) data.length);
+ buffer.put(data);
+ }
+ else
+ {
+ // really writing out unsigned byte
+ buffer.put((byte) 0);
+ }
+ }
}
diff --git a/java/common/src/main/java/org/apache/qpid/framing/FieldTable.java b/java/common/src/main/java/org/apache/qpid/framing/FieldTable.java
index be456c8754..44d0268561 100644
--- a/java/common/src/main/java/org/apache/qpid/framing/FieldTable.java
+++ b/java/common/src/main/java/org/apache/qpid/framing/FieldTable.java
@@ -1,322 +1,96 @@
/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
+ * 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.
*
+ *
*/
package org.apache.qpid.framing;
-import org.apache.log4j.Logger;
import org.apache.mina.common.ByteBuffer;
-import java.util.*;
-
-/**
- * From the protocol document:
- * field-table = short-integer *field-value-pair
- * field-value-pair = field-name field-value
- * field-name = short-string
- * field-value = 'S' long-string
- * / 'I' long-integer
- * / 'D' decimal-value
- * / 'T' long-integer
- * decimal-value = decimals long-integer
- * decimals = OCTET
- */
-public class FieldTable extends LinkedHashMap
+import java.util.Map;
+import java.util.Enumeration;
+
+public interface FieldTable extends Map
{
- private static final Logger _logger = Logger.getLogger(FieldTable.class);
- private long _encodedSize = 0;
-
- public FieldTable()
- {
- super();
- }
-
- /**
- * Construct a new field table.
- *
- * @param buffer the buffer from which to read data. The length byte must be read already
- * @param length the length of the field table. Must be > 0.
- * @throws AMQFrameDecodingException if there is an error decoding the table
- */
- public FieldTable(ByteBuffer buffer, long length) throws AMQFrameDecodingException
- {
- super();
- final boolean debug = _logger.isDebugEnabled();
- assert length > 0;
- _encodedSize = length;
- int sizeRead = 0;
- while (sizeRead < _encodedSize)
- {
- int sizeRemaining = buffer.remaining();
- final String key = EncodingUtils.readShortString(buffer);
- // TODO: use proper charset decoder
- byte iType = buffer.get();
- final char type = (char) iType;
- Object value;
- switch (type)
- {
- case 'S':
- value = EncodingUtils.readLongString(buffer);
- break;
- case 'I':
- value = new Long(buffer.getUnsignedInt());
- break;
- default:
- String msg = "Field '" + key + "' - unsupported field table type: " + type;
- //some extra debug information...
- msg += " (" + iType + "), length=" + length + ", sizeRead=" + sizeRead + ", sizeRemaining=" + sizeRemaining;
- throw new AMQFrameDecodingException(msg);
- }
- sizeRead += (sizeRemaining - buffer.remaining());
-
- if (debug)
- {
- _logger.debug("FieldTable::FieldTable(buffer," + length + "): Read type '" + type + "', key '" + key + "', value '" + value + "' (now read " + sizeRead + " of " + length + " encoded bytes)...");
- }
-
- // we deliberately want to call put in the parent class since we do
- // not need to do the size calculations
- super.put(key, value);
- }
-
- if (debug)
- {
- _logger.debug("FieldTable::FieldTable(buffer," + length + "): Done.");
- }
- }
-
- public void writeToBuffer(ByteBuffer buffer)
- {
- final boolean debug = _logger.isDebugEnabled();
-
- if (debug)
- {
- _logger.debug("FieldTable::writeToBuffer: Writing encoded size of " + _encodedSize + "...");
- }
-
- // write out the total length, which we have kept up to date as data is added
- EncodingUtils.writeUnsignedInteger(buffer, _encodedSize);
- final Iterator it = this.entrySet().iterator();
- while (it.hasNext())
- {
- Map.Entry me = (Map.Entry) it.next();
- String key = (String) me.getKey();
-
- EncodingUtils.writeShortStringBytes(buffer, key);
- Object value = me.getValue();
-
- if (debug)
- {
- _logger.debug("FieldTable::writeToBuffer: Writing key '" + key + "' of type " + value.getClass() + ", value '" + value + "'...");
- }
-
- if (value instanceof byte[])
- {
- buffer.put((byte) 'S');
- EncodingUtils.writeLongstr(buffer, (byte[]) value);
- }
- else if (value instanceof String)
- {
- // TODO: look at using proper charset encoder
- buffer.put((byte) 'S');
- EncodingUtils.writeLongStringBytes(buffer, (String) value);
- }
- else if (value instanceof Long)
- {
- // TODO: look at using proper charset encoder
- buffer.put((byte) 'I');
- EncodingUtils.writeUnsignedInteger(buffer, ((Long) value).longValue());
- }
- else
- {
- // Should never get here
- throw new IllegalArgumentException("Key '" + key + "': Unsupported type in field table, type: " + ((value == null) ? "null-object" : value.getClass()));
- }
- }
-
- if (debug)
- {
- _logger.debug("FieldTable::writeToBuffer: Done.");
- }
- }
-
- public byte[] getDataAsBytes()
- {
- final ByteBuffer buffer = ByteBuffer.allocate((int) _encodedSize); // XXX: Is cast a problem?
- final Iterator it = this.entrySet().iterator();
- while (it.hasNext())
- {
- Map.Entry me = (Map.Entry) it.next();
- String key = (String) me.getKey();
- EncodingUtils.writeShortStringBytes(buffer, key);
- Object value = me.getValue();
- if (value instanceof byte[])
- {
- buffer.put((byte) 'S');
- EncodingUtils.writeLongstr(buffer, (byte[]) value);
- }
- else if (value instanceof String)
- {
- // TODO: look at using proper charset encoder
- buffer.put((byte) 'S');
- EncodingUtils.writeLongStringBytes(buffer, (String) value);
- }
- else if (value instanceof char[])
- {
- // TODO: look at using proper charset encoder
- buffer.put((byte) 'S');
- EncodingUtils.writeLongStringBytes(buffer, (char[]) value);
- }
- else if (value instanceof Long || value instanceof Integer)
- {
- // TODO: look at using proper charset encoder
- buffer.put((byte) 'I');
- EncodingUtils.writeUnsignedInteger(buffer, ((Long) value).longValue());
- }
- else
- {
- // Should never get here
- assert false;
- }
- }
- final byte[] result = new byte[(int) _encodedSize];
- buffer.flip();
- buffer.get(result);
- buffer.release();
- return result;
- }
-
- public Object put(Object key, Object value)
- {
- final boolean debug = _logger.isDebugEnabled();
-
- if (key == null)
- {
- throw new IllegalArgumentException("All keys must be Strings - was passed: null");
- }
- else if (!(key instanceof String))
- {
- throw new IllegalArgumentException("All keys must be Strings - was passed: " + key.getClass());
- }
-
- Object existing;
-
- if ((existing = super.remove(key)) != null)
- {
- if (debug)
- {
- _logger.debug("Found duplicate of key '" + key + "', previous value '" + existing + "' (" + existing.getClass() + "), to be replaced by '" + value + "', (" + value.getClass() + ") - stack trace of source of duplicate follows...", new Throwable().fillInStackTrace());
- }
-
- // If we are in effect deleting the value (see comment on null values being deleted
- // below) then we also need to remove the name from the encoding length.
- if (value == null)
- {
- _encodedSize -= EncodingUtils.encodedShortStringLength((String) key);
- }
-
- // FIXME: Should be able to short-cut this process if the old and new values are
- // the same object and/or type and size...
- _encodedSize -= getEncodingSize(existing);
- }
- else
- {
- if (value != null)
- {
- _encodedSize += EncodingUtils.encodedShortStringLength((String) key);
- }
- }
-
- // For now: Setting a null value is the equivalent of deleting it.
- // This is ambiguous in the JMS spec and needs thrashing out and potentially
- // testing against other implementations.
- if (value != null)
- {
- _encodedSize += getEncodingSize(value);
- }
-
- return super.put(key, value);
- }
-
- public Object remove(Object key)
- {
- if (super.containsKey(key))
- {
- final Object value = super.remove(key);
- _encodedSize -= EncodingUtils.encodedShortStringLength((String) key);
-
- // This check is, for now, unnecessary (we don't store null values).
- if (value != null)
- {
- _encodedSize -= getEncodingSize(value);
- }
-
- return value;
- }
- else
- {
- return null;
- }
- }
-
- /**
- * @return unsigned integer
- */
- public long getEncodedSize()
- {
- return _encodedSize;
- }
-
- /**
- * @return integer
- */
- private static int getEncodingSize(Object value)
- {
- int encodingSize;
-
- // the extra byte if for the type indicator that is written out
- if (value instanceof String)
- {
- encodingSize = 1 + EncodingUtils.encodedLongStringLength((String) value);
- }
- else if (value instanceof char[])
- {
- encodingSize = 1 + EncodingUtils.encodedLongStringLength((char[]) value);
- }
- else if (value instanceof Integer)
- {
- encodingSize = 1 + 4;
- }
- else if (value instanceof Long)
- {
- encodingSize = 1 + 4;
- }
- else
- {
- throw new IllegalArgumentException("Unsupported type in field table: " + value.getClass());
- }
-
- return encodingSize;
- }
-
- public Enumeration keys()
- {
- return new FieldTableKeyEnumeration(this);
- }
+ void writeToBuffer(ByteBuffer buffer);
+
+ void setFromBuffer(ByteBuffer buffer, long length) throws AMQFrameDecodingException;
+
+ byte[] getDataAsBytes();
+
+ public long getEncodedSize();
+
+ Object put(Object key, Object value);
+
+ Object remove(Object key);
+
+
+ public Enumeration getPropertyNames();
+
+ public boolean propertyExists(String propertyName);
+
+ //Getters
+
+ public Boolean getBoolean(String string);
+
+ public Byte getByte(String string);
+
+ public Short getShort(String string);
+
+ public Integer getInteger(String string);
+
+ public Long getLong(String string);
+
+ public Float getFloat(String string);
+
+ public Double getDouble(String string);
+
+ public String getString(String string);
+
+ public Character getCharacter(String string);
+
+ public byte[] getBytes(String string);
+
+ public Object getObject(String string);
+
+ // Setters
+ public Object setBoolean(String string, boolean b);
+
+ public Object setByte(String string, byte b);
+
+ public Object setShort(String string, short i);
+
+ public Object setInteger(String string, int i);
+
+ public Object setLong(String string, long l);
+
+ public Object setFloat(String string, float v);
+
+ public Object setDouble(String string, double v);
+
+ public Object setString(String string, String string1);
+
+ public Object setChar(String string, char c);
+
+ public Object setBytes(String string, byte[] bytes);
+
+ public Object setBytes(String string, byte[] bytes, int start, int length);
+
+ public Object setObject(String string, Object object);
+
}
diff --git a/java/common/src/main/java/org/apache/qpid/framing/FieldTableFactory.java b/java/common/src/main/java/org/apache/qpid/framing/FieldTableFactory.java
new file mode 100644
index 0000000000..1ec57da35b
--- /dev/null
+++ b/java/common/src/main/java/org/apache/qpid/framing/FieldTableFactory.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *
+ */
+package org.apache.qpid.framing;
+
+import org.apache.mina.common.ByteBuffer;
+
+public class FieldTableFactory
+{
+ public static FieldTable newFieldTable()
+ {
+ return new PropertyFieldTable();
+ }
+
+ public static FieldTable newFieldTable(ByteBuffer byteBuffer, long length) throws AMQFrameDecodingException
+ {
+ return new PropertyFieldTable(byteBuffer, length);
+ }
+
+ public static PropertyFieldTable newFieldTable(String text)
+ {
+ return new PropertyFieldTable(text);
+ }
+}
diff --git a/java/common/src/main/java/org/apache/qpid/framing/PropertyFieldTable.java b/java/common/src/main/java/org/apache/qpid/framing/PropertyFieldTable.java
index 96360e4aaa..48ca34abfe 100644
--- a/java/common/src/main/java/org/apache/qpid/framing/PropertyFieldTable.java
+++ b/java/common/src/main/java/org/apache/qpid/framing/PropertyFieldTable.java
@@ -21,31 +21,44 @@
package org.apache.qpid.framing;
import org.apache.log4j.Logger;
+import org.apache.mina.common.ByteBuffer;
+import java.util.Collection;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
+import java.util.Set;
import java.util.StringTokenizer;
import java.util.Vector;
//extends FieldTable
-public class PropertyFieldTable
+public class PropertyFieldTable implements FieldTable, Map
{
-
private static final Logger _logger = Logger.getLogger(PropertyFieldTable.class);
- public static final char BOOLEAN_PROPERTY_PREFIX = 'B';
+ public static final char AMQP_DECIMAL_PROPERTY_PREFIX = 'D';
+ public static final char AMQP_UNSIGNEDINT_PROPERTY_PREFIX = 'I';
+ public static final char AMQP_TIMESTAMP_PROPERTY_PREFIX = 'T';
+ public static final char AMQP_STRING_PROPERTY_PREFIX = 'S';
+ public static final char AMQP_ASCII_STRING_PROPERTY_PREFIX = 'c';
+ public static final char AMQP_WIDE_STRING_PROPERTY_PREFIX = 'C';
+ public static final char AMQP_BINARY_PROPERTY_PREFIX = 'x';
+
+ public static final char BOOLEAN_PROPERTY_PREFIX = 't';
public static final char BYTE_PROPERTY_PREFIX = 'b';
public static final char SHORT_PROPERTY_PREFIX = 's';
public static final char INT_PROPERTY_PREFIX = 'i';
public static final char LONG_PROPERTY_PREFIX = 'l';
public static final char FLOAT_PROPERTY_PREFIX = 'f';
public static final char DOUBLE_PROPERTY_PREFIX = 'd';
- public static final char STRING_PROPERTY_PREFIX = 'S';
- public static final char CHAR_PROPERTY_PREFIX = 'c';
- public static final char BYTES_PROPERTY_PREFIX = 'y';
+ public static final char STRING_PROPERTY_PREFIX = AMQP_STRING_PROPERTY_PREFIX;
+ public static final char CHAR_PROPERTY_PREFIX = AMQP_ASCII_STRING_PROPERTY_PREFIX;
+ public static final char BYTES_PROPERTY_PREFIX = AMQP_BINARY_PROPERTY_PREFIX;
+
+ //Our custom prefix for encoding across the wire
+ private static final char XML_PROPERTY_PREFIX = 'X';
private static final String BOOLEAN = "boolean";
private static final String BYTE = "byte";
@@ -66,7 +79,7 @@ public class PropertyFieldTable
private LinkedHashMap<String, Object> _properties;
private LinkedHashMap<String, String> _propertyNamesTypeMap;
-
+ private long _encodedSize = 0;
public PropertyFieldTable()
{
@@ -84,73 +97,167 @@ public class PropertyFieldTable
}
catch (Exception e)
{
- System.out.println(textFormat);
- e.printStackTrace();
+ _logger.error("Unable to decode PropertyFieldTable format:" + textFormat, e);
}
+ }
+ /**
+ * Construct a new field table.
+ *
+ * @param buffer the buffer from which to read data. The length byte must be read already
+ * @param length the length of the field table. Must be > 0.
+ * @throws AMQFrameDecodingException if there is an error decoding the table
+ */
+ public PropertyFieldTable(ByteBuffer buffer, long length) throws AMQFrameDecodingException
+ {
+ this();
+ setFromBuffer(buffer, length);
}
// ************ Getters
+ private Object get(String propertyName, char prefix)
+ {
+ String type = _propertyNamesTypeMap.get(propertyName);
+
+ if (type == null)
+ {
+ return null;
+ }
+
+ if (type.equals("" + prefix))
+ {
+ return _properties.get(propertyName);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
public Boolean getBoolean(String string)
{
- return (Boolean) _properties.get(BOOLEAN_PROPERTY_PREFIX + string);
+ Object o = get(string, BOOLEAN_PROPERTY_PREFIX);
+ if (o != null)
+ {
+ return (Boolean) o;
+ }
+ else
+ {
+ return null;
+ }
}
public Byte getByte(String string)
{
- return (Byte) _properties.get(BYTE_PROPERTY_PREFIX + string);
+ Object o = get(string, BYTE_PROPERTY_PREFIX);
+ if (o != null)
+ {
+ return (Byte) o;
+ }
+ else
+ {
+ return null;
+ }
}
public Short getShort(String string)
{
- return (Short) _properties.get(SHORT_PROPERTY_PREFIX + string);
+ Object o = get(string, SHORT_PROPERTY_PREFIX);
+ if (o != null)
+ {
+ return (Short) o;
+ }
+ else
+ {
+ return null;
+ }
}
public Integer getInteger(String string)
{
- return (Integer) _properties.get(INT_PROPERTY_PREFIX + string);
+ Object o = get(string, INT_PROPERTY_PREFIX);
+ if (o != null)
+ {
+ return (Integer) o;
+ }
+ else
+ {
+ return null;
+ }
}
public Long getLong(String string)
{
- return (Long) _properties.get(LONG_PROPERTY_PREFIX + string);
+ Object o = get(string, LONG_PROPERTY_PREFIX);
+ if (o != null)
+ {
+ return (Long) o;
+ }
+ else
+ {
+ return null;
+ }
}
public Float getFloat(String string)
{
- return (Float) _properties.get(FLOAT_PROPERTY_PREFIX + string);
+ Object o = get(string, FLOAT_PROPERTY_PREFIX);
+ if (o != null)
+ {
+ return (Float) o;
+ }
+ else
+ {
+ return null;
+ }
}
public Double getDouble(String string)
{
- return (Double) _properties.get(DOUBLE_PROPERTY_PREFIX + string);
+ Object o = get(string, DOUBLE_PROPERTY_PREFIX);
+ if (o != null)
+ {
+ return (Double) o;
+ }
+ else
+ {
+ return null;
+ }
}
public String getString(String string)
{
- return (String) _properties.get(STRING_PROPERTY_PREFIX + string);
+ Object o = get(string, STRING_PROPERTY_PREFIX);
+ if (o != null)
+ {
+ return (String) o;
+ }
+ else
+ {
+ return null;
+ }
}
public Character getCharacter(String string)
{
- return (Character) _properties.get(CHAR_PROPERTY_PREFIX + string);
+ Object o = get(string, CHAR_PROPERTY_PREFIX);
+ if (o != null)
+ {
+ return (Character) o;
+ }
+ else
+ {
+ return null;
+ }
}
public byte[] getBytes(String string)
{
- return (byte[]) _properties.get(BYTES_PROPERTY_PREFIX + string);
- }
-
- public Object getObject(String string)
- {
- String typestring = _propertyNamesTypeMap.get(string);
-
- if (typestring != null && !typestring.equals(""))
+ Object o = get(string, BYTES_PROPERTY_PREFIX);
+ if (o != null)
{
- char type = typestring.charAt(0);
-
- return _properties.get(type + string);
+ return (byte[]) o;
}
else
{
@@ -158,91 +265,66 @@ public class PropertyFieldTable
}
}
- // ************ Setters
-
-
- public void setBoolean(String string, boolean b)
+ public Object getObject(String string)
{
- checkPropertyName(string, BOOLEAN_PROPERTY_PREFIX);
+ return _properties.get(string);
+ }
+ // ************ Setters
- _propertyNamesTypeMap.put(string, "" + BOOLEAN_PROPERTY_PREFIX);
- _properties.put(BOOLEAN_PROPERTY_PREFIX + string, b);// ? new Long(1) : new Long(0));
+ public Object setBoolean(String string, boolean b)
+ {
+ return put(BOOLEAN_PROPERTY_PREFIX + string, b);
}
- public void setByte(String string, byte b)
+ public Object setByte(String string, byte b)
{
- checkPropertyName(string, BYTE_PROPERTY_PREFIX);
-
-
- _properties.put(BYTE_PROPERTY_PREFIX + string, b);
+ return put(BYTE_PROPERTY_PREFIX + string, b);
}
- public void setShort(String string, short i)
+ public Object setShort(String string, short i)
{
- checkPropertyName(string, SHORT_PROPERTY_PREFIX);
-
-
- _properties.put(SHORT_PROPERTY_PREFIX + string, i);
+ return put(SHORT_PROPERTY_PREFIX + string, i);
}
- public void setInteger(String string, int i)
+ public Object setInteger(String string, int i)
{
- checkPropertyName(string, INT_PROPERTY_PREFIX);
-
-
- _properties.put(INT_PROPERTY_PREFIX + string, i);
+ return put(INT_PROPERTY_PREFIX + string, i);
}
- public void setLong(String string, long l)
+ public Object setLong(String string, long l)
{
- checkPropertyName(string, LONG_PROPERTY_PREFIX);
-
-
- _properties.put(LONG_PROPERTY_PREFIX + string, l);
+ return put(LONG_PROPERTY_PREFIX + string, l);
}
- public void setFloat(String string, float v)
+ public Object setFloat(String string, float v)
{
- checkPropertyName(string, FLOAT_PROPERTY_PREFIX);
-
-
- _properties.put(FLOAT_PROPERTY_PREFIX + string, v);
+ return put(FLOAT_PROPERTY_PREFIX + string, v);
}
- public void setDouble(String string, double v)
+ public Object setDouble(String string, double v)
{
- checkPropertyName(string, DOUBLE_PROPERTY_PREFIX);
-
-
- _properties.put(DOUBLE_PROPERTY_PREFIX + string, v);
+ return put(DOUBLE_PROPERTY_PREFIX + string, v);
}
- public void setString(String string, String string1)
+ public Object setString(String string, String string1)
{
- checkPropertyName(string, STRING_PROPERTY_PREFIX);
-
-
- _properties.put(STRING_PROPERTY_PREFIX + string, string1);
+ return put(STRING_PROPERTY_PREFIX + string, string1);
}
- public void setChar(String string, char c)
+ public Object setChar(String string, char c)
{
- checkPropertyName(string, CHAR_PROPERTY_PREFIX);
-
- _properties.put(CHAR_PROPERTY_PREFIX + string, c);
+ return put(CHAR_PROPERTY_PREFIX + string, c);
}
- public void setBytes(String string, byte[] bytes)
+ public Object setBytes(String string, byte[] bytes)
{
- setBytes(string, bytes, 0, bytes.length);
+ return setBytes(string, bytes, 0, bytes.length);
}
- public void setBytes(String string, byte[] bytes, int start, int length)
+ public Object setBytes(String string, byte[] bytes, int start, int length)
{
- checkPropertyName(string, BYTES_PROPERTY_PREFIX);
-
- _properties.put(BYTES_PROPERTY_PREFIX + string, sizeByteArray(bytes, start, length));
+ return put(BYTES_PROPERTY_PREFIX + string, sizeByteArray(bytes, start, length));
}
private byte[] sizeByteArray(byte[] bytes, int start, int length)
@@ -259,65 +341,65 @@ public class PropertyFieldTable
}
- public void setObject(String string, Object object)
+ public Object setObject(String string, Object object)
{
if (object instanceof Boolean)
{
- setBoolean(string, (Boolean) object);
+ return setBoolean(string, (Boolean) object);
}
else
{
if (object instanceof Byte)
{
- setByte(string, (Byte) object);
+ return setByte(string, (Byte) object);
}
else
{
if (object instanceof Short)
{
- setShort(string, (Short) object);
+ return setShort(string, (Short) object);
}
else
{
if (object instanceof Integer)
{
- setInteger(string, (Integer) object);
+ return setInteger(string, (Integer) object);
}
else
{
if (object instanceof Long)
{
- setLong(string, (Long) object);
+ return setLong(string, (Long) object);
}
else
{
if (object instanceof Float)
{
- setFloat(string, (Float) object);
+ return setFloat(string, (Float) object);
}
else
{
if (object instanceof Double)
{
- setDouble(string, (Double) object);
+ return setDouble(string, (Double) object);
}
else
{
if (object instanceof String)
{
- setString(string, (String) object);
+ return setString(string, (String) object);
}
else
{
if (object instanceof Character)
{
- setChar(string, (Character) object);
+ return setChar(string, (Character) object);
}
else
{
if (object instanceof byte[])
{
- setBytes(string, (byte[]) object);
+ return setBytes(string, (byte[]) object);
}
}
}
@@ -328,8 +410,7 @@ public class PropertyFieldTable
}
}
}
-
-
+ return null;
}
// ***** Methods
@@ -344,12 +425,16 @@ public class PropertyFieldTable
{
String key = (String) keys.next();
- names.add(key.substring(1));
+ names.add(key);
}
return names.elements();
}
+ public boolean propertyExists(String propertyName)
+ {
+ return _propertyNamesTypeMap.containsKey(propertyName);
+ }
public boolean itemExists(String string)
{
@@ -367,7 +452,6 @@ public class PropertyFieldTable
return false;
}
-
public String toString()
{
return valueOf(this);
@@ -390,35 +474,55 @@ public class PropertyFieldTable
else
{
buf.append('\n');
- buf.append(propertyXML(propertyName, true));
- if (propertyName.charAt(0) == BYTES_PROPERTY_PREFIX)
- {
- //remove '>'
- buf.deleteCharAt(buf.length() - 1);
+ buf.append(valueAsXML(table._propertyNamesTypeMap.get(propertyName) + propertyName, entry.getValue()));
+ }
+ }
+ buf.append("\n");
+ buf.append(PROPERTY_FIELD_TABLE_CLOSE_XML);
- byte[] bytes = (byte[]) entry.getValue();
- buf.append(" length='").append(bytes.length).append("'>");
+ return buf.toString();
+ }
- buf.append(byteArrayToXML(propertyName.substring(1), bytes));
- }
- else
- {
+ private static String valueAsXML(String name, Object value)
+ {
+ char propertyPrefix = name.charAt(0);
+ String propertyName = name.substring(1);
- buf.append(String.valueOf(entry.getValue()));
- }
- buf.append(propertyXML(propertyName, false));
- }
+ StringBuffer buf = new StringBuffer();
+ // Start Tag
+ buf.append(propertyXML(name, true));
+
+ // Value
+ if (propertyPrefix == BYTES_PROPERTY_PREFIX)
+ {
+ //remove '>'
+ buf.deleteCharAt(buf.length() - 1);
+
+ byte[] bytes = (byte[]) value;
+ buf.append(" length='").append(bytes.length).append("'>");
+
+ buf.append(byteArrayToXML(propertyName, bytes));
+ }
+ else
+ {
+ buf.append(String.valueOf(value));
}
- buf.append("\n");
- buf.append(PROPERTY_FIELD_TABLE_CLOSE_XML);
+
+ //End Tag
+ buf.append(propertyXML(name, false));
return buf.toString();
}
- private void checkPropertyName(String propertyName, char propertyPrefix)
+ private Object checkPropertyName(String name)
{
+ String propertyName = name.substring(1);
+ char propertyPrefix = name.charAt(0);
+
+ Object previous = null;
+
if (propertyName == null)
{
throw new IllegalArgumentException("Property name must not be null");
@@ -428,19 +532,134 @@ public class PropertyFieldTable
throw new IllegalArgumentException("Property name must not be the empty string");
}
+ checkIdentiferFormat(propertyName);
+
String currentValue = _propertyNamesTypeMap.get(propertyName);
if (currentValue != null)
{
- _properties.remove(currentValue + propertyName);
+ previous = _properties.remove(currentValue + propertyName);
+
+ // If we are in effect deleting the value (see comment on null values being deleted
+ // below) then we also need to remove the name from the encoding length.
+ if (previous == null)
+ {
+ _encodedSize -= EncodingUtils.encodedShortStringLength(propertyName);
+ }
+
+ // FIXME: Should be able to short-cut this process if the old and new values are
+ // the same object and/or type and size...
+ _encodedSize -= getEncodingSize(currentValue + propertyName, previous);
}
_propertyNamesTypeMap.put(propertyName, "" + propertyPrefix);
+
+ return previous;
}
- private static String propertyXML(String propertyName, boolean start)
+
+ protected static void checkIdentiferFormat(String propertyName)
{
- char typeIdentifier = propertyName.charAt(0);
+
+// AMQP Spec: 4.2.5.5 Field Tables
+// Guidelines for implementers:
+// * Field names MUST start with a letter, '$' or '#' and may continue with
+// letters, '$' or '#', digits, or underlines, to a maximum length of 128
+// characters.
+// * The server SHOULD validate field names and upon receiving an invalid
+// field name, it SHOULD signal a connection exception with reply code
+// 503 (syntax error). Conformance test: amq_wlp_table_01.
+// * A peer MUST handle duplicate fields by using only the first instance.
+
+// JMS requirements 3.5.1 Property Names
+// Identifiers:
+// - An identifier is an unlimited-length character sequence that must begin
+// with a Java identifier start character; all following characters must be Java
+// identifier part characters. An identifier start character is any character for
+// which the method Character.isJavaIdentifierStart returns true. This includes
+// '_' and '$'. An identifier part character is any character for which the
+// method Character.isJavaIdentifierPart returns true.
+// - Identifiers cannot be the names NULL, TRUE, or FALSE.
+// – Identifiers cannot be NOT, AND, OR, BETWEEN, LIKE, IN, IS, or
+// ESCAPE.
+// – Identifiers are either header field references or property references. The
+// type of a property value in a message selector corresponds to the type
+// used to set the property. If a property that does not exist in a message is
+// referenced, its value is NULL. The semantics of evaluating NULL values
+// in a selector are described in Section 3.8.1.2, “Null Values.”
+// – The conversions that apply to the get methods for properties do not
+// apply when a property is used in a message selector expression. For
+// example, suppose you set a property as a string value, as in the
+// following:
+// myMessage.setStringProperty("NumberOfOrders", "2");
+// The following expression in a message selector would evaluate to false,
+// because a string cannot be used in an arithmetic expression:
+// "NumberOfOrders > 1"
+// – Identifiers are case sensitive.
+// – Message header field references are restricted to JMSDeliveryMode,
+// JMSPriority, JMSMessageID, JMSTimestamp, JMSCorrelationID, and
+// JMSType. JMSMessageID, JMSCorrelationID, and JMSType values may be
+// null and if so are treated as a NULL value.
+
+
+ if (Boolean.getBoolean("strict-jms"))
+ {
+ // JMS start character
+ if (!(Character.isJavaIdentifierStart(propertyName.charAt(0))))
+ {
+ throw new IllegalArgumentException("Identifier '" + propertyName + "' does not start with a valid JMS identifier start character");
+ }
+
+ // JMS part character
+ int length = propertyName.length();
+ for (int c = 1; c < length; c++)
+ {
+ if (!(Character.isJavaIdentifierPart(propertyName.charAt(c))))
+ {
+ throw new IllegalArgumentException("Identifier '" + propertyName + "' contains an invalid JMS identifier character");
+ }
+ }
+
+ // JMS invalid names
+ if (!(propertyName.equals("NULL")
+ || propertyName.equals("TRUE")
+ || propertyName.equals("FALSE")
+ || propertyName.equals("NOT")
+ || propertyName.equals("AND")
+ || propertyName.equals("OR")
+ || propertyName.equals("BETWEEN")
+ || propertyName.equals("LIKE")
+ || propertyName.equals("IN")
+ || propertyName.equals("IS")
+ || propertyName.equals("ESCAPE")))
+ {
+ throw new IllegalArgumentException("Identifier '" + propertyName + "' is not allowed in JMS");
+ }
+
+ }
+ else
+ {
+ // AMQP length limit
+ if (propertyName.length() > 128)
+ {
+ throw new IllegalArgumentException("AMQP limits property names to 128 characters");
+ }
+
+ // AMQ start character
+ if (!(Character.isLetter(propertyName.charAt(0))
+ || propertyName.charAt(0) == '$'
+ || propertyName.charAt(0) == '#'))
+ {
+ throw new IllegalArgumentException("Identifier '" + propertyName + "' does not start with a valid AMQP start character");
+ }
+ }
+
+ }
+
+ private static String propertyXML(String name, boolean start)
+ {
+ char propertyPrefix = name.charAt(0);
+ String propertyName = name.substring(1);
StringBuffer buf = new StringBuffer();
@@ -453,8 +672,7 @@ public class PropertyFieldTable
buf.append("</");
}
-
- switch (typeIdentifier)
+ switch (propertyPrefix)
{
case BOOLEAN_PROPERTY_PREFIX:
buf.append(BOOLEAN);
@@ -487,14 +705,13 @@ public class PropertyFieldTable
buf.append(CHAR);
break;
default:
- buf.append(UNKNOWN + " (identifier ").append(typeIdentifier).append(")");
+ buf.append(UNKNOWN + " (identifier ").append(propertyPrefix).append(")");
break;
}
-
if (start)
{
- buf.append(" name='").append(propertyName.substring(1)).append("'");
+ buf.append(" name='").append(propertyName).append("'");
}
buf.append(">");
@@ -519,8 +736,6 @@ public class PropertyFieldTable
private void processBytesXMLLine(String xmlline)
{
- String type = xmlline.substring(1, xmlline.indexOf(" "));
-
String propertyName = xmlline.substring(xmlline.indexOf('\'') + 1,
xmlline.indexOf('\'', xmlline.indexOf('\'') + 1));
String value = xmlline.substring(xmlline.indexOf(">") + 1,
@@ -545,7 +760,6 @@ public class PropertyFieldTable
{
String token = tokenizer.nextToken();
-
if (token.equals(PROPERTY_FIELD_TABLE_CLOSE_XML)
|| token.equals(BYTES_CLOSE_XML))
{
@@ -555,7 +769,6 @@ public class PropertyFieldTable
if (token.equals(BYTES_CLOSE_XML))
{
processing_bytes = false;
-
}
if (processing)
@@ -578,11 +791,9 @@ public class PropertyFieldTable
{
processing = true;
}
-
}
}
-
private void processXMLLine(String xmlline)
{
// <<type> name='<property>'><value></<type>>
@@ -611,11 +822,39 @@ public class PropertyFieldTable
}
if (type.equals(BYTES))
{
- Integer length = Integer.parseInt(xmlline.substring(
- xmlline.lastIndexOf("=") + 2
- , xmlline.lastIndexOf("'")));
+ int headerEnd = xmlline.indexOf('>');
+ String bytesHeader = xmlline.substring(0, headerEnd);
+
+ //Extract length value
+ Integer length = Integer.parseInt(bytesHeader.substring(
+ bytesHeader.lastIndexOf("=") + 2
+ , bytesHeader.lastIndexOf("'")));
+
+
byte[] bytes = new byte[length];
setBytes(propertyName, bytes);
+
+ //Check if the line contains all the byte values
+ // This is needed as the XMLLine sent across the wire is the bytes value
+
+ int byteStart = xmlline.indexOf('<', headerEnd);
+
+ if (byteStart > 0)
+ {
+ while (!xmlline.startsWith(BYTES_CLOSE_XML, byteStart))
+ {
+ //This should be the next byte line
+ int bytePrefixEnd = xmlline.indexOf('>', byteStart) + 1;
+ int byteEnd = xmlline.indexOf('>', bytePrefixEnd) + 1;
+
+ String byteline = xmlline.substring(byteStart, byteEnd);
+
+ processBytesXMLLine(byteline);
+
+ byteStart = xmlline.indexOf('<', byteEnd);
+ }
+ }
+
}
if (type.equals(SHORT))
{
@@ -651,6 +890,391 @@ public class PropertyFieldTable
}
}
+ // ************************* Byte Buffer Processing
+
+ public void writeToBuffer(ByteBuffer buffer)
+ {
+ final boolean debug = _logger.isDebugEnabled();
+
+ if (debug)
+ {
+ _logger.debug("FieldTable::writeToBuffer: Writing encoded size of " + _encodedSize + "...");
+ }
+
+ EncodingUtils.writeUnsignedInteger(buffer, _encodedSize);
+
+ putDataInBuffer(buffer);
+ }
+
+ public byte[] getDataAsBytes()
+ {
+ final ByteBuffer buffer = ByteBuffer.allocate((int) _encodedSize); // FIXME XXX: Is cast a problem?
+
+ putDataInBuffer(buffer);
+
+ final byte[] result = new byte[(int) _encodedSize];
+ buffer.flip();
+ buffer.get(result);
+ buffer.release();
+ return result;
+ }
+
+
+ public int size()
+ {
+ return _properties.size();
+ }
+
+ public boolean isEmpty()
+ {
+ return _properties.isEmpty();
+ }
+
+ public boolean containsKey(Object key)
+ {
+ return _properties.containsKey(key);
+ }
+
+ public boolean containsValue(Object value)
+ {
+ return _properties.containsValue(value);
+ }
+
+ public Object get(Object key)
+ {
+ return _properties.get(key);
+ }
+
+
+ public Object put(Object key, Object value)
+ {
+ return setObject(key.toString(), value);
+ }
+
+ protected Object put(String key, Object value)
+ {
+ Object previous = checkPropertyName(key);
+
+
+ String propertyName = key.substring(1);
+ char propertyPrefix = _propertyNamesTypeMap.get(propertyName).charAt(0);
+
+ if (value != null)
+ {
+ //Add the size of the propertyName
+ _encodedSize += EncodingUtils.encodedShortStringLength(propertyName);
+
+ // For now: Setting a null value is the equivalent of deleting it.
+ // This is ambiguous in the JMS spec and needs thrashing out and potentially
+ // testing against other implementations.
+
+ //Add the size of the content
+ _encodedSize += getEncodingSize(key, value);
+ }
+
+ _properties.put((String) propertyName, value);
+
+ return previous;
+ }
+
+ public Object remove(Object key)
+ {
+ if (key instanceof String)
+ {
+ throw new IllegalArgumentException("Property key be a string");
+ }
+
+ char propertyPrefix = ((String) key).charAt(0);
+
+ if (_properties.containsKey(key))
+ {
+ final Object value = _properties.remove(key);
+ // plus one for the type
+ _encodedSize -= EncodingUtils.encodedShortStringLength(((String) key));
+
+ // This check is, for now, unnecessary (we don't store null values).
+ if (value != null)
+ {
+ _encodedSize -= getEncodingSize(propertyPrefix + (String) key, value);
+ }
+
+ return value;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ public void putAll(Map t)
+ {
+ Iterator it = t.keySet().iterator();
+
+ while (it.hasNext())
+ {
+ Object key = it.next();
+ put(key, t.get(key));
+ }
+ }
+
+ public void clear()
+ {
+ _properties.clear();
+ _propertyNamesTypeMap.clear();
+ }
+
+ public Set keySet()
+ {
+ return _properties.keySet();
+ }
+
+ public Collection values()
+ {
+ return _properties.values();
+ }
+
+ public Set entrySet()
+ {
+ return _properties.entrySet();
+ }
+
+ public long getEncodedSize()
+ {
+ return _encodedSize;
+ }
+
+
+ private void putDataInBuffer(ByteBuffer buffer)
+ {
+ final Iterator it = _properties.entrySet().iterator();
+
+ //If there are values then write out the encoded Size... could check _encodedSize != 0
+ // write out the total length, which we have kept up to date as data is added
+
+
+ while (it.hasNext())
+ {
+ Map.Entry me = (Map.Entry) it.next();
+ String propertyName = (String) me.getKey();
+
+ //The type value
+ char propertyPrefix = _propertyNamesTypeMap.get(propertyName).charAt(0);
+ //The actual param name skipping type
+
+ EncodingUtils.writeShortStringBytes(buffer, propertyName);
+ Object value = me.getValue();
+
+ switch (propertyPrefix)
+ {
+
+ case BOOLEAN_PROPERTY_PREFIX:
+ buffer.put((byte) BOOLEAN_PROPERTY_PREFIX);
+ EncodingUtils.writeBoolean(buffer, (Boolean) value);
+ break;
+ case BYTE_PROPERTY_PREFIX:
+ buffer.put((byte) BYTE_PROPERTY_PREFIX);
+ EncodingUtils.writeByte(buffer, (Byte) value);
+ break;
+ case SHORT_PROPERTY_PREFIX:
+ buffer.put((byte) SHORT_PROPERTY_PREFIX);
+ EncodingUtils.writeShort(buffer, (Short) value);
+ break;
+ case INT_PROPERTY_PREFIX:
+ buffer.put((byte) INT_PROPERTY_PREFIX);
+ EncodingUtils.writeInteger(buffer, (Integer) value);
+ break;
+ case AMQP_UNSIGNEDINT_PROPERTY_PREFIX: // Currently we don't create these
+ buffer.put((byte) AMQP_UNSIGNEDINT_PROPERTY_PREFIX);
+ EncodingUtils.writeUnsignedInteger(buffer, (Long) value);
+ break;
+ case LONG_PROPERTY_PREFIX:
+ buffer.put((byte) LONG_PROPERTY_PREFIX);
+ EncodingUtils.writeLong(buffer, (Long) value);
+ break;
+ case FLOAT_PROPERTY_PREFIX:
+ buffer.put((byte) FLOAT_PROPERTY_PREFIX);
+ EncodingUtils.writeFloat(buffer, (Float) value);
+ break;
+ case DOUBLE_PROPERTY_PREFIX:
+ buffer.put((byte) DOUBLE_PROPERTY_PREFIX);
+ EncodingUtils.writeDouble(buffer, (Double) value);
+ break;
+
+ case AMQP_WIDE_STRING_PROPERTY_PREFIX:
+ //case AMQP_STRING_PROPERTY_PREFIX:
+ case STRING_PROPERTY_PREFIX:
+ // TODO: look at using proper charset encoder
+ buffer.put((byte) STRING_PROPERTY_PREFIX);
+ EncodingUtils.writeLongStringBytes(buffer, (String) value);
+ break;
+
+ //case AMQP_ASCII_STRING_PROPERTY_PREFIX:
+ case CHAR_PROPERTY_PREFIX:
+ // TODO: look at using proper charset encoder
+ buffer.put((byte) CHAR_PROPERTY_PREFIX);
+ EncodingUtils.writeShortStringBytes(buffer, "" + (Character) value);
+ break;
+
+ case BYTES_PROPERTY_PREFIX:
+ buffer.put((byte) BYTES_PROPERTY_PREFIX);
+ EncodingUtils.writeBytes(buffer, (byte[]) value);
+ break;
+
+ case XML_PROPERTY_PREFIX:
+ // Encode as XML
+ buffer.put((byte) XML_PROPERTY_PREFIX);
+ EncodingUtils.writeLongStringBytes(buffer, valueAsXML(propertyPrefix + propertyName, value));
+ break;
+ default:
+ {
+ // Should never get here
+ throw new IllegalArgumentException("Key '" + propertyName + "': Unsupported type in field table, type: " + ((value == null) ? "null-object" : value.getClass()));
+ }
+ }
+ }
+ }
+
+
+ public void setFromBuffer(ByteBuffer buffer, long length) throws AMQFrameDecodingException
+ {
+ final boolean debug = _logger.isDebugEnabled();
+
+ int sizeRead = 0;
+ while (sizeRead < length)
+ {
+ int sizeRemaining = buffer.remaining();
+ final String key = EncodingUtils.readShortString(buffer);
+ // TODO: use proper charset decoder
+ byte iType = buffer.get();
+ final char type = (char) iType;
+ Object value = null;
+
+ switch (type)
+ {
+ case BOOLEAN_PROPERTY_PREFIX:
+ value = EncodingUtils.readBoolean(buffer);
+ break;
+ case BYTE_PROPERTY_PREFIX:
+ value = EncodingUtils.readByte(buffer);
+ break;
+ case SHORT_PROPERTY_PREFIX:
+ value = EncodingUtils.readShort(buffer);
+ break;
+ case INT_PROPERTY_PREFIX:
+ value = EncodingUtils.readInteger(buffer);
+ break;
+ case AMQP_UNSIGNEDINT_PROPERTY_PREFIX:// This will only fit in a long
+ case LONG_PROPERTY_PREFIX:
+ value = EncodingUtils.readLong(buffer);
+ break;
+ case FLOAT_PROPERTY_PREFIX:
+ value = EncodingUtils.readFloat(buffer);
+ break;
+ case DOUBLE_PROPERTY_PREFIX:
+ value = EncodingUtils.readDouble(buffer);
+ break;
+
+ // TODO: use proper charset decoder
+ case AMQP_WIDE_STRING_PROPERTY_PREFIX:
+ //case AMQP_STRING_PROPERTY_PREFIX:
+ case STRING_PROPERTY_PREFIX:
+ value = EncodingUtils.readLongString(buffer);
+ break;
+ //case AMQP_ASCII_STRING_PROPERTY_PREFIX:
+ case CHAR_PROPERTY_PREFIX:
+ value = EncodingUtils.readShortString(buffer).charAt(0);
+ break;
+ case BYTES_PROPERTY_PREFIX:
+ value = EncodingUtils.readBytes(buffer);
+ break;
+ case XML_PROPERTY_PREFIX:
+ processXMLLine(EncodingUtils.readLongString(buffer));
+ break;
+ default:
+ String msg = "Field '" + key + "' - unsupported field table type: " + type + ".";
+ //some extra debug information...
+ msg += " (" + iType + "), length=" + length + ", sizeRead=" + sizeRead + ", sizeRemaining=" + sizeRemaining;
+ throw new AMQFrameDecodingException(msg);
+ }
+
+ sizeRead += (sizeRemaining - buffer.remaining());
+
+ if (debug)
+ {
+ _logger.debug("FieldTable::PropFieldTable(buffer," + length + "): Read type '" + type + "', key '" + key + "', value '" + value + "' (now read " + sizeRead + " of " + length + " encoded bytes)...");
+ }
+
+ if (type != XML_PROPERTY_PREFIX)
+ {
+ setObject(key, value);
+ }
+ }
+
+ if (debug)
+ {
+ _logger.debug("FieldTable::FieldTable(buffer," + length + "): Done.");
+ }
+ }
-}
+ /**
+ * @param name the property name with type prefix
+ * @param value the property value
+ * @return integer
+ */
+ private static int getEncodingSize(String name, Object value)
+ {
+ int encodingSize;
+
+ char propertyPrefix = name.charAt(0);
+
+ switch (propertyPrefix)
+ {
+ case BOOLEAN_PROPERTY_PREFIX:
+ encodingSize = 1 + EncodingUtils.encodedBooleanLength();
+ break;
+ case BYTE_PROPERTY_PREFIX:
+ encodingSize = 1 + EncodingUtils.encodedByteLength();
+ break;
+ case SHORT_PROPERTY_PREFIX:
+ encodingSize = 1 + EncodingUtils.encodedShortLength();
+ break;
+ case INT_PROPERTY_PREFIX:
+ encodingSize = 1 + EncodingUtils.encodedIntegerLength();
+ break;
+ case LONG_PROPERTY_PREFIX:
+ encodingSize = 1 + EncodingUtils.encodedLongLength();
+ break;
+ case FLOAT_PROPERTY_PREFIX:
+ encodingSize = 1 + EncodingUtils.encodedFloatLength();
+ break;
+ case DOUBLE_PROPERTY_PREFIX:
+ encodingSize = 1 + EncodingUtils.encodedDoubleLength();
+ break;
+ case AMQP_WIDE_STRING_PROPERTY_PREFIX:
+ //case AMQP_STRING_PROPERTY_PREFIX:
+ case STRING_PROPERTY_PREFIX:
+ encodingSize = 1 + EncodingUtils.encodedLongStringLength((String) value);
+ break;
+ //case AMQP_ASCII_STRING_PROPERTY_PREFIX:
+ case CHAR_PROPERTY_PREFIX:
+ encodingSize = 1 + EncodingUtils.encodedShortStringLength("" + (Character) value);
+ break;
+ case BYTES_PROPERTY_PREFIX:
+ encodingSize = 1 + ((byte[]) value).length;
+ break;
+ case XML_PROPERTY_PREFIX:
+ encodingSize = 1 + EncodingUtils.encodedLongStringLength(valueAsXML(name, value));
+ break;
+ default:
+ //encodingSize = 1 + EncodingUtils.encodedLongStringLength(String.valueOf(value));
+ // We are using XML String encoding
+ throw new IllegalArgumentException("Unsupported type in field table: " + value.getClass());
+ }
+
+// the extra byte for the type indicator is calculated in the name
+ return encodingSize;
+ }
+
+
+}
diff --git a/java/common/src/test/java/org/apache/qpid/framing/BasicContentHeaderPropertiesTest.java b/java/common/src/test/java/org/apache/qpid/framing/BasicContentHeaderPropertiesTest.java
new file mode 100644
index 0000000000..66dd1b10ef
--- /dev/null
+++ b/java/common/src/test/java/org/apache/qpid/framing/BasicContentHeaderPropertiesTest.java
@@ -0,0 +1,192 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.framing;
+
+import org.apache.mina.common.ByteBuffer;
+
+import java.util.HashMap;
+
+import junit.framework.TestCase;
+
+
+public class BasicContentHeaderPropertiesTest extends TestCase
+{
+
+ BasicContentHeaderProperties _testProperties;
+ PropertyFieldTable _testTable;
+ String _testString = "This is a test string";
+ int _testint = 666;
+
+ /**
+ * Currently only test setting/getting String, int and boolean props
+ */
+ public BasicContentHeaderPropertiesTest()
+ {
+ _testProperties = new BasicContentHeaderProperties();
+ }
+
+ public void setUp()
+ {
+ HashMap _testMap = new HashMap(10);
+ _testMap.put("TestString", _testString);
+ _testMap.put("Testint", _testint);
+ _testTable = new PropertyFieldTable();
+ _testTable.putAll(_testMap);
+ _testProperties = new BasicContentHeaderProperties();
+ _testProperties.setHeaders(_testTable);
+ }
+
+ public void testGetPropertyListSize()
+ {
+ //needs a better test but at least we're exercising the code !
+ // FT size is encoded in an int
+ int expectedSize = EncodingUtils.encodedIntegerLength();
+
+ expectedSize += EncodingUtils.encodedShortStringLength("TestInt");
+ // 1 is for the Encoding Letter. here an 'i'
+ expectedSize += 1 + EncodingUtils.encodedIntegerLength();
+
+ expectedSize += EncodingUtils.encodedShortStringLength("TestString");
+ // 1 is for the Encoding Letter. here an 'S'
+ expectedSize += 1 + EncodingUtils.encodedLongStringLength(_testString);
+
+
+ int size = _testProperties.getPropertyListSize();
+
+ assertEquals(expectedSize, size);
+ }
+
+ public void testGetSetPropertyFlags()
+ {
+ _testProperties.setPropertyFlags(99);
+ assertEquals(99, _testProperties.getPropertyFlags());
+ }
+
+ public void testWritePropertyListPayload()
+ {
+ ByteBuffer buf = ByteBuffer.allocate(300);
+ _testProperties.writePropertyListPayload(buf);
+ }
+
+ public void testPopulatePropertiesFromBuffer() throws Exception
+ {
+ ByteBuffer buf = ByteBuffer.allocate(300);
+ _testProperties.populatePropertiesFromBuffer(buf, 99, 99);
+ }
+
+ public void testSetGetContentType()
+ {
+ String contentType = "contentType";
+ _testProperties.setContentType(contentType);
+ assertEquals(contentType, _testProperties.getContentType());
+ }
+
+ public void testSetGetEncoding()
+ {
+ String encoding = "encoding";
+ _testProperties.setEncoding(encoding);
+ assertEquals(encoding, _testProperties.getEncoding());
+ }
+
+ public void testSetGetHeaders()
+ {
+ _testProperties.setHeaders(_testTable);
+ assertEquals(_testTable, _testProperties.getHeaders());
+ }
+
+ public void testSetGetDeliveryMode()
+ {
+ byte deliveryMode = 1;
+ _testProperties.setDeliveryMode(deliveryMode);
+ assertEquals(deliveryMode, _testProperties.getDeliveryMode());
+ }
+
+ public void testSetGetPriority()
+ {
+ byte priority = 1;
+ _testProperties.setPriority(priority);
+ assertEquals(priority, _testProperties.getPriority());
+ }
+
+ public void testSetGetCorrelationId()
+ {
+ String correlationId = "correlationId";
+ _testProperties.setCorrelationId(correlationId);
+ assertEquals(correlationId, _testProperties.getCorrelationId());
+ }
+
+ public void testSetGetReplyTo()
+ {
+ String replyTo = "replyTo";
+ _testProperties.setReplyTo(replyTo);
+ assertEquals(replyTo, _testProperties.getReplyTo());
+ }
+
+ public void testSetGetExpiration()
+ {
+ long expiration = 999999999;
+ _testProperties.setExpiration(expiration);
+ assertEquals(expiration, _testProperties.getExpiration());
+ }
+
+ public void testSetGetMessageId()
+ {
+ String messageId = "messageId";
+ _testProperties.setMessageId(messageId);
+ assertEquals(messageId, _testProperties.getMessageId());
+ }
+
+ public void testSetGetTimestamp()
+ {
+ long timestamp = 999999999;
+ _testProperties.setTimestamp(timestamp);
+ assertEquals(timestamp, _testProperties.getTimestamp());
+ }
+
+ public void testSetGetType()
+ {
+ String type = "type";
+ _testProperties.setType(type);
+ assertEquals(type, _testProperties.getType());
+ }
+
+ public void testSetGetUserId()
+ {
+ String userId = "userId";
+ _testProperties.setUserId(userId);
+ assertEquals(userId, _testProperties.getUserId());
+ }
+
+ public void testSetGetAppId()
+ {
+ String appId = "appId";
+ _testProperties.setAppId(appId);
+ assertEquals(appId, _testProperties.getAppId());
+ }
+
+ public void testSetGetClusterId()
+ {
+ String clusterId = "clusterId";
+ _testProperties.setClusterId(clusterId);
+ assertEquals(clusterId, _testProperties.getClusterId());
+ }
+
+}
diff --git a/java/common/src/test/java/org/apache/qpid/framing/PropertyFieldTableTest.java b/java/common/src/test/java/org/apache/qpid/framing/PropertyFieldTableTest.java
index 5070b6ecb1..5166168b04 100644
--- a/java/common/src/test/java/org/apache/qpid/framing/PropertyFieldTableTest.java
+++ b/java/common/src/test/java/org/apache/qpid/framing/PropertyFieldTableTest.java
@@ -25,6 +25,10 @@ import junit.framework.TestCase;
import java.util.Enumeration;
+import org.apache.mina.common.ByteBuffer;
+import org.apache.mina.common.ByteBufferProxy;
+import org.apache.mina.common.support.BaseByteBuffer;
+
public class PropertyFieldTableTest extends TestCase
{
@@ -206,7 +210,7 @@ public class PropertyFieldTableTest extends TestCase
PropertyFieldTable table2 = new PropertyFieldTable(table1XML);
- Assert.assertEquals(table1XML, table2.toString());
+ Assert.assertEquals(table1XML, table2.toString());
}
public void testKeyEnumeration()
@@ -273,6 +277,110 @@ public class PropertyFieldTableTest extends TestCase
Assert.assertEquals(Short.MAX_VALUE, table.getObject("object-short"));
}
+
+ public void testwriteBuffer()
+ {
+ byte[] bytes = {99, 98, 97, 96, 95};
+
+ PropertyFieldTable table = new PropertyFieldTable();
+ table.setBoolean("bool", true);
+ table.setByte("byte", Byte.MAX_VALUE);
+
+ table.setBytes("bytes", bytes);
+ table.setChar("char", 'c');
+ table.setDouble("double", Double.MAX_VALUE);
+ table.setFloat("float", Float.MAX_VALUE);
+ table.setInteger("int", Integer.MAX_VALUE);
+ table.setLong("long", Long.MAX_VALUE);
+ table.setShort("short", Short.MAX_VALUE);
+
+
+ final ByteBuffer buffer = ByteBuffer.allocate((int) table.getEncodedSize()); // FIXME XXX: Is cast a problem?
+
+ table.writeToBuffer(buffer);
+
+ buffer.flip();
+
+ long length = buffer.getUnsignedInt();
+
+ try
+ {
+ PropertyFieldTable table2 = new PropertyFieldTable(buffer, length);
+
+ Assert.assertEquals((Boolean) true, table2.getBoolean("bool"));
+ Assert.assertEquals((Byte) Byte.MAX_VALUE, table2.getByte("byte"));
+ assertBytesEqual(bytes, table2.getBytes("bytes"));
+ Assert.assertEquals((Character) 'c', table2.getCharacter("char"));
+ Assert.assertEquals(Double.MAX_VALUE, table2.getDouble("double"));
+ Assert.assertEquals(Float.MAX_VALUE, table2.getFloat("float"));
+ Assert.assertEquals((Integer) Integer.MAX_VALUE, table2.getInteger("int"));
+ Assert.assertEquals((Long) Long.MAX_VALUE, table2.getLong("long"));
+ Assert.assertEquals((Short) Short.MAX_VALUE, table2.getShort("short"));
+ }
+ catch (AMQFrameDecodingException e)
+ {
+ e.printStackTrace();
+ fail("PFT should be instantiated from bytes." + e.getCause());
+ }
+ }
+
+ public void testEncodingSize()
+ {
+ FieldTable result = FieldTableFactory.newFieldTable();
+ int size = 0;
+ result.put("one", 1L);
+ size = EncodingUtils.encodedShortStringLength("one");
+ size += 1 + EncodingUtils.encodedLongLength();
+ assertEquals(size, result.getEncodedSize());
+
+ result.put("two", 2L);
+ size += EncodingUtils.encodedShortStringLength("two");
+ size += 1 + EncodingUtils.encodedLongLength();
+ assertEquals(size, result.getEncodedSize());
+
+ result.put("three", 3L);
+ size += EncodingUtils.encodedShortStringLength("three");
+ size += 1 + EncodingUtils.encodedLongLength();
+ assertEquals(size, result.getEncodedSize());
+
+ result.put("four", 4L);
+ size += EncodingUtils.encodedShortStringLength("four");
+ size += 1 + EncodingUtils.encodedLongLength();
+ assertEquals(size, result.getEncodedSize());
+
+ result.put("five", 5L);
+ size += EncodingUtils.encodedShortStringLength("five");
+ size += 1 + EncodingUtils.encodedLongLength();
+ assertEquals(size, result.getEncodedSize());
+
+ //fixme should perhaps be expanded to incorporate all types.
+
+ final ByteBuffer buffer = ByteBuffer.allocate((int) result.getEncodedSize()); // FIXME XXX: Is cast a problem?
+
+ result.writeToBuffer(buffer);
+
+ buffer.flip();
+
+ long length = buffer.getUnsignedInt();
+
+ try
+ {
+ PropertyFieldTable table2 = new PropertyFieldTable(buffer, length);
+
+ Assert.assertEquals((Long) 1L, table2.getLong("one"));
+ Assert.assertEquals((Long) 2L, table2.getLong("two"));
+ Assert.assertEquals((Long) 3L, table2.getLong("three"));
+ Assert.assertEquals((Long) 4L, table2.getLong("four"));
+ Assert.assertEquals((Long) 5L, table2.getLong("five"));
+ }
+ catch (AMQFrameDecodingException e)
+ {
+ e.printStackTrace();
+ fail("PFT should be instantiated from bytes." + e.getCause());
+ }
+
+ }
+
private void assertBytesEqual(byte[] expected, byte[] actual)
{
Assert.assertEquals(expected.length, actual.length);
diff --git a/java/management/eclipse-plugin/META-INF/MANIFEST.MF b/java/management/eclipse-plugin/META-INF/MANIFEST.MF
new file mode 100644
index 0000000000..5e5ba41be0
--- /dev/null
+++ b/java/management/eclipse-plugin/META-INF/MANIFEST.MF
@@ -0,0 +1,12 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Qpid Management Console Plug-in
+Bundle-SymbolicName: org.apache.qpid.management.ui; singleton:=true
+Bundle-Version: 0.1.0
+Bundle-Activator: org.apache.qpid.management.ui.Activator
+Bundle-Localization: plugin
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.eclipse.ui.forms
+Eclipse-LazyStart: true
+Bundle-Vendor: Apache Software Foundation
diff --git a/java/management/eclipse-plugin/README.txt b/java/management/eclipse-plugin/README.txt
new file mode 100644
index 0000000000..2cbfbc623c
--- /dev/null
+++ b/java/management/eclipse-plugin/README.txt
@@ -0,0 +1,7 @@
+
+Running the Qpid Management Console (eclipse-plugin)
+----------------------------------------------------
+
+To run the management console, set the QPIDMC_HOME environment variable to
+qpid management console root directory (e.g. C:/qpidmc)and add $QPIDMC_HOME/bin to your PATH.
+Then run the qpidmc.bat batch file to launch the management console.
diff --git a/java/management/eclipse-plugin/bin/qpidmc.bat b/java/management/eclipse-plugin/bin/qpidmc.bat
new file mode 100644
index 0000000000..4ed55df644
--- /dev/null
+++ b/java/management/eclipse-plugin/bin/qpidmc.bat
@@ -0,0 +1,55 @@
+@REM
+@REM Licensed to the Apache Software Foundation (ASF) under one
+@REM or more contributor license agreements. See the NOTICE file
+@REM distributed with this work for additional information
+@REM regarding copyright ownership. The ASF licenses this file
+@REM to you under the Apache License, Version 2.0 (the
+@REM "License"); you may not use this file except in compliance
+@REM with the License. You may obtain a copy of the License at
+@REM
+@REM http://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing,
+@REM software distributed under the License is distributed on an
+@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@REM KIND, either express or implied. See the License for the
+@REM specific language governing permissions and limitations
+@REM under the License.
+@REM
+
+@echo off
+REM Script to run the Qpid Management Console
+
+rem Guess QPIDMC_HOME if not defined
+set CURRENT_DIR=%cd%
+if not "%QPIDMC_HOME%" == "" goto gotHome
+set QPIDMC_HOME=%CURRENT_DIR%
+echo %QPIDMC_HOME%
+if exist "%QPIDMC_HOME%\bin\qpidmc.bat" goto okHome
+cd ..
+set QPIDMC_HOME=%cd%
+cd %CURRENT_DIR%
+:gotHome
+if exist "%QPIDMC_HOME%\bin\qpidmc.bat" goto okHome
+echo The QPIDMC_HOME environment variable is not defined correctly
+echo This environment variable is needed to run this program
+goto end
+:okHome
+
+if not "%JAVA_HOME%" == "" goto gotJavaHome
+echo The JAVA_HOME environment variable is not defined
+echo This environment variable is needed to run this program
+goto exit
+:gotJavaHome
+if not exist "%JAVA_HOME%\bin\java.exe" goto noJavaHome
+goto okJavaHome
+:noJavaHome
+echo The JAVA_HOME environment variable is not defined correctly
+echo This environment variable is needed to run this program.
+goto exit
+:okJavaHome
+
+rem Slurp the command line arguments. This loop allows for an unlimited number
+rem of agruments (up to the command line limit, anyway).
+
+"%JAVA_HOME%\bin\java" -Xms40m -Xmx256m -Declipse.consoleLog=true -jar %QPIDMC_HOME%\startup.jar org.eclipse.core.launcher.Main -launcher %QPIDMC_HOME%\qpidmc.exe -name "Qpid Management Console" -showsplash 600 -data %QPIDMC_HOME%\data -configuration "file:%QPIDMC_HOME%/configuration" -os win32 -ws win32 -arch x86
diff --git a/java/management/eclipse-plugin/bin/qpidmc.sh b/java/management/eclipse-plugin/bin/qpidmc.sh
new file mode 100755
index 0000000000..aa99635d83
--- /dev/null
+++ b/java/management/eclipse-plugin/bin/qpidmc.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+"$JAVA_HOME/bin/java" -Xms40m -Xmx256m -Declipse.consoleLog=true -jar $QPIDMC_HOME/startup.jar org.eclipse.core.launcher.Main -launcher $QPIDMC_HOME/qpidmc.exe -name "Qpid Management Console" -showsplash 600 -data $QPIDMC_HOME/data -configuration "file:$QPIDMC_HOME/configuration" \ No newline at end of file
diff --git a/java/management/eclipse-plugin/icons/Thumbs.db b/java/management/eclipse-plugin/icons/Thumbs.db
new file mode 100644
index 0000000000..306bfb2eda
--- /dev/null
+++ b/java/management/eclipse-plugin/icons/Thumbs.db
Binary files differ
diff --git a/java/management/eclipse-plugin/icons/add.gif b/java/management/eclipse-plugin/icons/add.gif
new file mode 100644
index 0000000000..252d7ebcb8
--- /dev/null
+++ b/java/management/eclipse-plugin/icons/add.gif
Binary files differ
diff --git a/java/management/eclipse-plugin/icons/delete.gif b/java/management/eclipse-plugin/icons/delete.gif
new file mode 100644
index 0000000000..6f647666d3
--- /dev/null
+++ b/java/management/eclipse-plugin/icons/delete.gif
Binary files differ
diff --git a/java/management/eclipse-plugin/icons/icon_ClosedFolder.gif b/java/management/eclipse-plugin/icons/icon_ClosedFolder.gif
new file mode 100644
index 0000000000..beb6ed134c
--- /dev/null
+++ b/java/management/eclipse-plugin/icons/icon_ClosedFolder.gif
Binary files differ
diff --git a/java/management/eclipse-plugin/icons/icon_OpenFolder.gif b/java/management/eclipse-plugin/icons/icon_OpenFolder.gif
new file mode 100644
index 0000000000..a9c777343c
--- /dev/null
+++ b/java/management/eclipse-plugin/icons/icon_OpenFolder.gif
Binary files differ
diff --git a/java/management/eclipse-plugin/icons/mbean_view.png b/java/management/eclipse-plugin/icons/mbean_view.png
new file mode 100644
index 0000000000..9871b72bb8
--- /dev/null
+++ b/java/management/eclipse-plugin/icons/mbean_view.png
Binary files differ
diff --git a/java/management/eclipse-plugin/icons/notifications.gif b/java/management/eclipse-plugin/icons/notifications.gif
new file mode 100644
index 0000000000..f1e585bdf7
--- /dev/null
+++ b/java/management/eclipse-plugin/icons/notifications.gif
Binary files differ
diff --git a/java/management/eclipse-plugin/icons/qpidConnections.gif b/java/management/eclipse-plugin/icons/qpidConnections.gif
new file mode 100644
index 0000000000..89489f11f2
--- /dev/null
+++ b/java/management/eclipse-plugin/icons/qpidConnections.gif
Binary files differ
diff --git a/java/management/eclipse-plugin/icons/qpidmc.gif b/java/management/eclipse-plugin/icons/qpidmc.gif
new file mode 100644
index 0000000000..baf929fbc5
--- /dev/null
+++ b/java/management/eclipse-plugin/icons/qpidmc.gif
Binary files differ
diff --git a/java/management/eclipse-plugin/icons/qpidmc16.gif b/java/management/eclipse-plugin/icons/qpidmc16.gif
new file mode 100644
index 0000000000..4df535bb9a
--- /dev/null
+++ b/java/management/eclipse-plugin/icons/qpidmc16.gif
Binary files differ
diff --git a/java/management/eclipse-plugin/icons/qpidmc32.bmp b/java/management/eclipse-plugin/icons/qpidmc32.bmp
new file mode 100644
index 0000000000..e42ce01dff
--- /dev/null
+++ b/java/management/eclipse-plugin/icons/qpidmc32.bmp
Binary files differ
diff --git a/java/management/eclipse-plugin/icons/qpidmc32.gif b/java/management/eclipse-plugin/icons/qpidmc32.gif
new file mode 100644
index 0000000000..e42ce01dff
--- /dev/null
+++ b/java/management/eclipse-plugin/icons/qpidmc32.gif
Binary files differ
diff --git a/java/management/eclipse-plugin/icons/reconnect.gif b/java/management/eclipse-plugin/icons/reconnect.gif
new file mode 100644
index 0000000000..e2f8c3e1fe
--- /dev/null
+++ b/java/management/eclipse-plugin/icons/reconnect.gif
Binary files differ
diff --git a/java/management/eclipse-plugin/icons/refresh.gif b/java/management/eclipse-plugin/icons/refresh.gif
new file mode 100644
index 0000000000..a063c230ac
--- /dev/null
+++ b/java/management/eclipse-plugin/icons/refresh.gif
Binary files differ
diff --git a/java/management/eclipse-plugin/icons/splash.bmp b/java/management/eclipse-plugin/icons/splash.bmp
new file mode 100644
index 0000000000..b528a508c5
--- /dev/null
+++ b/java/management/eclipse-plugin/icons/splash.bmp
Binary files differ
diff --git a/java/management/eclipse-plugin/icons/stop.gif b/java/management/eclipse-plugin/icons/stop.gif
new file mode 100644
index 0000000000..dc47edf069
--- /dev/null
+++ b/java/management/eclipse-plugin/icons/stop.gif
Binary files differ
diff --git a/java/management/eclipse-plugin/plugin.properties b/java/management/eclipse-plugin/plugin.properties
new file mode 100644
index 0000000000..8507441886
--- /dev/null
+++ b/java/management/eclipse-plugin/plugin.properties
@@ -0,0 +1,20 @@
+###############################################################################
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+###############################################################################
+pluginName = Qpid Management Console Plug-in
+providerName = Apache Software Foundation \ No newline at end of file
diff --git a/java/management/eclipse-plugin/plugin.xml b/java/management/eclipse-plugin/plugin.xml
new file mode 100644
index 0000000000..bd7ae0a474
--- /dev/null
+++ b/java/management/eclipse-plugin/plugin.xml
@@ -0,0 +1,222 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.2"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<plugin>
+
+ <extension
+ id="application"
+ point="org.eclipse.core.runtime.applications">
+ <application>
+ <run
+ class="org.apache.qpid.management.ui.Application">
+ </run>
+ </application>
+ </extension>
+ <extension
+ point="org.eclipse.ui.perspectives">
+ <perspective
+ name="qpid.management.perspective"
+ class="org.apache.qpid.management.ui.Perspective"
+ id="org.apache.qpid.management.ui.perspective">
+ </perspective>
+ </extension>
+ <extension
+ point="org.eclipse.ui.views">
+ <category
+ id="org.apache.qpid.management.ui.viewcategory"
+ name="Qpid Management Console"/>
+ <view
+ allowMultiple="false"
+ category="org.apache.qpid.management.ui.viewcategory"
+ class="org.apache.qpid.management.ui.views.NavigationView"
+ icon="icons/qpidConnections.gif"
+ id="org.apache.qpid.management.ui.navigationView"
+ name="Qpid Connections">
+ </view>
+ <view
+ allowMultiple="false"
+ category="org.apache.qpid.management.ui.viewcategory"
+ class="org.apache.qpid.management.ui.views.MBeanView"
+ icon="icons/mbean_view.png"
+ id="org.apache.qpid.management.ui.mbeanView"
+ name="Qpid Management">
+ </view>
+ </extension>
+ <extension
+ point="org.eclipse.ui.commands">
+ <category
+ name="qpid.manager.commands"
+ id="org.apache.qpid.management.ui.category">
+ </category>
+ <command
+ name="New Connection"
+ description="Created a new Qpid server connection"
+ categoryId="org.apache.qpid.management.ui.category"
+ id="org.apache.qpid.management.ui.actions.cmd_add">
+ </command>
+ <command
+ categoryId="org.apache.qpid.management.ui.category"
+ description="Reconnect the Qpid server connection"
+ id="org.apache.qpid.management.ui.actions.cmd_reconnect"
+ name="Reconnect"/>
+ <command
+ categoryId="org.apache.qpid.management.ui.category"
+ description="Disconnects the Qpid server connection"
+ id="org.apache.qpid.management.ui.actions.cmd_disconnect"
+ name="Disconnect"/>
+ <command
+ categoryId="org.apache.qpid.management.ui.category"
+ description="Removes the server from management console"
+ id="org.apache.qpid.management.ui.actions.cmd_remove"
+ name="Remove Connection"/>
+ <command
+ categoryId="org.apache.qpid.management.ui.category"
+ description="refreshes the views"
+ id="org.apache.qpid.management.ui.actions.cmd_refresh"
+ name="Refresh"/>
+ <command
+ categoryId="org.apache.qpid.management.ui.category"
+ description="pops up the window for editing selected attribute"
+ id="org.apache.qpid.management.ui.actions.cmd_editAttribute"
+ name="Edit Attribute"/>
+ </extension>
+ <extension
+ point="org.eclipse.ui.bindings">
+ <key
+ commandId="org.apache.qpid.management.ui.actions.cmd_add"
+ schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"
+ sequence="CTRL+Alt+N">
+ </key>
+ <key
+ commandId="org.apache.qpid.management.ui.actions.cmd_reconnect"
+ schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"
+ sequence="CTRL+Alt+C"/>
+ <key
+ commandId="org.apache.qpid.management.ui.actions.cmd_disconnect"
+ schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"
+ sequence="CTRL+Alt+D">
+ </key>
+ <key
+ commandId="org.apache.qpid.management.ui.actions.cmd_remove"
+ schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"
+ sequence="CTRL+Alt+R"/>
+ <key
+ commandId="org.apache.qpid.management.ui.actions.cmd_refresh"
+ schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"
+ sequence="CTRL+Alt+F5"/>
+ <key
+ commandId="org.apache.qpid.management.ui.actions.cmd_editAttribute"
+ schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"
+ sequence="CTRL+Alt+E"/>
+ <key
+ commandId="org.eclipse.ui.file.exit"
+ schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"
+ sequence="CTRL+Alt+X">
+ </key>
+ </extension>
+
+ <extension
+ id="product"
+ point="org.eclipse.core.runtime.products">
+ <product
+ application="org.apache.qpid.management.ui.application"
+ name="Qpid Management Console">
+ <property
+ name="about Qpid Management Console"
+ value="version 0.1.0">
+ </property>
+ <property
+ name="windowImages"
+ value="icons/qpidmc16.gif,icons/qpidmc32.gif">
+ </property>
+ <property
+ name="aboutText"
+ value="Qpid Management Console&#x0A;version 0.1.0"/>
+ </product>
+ </extension>
+ <extension
+ point="org.eclipse.ui.actionSets">
+ <actionSet
+ id="org.apache.qpid.management.ui.actionSet"
+ label="Qpid Action Set"
+ visible="true">
+ <menu
+ id="qpidmanager"
+ label="&amp;Qpid Manager">
+ <separator name="qpidActionsGroup"/>
+ </menu>
+ <action
+ class="org.apache.qpid.management.ui.actions.EditAttribute"
+ definitionId="org.apache.qpid.management.ui.actions.cmd_editAttribute"
+ id="org.apache.qpid.management.ui.actions.editAttribute"
+ label="Edit Attribute"
+ menubarPath="qpidmanager/mbeanactions"
+ style="push"
+ tooltip="Edit Attribute"/>
+ <action
+ class="org.apache.qpid.management.ui.actions.Refresh"
+ definitionId="org.apache.qpid.management.ui.actions.cmd_refresh"
+ icon="icons/refresh.gif"
+ id="org.apache.qpid.management.ui.actions.refresh"
+ label="Refresh"
+ menubarPath="qpidmanager/additions"
+ style="push"
+ toolbarPath="qpidActionsGroup"
+ tooltip="Refresh"/>
+ <action
+ class="org.apache.qpid.management.ui.actions.RemoveServer"
+ definitionId="org.apache.qpid.management.ui.actions.cmd_remove"
+ icon="icons/delete.gif"
+ id="org.apache.qpid.management.ui.actions.remove"
+ label="Remove Connection"
+ menubarPath="qpidmanager/additions"
+ style="push"
+ toolbarPath="qpidActionsGroup"/>
+ <action
+ class="org.apache.qpid.management.ui.actions.CloseConnection"
+ definitionId="org.apache.qpid.management.ui.actions.cmd_disconnect"
+ icon="icons/stop.gif"
+ id="org.apache.qpid.management.ui.disconnect"
+ label="Disconnect"
+ menubarPath="qpidmanager/additions"
+ toolbarPath="qpidActionsGroup"
+ tooltip="Disconnect"/>
+ <action
+ class="org.apache.qpid.management.ui.actions.ReconnectServer"
+ definitionId="org.apache.qpid.management.ui.actions.cmd_reconnect"
+ icon="icons/reconnect.gif"
+ id="org.apache.qpid.management.ui.reconnect"
+ label="Reconnect"
+ menubarPath="qpidmanager/additions"
+ toolbarPath="qpidActionsGroup"
+ tooltip="Reconnect"/>
+ <action
+ class="org.apache.qpid.management.ui.actions.AddServer"
+ definitionId="org.apache.qpid.management.ui.actions.cmd_add"
+ icon="icons/add.gif"
+ id="org.apache.qpid.management.ui.add"
+ label="New Connection"
+ menubarPath="qpidmanager/additions"
+ toolbarPath="qpidActionsGroup"
+ tooltip="New Connection"/>
+ </actionSet>
+ </extension>
+
+</plugin>
diff --git a/java/management/eclipse-plugin/plugins/com.ibm.icu_3.4.4.1.jar b/java/management/eclipse-plugin/plugins/com.ibm.icu_3.4.4.1.jar
new file mode 100644
index 0000000000..c33f004a95
--- /dev/null
+++ b/java/management/eclipse-plugin/plugins/com.ibm.icu_3.4.4.1.jar
Binary files differ
diff --git a/java/management/eclipse-plugin/plugins/license.eclipse.txt b/java/management/eclipse-plugin/plugins/license.eclipse.txt
new file mode 100644
index 0000000000..da433e89f9
--- /dev/null
+++ b/java/management/eclipse-plugin/plugins/license.eclipse.txt
@@ -0,0 +1,88 @@
+Eclipse Public License - v 1.0
+
+THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
+
+1. DEFINITIONS
+
+"Contribution" means:
+
+a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and
+b) in the case of each subsequent Contributor:
+
+i) changes to the Program, and
+
+ii) additions to the Program;
+
+where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program.
+
+"Contributor" means any person or entity that distributes the Program.
+
+"Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program.
+
+"Program" means the Contributions distributed in accordance with this Agreement.
+
+"Recipient" means anyone who receives the Program under this Agreement, including all Contributors.
+
+2. GRANT OF RIGHTS
+
+a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form.
+
+b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder.
+
+c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program.
+
+d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement.
+
+3. REQUIREMENTS
+
+A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that:
+
+a) it complies with the terms and conditions of this Agreement; and
+
+b) its license agreement:
+
+i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose;
+
+ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits;
+
+iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and
+
+iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange.
+
+When the Program is made available in source code form:
+
+a) it must be made available under this Agreement; and
+
+b) a copy of this Agreement must be included with each copy of the Program.
+
+Contributors may not remove or alter any copyright notices contained within the Program.
+
+Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution.
+
+4. COMMERCIAL DISTRIBUTION
+
+Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense.
+
+For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages.
+
+5. NO WARRANTY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED 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. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement , including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations.
+
+6. DISCLAIMER OF LIABILITY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+7. GENERAL
+
+If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.
+
+If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed.
+
+All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive.
+
+Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved.
+
+This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation.
+
+
diff --git a/java/management/eclipse-plugin/plugins/org.eclipse.core.commands_3.2.0.jar b/java/management/eclipse-plugin/plugins/org.eclipse.core.commands_3.2.0.jar
new file mode 100644
index 0000000000..215f09bf12
--- /dev/null
+++ b/java/management/eclipse-plugin/plugins/org.eclipse.core.commands_3.2.0.jar
Binary files differ
diff --git a/java/management/eclipse-plugin/plugins/org.eclipse.core.contenttype_3.2.0.jar b/java/management/eclipse-plugin/plugins/org.eclipse.core.contenttype_3.2.0.jar
new file mode 100644
index 0000000000..f7f8e93d22
--- /dev/null
+++ b/java/management/eclipse-plugin/plugins/org.eclipse.core.contenttype_3.2.0.jar
Binary files differ
diff --git a/java/management/eclipse-plugin/plugins/org.eclipse.core.expressions_3.2.0.jar b/java/management/eclipse-plugin/plugins/org.eclipse.core.expressions_3.2.0.jar
new file mode 100644
index 0000000000..9672474250
--- /dev/null
+++ b/java/management/eclipse-plugin/plugins/org.eclipse.core.expressions_3.2.0.jar
Binary files differ
diff --git a/java/management/eclipse-plugin/plugins/org.eclipse.core.jobs_3.2.0.jar b/java/management/eclipse-plugin/plugins/org.eclipse.core.jobs_3.2.0.jar
new file mode 100644
index 0000000000..63ae34b87b
--- /dev/null
+++ b/java/management/eclipse-plugin/plugins/org.eclipse.core.jobs_3.2.0.jar
Binary files differ
diff --git a/java/management/eclipse-plugin/plugins/org.eclipse.core.runtime.compatibility.auth_3.2.0.jar b/java/management/eclipse-plugin/plugins/org.eclipse.core.runtime.compatibility.auth_3.2.0.jar
new file mode 100644
index 0000000000..9e1a33cfa9
--- /dev/null
+++ b/java/management/eclipse-plugin/plugins/org.eclipse.core.runtime.compatibility.auth_3.2.0.jar
Binary files differ
diff --git a/java/management/eclipse-plugin/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.0/META-INF/MANIFEST.MF b/java/management/eclipse-plugin/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.0/META-INF/MANIFEST.MF
new file mode 100644
index 0000000000..0e8c61f1b7
--- /dev/null
+++ b/java/management/eclipse-plugin/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.0/META-INF/MANIFEST.MF
@@ -0,0 +1,12 @@
+Manifest-Version: 1.0
+Bundle-Name: %fragmentName
+Bundle-ClassPath: runtime_registry_compatibility.jar
+Bundle-RequiredExecutionEnvironment: CDC-1.0/Foundation-1.0,J2SE-1.3
+Eclipse-PatchFragment: true
+Bundle-Vendor: %providerName
+Bundle-ManifestVersion: 2
+Fragment-Host: org.eclipse.equinox.registry
+Bundle-Localization: fragment
+Bundle-SymbolicName: org.eclipse.core.runtime.compatibility.registry
+Bundle-Version: 3.2.0.v20060603
+
diff --git a/java/management/eclipse-plugin/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.0/runtime_registry_compatibility.jar b/java/management/eclipse-plugin/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.0/runtime_registry_compatibility.jar
new file mode 100644
index 0000000000..aae3e74ad7
--- /dev/null
+++ b/java/management/eclipse-plugin/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.0/runtime_registry_compatibility.jar
Binary files differ
diff --git a/java/management/eclipse-plugin/plugins/org.eclipse.core.runtime_3.2.0.jar b/java/management/eclipse-plugin/plugins/org.eclipse.core.runtime_3.2.0.jar
new file mode 100644
index 0000000000..3834c9802c
--- /dev/null
+++ b/java/management/eclipse-plugin/plugins/org.eclipse.core.runtime_3.2.0.jar
Binary files differ
diff --git a/java/management/eclipse-plugin/plugins/org.eclipse.equinox.common_3.2.0.jar b/java/management/eclipse-plugin/plugins/org.eclipse.equinox.common_3.2.0.jar
new file mode 100644
index 0000000000..ee0e7865c2
--- /dev/null
+++ b/java/management/eclipse-plugin/plugins/org.eclipse.equinox.common_3.2.0.jar
Binary files differ
diff --git a/java/management/eclipse-plugin/plugins/org.eclipse.equinox.preferences_3.2.0.jar b/java/management/eclipse-plugin/plugins/org.eclipse.equinox.preferences_3.2.0.jar
new file mode 100644
index 0000000000..32f8e048dc
--- /dev/null
+++ b/java/management/eclipse-plugin/plugins/org.eclipse.equinox.preferences_3.2.0.jar
Binary files differ
diff --git a/java/management/eclipse-plugin/plugins/org.eclipse.equinox.registry_3.2.0.jar b/java/management/eclipse-plugin/plugins/org.eclipse.equinox.registry_3.2.0.jar
new file mode 100644
index 0000000000..1fe65676d5
--- /dev/null
+++ b/java/management/eclipse-plugin/plugins/org.eclipse.equinox.registry_3.2.0.jar
Binary files differ
diff --git a/java/management/eclipse-plugin/plugins/org.eclipse.help_3.2.0.jar b/java/management/eclipse-plugin/plugins/org.eclipse.help_3.2.0.jar
new file mode 100644
index 0000000000..809be21af0
--- /dev/null
+++ b/java/management/eclipse-plugin/plugins/org.eclipse.help_3.2.0.jar
Binary files differ
diff --git a/java/management/eclipse-plugin/plugins/org.eclipse.jface_3.2.0.jar b/java/management/eclipse-plugin/plugins/org.eclipse.jface_3.2.0.jar
new file mode 100644
index 0000000000..5c7509b07e
--- /dev/null
+++ b/java/management/eclipse-plugin/plugins/org.eclipse.jface_3.2.0.jar
Binary files differ
diff --git a/java/management/eclipse-plugin/plugins/org.eclipse.osgi_3.2.0.jar b/java/management/eclipse-plugin/plugins/org.eclipse.osgi_3.2.0.jar
new file mode 100644
index 0000000000..5f86e420d6
--- /dev/null
+++ b/java/management/eclipse-plugin/plugins/org.eclipse.osgi_3.2.0.jar
Binary files differ
diff --git a/java/management/eclipse-plugin/plugins/org.eclipse.swt.win32.win32.x86_3.2.0.jar b/java/management/eclipse-plugin/plugins/org.eclipse.swt.win32.win32.x86_3.2.0.jar
new file mode 100644
index 0000000000..392713689c
--- /dev/null
+++ b/java/management/eclipse-plugin/plugins/org.eclipse.swt.win32.win32.x86_3.2.0.jar
Binary files differ
diff --git a/java/management/eclipse-plugin/plugins/org.eclipse.swt_3.2.0.jar b/java/management/eclipse-plugin/plugins/org.eclipse.swt_3.2.0.jar
new file mode 100644
index 0000000000..7e1dbb85da
--- /dev/null
+++ b/java/management/eclipse-plugin/plugins/org.eclipse.swt_3.2.0.jar
Binary files differ
diff --git a/java/management/eclipse-plugin/plugins/org.eclipse.ui.forms_3.2.0.jar b/java/management/eclipse-plugin/plugins/org.eclipse.ui.forms_3.2.0.jar
new file mode 100644
index 0000000000..9c1bee69f4
--- /dev/null
+++ b/java/management/eclipse-plugin/plugins/org.eclipse.ui.forms_3.2.0.jar
Binary files differ
diff --git a/java/management/eclipse-plugin/plugins/org.eclipse.ui.workbench.compatibility_3.2.0/META-INF/MANIFEST.MF b/java/management/eclipse-plugin/plugins/org.eclipse.ui.workbench.compatibility_3.2.0/META-INF/MANIFEST.MF
new file mode 100644
index 0000000000..04a1db7c85
--- /dev/null
+++ b/java/management/eclipse-plugin/plugins/org.eclipse.ui.workbench.compatibility_3.2.0/META-INF/MANIFEST.MF
@@ -0,0 +1,12 @@
+Manifest-Version: 1.0
+Bundle-Name: %fragmentName
+Bundle-RequiredExecutionEnvironment: J2SE-1.4
+Bundle-Vendor: %providerName
+Bundle-ManifestVersion: 2
+Fragment-Host: org.eclipse.ui.workbench;bundle-version="[3.0.0,4.0.0)"
+Bundle-Localization: fragment-compatibility
+Bundle-SymbolicName: org.eclipse.ui.workbench.compatibility
+Require-Bundle: org.eclipse.core.resources;bundle-version="[3.2.0,4.0.
+ 0)"
+Bundle-Version: 3.2.0.I20060605-1400
+
diff --git a/java/management/eclipse-plugin/plugins/org.eclipse.ui.workbench.compatibility_3.2.0/compatibility.jar b/java/management/eclipse-plugin/plugins/org.eclipse.ui.workbench.compatibility_3.2.0/compatibility.jar
new file mode 100644
index 0000000000..13682c5d36
--- /dev/null
+++ b/java/management/eclipse-plugin/plugins/org.eclipse.ui.workbench.compatibility_3.2.0/compatibility.jar
Binary files differ
diff --git a/java/management/eclipse-plugin/plugins/org.eclipse.ui.workbench_3.2.0.jar b/java/management/eclipse-plugin/plugins/org.eclipse.ui.workbench_3.2.0.jar
new file mode 100644
index 0000000000..40e7d55f58
--- /dev/null
+++ b/java/management/eclipse-plugin/plugins/org.eclipse.ui.workbench_3.2.0.jar
Binary files differ
diff --git a/java/management/eclipse-plugin/plugins/org.eclipse.ui_3.2.0.jar b/java/management/eclipse-plugin/plugins/org.eclipse.ui_3.2.0.jar
new file mode 100644
index 0000000000..5821d85bac
--- /dev/null
+++ b/java/management/eclipse-plugin/plugins/org.eclipse.ui_3.2.0.jar
Binary files differ
diff --git a/java/management/eclipse-plugin/pom.xml b/java/management/eclipse-plugin/pom.xml
new file mode 100644
index 0000000000..71b2a08058
--- /dev/null
+++ b/java/management/eclipse-plugin/pom.xml
@@ -0,0 +1,216 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.qpid.management</groupId>
+ <artifactId>org.apache.qpid.management.ui</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0-incubating-M2-SNAPSHOT</version>
+ <name>Qpid Management</name>
+ <url>http://cwiki.apache.org/confluence/display/qpid</url>
+
+ <parent>
+ <groupId>org.apache.qpid</groupId>
+ <artifactId>qpid</artifactId>
+ <version>1.0-incubating-M2-SNAPSHOT</version>
+ </parent>
+
+ <properties>
+ <topDirectoryLocation>../../</topDirectoryLocation>
+ </properties>
+
+ <repositories>
+ <repository>
+ <id>repo1.maven.org</id>
+ <name>Maven eclipse Repository</name>
+ <url>http://repo1.maven.org/eclipse</url>
+ </repository>
+ <repository>
+ <id>apache.snapshots</id>
+ <name>Apache SNAPSHOT Repository</name>
+ <url>http://people.apache.org/repo/m2-snapshot-repository</url>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ </repository>
+ </repositories>
+
+ <dependencies>
+ <dependency>
+ <groupId>com.ibm.icu</groupId>
+ <artifactId>com.ibm.icu</artifactId>
+ <version>3.4.4</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.jface</groupId>
+ <artifactId>org.eclipse.jface</artifactId>
+ <version>3.2.0</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.core</groupId>
+ <artifactId>org.eclipse.core.commands</artifactId>
+ <version>3.2.0</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.core</groupId>
+ <artifactId>org.eclipse.core.contenttype</artifactId>
+ <version>3.2.0</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.core</groupId>
+ <artifactId>org.eclipse.core.expressions</artifactId>
+ <version>3.2.0</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.core</groupId>
+ <artifactId>org.eclipse.core.jobs</artifactId>
+ <version>3.2.0</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.core</groupId>
+ <artifactId>org.eclipse.core.runtime</artifactId>
+ <version>3.2.0</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.core</groupId>
+ <artifactId>org.eclipse.core.runtime.compatibility.auth</artifactId>
+ <version>3.2.0</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.core</groupId>
+ <artifactId>org.eclipse.core.runtime.compatibility.registry</artifactId>
+ <version>3.2.0</version>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.equinox</groupId>
+ <artifactId>org.eclipse.equinox.common</artifactId>
+ <version>3.2.0</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.equinox</groupId>
+ <artifactId>org.eclipse.equinox.preferences</artifactId>
+ <version>3.2.0</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.equinox</groupId>
+ <artifactId>org.eclipse.equinox.registry</artifactId>
+ <version>3.2.0</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.help</groupId>
+ <artifactId>org.eclipse.help</artifactId>
+ <version>3.2.0</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.osgi</groupId>
+ <artifactId>org.eclipse.osgi</artifactId>
+ <version>3.2.0</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.swt</groupId>
+ <artifactId>org.eclipse.swt.win32.win32.x86</artifactId>
+ <version>3.2.0</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.swt</groupId>
+ <artifactId>org.eclipse.swt</artifactId>
+ <version>3.2.0</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.ui</groupId>
+ <artifactId>org.eclipse.ui.forms</artifactId>
+ <version>3.2.0</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.ui</groupId>
+ <artifactId>org.eclipse.ui.workbench</artifactId>
+ <version>3.2.1</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.ui</groupId>
+ <artifactId>org.eclipse.ui</artifactId>
+ <version>3.2.0</version>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <resources>
+ <resource>
+ <directory>icons/</directory>
+ <targetPath>icons/</targetPath>
+ <includes>
+ <include>**</include>
+ </includes>
+ </resource>
+ <resource>
+ <directory>icons/</directory>
+ <targetPath>/</targetPath>
+ <includes>
+ <include>splash.bmp</include>
+ </includes>
+ </resource>
+ <resource>
+ <directory>${basedir}</directory>
+ <targetPath>/</targetPath>
+ <includes>
+ <include>plugin.xml</include>
+ <include>plugin.properties</include>
+ </includes>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <configuration>
+ <archive>
+ <manifestFile>META-INF/MANIFEST.MF</manifestFile>
+ </archive>
+ <finalName>${artifactId}_${version}</finalName>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Activator.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Activator.java
new file mode 100644
index 0000000000..61b6cfaa59
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Activator.java
@@ -0,0 +1,84 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * 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.apache.qpid.management.ui";
+
+ // The shared instance
+ private static Activator plugin;
+
+ /**
+ * The constructor
+ */
+ public Activator()
+ {
+ plugin = this;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext context) throws Exception
+ {
+ super.start(context);
+ }
+
+ /*
+ * (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;
+ }
+
+ /**
+ * Returns an image descriptor for the image file at the given
+ * plug-in relative path
+ *
+ * @param path the path
+ * @return the image descriptor
+ */
+ public static ImageDescriptor getImageDescriptor(String path) {
+ return imageDescriptorFromPlugin(PLUGIN_ID, path);
+ }
+}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Application.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Application.java
new file mode 100644
index 0000000000..3d014e6968
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Application.java
@@ -0,0 +1,63 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui;
+
+import org.eclipse.core.runtime.IPlatformRunnable;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * This class controls all aspects of the application's execution
+ * @author Bhupendra Bhardwaj
+ */
+public class Application implements IPlatformRunnable
+{
+ static Shell shell = null;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.core.runtime.IPlatformRunnable#run(java.lang.Object)
+ */
+ public Object run(Object args) throws Exception
+ {
+ Display display = PlatformUI.createDisplay();
+ try
+ {
+ int returnCode = PlatformUI.createAndRunWorkbench(display,
+ new ApplicationWorkbenchAdvisor());
+ if (returnCode == PlatformUI.RETURN_RESTART)
+ {
+ return IPlatformRunnable.EXIT_RESTART;
+ }
+ return IPlatformRunnable.EXIT_OK;
+ } finally
+ {
+ display.dispose();
+ }
+ }
+
+ static Shell getActiveShell()
+ {
+ return shell;
+ }
+}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationActionBarAdvisor.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationActionBarAdvisor.java
new file mode 100644
index 0000000000..9015b74f3f
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationActionBarAdvisor.java
@@ -0,0 +1,96 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui;
+
+import org.eclipse.jface.action.GroupMarker;
+import org.eclipse.jface.action.ICoolBarManager;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.ui.IWorkbenchActionConstants;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.actions.ActionFactory;
+import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction;
+import org.eclipse.ui.application.ActionBarAdvisor;
+import org.eclipse.ui.application.IActionBarConfigurer;
+
+/**
+ * An action bar advisor is responsible for creating, adding, and disposing of the
+ * actions added to a workbench window. Each window will be populated with
+ * new actions.
+ */
+public class ApplicationActionBarAdvisor extends ActionBarAdvisor
+{
+
+ // Actions - important to allocate these only in makeActions, and then use them
+ // in the fill methods. This ensures that the actions aren't recreated
+ // when fillActionBars is called with FILL_PROXY.
+ private IWorkbenchAction exitAction;
+ private IWorkbenchAction aboutAction;
+
+
+ public ApplicationActionBarAdvisor(IActionBarConfigurer configurer)
+ {
+ super(configurer);
+ }
+
+ protected void makeActions(final IWorkbenchWindow window)
+ {
+ // Creates the actions and registers them.
+ // Registering is needed to ensure that key bindings work.
+ // The corresponding commands keybindings are defined in the plugin.xml file.
+ // Registering also provides automatic disposal of the actions when
+ // the window is closed.
+
+ exitAction = ActionFactory.QUIT.create(window);
+ register(exitAction);
+
+ aboutAction = ActionFactory.ABOUT.create(window);
+ register(aboutAction);
+ }
+
+
+ protected void fillMenuBar(IMenuManager menuBar)
+ {
+ MenuManager fileMenu = new MenuManager("&Qpid Manager", "qpidmanager");
+ MenuManager helpMenu = new MenuManager("&Help", IWorkbenchActionConstants.M_HELP);
+
+ menuBar.add(fileMenu);
+ // Add a group marker indicating where action set menus will appear.
+ menuBar.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
+ menuBar.add(helpMenu);
+
+ fileMenu.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
+ fileMenu.add(new Separator());
+ fileMenu.add(new GroupMarker("mbeanactions"));
+ fileMenu.add(new Separator());
+ fileMenu.add(exitAction);
+
+ // Help
+ //aboutAction.setText("about Qpid Management Console");
+ helpMenu.add(aboutAction);
+ }
+
+ protected void fillCoolBar(ICoolBarManager coolBar)
+ {
+
+ }
+}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationRegistry.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationRegistry.java
new file mode 100644
index 0000000000..175130aea9
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationRegistry.java
@@ -0,0 +1,129 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.eclipse.jface.resource.FontRegistry;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.PlatformUI;
+
+public abstract class ApplicationRegistry
+{
+ private static ImageRegistry imageRegistry = new ImageRegistry();
+ private static FontRegistry fontRegistry = new FontRegistry();
+
+ static
+ {
+ imageRegistry.put(Constants.CONSOLE_IMAGE,
+ org.apache.qpid.management.ui.Activator.getImageDescriptor("/icons/qpidmc.gif"));
+ imageRegistry.put(Constants.CLOSED_FOLDER_IMAGE,
+ org.apache.qpid.management.ui.Activator.getImageDescriptor("/icons/icon_ClosedFolder.gif"));
+ imageRegistry.put(Constants.OPEN_FOLDER_IMAGE,
+ PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FOLDER));
+ imageRegistry.put(Constants.MBEAN_IMAGE,
+ PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_ELEMENT));
+ imageRegistry.put(Constants.NOTIFICATION_IMAGE,
+ org.apache.qpid.management.ui.Activator.getImageDescriptor("/icons/notifications.gif"));
+ }
+
+ static
+ {
+ fontRegistry.put(Constants.FONT_BUTTON, new FontData[]{new FontData("Arial", 8, SWT.BOLD)} );
+ fontRegistry.put(Constants.FONT_BOLD, new FontData[]{new FontData("Bold", 9, SWT.BOLD)} );
+ fontRegistry.put(Constants.FONT_ITALIC, new FontData[]{new FontData("Italic", 9, SWT.ITALIC)} );
+ fontRegistry.put(Constants.FONT_TABLE_CELL, new FontData[]{new FontData("Tablecell", 8, SWT.NORMAL)} );
+ fontRegistry.put(Constants.FONT_NORMAL, new FontData[]{new FontData("Normal", 9, SWT.NORMAL)} );
+ }
+
+ /*
+ * This maps all the managed servers to the respective server registry.
+ * Server can be JMX MBeanServer or a C++ server
+ */
+ private static HashMap<ManagedServer, ServerRegistry> _serverRegistryMap = new HashMap<ManagedServer, ServerRegistry>();
+
+ // This map gets updated when a server connection closes.
+ private static List<ManagedServer> _closedServerList = new CopyOnWriteArrayList<ManagedServer>();
+
+ public static Image getImage(String key)
+ {
+ return imageRegistry.get(key);
+ }
+
+ public static Font getFont(String key)
+ {
+ return fontRegistry.get(key);
+ }
+
+ public static void addServer(ManagedServer server, ServerRegistry registry)
+ {
+ _serverRegistryMap.put(server, registry);
+ }
+
+ public static void removeServer(ManagedServer server)
+ {
+ _serverRegistryMap.remove(server);
+ }
+
+ public static ServerRegistry getServerRegistry(ManagedServer server)
+ {
+ return _serverRegistryMap.get(server);
+ }
+
+ public static ServerRegistry getServerRegistry(ManagedBean mbean)
+ {
+ ManagedServer server = mbean.getServer();
+ return _serverRegistryMap.get(server);
+ }
+
+ public static boolean isServerConnected(ManagedServer server)
+ {
+ return _serverRegistryMap.containsKey(server);
+ }
+
+ // remove the server from the registry
+ public static void serverConnectionClosed(ManagedServer server)
+ {
+ _closedServerList.add(server);
+ _serverRegistryMap.remove(server);
+ }
+
+ /*
+ * Returns the lis of closed servers. The Thread in GUI, which keeps checking for closed connection
+ * will check this and will remove the server links from the GUI.
+ */
+ public static List<ManagedServer> getClosedServers()
+ {
+ if (_closedServerList.isEmpty())
+ return null;
+
+ List<ManagedServer> list = new CopyOnWriteArrayList<ManagedServer>(_closedServerList);
+ _closedServerList.clear();
+ return list;
+ }
+}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationWorkbenchAdvisor.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationWorkbenchAdvisor.java
new file mode 100644
index 0000000000..a46fa870e4
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationWorkbenchAdvisor.java
@@ -0,0 +1,46 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui;
+
+import org.eclipse.ui.application.IWorkbenchWindowConfigurer;
+import org.eclipse.ui.application.WorkbenchAdvisor;
+import org.eclipse.ui.application.WorkbenchWindowAdvisor;
+
+/**
+ * This workbench advisor creates the window advisor, and specifies
+ * the perspective id for the initial window.
+ */
+public class ApplicationWorkbenchAdvisor extends WorkbenchAdvisor
+{
+ public static final String PERSPECTIVE_ID = "org.apache.qpid.management.ui.perspective";
+
+ public WorkbenchWindowAdvisor createWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer configurer)
+ {
+ return new ApplicationWorkbenchWindowAdvisor(configurer);
+ }
+
+
+ public String getInitialWindowPerspectiveId()
+ {
+ return PERSPECTIVE_ID;
+ }
+
+}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationWorkbenchWindowAdvisor.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationWorkbenchWindowAdvisor.java
new file mode 100644
index 0000000000..472d003657
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationWorkbenchWindowAdvisor.java
@@ -0,0 +1,61 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui;
+
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.application.ActionBarAdvisor;
+import org.eclipse.ui.application.IActionBarConfigurer;
+import org.eclipse.ui.application.IWorkbenchWindowConfigurer;
+import org.eclipse.ui.application.WorkbenchWindowAdvisor;
+
+public class ApplicationWorkbenchWindowAdvisor extends WorkbenchWindowAdvisor
+{
+ public ApplicationWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer configurer)
+ {
+ super(configurer);
+ }
+
+ public ActionBarAdvisor createActionBarAdvisor(IActionBarConfigurer configurer)
+ {
+ return new ApplicationActionBarAdvisor(configurer);
+ }
+
+ public void preWindowOpen()
+ {
+ IWorkbenchWindowConfigurer configurer = getWindowConfigurer();
+ int x = Display.getDefault().getBounds().width;
+ int y = Display.getDefault().getBounds().height;
+ configurer.setInitialSize(new Point(4*x/5, 3*y/4));
+ configurer.setShowCoolBar(true);
+ configurer.setShowStatusLine(false);
+
+ configurer.setTitle("Qpid Management Console");
+ }
+
+ public void postWindowCreate()
+ {
+ IWorkbenchWindowConfigurer configurer = getWindowConfigurer();
+ Shell shell = configurer.getWindow().getShell();
+ shell.setImage(ApplicationRegistry.getImage(Constants.CONSOLE_IMAGE));
+ }
+} \ No newline at end of file
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Constants.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Constants.java
new file mode 100644
index 0000000000..1678cbac62
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Constants.java
@@ -0,0 +1,79 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui;
+
+public class Constants
+{
+ public final static String APPLICATION_NAME = "Qpid Management Console";
+ public final static String ITEM_VALUE = "value";
+ public final static String ITEM_TYPE = "type";
+ public final static String SERVER = "server";
+ public final static String DOMAIN = "domain";
+ public final static String TYPE = "mbeantype";
+ public final static String MBEAN = "mbean";
+ public final static String ATTRIBUTES = "Attributes";
+ public final static String NOTIFICATION = "Notifications";
+
+ public final static String ALL = "All";
+
+ public final static String NAVIGATION_ROOT = "Qpid Connections";
+ public final static String DESCRIPTION = " Description : ";
+
+ public final static String BROKER_MANAGER = "Broker_Manager";
+ public final static String QUEUE = "Queue";
+ public final static String EXCHANGE = "Exchange";
+ public final static String EXCHANGE_TYPE = "ExchangeType";
+ public final static String[] EXCHANGE_TYPE_VALUES = {"direct", "topic", "headers"};
+ public final static String CONNECTION ="Connection";
+
+ public final static String ACTION_ADDSERVER = "New Connection";
+
+
+ public final static String SUBSCRIBE_BUTTON = "Subscribe";
+ public final static String UNSUBSCRIBE_BUTTON = "Unsubscribe";
+
+ public final static String CONSOLE_IMAGE = "ConsoelImage";
+ public final static String CLOSED_FOLDER_IMAGE = "ClosedFolderImage";
+ public final static String OPEN_FOLDER_IMAGE = "OpenFolderImage";
+ public final static String MBEAN_IMAGE = "MBeanImage";
+ public final static String NOTIFICATION_IMAGE = "NotificationImage";
+
+ public final static String FONT_BUTTON = "ButtonFont";
+ public final static String FONT_BOLD = "BoldFont";
+ public final static String FONT_ITALIC = "ItalicFont";
+ public final static String FONT_TABLE_CELL = "TableCellFont";
+ public final static String FONT_NORMAL = "Normal";
+
+ public final static String BUTTON_DETAILS = "Details";
+ public final static String BUTTON_EDIT_ATTRIBUTE = "Edit Attribute";
+ public final static String BUTTON_REFRESH = "Refresh";
+ public final static String BUTTON_GRAPH = "Graph";
+ public final static int TIMER_INTERVAL = 5000;
+ public final static String BUTTON_EXECUTE = "Execute";
+ public final static String BUTTON_CLEAR = "Clear";
+ public final static String BUTTON_CONNECT = "Connect";
+ public final static String BUTTON_CANCEL = "Cancel";
+
+ public final static int OPERATION_IMPACT_INFO = 0;
+ public final static int OPERATION_IMPACT_ACTION = 1;
+ public final static int OPERATION_IMPACT_ACTIONINFO = 2;
+ public final static int OPERATION_IMPACT_UNKNOWN = 3;
+}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ICommandIds.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ICommandIds.java
new file mode 100644
index 0000000000..12dea649c6
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ICommandIds.java
@@ -0,0 +1,36 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui;
+
+/**
+ * Interface defining the application's command IDs.
+ * Key bindings can be defined for specific commands.
+ * To associate an action with a command, use IAction.setActionDefinitionId(commandId).
+ *
+ * @see org.eclipse.jface.action.IAction#setActionDefinitionId(String)
+ */
+public interface ICommandIds
+{
+ //public static final String CMD_ADD_SERVER = "org.apache.qpid.management.ui.add";
+ //public static final String CMD_RECONNECT_SERVER = "org.apache.qpid.management.ui.reconnect";
+ //public static final String CMD_DISCONNECT_SERVER = "org.apache.qpid.management.ui.disconnect";
+ //public static final String CMD_REFRESH = "org.apache.qpid.management.ui.actions.refresh";
+}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedBean.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedBean.java
new file mode 100644
index 0000000000..767fd8b721
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedBean.java
@@ -0,0 +1,80 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui;
+
+import java.util.HashMap;
+
+public abstract class ManagedBean extends ManagedObject
+{
+ private String _uniqueName = "";
+ private String _domain = "";
+ private String _type = "";
+ private ManagedServer _server = null;
+ private HashMap _properties = null;
+
+ public String getProperty(String key)
+ {
+ return (String)_properties.get(key);
+ }
+
+ public HashMap getProperties()
+ {
+ return _properties;
+ }
+ public void setProperties(HashMap properties)
+ {
+ this._properties = properties;
+ }
+ public String getDomain()
+ {
+ return _domain;
+ }
+ public void setDomain(String domain)
+ {
+ this._domain = domain;
+ }
+
+ public ManagedServer getServer()
+ {
+ return _server;
+ }
+ public void setServer(ManagedServer server)
+ {
+ this._server = server;
+ }
+ public String getType()
+ {
+ return _type;
+ }
+ public void setType(String type)
+ {
+ this._type = type;
+ }
+ public String getUniqueName()
+ {
+ return _uniqueName;
+ }
+ public void setUniqueName(String uniqueName)
+ {
+ this._uniqueName = uniqueName;
+ }
+
+}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedObject.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedObject.java
new file mode 100644
index 0000000000..2ed463bdf8
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedObject.java
@@ -0,0 +1,36 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui;
+
+public abstract class ManagedObject
+{
+ private String _name;
+
+ public String getName()
+ {
+ return _name;
+ }
+
+ public void setName(String name)
+ {
+ this._name = name;
+ }
+}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedServer.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedServer.java
new file mode 100644
index 0000000000..44f933a5d1
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedServer.java
@@ -0,0 +1,75 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui;
+
+public class ManagedServer extends ManagedObject
+{
+ private String host;
+ private String port;
+ private String url;
+ private String domain;
+
+ public ManagedServer(String host, String port, String domain)
+ {
+ this.host = host;
+ this.port = port;
+ this.domain = domain;
+ setName(host + ":" + port);
+ }
+
+ public ManagedServer(String url, String domain)
+ {
+ this.url = url;
+ this.domain = domain;
+ }
+
+ public String getDomain()
+ {
+ return domain;
+ }
+
+ public String getHost()
+ {
+ return host;
+ }
+
+ public String getPort()
+ {
+ return port;
+ }
+
+ public String getUrl()
+ {
+ return url;
+ }
+
+ public void setHostAndPort(String host, String port)
+ {
+ this.host = host;
+ this.port = port;
+ setName(host + ":" + port);
+ }
+
+ public void setUrl(String url)
+ {
+ this.url = url;
+ }
+}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Perspective.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Perspective.java
new file mode 100644
index 0000000000..03477cb117
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Perspective.java
@@ -0,0 +1,53 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui;
+
+import org.apache.qpid.management.ui.views.MBeanView;
+import org.apache.qpid.management.ui.views.NavigationView;
+import org.eclipse.ui.IPageLayout;
+import org.eclipse.ui.IPerspectiveFactory;
+
+public class Perspective implements IPerspectiveFactory
+{
+ public void createInitialLayout(IPageLayout layout)
+ {
+ String editorArea = layout.getEditorArea();
+ layout.setEditorAreaVisible(false);
+
+ // standalone view meaning it can't be docked or stacked with other views,
+ // and it doesn't have a title bar.
+
+ layout.addStandaloneView(NavigationView.ID,
+ true,
+ IPageLayout.LEFT,
+ 0.25f,
+ editorArea);
+
+ layout.addStandaloneView(MBeanView.ID,
+ true,
+ IPageLayout.RIGHT,
+ 0.75f,
+ editorArea);
+
+ layout.getViewLayout(NavigationView.ID).setCloseable(false);
+ layout.getViewLayout(MBeanView.ID).setCloseable(false);
+ }
+}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ServerRegistry.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ServerRegistry.java
new file mode 100644
index 0000000000..0beeda84dd
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ServerRegistry.java
@@ -0,0 +1,79 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui;
+
+
+import java.util.List;
+
+import org.apache.qpid.management.ui.jmx.ClientListener;
+import org.apache.qpid.management.ui.model.NotificationObject;
+import org.apache.qpid.management.ui.model.OperationDataModel;
+
+public abstract class ServerRegistry
+{
+ private ManagedServer _managedServer = null;
+
+ public ServerRegistry()
+ {
+
+ }
+
+ public ServerRegistry(ManagedServer server)
+ {
+ _managedServer = server;
+ }
+
+ public ManagedServer getManagedServer()
+ {
+ return _managedServer;
+ }
+
+ public void setManagedServer(ManagedServer server)
+ {
+ _managedServer = server;
+ }
+
+ public abstract Object getServerConnection();
+
+ public abstract void closeServerConnection() throws Exception;
+
+ public abstract OperationDataModel getOperationModel(ManagedBean mbean);
+
+ public abstract String[] getQueueNames();
+
+ public abstract String[] getExchangeNames();
+
+ public abstract List<NotificationObject> getNotifications(ManagedBean mbean);
+
+ public abstract boolean hasSubscribedForNotifications(ManagedBean mbean, String name, String type);
+
+ public abstract void clearNotifications(ManagedBean mbean);
+
+ public ClientListener getNotificationListener()
+ {
+ return null;
+ }
+
+ public ClientListener getClientListener()
+ {
+ return null;
+ }
+}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/AddServer.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/AddServer.java
new file mode 100644
index 0000000000..14c214ad5f
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/AddServer.java
@@ -0,0 +1,282 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui.actions;
+
+import org.apache.qpid.management.ui.ApplicationRegistry;
+import org.apache.qpid.management.ui.ApplicationWorkbenchAdvisor;
+import org.apache.qpid.management.ui.Constants;
+import org.apache.qpid.management.ui.exceptions.InfoRequiredException;
+import org.apache.qpid.management.ui.views.NavigationView;
+import org.apache.qpid.management.ui.views.ViewUtility;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.VerifyEvent;
+import org.eclipse.swt.events.VerifyListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.IWorkbenchWindowActionDelegate;
+
+public class AddServer/* extends Action*/ implements IWorkbenchWindowActionDelegate
+{
+ private IWorkbenchWindow _window;
+ private static final String[] _connectionTypes ={"RMI"};
+ private static final String[] _domains ={"org.apache.qpid"};
+
+ public AddServer()
+ {
+
+ }
+
+ /*
+ public AddServer(IWorkbenchWindow window)//, String label)
+ {
+ _window = window;
+ //setText(label);
+ // The id is used to refer to the action in a menu or toolbar
+ setId(ICommandIds.CMD_ADD_SERVER);
+ // Associate the action with a pre-defined command, to allow key bindings.
+ setActionDefinitionId(ICommandIds.CMD_ADD_SERVER);
+ //setImageDescriptor(org.apache.qpid.management.ui.Activator.getImageDescriptor("/icons/add.gif"));
+ }
+ */
+
+ public void run(IAction action)
+ {
+ if(_window != null)
+ {
+ try
+ {
+ // TODO
+ //_window.getActivePage().showView(NavigationView.ID, Integer.toString(0), IWorkbenchPage.VIEW_ACTIVATE);
+ //_window.getActivePage().showView(MBeanView.ID, Integer.toString(0), IWorkbenchPage.VIEW_ACTIVATE);
+ }
+ catch (Exception ex)
+ {
+
+ }
+ createWidgets();
+ }
+ }
+
+ /**
+ * Selection in the workbench has been changed. We
+ * can change the state of the 'real' action here
+ * if we want, but this can only happen after
+ * the delegate has been created.
+ * @see IWorkbenchWindowActionDelegate#selectionChanged
+ */
+ public void selectionChanged(IAction action, ISelection selection) {
+ }
+
+ /**
+ * We can use this method to dispose of any system
+ * resources we previously allocated.
+ * @see IWorkbenchWindowActionDelegate#dispose
+ */
+ public void dispose() {
+ }
+
+ /**
+ * We will cache window object in order to
+ * be able to provide parent shell for the message dialog.
+ * @see IWorkbenchWindowActionDelegate#init
+ */
+ public void init(IWorkbenchWindow window) {
+ this._window = window;
+ }
+
+
+ /*
+ public void run()
+ {
+ if(_window != null)
+ {
+ createWidgets();
+ }
+ }
+ */
+ private void createWidgets()
+ {
+ Display display = Display.getCurrent();
+ final Shell shell = new Shell(display, SWT.BORDER | SWT.CLOSE);
+ shell.setText(Constants.ACTION_ADDSERVER);
+ shell.setLayout(new GridLayout());
+
+ int x = display.getBounds().width;
+ int y = display.getBounds().height;
+ shell.setBounds(x/4, y/4, 425, 250);
+
+ Composite composite = new Composite(shell, SWT.NONE);
+ composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ GridLayout layout = new GridLayout(2, false);
+ layout.horizontalSpacing = 10;
+ layout.verticalSpacing = 10;
+ layout.marginHeight = 20;
+ layout.marginWidth = 20;
+ composite.setLayout(layout);
+
+ Label name = new Label(composite, SWT.NONE);
+ name.setText("Connection Type");
+ GridData layoutData = new GridData(SWT.TRAIL, SWT.TOP, false, false);
+ name.setLayoutData(layoutData);
+
+ final Combo comboTransport = new Combo(composite, SWT.READ_ONLY);
+ comboTransport.setItems(_connectionTypes);
+ comboTransport.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+ comboTransport.select(0);
+
+ Label host = new Label(composite, SWT.NONE);
+ host.setText("Host");
+ host.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, false, false));
+
+ final Text textHost = new Text(composite, SWT.BORDER);
+ textHost.setText("");
+ textHost.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+ textHost.setFocus();
+ textHost.addVerifyListener(new VerifyListener(){
+ public void verifyText(VerifyEvent event)
+ {
+ if (!(Character.isLetterOrDigit(event.character) ||
+ (event.character == '.') ||
+ (event.character == '\b') ))
+ {
+ event.doit = false;
+ }
+ }
+ });
+
+
+ Label port = new Label(composite, SWT.NONE);
+ port.setText("Port");
+ port.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, false, false));
+
+ final Text textPort = new Text(composite, SWT.BORDER);
+ textPort.setText("");
+ textPort.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+ textPort.addVerifyListener(new VerifyListener(){
+ public void verifyText(VerifyEvent event)
+ {
+ if (textPort.getText().length() == 4)
+ event.doit = false;
+ else if (!(Character.isDigit(event.character) ||
+ (event.character == '\b')))
+ {
+ event.doit = false;
+ }
+ }
+ });
+
+
+ Label domain = new Label(composite, SWT.NONE);
+ domain.setText("Domain");
+ domain.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, false, false));
+
+ final Combo comboDomain = new Combo(composite, SWT.DROP_DOWN | SWT.READ_ONLY);
+ comboDomain.setItems(_domains);
+ comboDomain.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+ comboDomain.select(0);
+
+ Composite buttonsComposite = new Composite(composite, SWT.NONE);
+ buttonsComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
+ buttonsComposite.setLayout(new GridLayout(2, true));
+
+
+ final Button connectButton = new Button(buttonsComposite, SWT.PUSH | SWT.CENTER);
+ connectButton.setText(Constants.BUTTON_CONNECT);
+ GridData gridData = new GridData (SWT.TRAIL, SWT.BOTTOM, true, true);
+ gridData.widthHint = 100;
+ connectButton.setLayoutData(gridData);
+ connectButton.setFont(ApplicationRegistry.getFont(Constants.FONT_BUTTON));
+ connectButton.addSelectionListener(new SelectionAdapter(){
+ public void widgetSelected(SelectionEvent event)
+ {
+ String transport = comboTransport.getText();
+ String host = textHost.getText();
+ String port = textPort.getText();
+ String domain = comboDomain.getText();
+
+ NavigationView view = (NavigationView)_window.getActivePage().findView(NavigationView.ID);
+ try
+ {
+ view.addNewServer(transport, host, port, domain);
+
+ if (!connectButton.getShell().isDisposed())
+ connectButton.getShell().dispose();
+ }
+ catch(InfoRequiredException ex)
+ {
+ ViewUtility.popupInfoMessage("New connection", ex.getMessage());
+ }
+ catch(Exception ex)
+ {
+ IStatus status = new Status(IStatus.ERROR, ApplicationWorkbenchAdvisor.PERSPECTIVE_ID,
+ IStatus.OK, ex.getMessage(), ex.getCause());
+ ErrorDialog.openError(shell, "Error", "Server could not be added", status);
+ }
+ }
+ });
+
+ final Button cancelButton = new Button(buttonsComposite, SWT.PUSH);
+ cancelButton.setText(Constants.BUTTON_CANCEL);
+ gridData = new GridData (SWT.LEAD, SWT.BOTTOM, true, true);
+ gridData.widthHint = 100;
+ cancelButton.setLayoutData(gridData);
+ cancelButton.setFont(ApplicationRegistry.getFont(Constants.FONT_BUTTON));
+ cancelButton.addSelectionListener(new SelectionAdapter(){
+ public void widgetSelected(SelectionEvent event)
+ {
+ shell.dispose();
+ }
+ });
+
+ shell.open();
+ _window.getShell().setEnabled(false);
+ while (!shell.isDisposed())
+ {
+ if (!display.readAndDispatch())
+ {
+ display.sleep();
+ }
+ }
+
+ //If you create it, you dispose it.
+ shell.dispose();
+
+ // enable the main shell
+ _window.getShell().setEnabled(true);
+ _window.getShell().open();
+ }
+
+}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/CloseConnection.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/CloseConnection.java
new file mode 100644
index 0000000000..3f44274a92
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/CloseConnection.java
@@ -0,0 +1,93 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui.actions;
+
+import org.apache.qpid.management.ui.ApplicationWorkbenchAdvisor;
+import org.apache.qpid.management.ui.exceptions.InfoRequiredException;
+import org.apache.qpid.management.ui.views.NavigationView;
+import org.apache.qpid.management.ui.views.ViewUtility;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.IWorkbenchWindowActionDelegate;
+
+public class CloseConnection implements IWorkbenchWindowActionDelegate
+{
+ private IWorkbenchWindow _window;
+
+ public CloseConnection()
+ {
+
+ }
+
+ public void run(IAction action)
+ {
+ if(_window != null)
+ {
+ NavigationView view = (NavigationView)_window.getActivePage().findView(NavigationView.ID);
+ try
+ {
+ view.disconnect();
+ }
+ catch(InfoRequiredException ex)
+ {
+ ViewUtility.popupInfoMessage("Close connection", ex.getMessage());
+ }
+ catch(Exception ex)
+ {
+ IStatus status = new Status(IStatus.ERROR, ApplicationWorkbenchAdvisor.PERSPECTIVE_ID,
+ IStatus.OK, ex.getMessage(), ex.getCause());
+ ErrorDialog.openError(_window.getShell(), "Error", "Server could not be removed", status);
+ }
+ }
+ }
+
+ /**
+ * Selection in the workbench has been changed. We
+ * can change the state of the 'real' action here
+ * if we want, but this can only happen after
+ * the delegate has been created.
+ * @see IWorkbenchWindowActionDelegate#selectionChanged
+ */
+ public void selectionChanged(IAction action, ISelection selection) {
+ }
+
+ /**
+ * We can use this method to dispose of any system
+ * resources we previously allocated.
+ * @see IWorkbenchWindowActionDelegate#dispose
+ */
+ public void dispose() {
+ }
+
+ /**
+ * We will cache window object in order to
+ * be able to provide parent shell for the message dialog.
+ * @see IWorkbenchWindowActionDelegate#init
+ */
+ public void init(IWorkbenchWindow window) {
+ this._window = window;
+ }
+
+}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/EditAttribute.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/EditAttribute.java
new file mode 100644
index 0000000000..0030330b06
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/EditAttribute.java
@@ -0,0 +1,87 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui.actions;
+
+import org.apache.qpid.management.ui.ApplicationWorkbenchAdvisor;
+import org.apache.qpid.management.ui.exceptions.InfoRequiredException;
+import org.apache.qpid.management.ui.views.MBeanView;
+import org.apache.qpid.management.ui.views.ViewUtility;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.IWorkbenchWindowActionDelegate;
+
+public class EditAttribute implements IWorkbenchWindowActionDelegate
+{
+ private IWorkbenchWindow _window;
+
+ public void run(IAction action)
+ {
+ if(_window != null)
+ {
+ MBeanView view = (MBeanView)_window.getActivePage().findView(MBeanView.ID);
+ try
+ {
+ view.editAttribute();
+ }
+ catch(InfoRequiredException ex)
+ {
+ ViewUtility.popupInfoMessage("Edit Attribute", ex.getMessage());
+ }
+ catch(Exception ex)
+ {
+ IStatus status = new Status(IStatus.ERROR, ApplicationWorkbenchAdvisor.PERSPECTIVE_ID,
+ IStatus.OK, ex.getMessage(), ex.getCause());
+ ErrorDialog.openError(_window.getShell(), "Error", "Attribute could not be edited", status);
+ }
+ }
+ }
+
+ /**
+ * Selection in the workbench has been changed. We
+ * can change the state of the 'real' action here
+ * if we want, but this can only happen after
+ * the delegate has been created.
+ * @see IWorkbenchWindowActionDelegate#selectionChanged
+ */
+ public void selectionChanged(IAction action, ISelection selection) {
+ }
+
+ /**
+ * We can use this method to dispose of any system
+ * resources we previously allocated.
+ * @see IWorkbenchWindowActionDelegate#dispose
+ */
+ public void dispose() {
+ }
+
+ /**
+ * We will cache window object in order to
+ * be able to provide parent shell for the message dialog.
+ * @see IWorkbenchWindowActionDelegate#init
+ */
+ public void init(IWorkbenchWindow window) {
+ this._window = window;
+ }
+}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/ReconnectServer.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/ReconnectServer.java
new file mode 100644
index 0000000000..25337f3fbe
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/ReconnectServer.java
@@ -0,0 +1,92 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui.actions;
+
+import org.apache.qpid.management.ui.ApplicationWorkbenchAdvisor;
+import org.apache.qpid.management.ui.exceptions.InfoRequiredException;
+import org.apache.qpid.management.ui.views.NavigationView;
+import org.apache.qpid.management.ui.views.ViewUtility;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.IWorkbenchWindowActionDelegate;
+
+public class ReconnectServer implements IWorkbenchWindowActionDelegate
+{
+ private IWorkbenchWindow _window;
+
+ /**
+ * Selection in the workbench has been changed. We
+ * can change the state of the 'real' action here
+ * if we want, but this can only happen after
+ * the delegate has been created.
+ * @see IWorkbenchWindowActionDelegate#selectionChanged
+ */
+ public void selectionChanged(IAction action, ISelection selection)
+ {
+
+ }
+
+ /**
+ * We can use this method to dispose of any system
+ * resources we previously allocated.
+ * @see IWorkbenchWindowActionDelegate#dispose
+ */
+ public void dispose()
+ {
+
+ }
+
+ /**
+ * We will cache window object in order to
+ * be able to provide parent shell for the message dialog.
+ * @see IWorkbenchWindowActionDelegate#init
+ */
+ public void init(IWorkbenchWindow window)
+ {
+ this._window = window;
+ }
+
+ public void run(IAction action)
+ {
+ if(_window != null)
+ {
+ NavigationView view = (NavigationView)_window.getActivePage().findView(NavigationView.ID);
+ try
+ {
+ view.reconnect();
+ }
+ catch(InfoRequiredException ex)
+ {
+ ViewUtility.popupInfoMessage("Reconnect Qpid server", ex.getMessage());
+ }
+ catch(Exception ex)
+ {
+ IStatus status = new Status(IStatus.ERROR, ApplicationWorkbenchAdvisor.PERSPECTIVE_ID,
+ IStatus.OK, ex.getMessage(), ex.getCause());
+ ErrorDialog.openError(_window.getShell(), "Error", "Server could not be connected", status);
+ }
+ }
+ }
+}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/Refresh.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/Refresh.java
new file mode 100644
index 0000000000..85b312cf99
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/Refresh.java
@@ -0,0 +1,77 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui.actions;
+
+import org.apache.qpid.management.ui.views.MBeanView;
+import org.apache.qpid.management.ui.views.NavigationView;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.IWorkbenchWindowActionDelegate;
+
+public class Refresh implements IWorkbenchWindowActionDelegate
+{
+ private IWorkbenchWindow _window;
+
+ /**
+ * Selection in the workbench has been changed. We
+ * can change the state of the 'real' action here
+ * if we want, but this can only happen after
+ * the delegate has been created.
+ * @see IWorkbenchWindowActionDelegate#selectionChanged
+ */
+ public void selectionChanged(IAction action, ISelection selection)
+ {
+
+ }
+
+ /**
+ * We can use this method to dispose of any system
+ * resources we previously allocated.
+ * @see IWorkbenchWindowActionDelegate#dispose
+ */
+ public void dispose()
+ {
+
+ }
+
+ /**
+ * We will cache window object in order to
+ * be able to provide parent shell for the message dialog.
+ * @see IWorkbenchWindowActionDelegate#init
+ */
+ public void init(IWorkbenchWindow window)
+ {
+ this._window = window;
+ }
+
+ public void run(IAction action)
+ {
+ if(_window != null)
+ {
+ NavigationView view = (NavigationView)_window.getActivePage().findView(NavigationView.ID);
+ view.refresh();
+
+ MBeanView mbeanview = (MBeanView)_window.getActivePage().findView(MBeanView.ID);
+ mbeanview.refreshMBeanView();
+ }
+ }
+}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/RemoveServer.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/RemoveServer.java
new file mode 100644
index 0000000000..189f0f811b
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/RemoveServer.java
@@ -0,0 +1,92 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui.actions;
+
+import org.apache.qpid.management.ui.ApplicationWorkbenchAdvisor;
+import org.apache.qpid.management.ui.exceptions.InfoRequiredException;
+import org.apache.qpid.management.ui.views.NavigationView;
+import org.apache.qpid.management.ui.views.ViewUtility;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.IWorkbenchWindowActionDelegate;
+
+public class RemoveServer implements IWorkbenchWindowActionDelegate
+{
+ private IWorkbenchWindow _window;
+
+ /**
+ * Selection in the workbench has been changed. We
+ * can change the state of the 'real' action here
+ * if we want, but this can only happen after
+ * the delegate has been created.
+ * @see IWorkbenchWindowActionDelegate#selectionChanged
+ */
+ public void selectionChanged(IAction action, ISelection selection)
+ {
+
+ }
+
+ /**
+ * We can use this method to dispose of any system
+ * resources we previously allocated.
+ * @see IWorkbenchWindowActionDelegate#dispose
+ */
+ public void dispose()
+ {
+
+ }
+
+ /**
+ * We will cache window object in order to
+ * be able to provide parent shell for the message dialog.
+ * @see IWorkbenchWindowActionDelegate#init
+ */
+ public void init(IWorkbenchWindow window)
+ {
+ this._window = window;
+ }
+
+ public void run(IAction action)
+ {
+ if(_window != null)
+ {
+ NavigationView view = (NavigationView)_window.getActivePage().findView(NavigationView.ID);
+ try
+ {
+ view.removeServer();
+ }
+ catch(InfoRequiredException ex)
+ {
+ ViewUtility.popupInfoMessage("Remove Qpid server", ex.getMessage());
+ }
+ catch(Exception ex)
+ {
+ IStatus status = new Status(IStatus.ERROR, ApplicationWorkbenchAdvisor.PERSPECTIVE_ID,
+ IStatus.OK, ex.getMessage(), ex.getCause());
+ ErrorDialog.openError(_window.getShell(), "Error", "Server could not be removed", status);
+ }
+ }
+ }
+}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/exceptions/InfoRequiredException.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/exceptions/InfoRequiredException.java
new file mode 100644
index 0000000000..672426a59d
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/exceptions/InfoRequiredException.java
@@ -0,0 +1,36 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui.exceptions;
+
+public class InfoRequiredException extends Exception
+{
+ private static final long serialVersionUID = 1L;
+
+ public InfoRequiredException(String message)
+ {
+ super(message);
+ }
+
+ public InfoRequiredException(String msg, Throwable t)
+ {
+ super(msg, t);
+ }
+}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientListener.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientListener.java
new file mode 100644
index 0000000000..00a9ae7653
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientListener.java
@@ -0,0 +1,77 @@
+
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */package org.apache.qpid.management.ui.jmx;
+
+import javax.management.MBeanServerNotification;
+import javax.management.Notification;
+import javax.management.NotificationListener;
+import javax.management.ObjectName;
+import javax.management.remote.JMXConnectionNotification;
+
+import org.apache.qpid.management.ui.ApplicationRegistry;
+import org.apache.qpid.management.ui.ManagedServer;
+
+
+public class ClientListener implements NotificationListener
+{
+ protected ManagedServer server = null;
+ protected JMXServerRegistry serverRegistry = null;
+
+ public ClientListener(ManagedServer server)
+ {
+ this.server = server;
+ serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(server);
+ }
+
+ public void handleNotification(Notification notification, Object handback)
+ {
+ System.out.println("\nReceived server notification: " + notification);
+
+ ObjectName objName = null;
+ String type = notification.getType();
+ if (MBeanServerNotification.REGISTRATION_NOTIFICATION.equals(type))
+ {
+ objName = ((MBeanServerNotification)notification).getMBeanName();
+ getServerRegistry().registerManagedObject(objName);
+ }
+ else if (MBeanServerNotification.UNREGISTRATION_NOTIFICATION.equals(type))
+ {
+ objName = ((MBeanServerNotification)notification).getMBeanName();
+ getServerRegistry().unregisterManagedObject(objName);
+ }
+ else if (JMXConnectionNotification.FAILED.equals(type))
+ {
+ ApplicationRegistry.serverConnectionClosed(server);
+ }
+ }
+
+ protected JMXServerRegistry getServerRegistry()
+ {
+ if (serverRegistry == null)
+ serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(server);
+
+ return serverRegistry;
+ }
+ public ManagedServer getServer()
+ {
+ return server;
+ }
+}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientNotificationListener.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientNotificationListener.java
new file mode 100644
index 0000000000..31b761fcf3
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientNotificationListener.java
@@ -0,0 +1,42 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui.jmx;
+
+import javax.management.Notification;
+import javax.management.ObjectName;
+
+import org.apache.qpid.management.ui.ManagedServer;
+
+public class ClientNotificationListener extends ClientListener
+{
+ public ClientNotificationListener(ManagedServer server)
+ {
+ super(server);
+ }
+
+ public void handleNotification(Notification notification, Object handback)
+ {
+ System.out.println("\nReceived mbean notification: " + notification);
+ ObjectName objName = (ObjectName)notification.getSource();
+ //String type = notification.getType();
+ getServerRegistry().addNotification(objName, notification);
+ }
+}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXManagedObject.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXManagedObject.java
new file mode 100644
index 0000000000..dd665eabb3
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXManagedObject.java
@@ -0,0 +1,50 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui.jmx;
+
+import java.util.HashMap;
+
+import javax.management.ObjectName;
+
+import org.apache.qpid.management.ui.ManagedBean;
+
+
+public class JMXManagedObject extends ManagedBean
+{
+ private ObjectName _objName;
+
+ @SuppressWarnings("unchecked")
+ public JMXManagedObject(ObjectName objName)
+ {
+ super();
+ this._objName = objName;
+ setName(_objName.getKeyProperty("name"));
+ setType(_objName.getKeyProperty("type"));
+ setUniqueName(_objName.toString());
+ setDomain(_objName.getDomain());
+ super.setProperties(new HashMap(_objName.getKeyPropertyList()));
+ }
+
+ public ObjectName getObjectName()
+ {
+ return _objName;
+ }
+}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXServerRegistry.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXServerRegistry.java
new file mode 100644
index 0000000000..9bc3ea1b0f
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXServerRegistry.java
@@ -0,0 +1,336 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui.jmx;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import javax.management.MBeanInfo;
+import javax.management.MBeanServerConnection;
+import javax.management.Notification;
+import javax.management.ObjectName;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXServiceURL;
+
+import org.apache.qpid.management.ui.Constants;
+import org.apache.qpid.management.ui.ManagedBean;
+import org.apache.qpid.management.ui.ManagedServer;
+import org.apache.qpid.management.ui.ServerRegistry;
+import org.apache.qpid.management.ui.model.ManagedAttributeModel;
+import org.apache.qpid.management.ui.model.NotificationInfoModel;
+import org.apache.qpid.management.ui.model.NotificationObject;
+import org.apache.qpid.management.ui.model.OperationDataModel;
+
+
+public class JMXServerRegistry extends ServerRegistry
+{
+ private ObjectName _serverObjectName = null;
+ private JMXConnector _jmxc = null;
+ private MBeanServerConnection _mbsc = null;
+
+ private List<ManagedBean> _mbeansToBeAdded = new ArrayList<ManagedBean>();
+ private List<ManagedBean> _mbeansToBeRemoved = new ArrayList<ManagedBean>();
+
+ private List<String> _queues = new ArrayList<String>();
+ private List<String> _exchanges = new ArrayList<String>();
+
+ private HashMap<String, ManagedBean> _mbeansMap = new HashMap<String, ManagedBean>();
+ private HashMap<String, MBeanInfo> _mbeanInfoMap = new HashMap<String, MBeanInfo>();
+ private HashMap<String, ManagedAttributeModel> _attributeModelMap = new HashMap<String, ManagedAttributeModel>();
+ private HashMap<String, OperationDataModel> _operationModelMap = new HashMap<String, OperationDataModel>();
+ private HashMap<String, List<NotificationInfoModel>> _notificationInfoMap = new HashMap<String, List<NotificationInfoModel>>();
+ private HashMap<String, List<NotificationObject>> _notificationsMap = new HashMap<String, List<NotificationObject>>();
+ private HashMap<String, HashMap<String, List<String>>> _subscribedNotificationMap = new HashMap<String, HashMap<String, List<String>>>();
+
+ private ClientNotificationListener _notificationListener = null;
+ private ClientListener _clientListener = null;
+
+ public JMXServerRegistry(ManagedServer server) throws Exception
+ {
+ super(server);
+ JMXServiceURL jmxUrl = new JMXServiceURL(server.getUrl());
+ _jmxc = JMXConnectorFactory.connect(jmxUrl, null);
+ _mbsc = _jmxc.getMBeanServerConnection();
+
+ _clientListener = new ClientListener(server);
+ _notificationListener = new ClientNotificationListener(server);
+
+ _jmxc.addConnectionNotificationListener(_clientListener, null, null);
+ _serverObjectName = new ObjectName("JMImplementation:type=MBeanServerDelegate");
+ _mbsc.addNotificationListener(_serverObjectName, _clientListener, null, null);
+ }
+
+ public MBeanServerConnection getServerConnection()
+ {
+ return _mbsc;
+ }
+
+ /**
+ * removes all listeners from the mbean server. This is required when user
+ * disconnects the Qpid server connection
+ */
+ public void closeServerConnection() throws Exception
+ {
+ if (_jmxc != null)
+ _jmxc.removeConnectionNotificationListener(_clientListener);
+
+ if (_mbsc != null)
+ _mbsc.removeNotificationListener(_serverObjectName, _clientListener);
+
+ // remove mbean notification listeners
+ for (String mbeanName : _subscribedNotificationMap.keySet())
+ {
+ _mbsc.removeNotificationListener(new ObjectName(mbeanName), _notificationListener);
+ }
+ }
+
+ public ManagedBean getManagedObject(String uniqueName)
+ {
+ return _mbeansMap.get(uniqueName);
+ }
+
+ public void addManagedObject(ManagedBean key)
+ {
+ if (Constants.QUEUE.equals(key.getType()))
+ _queues.add(key.getName());
+ else if (Constants.EXCHANGE.equals(key.getType()))
+ _exchanges.add(key.getName());
+
+ _mbeansMap.put(key.getUniqueName(), key);
+ }
+
+ public void removeManagedObject(ManagedBean mbean)
+ {
+ if (Constants.QUEUE.equals(mbean.getType()))
+ _queues.remove(mbean.getName());
+ else if (Constants.EXCHANGE.equals(mbean.getType()))
+ _exchanges.remove(mbean.getName());
+
+ _mbeansMap.remove(mbean.getUniqueName());
+ }
+
+ public void putMBeanInfo(ManagedBean mbean, MBeanInfo mbeanInfo)
+ {
+ _mbeanInfoMap.put(mbean.getUniqueName(), mbeanInfo);
+ }
+ public MBeanInfo getMBeanInfo(ManagedBean mbean)
+ {
+ return _mbeanInfoMap.get(mbean.getUniqueName());
+ }
+
+ public void setNotificationInfo(ManagedBean mbean, List<NotificationInfoModel>value)
+ {
+ _notificationInfoMap.put(mbean.getUniqueName(), value);
+ }
+
+ public List<NotificationInfoModel> getNotificationInfo(ManagedBean mbean)
+ {
+ return _notificationInfoMap.get(mbean.getUniqueName());
+ }
+
+ public void addNotification(ObjectName objName, Notification notification)
+ {
+ List<NotificationObject> list = _notificationsMap.get(objName.toString());
+ NotificationObject obj = new NotificationObject(notification.getSequenceNumber(),
+ new Date(notification.getTimeStamp()),
+ notification.getMessage(),
+ notification.getSource(),
+ notification.getType());
+
+ if (list == null)
+ {
+ list = new ArrayList<NotificationObject>();
+ _notificationsMap.put(objName.toString(), list);
+ }
+
+ list.add(obj);
+ }
+
+ public List<NotificationObject> getNotifications(ManagedBean mbean)
+ {
+ return _notificationsMap.get(mbean.getUniqueName());
+ }
+
+ public void clearNotifications(ManagedBean mbean)
+ {
+ if (_notificationsMap.containsKey(mbean.getUniqueName()))
+ _notificationsMap.get(mbean.getUniqueName()).clear();
+ }
+
+ public void addNotificationListener(ManagedBean mbean, String name, String type)
+ {
+ HashMap<String, List<String>> map = _subscribedNotificationMap.get(mbean.getUniqueName());
+ if (map == null)
+ {
+ map = new HashMap<String, List<String>>();
+ _subscribedNotificationMap.put(mbean.getUniqueName(),map);
+ }
+
+ List<String> list = map.get(name);
+ if (list == null)
+ {
+ list = new ArrayList<String>();
+ map.put(name, list);
+ }
+ if (Constants.ALL.equals(type))
+ {
+ List<NotificationInfoModel> infoList = _notificationInfoMap.get(mbean.getUniqueName());
+ for (NotificationInfoModel model : infoList)
+ {
+ if (model.getName().equals(name))
+ {
+ String[] types = model.getTypes();
+ for (int i = 0; i < types.length; i++)
+ {
+ list.add(types[i]);
+ }
+ }
+ }
+ }
+ else
+ {
+ list.add(type);
+ }
+
+ System.out.println("Subscribed for notification :" + mbean.getUniqueName());
+ }
+
+ public boolean hasSubscribedForNotifications(ManagedBean mbean, String name, String type)
+ {
+ if (_subscribedNotificationMap.containsKey(mbean.getUniqueName()))
+ {
+ HashMap<String, List<String>> map = _subscribedNotificationMap.get(mbean.getUniqueName());
+ if (map.containsKey(name))
+ {
+ if (map.get(name).contains(type))
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ public void removeNotificationListener(ManagedBean mbean, String name, String type) throws Exception
+ {
+ System.out.println("Removed notification listener :" + mbean.getUniqueName() + name +type);
+ if (_subscribedNotificationMap.containsKey(mbean.getUniqueName()))
+ {
+ HashMap<String, List<String>> map = _subscribedNotificationMap.get(mbean.getUniqueName());
+ if (map.containsKey(name))
+ {
+ if (Constants.ALL.equals(type))
+ {
+ map.remove(name);
+ }
+ else if (type != null)
+ {
+ map.get(name).remove(type);
+ }
+ }
+
+ JMXManagedObject jmxbean = (JMXManagedObject)mbean;
+ _mbsc.removeNotificationListener(jmxbean.getObjectName(), _notificationListener);
+ }
+ }
+
+ public void registerManagedObject(ObjectName objName)
+ {
+ JMXManagedObject managedObject = new JMXManagedObject(objName);
+ managedObject.setServer(getManagedServer());
+ _mbeansToBeAdded.add(managedObject);
+ }
+
+ public void unregisterManagedObject(ObjectName objName)
+ {
+ JMXManagedObject managedObject = new JMXManagedObject(objName);
+ managedObject.setServer(getManagedServer());
+ _mbeansToBeRemoved.add(managedObject);
+ }
+
+ public List<ManagedBean> getObjectsToBeAdded()
+ {
+ if (_mbeansToBeAdded.isEmpty())
+ return null;
+ else
+ {
+ List<ManagedBean> list = _mbeansToBeAdded;
+ _mbeansToBeAdded = new ArrayList<ManagedBean>();
+ return list;
+ }
+ }
+
+ public List<ManagedBean> getObjectsToBeRemoved()
+ {
+ if (_mbeansToBeRemoved.isEmpty())
+ return null;
+ else
+ {
+ List<ManagedBean> list = new CopyOnWriteArrayList<ManagedBean>(_mbeansToBeRemoved);
+ _mbeansToBeRemoved.clear();
+ return list;
+ }
+ }
+
+ public void setAttributeModel(ManagedBean mbean, ManagedAttributeModel value)
+ {
+ _attributeModelMap.put(mbean.getUniqueName(), value);
+ }
+
+ public ManagedAttributeModel getAttributeModel(ManagedBean mbean)
+ {
+ return _attributeModelMap.get(mbean.getUniqueName());
+ }
+
+ public void setOperationModel(ManagedBean mbean, OperationDataModel value)
+ {
+ _operationModelMap.put(mbean.getUniqueName(), value);
+ }
+
+ public OperationDataModel getOperationModel(ManagedBean mbean)
+ {
+ return _operationModelMap.get(mbean.getUniqueName());
+ }
+
+ public String[] getQueueNames()
+ {
+ return _queues.toArray(new String[0]);
+ }
+
+ public String[] getExchangeNames()
+ {
+ return _exchanges.toArray(new String[0]);
+ }
+
+ public ClientNotificationListener getNotificationListener()
+ {
+ return _notificationListener;
+ }
+
+ public ClientListener getClientListener()
+ {
+ return _clientListener;
+ }
+}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/MBeanUtility.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/MBeanUtility.java
new file mode 100644
index 0000000000..800a5b6ce3
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/MBeanUtility.java
@@ -0,0 +1,349 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui.jmx;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.management.Attribute;
+import javax.management.AttributeList;
+import javax.management.InstanceNotFoundException;
+import javax.management.JMException;
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanException;
+import javax.management.MBeanInfo;
+import javax.management.MBeanNotificationInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectName;
+import javax.management.ReflectionException;
+
+import org.apache.qpid.management.ui.ApplicationRegistry;
+import org.apache.qpid.management.ui.ManagedBean;
+import org.apache.qpid.management.ui.ManagedServer;
+import org.apache.qpid.management.ui.model.AttributeData;
+import org.apache.qpid.management.ui.model.ManagedAttributeModel;
+import org.apache.qpid.management.ui.model.NotificationInfoModel;
+import org.apache.qpid.management.ui.model.OperationData;
+import org.apache.qpid.management.ui.model.OperationDataModel;
+import org.apache.qpid.management.ui.model.ParameterData;
+import org.apache.qpid.management.ui.views.ViewUtility;
+
+
+public class MBeanUtility
+{
+
+ public static MBeanInfo getMBeanInfo(ManagedBean mbean)
+ throws IOException, JMException
+ {
+ ManagedServer server = mbean.getServer();
+ JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(server);
+
+ MBeanServerConnection mbsc = serverRegistry.getServerConnection();
+ if (mbsc == null)
+ System.out.println("MBeanServerConnection does not exist in the Application registry.");
+
+ JMXManagedObject jmxbean = (JMXManagedObject)mbean;
+ MBeanInfo mbeanInfo = mbsc.getMBeanInfo(jmxbean.getObjectName());
+ serverRegistry.putMBeanInfo(mbean, mbeanInfo);
+
+ getAttributes(mbean);
+ getOperations(mbean);
+
+ return mbeanInfo;
+ }
+
+
+ public static Object execute(ManagedBean mbean, OperationData opData) throws Exception
+ {
+ String opName = opData.getName();
+ Object[] values = null;
+ String[] signature = null;
+
+ List<ParameterData> params = opData.getParameters();
+ if (params != null && !params.isEmpty())
+ {
+ signature = new String[params.size()];;
+ values = new Object[params.size()];
+ for (int i = 0; i < params.size(); i++)
+ {
+ signature[i] = params.get(i).getType();
+ values[i] = params.get(i).getValue();
+ System.out.println(params.get(i).getName() + " : " + params.get(i).getValue());
+ }
+ }
+
+ ManagedServer server = mbean.getServer();
+ JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(server);
+
+ MBeanServerConnection mbsc = serverRegistry.getServerConnection();
+ if (mbsc == null)
+ {
+ System.out.println("MBeanServerConnection doesn't exist in the Application registry.");
+ // TODO
+ // throw exception to check if the server is added
+ // Or try and get the connection again if it was disconnected
+ return null;
+ }
+ JMXManagedObject jmxbean = (JMXManagedObject)mbean;
+ return mbsc.invoke(jmxbean.getObjectName(), opName, values, signature);
+
+ /*
+ try
+ {
+
+ }
+ catch(MBeanException ex)
+ {
+ ex.printStackTrace();
+
+ }
+ catch(OperationsException ex)
+ {
+ ex.printStackTrace();
+
+ }
+ catch(JMException ex)
+ {
+ ex.printStackTrace();
+ ViewUtility.popupError(new Exception(ex), "Operation failed");
+ }
+ catch(IOException ex)
+ {
+ ex.printStackTrace();
+ ViewUtility.popupError(new Exception(ex), "Operation failed");
+ }
+ */
+ }
+
+ public static void handleException(Exception ex)
+ {
+ handleException(null, ex);
+ }
+
+ public static void handleException(ManagedBean mbean, Exception ex)
+ {
+ if (mbean == null)
+ {
+ ViewUtility.popupErrorMessage("Error", ex.getMessage());
+ }
+ else if (ex instanceof IOException)
+ {
+ ViewUtility.popupErrorMessage(mbean.getName(), ex.getMessage());
+ }
+ else if (ex instanceof ReflectionException)
+ {
+ ViewUtility.popupErrorMessage(mbean.getName(), ex.getMessage());
+ }
+ else if (ex instanceof InstanceNotFoundException)
+ {
+ ViewUtility.popupErrorMessage(mbean.getName(), ex.getMessage());
+ }
+ else if (ex instanceof MBeanException)
+ {
+ ViewUtility.popupInfoMessage(mbean.getName(), ex.getMessage());
+ }
+ else
+ {
+ ViewUtility.popupError(mbean.getName(), "Error occured", ex);
+ }
+ ex.printStackTrace();
+ }
+
+ public static void createNotificationlistener(ManagedBean mbean, String name, String type)
+ throws IOException, Exception
+ {
+ JMXManagedObject jmxbean = (JMXManagedObject)mbean;
+ JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(mbean);
+ serverRegistry.addNotificationListener(mbean, name, type);
+ MBeanServerConnection mbsc = serverRegistry.getServerConnection();
+
+ if (mbsc == null)
+ {
+ throw new Exception("MBeanServer connection is broken");
+ }
+ mbsc.addNotificationListener(jmxbean.getObjectName(), serverRegistry.getNotificationListener(), null, null);
+ System.out.println("Listener created : " + jmxbean.getObjectName());
+ }
+
+ public static void removeNotificationListener(ManagedBean mbean, String name, String type) throws Exception
+ {
+ //JMXManagedObject jmxbean = (JMXManagedObject)mbean;
+ JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(mbean);
+ serverRegistry.removeNotificationListener(mbean, name, type);
+ //MBeanServerConnection mbsc = serverRegistry.getServerConnection();
+
+ //if (mbsc != null)
+ //{
+ // mbsc.removeNotificationListener(jmxbean.getObjectName(), serverRegistry.getNotificationListener());
+ //}
+ }
+
+ public static int refreshAttribute(ManagedBean mbean, String attribute) throws Exception
+ {
+ JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(mbean);
+ MBeanServerConnection mbsc = serverRegistry.getServerConnection();
+
+ if (mbsc == null)
+ throw new Exception("Server connection is not available for " + mbean.getUniqueName());
+
+ Object value = mbsc.getAttribute(((JMXManagedObject)mbean).getObjectName(), attribute);
+
+ ManagedAttributeModel attributeModel = serverRegistry.getAttributeModel(mbean);
+ attributeModel.setAttributeValue(attribute, value);
+ return Integer.parseInt(String.valueOf(value));
+ }
+
+ public static ManagedAttributeModel getAttributes(ManagedBean mbean)
+ {
+ ObjectName objName = ((JMXManagedObject)mbean).getObjectName();
+ String[] attributes = null;
+ AttributeList list = null;
+
+ JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(mbean);
+ MBeanServerConnection mbsc = serverRegistry.getServerConnection();
+ MBeanAttributeInfo[] attributesInfo = null;
+ ManagedAttributeModel attributeModel = serverRegistry.getAttributeModel(mbean);
+ // If retrieving attributeInfo for the first time.
+ if (attributeModel == null)
+ {
+ attributeModel = new ManagedAttributeModel();
+ attributesInfo = serverRegistry.getMBeanInfo(mbean).getAttributes();
+ attributes = new String[attributesInfo.length];
+ for (int i = 0; i< attributesInfo.length ; i++)
+ {
+ attributes[i] = attributesInfo[i].getName();
+ attributeModel.setAttributeDescription(attributes[i], attributesInfo[i].getDescription());
+ attributeModel.setAttributeWritable(attributes[i], attributesInfo[i].isWritable());
+ attributeModel.setAttributeReadable(attributes[i], attributesInfo[i].isReadable());
+ }
+ }
+ else
+ {
+ attributes = attributeModel.getAttributeNames().toArray(new String[0]);
+ }
+
+ try
+ {
+ if (attributes.length != 0)
+ {
+ list = mbsc.getAttributes(objName, attributes);
+ for (Iterator itr = list.iterator(); itr.hasNext();)
+ {
+ Attribute attrib = (Attribute)itr.next();
+ attributeModel.setAttributeValue(attrib.getName(), attrib.getValue());
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+
+ serverRegistry.setAttributeModel(mbean, attributeModel);
+
+ return attributeModel;
+ }
+
+ public static void updateAttribute(ManagedBean mbean, AttributeData attribute, String value)
+ {
+ JMXManagedObject jmxbean = (JMXManagedObject)mbean;
+ JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(mbean);
+
+ MBeanServerConnection mbsc = serverRegistry.getServerConnection();
+
+ Object newValue = value;
+ if (attribute.getDataType().equals(String.class.getName()))
+ {
+
+ }
+ else if (attribute.getDataType().equals(Long.class.getName()))
+ {
+ newValue = new Long(Long.parseLong(value));
+ }
+ else if (attribute.getDataType().equals(Integer.class.getName()))
+ {
+ newValue = new Integer(Integer.parseInt(value));
+ }
+
+ try
+ {
+ mbsc.setAttribute(jmxbean.getObjectName(), new Attribute(attribute.getName(), newValue));
+
+ // Update the value in the registry, to avoid refreshing from mbsc
+ ManagedAttributeModel attributeModel = serverRegistry.getAttributeModel(mbean);
+ attributeModel.setAttributeValue(attribute.getName(), newValue);
+ }
+ catch(Exception ex)
+ {
+ ex.printStackTrace();
+ }
+ }
+
+ public static OperationDataModel getOperations(ManagedBean mbean)
+ {
+ JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(mbean);
+
+ OperationDataModel dataModel = serverRegistry.getOperationModel(mbean);
+ if (dataModel == null)
+ {
+ MBeanInfo mbeanInfo = serverRegistry.getMBeanInfo(mbean);
+ MBeanOperationInfo[] operationsInfo = mbeanInfo.getOperations();
+ dataModel = new OperationDataModel();
+
+ for (int i = 0; i < operationsInfo.length; i++)
+ {
+ dataModel.addOperation(operationsInfo[i]);
+ }
+
+ serverRegistry.setOperationModel(mbean, dataModel);
+ }
+
+ return dataModel;
+ }
+
+ public static NotificationInfoModel[] getNotificationInfo(ManagedBean mbean)
+ {
+
+ JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(mbean);
+ MBeanNotificationInfo[] info = serverRegistry.getMBeanInfo(mbean).getNotifications();
+
+ if (info == null || info.length == 0)
+ return null;
+
+ List<NotificationInfoModel> list = serverRegistry.getNotificationInfo(mbean);
+
+ if (list != null)
+ return list.toArray(new NotificationInfoModel[0]);
+ else
+ list = new ArrayList<NotificationInfoModel>();
+
+ for (int i = 0; i < info.length; i++)
+ {
+ list.add(new NotificationInfoModel(info[i].getName(), info[i].getDescription(), info[i].getNotifTypes()));
+ }
+ serverRegistry.setNotificationInfo(mbean, list);
+
+ return list.toArray(new NotificationInfoModel[0]);
+ }
+}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/AttributeData.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/AttributeData.java
new file mode 100644
index 0000000000..601f499a0c
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/AttributeData.java
@@ -0,0 +1,95 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui.model;
+
+public class AttributeData
+{
+ String name = "";
+ String description = "";
+ String dataType = "";
+ Object value = null;
+ boolean readable = true;
+ boolean writable = false;
+
+
+ public String getDataType()
+ {
+ return dataType;
+ }
+ public void setDataType(String dataType)
+ {
+ this.dataType = dataType;
+ }
+
+ public String getDescription()
+ {
+ return description;
+ }
+ public void setDescription(String description)
+ {
+ this.description = description;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+ public void setName(String name)
+ {
+ this.name = name;
+ }
+
+ public Object getValue()
+ {
+ return value;
+ }
+ public void setValue(Object value)
+ {
+ this.value = value;
+ }
+ public boolean isReadable()
+ {
+ return readable;
+ }
+ public void setReadable(boolean readable)
+ {
+ this.readable = readable;
+ }
+ public boolean isWritable()
+ {
+ return writable;
+ }
+ public void setWritable(boolean writable)
+ {
+ this.writable = writable;
+ }
+
+ public boolean isNumber()
+ {
+ if ("int".equals(dataType) || "java.lang.Integer".equals(dataType) ||
+ "long".equals(dataType) || "java.lang.Long".equals(dataType) )
+ {
+ return true;
+ }
+ else
+ return false;
+ }
+}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/ManagedAttributeModel.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/ManagedAttributeModel.java
new file mode 100644
index 0000000000..692e72fc5a
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/ManagedAttributeModel.java
@@ -0,0 +1,113 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui.model;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+public class ManagedAttributeModel
+{
+ HashMap<String, AttributeData> _attributeMap = new HashMap<String, AttributeData>();
+
+ public void setAttributeValue(String name, Object value)
+ {
+ if (value == null)
+ return;
+
+ AttributeData data = null;
+ String dataType = value.getClass().getName();
+ if (_attributeMap.containsKey(name))
+ {
+ data = _attributeMap.get(name);
+ data.setValue(value);
+ }
+ else
+ {
+ data = new AttributeData();
+ data.setName(name);
+ data.setValue(value);
+ _attributeMap.put(name, data);
+ }
+ data.setDataType(dataType);
+ }
+
+
+ public void setAttributeDescription(String name, String value)
+ {
+ if (_attributeMap.containsKey(name))
+ {
+ _attributeMap.get(name).setDescription(value);
+ }
+ else
+ {
+ AttributeData data = new AttributeData();
+ data.setName(name);
+ data.setDescription(value);
+ _attributeMap.put(name, data);
+ }
+ }
+
+ public void setAttributeReadable(String name, boolean readable)
+ {
+ if (_attributeMap.containsKey(name))
+ {
+ _attributeMap.get(name).setReadable(readable);
+ }
+ else
+ {
+ AttributeData data = new AttributeData();
+ data.setName(name);
+ data.setReadable(readable);
+ _attributeMap.put(name, data);
+ }
+ }
+
+ public void setAttributeWritable(String name, boolean writable)
+ {
+ if (_attributeMap.containsKey(name))
+ {
+ _attributeMap.get(name).setWritable(writable);
+ }
+ else
+ {
+ AttributeData data = new AttributeData();
+ data.setName(name);
+ data.setWritable(writable);
+ _attributeMap.put(name, data);
+ }
+ }
+
+ public List<String> getAttributeNames()
+ {
+ return new ArrayList<String>(_attributeMap.keySet());
+ }
+
+ public AttributeData[] getAttributes()
+ {
+ return _attributeMap.values().toArray(new AttributeData[0]);
+ }
+
+ public int getCount()
+ {
+ return _attributeMap.size();
+ }
+}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/NotificationInfoModel.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/NotificationInfoModel.java
new file mode 100644
index 0000000000..6d4160889e
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/NotificationInfoModel.java
@@ -0,0 +1,51 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui.model;
+
+public class NotificationInfoModel
+{
+ String name;
+ String description;
+ String[] types;
+
+ public NotificationInfoModel(String name, String desc, String[] types)
+ {
+ this.name = name;
+ this.description = desc;
+ this.types = types;
+ }
+
+ public String getDescription()
+ {
+ return description;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public String[] getTypes()
+ {
+ return types;
+ }
+
+}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/NotificationObject.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/NotificationObject.java
new file mode 100644
index 0000000000..8ba74b3ce8
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/NotificationObject.java
@@ -0,0 +1,88 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui.model;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.TimeZone;
+
+public class NotificationObject
+{
+
+ private long _sequenceNo;
+ private Date _timeStamp;
+ private String _message;
+ private Object _source;
+ private String _type; // INFO, WARN, etc
+ private static final SimpleDateFormat dateFormat = new SimpleDateFormat("hh:mm:ss dd/MM/yy z");
+
+ public NotificationObject(long seqNo, Date timeStamp, String message, Object source, String type)
+ {
+ this._sequenceNo = seqNo;
+ this._message = message;
+ this._source = source;
+ this._type = type;
+ this._timeStamp = timeStamp;
+ dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
+ }
+
+ public Object getSource()
+ {
+ return _source;
+ }
+ public void setSource(Object _source)
+ {
+ this._source = _source;
+ }
+ public String getMessage()
+ {
+ return _message;
+ }
+ public void setMessage(String _message)
+ {
+ this._message = _message;
+ }
+ public long getSequenceNo()
+ {
+ return _sequenceNo;
+ }
+ public void setSequenceNo(long no)
+ {
+ _sequenceNo = no;
+ }
+ public String getTimeStamp()
+ {
+ return dateFormat.format(_timeStamp);
+ }
+ public void setTimeStamp(Date stamp)
+ {
+ _timeStamp = stamp;
+ }
+ public String getType()
+ {
+ return _type;
+ }
+ public void setType(String _type)
+ {
+ this._type = _type;
+ }
+
+}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/OperationData.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/OperationData.java
new file mode 100644
index 0000000000..9b6750c21a
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/OperationData.java
@@ -0,0 +1,84 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui.model;
+
+import java.util.List;
+
+public class OperationData
+{
+ private String _name;
+ private String _description;
+ private String _returnType;
+ private int _impact;
+ private List<ParameterData> _parameters;
+
+ public OperationData(String value)
+ {
+ this._name = value;
+ }
+
+ public String getName()
+ {
+ return _name;
+ }
+
+ public String getDescription()
+ {
+ return _description;
+ }
+
+ public void setDescription(String description)
+ {
+ this._description = description;
+ }
+
+ public List<ParameterData> getParameters()
+ {
+ return _parameters;
+ }
+
+ public void setParameters(List<ParameterData> parameters)
+ {
+ this._parameters = parameters;
+ }
+
+ public int getImpact()
+ {
+ return _impact;
+ }
+
+ public void setImpact(int impact)
+ {
+ this._impact = impact;
+ }
+
+ public String getReturnType()
+ {
+ return _returnType;
+ }
+
+ public void setReturnType(String returnType)
+ {
+ this._returnType = returnType;
+ }
+
+
+} \ No newline at end of file
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/OperationDataModel.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/OperationDataModel.java
new file mode 100644
index 0000000000..2df36ee8c6
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/OperationDataModel.java
@@ -0,0 +1,73 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui.model;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanParameterInfo;
+
+public class OperationDataModel
+{
+ HashMap<String, OperationData> _operationMap = new HashMap<String, OperationData>();
+
+ public void addOperation(MBeanOperationInfo opInfo)
+ {
+ OperationData opData = new OperationData(opInfo.getName());
+ opData.setDescription(opInfo.getDescription());
+ opData.setImpact(opInfo.getImpact());
+ opData.setReturnType(opInfo.getReturnType());
+
+ int parametersCount = opInfo.getSignature().length;
+ if (parametersCount != 0)
+ {
+ List<ParameterData> paramList = new ArrayList<ParameterData>();
+ for (int i = 0; i < parametersCount; i++)
+ {
+ MBeanParameterInfo paramInfo = opInfo.getSignature()[i];
+ ParameterData param = new ParameterData(paramInfo.getName());
+ param.setDescription(paramInfo.getDescription());
+ param.setType(paramInfo.getType());
+ paramList.add(param);
+ }
+ opData.setParameters(paramList);
+ }
+
+ _operationMap.put(opInfo.getName(), opData);
+ }
+
+ public OperationData getOperation(String name)
+ {
+ return _operationMap.get(name);
+ }
+
+ public List<OperationData> getOperations()
+ {
+ return new ArrayList<OperationData>(_operationMap.values());
+ }
+
+ public int getCount()
+ {
+ return _operationMap.size();
+ }
+}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/ParameterData.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/ParameterData.java
new file mode 100644
index 0000000000..4ca47c88ea
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/ParameterData.java
@@ -0,0 +1,79 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui.model;
+
+public class ParameterData
+{
+ private String name;
+ private String description;
+ private String type;
+ private Object value;
+
+ ParameterData(String value)
+ {
+ this.name = value;
+ }
+
+ public String getDescription()
+ {
+ return description;
+ }
+ public void setDescription(String description)
+ {
+ this.description = description;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public String getType()
+ {
+ return type;
+ }
+ public void setType(String type)
+ {
+ this.type = type;
+ }
+
+ public Object getValue()
+ {
+ return value;
+ }
+
+ public void setValueFromString(String strValue)
+ {
+ if ("int".equals(type))
+ value = Integer.parseInt(strValue);
+ else if ("boolean".equals(type))
+ value = Boolean.valueOf(strValue);
+ else if ("long".equals(type))
+ value = Long.parseLong(strValue);
+ else
+ value = strValue;
+ }
+
+ public void setValue(Object value)
+ {
+ this.value = value;
+ }
+}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/AttributesTabControl.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/AttributesTabControl.java
new file mode 100644
index 0000000000..b5c044e7be
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/AttributesTabControl.java
@@ -0,0 +1,937 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui.views;
+
+import javax.management.openmbean.TabularDataSupport;
+
+import org.apache.qpid.management.ui.ApplicationRegistry;
+import org.apache.qpid.management.ui.Constants;
+import org.apache.qpid.management.ui.ManagedBean;
+import org.apache.qpid.management.ui.jmx.JMXServerRegistry;
+import org.apache.qpid.management.ui.jmx.MBeanUtility;
+import org.apache.qpid.management.ui.model.AttributeData;
+import org.apache.qpid.management.ui.model.ManagedAttributeModel;
+import org.eclipse.jface.viewers.IColorProvider;
+import org.eclipse.jface.viewers.IFontProvider;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.events.MouseMoveListener;
+import org.eclipse.swt.events.MouseTrackListener;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.VerifyEvent;
+import org.eclipse.swt.events.VerifyListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Canvas;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.TabFolder;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.TableItem;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.forms.widgets.Form;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+
+
+public class AttributesTabControl extends TabControl
+{
+ private FormToolkit _toolkit;
+ private Form _form;
+ private Table _table = null;
+ private TableViewer _tableViewer = null;
+ private static final int[] tableWidths = new int[] {300, 300};
+ private static final String DESCRIPTION = "Description";
+ private static final String UPDATE_BUTTON = "Update";
+ private final String[] _tableTitles = {"Attribute Name", "Value"};
+
+ private DisposeListener tableDisposeListener = new DisposeListenerImpl();
+ final Image image;
+ private Button _detailsButton = null;
+ private Button _editButton = null;
+ private Button _graphButton = null;
+ private Button _refreshButton = null;
+ private boolean disableEditing = false;
+
+ private static final String MAX_VALUE = "MaxValue";
+ private static final String GRAPH_VALUES = "GraphValues";
+ private int GRAPH_WIDTH = 700;
+ private int GRAPH_HEIGHT = 450;
+ private int GRAPH_ITEM_GAP = 100;
+ private int startX = 80;
+ private int startY = 60;
+
+ static int number = 0;
+
+ public AttributesTabControl(TabFolder tabFolder)
+ {
+ super(tabFolder);
+ _toolkit = new FormToolkit(_tabFolder.getDisplay());
+ _form = _toolkit.createForm(_tabFolder);
+ GridLayout gridLayout = new GridLayout(2, false);
+ gridLayout.marginWidth = 0;
+ gridLayout.marginHeight = 0;
+ _form.getBody().setLayout(gridLayout);
+
+ image = Display.getCurrent().getSystemImage(SWT.ICON_INFORMATION);
+ createWidgets();
+ }
+
+ public Control getControl()
+ {
+ return _form;
+ }
+
+ protected void createWidgets()
+ {
+ createTable();
+ createTableViewer();
+ createButtons();
+ addTableListeners();
+ }
+
+ private void createTable()
+ {
+ _table = _toolkit.createTable(_form.getBody(), SWT.FULL_SELECTION);
+ GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false, 1, 6);
+ _table.setLayoutData(gridData);
+
+ for (int i = 0; i < _tableTitles.length; ++i)
+ {
+ final TableColumn column = new TableColumn(_table, SWT.NONE);
+ column.setText(_tableTitles[i]);
+ column.setWidth(tableWidths[i]);
+ column.setResizable(false);
+ }
+
+ _table.setLinesVisible (true);
+ _table.setHeaderVisible (true);
+ }
+
+ private void createTableViewer()
+ {
+ _tableViewer = new TableViewer(_table);
+ _tableViewer.setUseHashlookup(true);
+ //_tableViewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 1, 6));
+
+ // Set the column properties that will be used in callbacks to recognize
+ // the column on which we will want to operate
+ _tableViewer.setColumnProperties(_tableTitles);
+ /*
+ // Create the cell editors
+ CellEditor[] cellEditors = new CellEditor[_tableTitles.length];
+
+
+ TextCellEditor textEditor = new TextCellEditor(_table);
+ cellEditors[0] = textEditor;
+ textEditor = new TextCellEditor(_table);
+ cellEditors[1] = textEditor;
+
+ // Assign the cell editors to the viewer
+ _tableViewer.setCellEditors(cellEditors);
+ _tableViewer.setCellModifier(new TableCellModifier());
+ */
+
+
+
+ _tableViewer.setContentProvider(new ContentProviderImpl());
+ _tableViewer.setLabelProvider(new LabelProviderImpl());
+
+ }
+
+ private void createButtons()
+ {
+ addDetailsButton();
+ addEditButton();
+ addGraphButton();
+ addRefreshButton();
+ }
+
+
+ private void addDetailsButton()
+ {
+ // Create and configure the button for attribute details
+ _detailsButton = _toolkit.createButton(_form.getBody(),
+ Constants.BUTTON_DETAILS,
+ SWT.PUSH | SWT.CENTER);
+
+ _detailsButton.setFont(ApplicationRegistry.getFont(Constants.FONT_BUTTON));
+ GridData gridData = new GridData(SWT.BEGINNING, SWT.TOP, true, false);
+ gridData.widthHint = 80;
+ _detailsButton.setLayoutData(gridData);
+ _detailsButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ disableEditing = true;
+ int index = _table.getSelectionIndex();
+ TableItem item = _table.getItem(index);
+ createDetailsPopup((AttributeData)item.getData());
+ disableEditing = false;
+ setFocus();
+ }
+ });
+ }
+
+ private void addEditButton()
+ {
+ // Create and configure the button for editing attribute
+ _editButton = _toolkit.createButton(_form.getBody(),
+ Constants.BUTTON_EDIT_ATTRIBUTE,
+ SWT.PUSH | SWT.CENTER);
+ _editButton.setFont(ApplicationRegistry.getFont(Constants.FONT_BUTTON));
+ GridData gridData = new GridData(SWT.BEGINNING, SWT.TOP, true, false);
+ gridData.widthHint = 80;
+ _editButton.setLayoutData(gridData);
+ _editButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ int index = _table.getSelectionIndex();
+ TableItem item = _table.getItem(index);
+ createDetailsPopup((AttributeData)item.getData());
+ setFocus();
+ }
+ });
+ }
+
+ private void addGraphButton()
+ {
+ _graphButton = _toolkit.createButton(_form.getBody(),
+ Constants.BUTTON_GRAPH,
+ SWT.PUSH | SWT.CENTER);
+ _graphButton.setFont(ApplicationRegistry.getFont(Constants.FONT_BUTTON));
+ GridData gridData = new GridData(SWT.BEGINNING, SWT.TOP, true, false);
+ gridData.widthHint = 80;
+ _graphButton.setLayoutData(gridData);
+ _graphButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent event)
+ {
+ int selectionIndex = _table.getSelectionIndex();
+ AttributeData data = (AttributeData)_table.getItem(selectionIndex).getData();
+ createGraph(data);
+ setFocus();
+ }
+ });
+ }
+
+ private void addRefreshButton()
+ {
+ // Create and configure the "Refresh" button
+ _refreshButton = _toolkit.createButton(_form.getBody(),
+ Constants.BUTTON_REFRESH,
+ SWT.PUSH | SWT.CENTER);
+
+ _refreshButton.setFont(ApplicationRegistry.getFont(Constants.FONT_BUTTON));
+ GridData gridData = new GridData(SWT.BEGINNING, SWT.TOP, true, false);
+ gridData.widthHint = 80;
+ _refreshButton.setLayoutData(gridData);
+ _refreshButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ // refresh the attributes list
+ refresh(_mbean);
+ }
+ });
+ }
+
+ private void addTableListeners()
+ {
+ _tableViewer.addSelectionChangedListener(new ISelectionChangedListener(){
+ public void selectionChanged(SelectionChangedEvent evt)
+ {
+ IStructuredSelection ss = (IStructuredSelection)evt.getSelection();
+ checkForEnablingButtons((AttributeData)ss.getFirstElement());
+ }
+ });
+
+ MouseListenerImpl listener = new MouseListenerImpl();
+ _tableViewer.getTable().addMouseTrackListener(listener);
+ _tableViewer.getTable().addMouseMoveListener(listener);
+ _tableViewer.getTable().addMouseListener(listener);
+
+ _table.addDisposeListener(tableDisposeListener);
+
+ // _table is equal to _tableViewer.getControl()
+ _table.addListener(SWT.MeasureItem, new Listener() {
+ public void handleEvent(Event event)
+ {
+ event.height = event.gc.getFontMetrics().getHeight() * 3/2;
+ }
+ });
+
+ // Below to be worked on to set an image in front of each row.
+ /*
+ _table.addListener(SWT.PaintItem, new Listener() {
+ public void handleEvent(Event event)
+ {
+ int x = event.x + event.width;
+ Rectangle rect = image.getBounds();
+ int offset = Math.max(0, (event.height - rect.height) / 2);
+ event.gc.drawImage(image, event.x, event.y + offset);
+ }
+ });
+ */
+ }
+
+ private class MouseListenerImpl implements MouseTrackListener, MouseMoveListener,
+ KeyListener, MouseListener
+
+ {
+ Shell tooltipShell = null;
+ Label tooltipLabel = null;
+ public void mouseHover(MouseEvent event)
+ {
+ TableItem item = _table.getItem (new Point (event.x, event.y));
+
+ if (item != null)
+ {
+ AttributeData data = (AttributeData)item.getData();
+ if (tooltipShell != null && !tooltipShell.isDisposed ()) tooltipShell.dispose ();
+ tooltipShell = new Shell(_table.getShell(), SWT.ON_TOP | SWT.NO_FOCUS | SWT.TOOL);
+ tooltipShell.setBackground(event.display.getSystemColor(SWT.COLOR_INFO_BACKGROUND));
+ FillLayout layout = new FillLayout();
+ layout.marginWidth = 2;
+ tooltipShell.setLayout(layout);
+ tooltipLabel = new Label(tooltipShell, SWT.NONE);
+ tooltipLabel.setForeground(event.display.getSystemColor(SWT.COLOR_INFO_FOREGROUND));
+ tooltipLabel.setBackground(event.display.getSystemColor(SWT.COLOR_INFO_BACKGROUND));
+ tooltipLabel.setText(data.getDescription());
+ tooltipLabel.setData("_TABLEITEM", item);
+ tooltipLabel.addListener(SWT.MouseExit, tooltipLabelListener);
+ tooltipLabel.addListener(SWT.MouseDown, tooltipLabelListener);
+ Point size = tooltipShell.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+ Rectangle rect = item.getBounds(0);
+ Point pt = _table.toDisplay(rect.x, rect.y);
+ tooltipShell.setBounds(pt.x, pt.y, size.x, size.y);
+ tooltipShell.setVisible(true);
+ }
+ }
+ public void mouseEnter(MouseEvent e)
+ {
+ }
+ public void mouseExit(MouseEvent e)
+ {
+ }
+
+ // MouseMoveListener implementation
+ public void mouseMove(MouseEvent event)
+ {
+ if (tooltipShell == null)
+ return;
+
+ tooltipShell.dispose();
+ tooltipShell = null;
+ tooltipLabel = null;
+ }
+
+ // KeyListener implementation
+ public void keyPressed(KeyEvent e)
+ {
+ if (tooltipShell == null)
+ return;
+
+ tooltipShell.dispose();
+ tooltipShell = null;
+ tooltipLabel = null;
+ }
+ public void keyReleased(KeyEvent e)
+ {
+
+ }
+
+ // MouseListener implementation
+ public void mouseDoubleClick(MouseEvent event)
+ {
+ if (tooltipShell != null)
+ {
+ tooltipShell.dispose();
+ tooltipShell = null;
+ tooltipLabel = null;
+ }
+ Table table = (Table)event.getSource();
+ int selectionIndex = table.getSelectionIndex();
+ AttributeData data = (AttributeData)table.getItem(selectionIndex).getData();
+ createDetailsPopup(data);
+ }
+ public void mouseDown(MouseEvent e)
+ {
+ if (tooltipShell != null)
+ {
+ tooltipShell.dispose();
+ tooltipShell = null;
+ tooltipLabel = null;
+ }
+ }
+ public void mouseUp(MouseEvent e)
+ {
+
+ }
+ } // end of MouseListenerImpl
+
+ public void createDetailsPopup(AttributeData data)
+ {
+ int width = 500;
+ int height = 250;
+ if (data.getValue() instanceof TabularDataSupport)
+ {
+ width = 650;
+ height = 450;
+ }
+
+ Display display = Display.getCurrent();
+ Shell shell = ViewUtility.createPopupShell("Attribute", width, height);
+ createDetailsPopupContents(shell, data);
+
+ shell.open();
+ while (!shell.isDisposed()) {
+ if (!display.readAndDispatch()) {
+ display.sleep();
+ }
+ }
+ shell.dispose();
+ }
+
+ final Listener tooltipLabelListener = new Listener ()
+ {
+ public void handleEvent (Event event)
+ {
+ Label label = (Label)event.widget;
+ Shell shell = label.getShell();
+ switch (event.type)
+ {
+ case SWT.MouseDown:
+ Event e = new Event();
+ e.item = (TableItem)label.getData ("_TABLEITEM");
+ _table.setSelection(new TableItem[] {(TableItem)e.item});
+ shell.dispose();
+ _table.setFocus();
+ break;
+ case SWT.MouseExit:
+ shell.dispose();
+ break;
+ }
+ }
+ };
+
+
+ private void createDetailsPopupContents(Composite shell, AttributeData attribute)
+ {
+ GridLayout layout = new GridLayout(2, false);
+ layout.horizontalSpacing = 10;
+ layout.verticalSpacing = 10;
+ layout.marginHeight = 20;
+ layout.marginWidth = 20;
+
+ Composite parent = new Composite(shell, SWT.NONE);
+ parent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ parent.setLayout(layout);
+
+ // Name
+ Label label = new Label(parent, SWT.NONE);
+ label.setText(_tableTitles[0]);
+ GridData layoutData = new GridData(SWT.TRAIL, SWT.TOP, false, false);
+ label.setLayoutData(layoutData);
+ Text value = new Text(parent, SWT.BEGINNING | SWT.BORDER |SWT.READ_ONLY);
+ value.setText(attribute.getName());
+ value.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+
+
+ // Description
+ label = new Label(parent, SWT.NONE);
+ label.setText(DESCRIPTION);
+ label.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, false, false));
+ value = new Text(parent, SWT.BEGINNING | SWT.BORDER | SWT.READ_ONLY);
+ value.setText(attribute.getDescription());
+ value.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+
+ // value
+ label = new Label(parent, SWT.NONE);
+ label.setText(_tableTitles[1]);
+ label.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, false, false));
+
+ if (!attribute.isReadable())
+ {
+ value = new Text(parent, SWT.BEGINNING | SWT.BORDER | SWT.READ_ONLY);
+ value.setText("");
+ value.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+ }
+ else
+ {
+ if (attribute.getValue() instanceof TabularDataSupport)
+ {
+ Composite composite = new Composite(parent, SWT.BORDER);
+ composite.setLayout(new GridLayout());
+ composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+ ViewUtility.createTabularDataHolder(composite,(TabularDataSupport)attribute.getValue());
+ }
+ else
+ {
+ int style = 0;
+ if (attribute.isWritable())
+ {
+ style = SWT.BEGINNING | SWT.BORDER;
+ value = new Text(parent, style);
+ value.addVerifyListener(new VerifyListener()
+ {
+ public void verifyText(VerifyEvent event)
+ {
+ String string = event.text;
+ char [] chars = new char [string.length ()];
+ string.getChars (0, chars.length, chars, 0);
+ for (int i=0; i<chars.length; i++)
+ {
+ if (!('0' <= chars [i] && chars [i] <= '9'))
+ {
+ event.doit = false;
+ return;
+ }
+ }
+ }
+ });
+
+ // set data to access in the listener
+ parent.setData(attribute);
+ }
+ else
+ {
+ style = SWT.BEGINNING | SWT.BORDER | SWT.READ_ONLY;
+ value = new Text(parent, style);
+ }
+
+ value.setText(attribute.getValue().toString());
+ value.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+ }
+ }
+
+
+ // Update button
+ Button updateButton = addUpdateButton(parent);
+ updateButton.setData(value);
+ if (!attribute.isWritable())
+ {
+ updateButton.setVisible(false);
+ }
+
+ if (disableEditing)
+ {
+ value.setEditable(false);
+ updateButton.setVisible(false);
+ }
+ }
+
+ private Button addUpdateButton(Composite parent)
+ {
+ final Button updateButton = new Button(parent, SWT.PUSH | SWT.CENTER);
+ // set the data to access in the listener
+ parent.setData(UPDATE_BUTTON, updateButton);
+
+ updateButton.setText(UPDATE_BUTTON);
+ GridData gridData = new GridData (SWT.CENTER, SWT.BOTTOM, true, true, 2, 1);
+ gridData.widthHint = 100;
+ updateButton.setLayoutData(gridData);
+ updateButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent event)
+ {
+ Button button = (Button)event.widget;
+ Text text = (Text)button.getData();
+ AttributeData data = (AttributeData)button.getParent().getData();
+ MBeanUtility.updateAttribute(_mbean, data, text.getText());
+ button.getShell().close();
+ refresh();
+ }
+ });
+
+ return updateButton;
+ }
+
+ // Refresh from the server registry
+ private void refresh()
+ {
+ JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(_mbean);
+ ManagedAttributeModel attributesList = serverRegistry.getAttributeModel(_mbean);
+ _tableViewer.setInput(attributesList);
+ }
+
+ // Refreshes the attribute tab by querying the mbean server for latest values
+ @Override
+ public void refresh(ManagedBean mbean)
+ {
+ _mbean = mbean;
+ if (_mbean == null)
+ {
+ _tableViewer.setInput(null);
+ return;
+ }
+ ManagedAttributeModel attributesList = MBeanUtility.getAttributes(mbean);
+ _tableViewer.setInput(attributesList);
+ _table.setItemCount(attributesList.getCount());
+
+ // No attribtue selected when refreshing the tab
+ checkForEnablingButtons(null);
+ _form.layout();
+ }
+
+ public void setFocus()
+ {
+ _table.setFocus();
+ }
+
+ private void checkForEnablingButtons(AttributeData attribute)
+ {
+ if (attribute == null)
+ {
+ _detailsButton.setEnabled(false);
+ _editButton.setEnabled(false);
+ _graphButton.setEnabled(false);
+ _refreshButton.setEnabled(false);
+ return;
+ }
+
+ _detailsButton.setEnabled(true);
+ _refreshButton.setEnabled(true);
+ if (attribute.isWritable())
+ {
+ _editButton.setEnabled(true);
+ _graphButton.setEnabled(false);
+ }
+ else
+ {
+ _editButton.setEnabled(false);
+ if (attribute.isNumber())
+ {
+ _graphButton.setEnabled(true);
+ }
+ else
+ {
+ _graphButton.setEnabled(false);
+ }
+ }
+ }
+
+ private void createGraph(final AttributeData data)
+ {
+ Display display = Display.getCurrent();
+ Shell shell = new Shell(display, SWT.BORDER | SWT.CLOSE | SWT.MIN | SWT.MAX);
+ shell.setText(_mbean.getName());
+ int x = display.getBounds().width;
+ int y = display.getBounds().height;
+ shell.setBounds(x/4, y/4, GRAPH_WIDTH, GRAPH_HEIGHT);
+ shell.setLayout(new FillLayout());
+
+ final Canvas canvas = new Canvas(shell, SWT.NONE);
+ long currentValue = Long.parseLong(data.getValue().toString());
+ long mValue = getGraphMaxValue(currentValue);
+ canvas.setData(MAX_VALUE, mValue);
+ canvas.setData(GRAPH_VALUES, new long[] {0,0,0,0,0,currentValue});
+
+ canvas.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE));
+ canvas.addPaintListener(new PaintListener()
+ {
+ public void paintControl(PaintEvent event)
+ {
+ Canvas canvas = (Canvas)event.widget;
+ int maxX = canvas.getSize().x;
+ int maxY = canvas.getSize().y;
+ event.gc.fillRectangle(canvas.getBounds());
+ event.gc.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_BLACK));
+ event.gc.setLineWidth(4);
+
+ Object canvasData = canvas.getData(MAX_VALUE);
+ String str = canvasData.toString();
+ long maxValue = Long.parseLong(str);
+ // Set the graph dimensions
+ event.gc.drawText("0", startX - 40, maxY - startY - 10);
+ event.gc.drawText("" + maxValue/2, startX - 40, maxY/2);
+ event.gc.drawText("" + maxValue, startX - 40, startY);
+
+ // horizontal line
+ event.gc.drawLine(startX, maxY - startY, maxX - 60, maxY - startY);
+ // vertical line
+ event.gc.drawLine(startX, maxY - startY, startX, startY);
+ // set graph text
+ event.gc.drawText(data.getName(), startX - 40, startY - 40);
+ event.gc.drawText("25 sec", startX, maxY - startY + 10);
+ event.gc.drawText("20 sec", startX + GRAPH_ITEM_GAP, maxY - startY + 10);
+ event.gc.drawText("15 sec", startX + GRAPH_ITEM_GAP * 2, maxY - startY + 10);
+ event.gc.drawText("10 sec", startX + GRAPH_ITEM_GAP * 3, maxY - startY + 10);
+ event.gc.drawText(" 5 sec", startX + GRAPH_ITEM_GAP * 4, maxY - startY + 10);
+ event.gc.drawText(" 0 sec", startX + GRAPH_ITEM_GAP * 5, maxY - startY + 10);
+
+ // plot the graph now for values
+ event.gc.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_BLUE));
+ canvasData = canvas.getData(GRAPH_VALUES);
+ long[] graphValues = (long[]) canvasData;
+ for (int i = 0; i < graphValues.length; i++)
+ {
+ int x = startX + i * GRAPH_ITEM_GAP;
+ int yTotalLength = (maxY - 2 * startY);
+ float ratio = ((float)graphValues[i]/(float)maxValue);
+ int itemlength = (int)(yTotalLength * ratio);
+ int y = maxY - startY - itemlength;
+ event.gc.drawLine(x, maxY- startY, x, y);
+ event.gc.drawText(String.valueOf(graphValues[i]), x, y - 20);
+ }
+ }
+ });
+
+ shell.open();
+
+ // Set up the timer for the animation
+ Runnable runnable = new Runnable()
+ {
+ public void run()
+ {
+ try
+ {
+ animate(canvas, data);
+ Display.getCurrent().timerExec(Constants.TIMER_INTERVAL, this);
+ }
+ catch(Exception ex)
+ {
+ MBeanUtility.handleException(ex);
+ }
+ }
+ };
+
+ // Launch the timer
+ display.timerExec(Constants.TIMER_INTERVAL, runnable);
+
+ while (!shell.isDisposed()) {
+ if (!display.readAndDispatch()) {
+ display.sleep();
+ }
+ }
+
+ // Kill the timer
+ display.timerExec(-1, runnable);
+ shell.dispose();
+ }
+
+ public AttributeData getSelectionAttribute()
+ {
+ int index = _table.getSelectionIndex();
+ if (index == -1)
+ return null;
+
+ return (AttributeData)_table.getItem(index).getData();
+ }
+
+ private void animate(Canvas canvas, AttributeData data) throws Exception
+ {
+ String attribute = data.getName();
+ int value = MBeanUtility.refreshAttribute(_mbean, attribute);
+ Object canvasData = canvas.getData(GRAPH_VALUES);
+ long[] graphValues = (long[]) canvasData;
+
+ for (int i = 0; i < graphValues.length -1; i++)
+ {
+ graphValues[i] = graphValues[i + 1];
+ }
+ graphValues[graphValues.length - 1] = value;
+
+ canvasData = canvas.getData(MAX_VALUE);
+ long maxValue = Long.parseLong(String.valueOf(canvasData));
+ if (maxValue < value)
+ {
+ maxValue = getGraphMaxValue(value);
+ canvas.setData(MAX_VALUE, maxValue);
+ }
+
+ canvas.redraw();
+ }
+
+ private long getGraphMaxValue(long maxAttributeValue)
+ {
+ long maxGraphValue = 100;
+ long temp = maxAttributeValue * 3/2;
+ if (temp > maxGraphValue)
+ {
+ long modulus = temp % 100;
+ maxGraphValue = temp + ( 100 - modulus);
+ }
+
+ return maxGraphValue;
+ }
+
+ private class ContentProviderImpl implements IStructuredContentProvider
+ {
+
+ public void inputChanged(Viewer v, Object oldInput, Object newInput)
+ {
+
+ }
+
+ public void dispose()
+ {
+
+ }
+
+ public Object[] getElements(Object parent)
+ {
+ return ((ManagedAttributeModel)parent).getAttributes();
+ }
+ }
+
+ private class LabelProviderImpl extends LabelProvider implements ITableLabelProvider,
+ IFontProvider,
+ IColorProvider
+ {
+
+ AttributeData attribute = null;
+ public String getColumnText(Object element, int columnIndex)
+ {
+ String result = "";
+ attribute = (AttributeData) element;
+
+ switch (columnIndex)
+ {
+ case 0 : // attribute name column
+ result = ViewUtility.getDisplayText(attribute.getName());
+ break;
+ case 1 : // attribute value column
+ if (attribute.getValue() != null)
+ result = String.valueOf(attribute.getValue());
+ break;
+ default :
+ result = "";
+ }
+
+ return result;
+ }
+
+ public Image getColumnImage(Object element, int columnIndex)
+ {
+ return null;
+ }
+
+ public Font getFont(Object element)
+ {
+ return ApplicationRegistry.getFont(Constants.FONT_TABLE_CELL);
+ }
+
+ public Color getForeground(Object element)
+ {
+ attribute = (AttributeData) element;
+ if (attribute.isWritable())
+ return Display.getCurrent().getSystemColor(SWT.COLOR_DARK_BLUE);
+ else
+ return Display.getCurrent().getSystemColor(SWT.COLOR_BLACK);
+ }
+ public Color getBackground(Object element)
+ {
+ return _form.getBackground();
+ }
+ }
+
+ private class DisposeListenerImpl implements DisposeListener
+ {
+ public void widgetDisposed(DisposeEvent e)
+ {
+
+ }
+ }
+
+ /*
+ class TableCellModifier implements ICellModifier
+ {
+
+ public boolean canModify(Object element, String property)
+ {
+ int columnIndex = Arrays.asList(_tableTitles).indexOf(property);
+ if (columnIndex == 0)
+ return false;
+
+ return true;
+ }
+
+ public Object getValue(Object element, String property) {
+
+ // Find the index of the column
+ int columnIndex = Arrays.asList(_tableTitles).indexOf(property);
+ Attribute attribute = (Attribute)element;
+
+
+ Object result = null;
+
+ switch (columnIndex)
+ {
+ case 0 : // attribute name column
+ result = attribute.getName();
+ break;
+ case 1 : // attribute value column
+ result = attribute.getValue();
+ break;
+ default :
+ result = "";
+ }
+
+ return result;
+ }
+
+
+ public void modify(Object element, String property, Object value)
+ {
+ // Find the index of the column
+ int columnIndex = Arrays.asList(_tableTitles).indexOf(property);
+
+ if (columnIndex == 1)
+ {
+ //TODO
+ // update the attribute value and call the MBean setAttribute method
+ // then refresh the attribute tab with new values
+ }
+ }
+ }
+ */
+
+} \ No newline at end of file
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/INotificationViewer.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/INotificationViewer.java
new file mode 100644
index 0000000000..bc560b6064
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/INotificationViewer.java
@@ -0,0 +1,32 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui.views;
+
+import java.util.List;
+
+import org.apache.qpid.management.ui.model.NotificationObject;
+
+public interface INotificationViewer
+{
+ public void addNotification(NotificationObject notification);
+
+ public void addNotification(List<NotificationObject> notificationList);
+}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanView.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanView.java
new file mode 100644
index 0000000000..063f80fd3f
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanView.java
@@ -0,0 +1,431 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui.views;
+
+import java.util.HashMap;
+
+import org.apache.qpid.management.ui.ApplicationRegistry;
+import org.apache.qpid.management.ui.Constants;
+import org.apache.qpid.management.ui.ManagedBean;
+import org.apache.qpid.management.ui.exceptions.InfoRequiredException;
+import org.apache.qpid.management.ui.jmx.JMXServerRegistry;
+import org.apache.qpid.management.ui.jmx.MBeanUtility;
+import org.apache.qpid.management.ui.model.AttributeData;
+import org.apache.qpid.management.ui.model.OperationData;
+import org.apache.qpid.management.ui.model.OperationDataModel;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.layout.FormLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.TabFolder;
+import org.eclipse.swt.widgets.TabItem;
+import org.eclipse.ui.ISelectionListener;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.forms.widgets.Form;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+import org.eclipse.ui.part.ViewPart;
+
+
+public class MBeanView extends ViewPart
+{
+ public static final String ID = "org.apache.qpid.management.ui.mbeanView";
+
+ private FormToolkit _toolkit = null;
+ private Form _form = null;
+ private ManagedBean _mbean = null;
+ private HashMap<String, TabFolder> tabFolderMap = new HashMap<String, TabFolder>();
+ private ISelectionListener selectionListener = new SelectionListenerImpl();
+
+ private static final String ATTRIBUTES_CONTROL = "AttributesTabControl";
+ private static final String OPERATIONS_CONTROL = "OperationsTabControl";
+ private static final String NOTIFICATIONS_CONTROL = "NotificationsTabControl";
+
+
+ /*
+ * Listener for the selection events in the navigation view
+ */
+ private class SelectionListenerImpl implements ISelectionListener
+ {
+ public void selectionChanged(IWorkbenchPart part, ISelection sel)
+ {
+ if (!(sel instanceof IStructuredSelection))
+ return;
+
+ IStructuredSelection ss = (IStructuredSelection) sel;
+ TreeObject node = (TreeObject)ss.getFirstElement();
+ showSelectedMBean(node);
+ /*
+ _mbean = null;
+ setInvisible();
+
+ if (node == null)
+ {
+ _form.setText("Qpid Management Console");
+ return;
+ }
+
+ if (Constants.NOTIFICATION.equals(node.getType()))
+ {
+ _mbean = (ManagedBean)node.getParent().getManagedObject();
+ }
+ else if (Constants.MBEAN.equals(node.getType()))
+ {
+ _mbean = (ManagedBean)node.getManagedObject();
+ }
+ else
+ {
+ _form.setText("Qpid Management Console");
+ return;
+ }
+
+ setFocus();
+ try
+ {
+ MBeanUtility.getMBeanInfo(_mbean);
+ }
+ catch(Exception ex)
+ {
+ MBeanUtility.handleException(_mbean, ex);
+ return;
+ }
+
+ TabFolder tabFolder = tabFolderMap.get(_mbean.getType());
+ if (tabFolder == null)
+ {
+ tabFolder = createTabFolder();
+ }
+
+ String text = _mbean.getType();
+ if (_mbean.getName() != null && _mbean.getName().length() != 0)
+ {
+ text = text + ": " + _mbean.getName();
+ }
+ _form.setText(text);
+ int tabIndex = 0;
+ if (Constants.NOTIFICATION.equals(node.getType()))
+ {
+ tabIndex = tabFolder.getItemCount() -1;
+ }
+
+ TabItem tab = tabFolder.getItem(tabIndex);
+ // refreshTab(tab);
+ // If folder is being set as visible after tab refresh, then the tab
+ // doesn't have the focus.
+
+ tabFolder.setSelection(tabIndex);
+ refreshTab(tab);
+ setVisible(tabFolder);
+ _form.layout();
+
+ // Set the focus on the first attribute in attributes table
+ if (tab.getText().equals(Constants.ATTRIBUTES))
+ {
+ ((TabControl)tabFolder.getData(ATTRIBUTES_CONTROL)).setFocus();
+ }*/
+ }
+ }
+
+ public void showSelectedMBean(TreeObject node)
+ {
+ _mbean = null;
+ setInvisible();
+
+ if (node == null)
+ {
+ _form.setText("Qpid Management Console");
+ return;
+ }
+
+ if (Constants.NOTIFICATION.equals(node.getType()))
+ {
+ _mbean = (ManagedBean)node.getParent().getManagedObject();
+ }
+ else if (Constants.MBEAN.equals(node.getType()))
+ {
+ _mbean = (ManagedBean)node.getManagedObject();
+ }
+ else
+ {
+ _form.setText("Qpid Management Console");
+ return;
+ }
+
+ setFocus();
+ try
+ {
+ MBeanUtility.getMBeanInfo(_mbean);
+ }
+ catch(Exception ex)
+ {
+ MBeanUtility.handleException(_mbean, ex);
+ return;
+ }
+
+ TabFolder tabFolder = tabFolderMap.get(_mbean.getType());
+ if (tabFolder == null)
+ {
+ tabFolder = createTabFolder();
+ }
+
+ String text = _mbean.getType();
+ if (_mbean.getName() != null && _mbean.getName().length() != 0)
+ {
+ text = text + ": " + _mbean.getName();
+ }
+ _form.setText(text);
+ int tabIndex = 0;
+ if (Constants.NOTIFICATION.equals(node.getType()))
+ {
+ tabIndex = tabFolder.getItemCount() -1;
+ }
+
+ TabItem tab = tabFolder.getItem(tabIndex);
+ // refreshTab(tab);
+ // If folder is being set as visible after tab refresh, then the tab
+ // doesn't have the focus.
+
+ tabFolder.setSelection(tabIndex);
+ refreshTab(tab);
+ setVisible(tabFolder);
+ _form.layout();
+ }
+
+ public void createPartControl(Composite parent)
+ {
+ // Create the Form
+ _toolkit = new FormToolkit(parent.getDisplay());
+ _form = _toolkit.createForm(parent);
+ _form.getBody().setLayout(new FormLayout());
+ _form.setText(Constants.APPLICATION_NAME);
+
+ // Add selection listener for selection events in the Navigation view
+ getSite().getPage().addSelectionListener(NavigationView.ID, selectionListener);
+ }
+
+ public void refreshMBeanView()
+ {
+ if (_mbean == null)
+ return;
+
+ TabFolder tabFolder = tabFolderMap.get(_mbean.getType());
+ if (tabFolder == null)
+ return;
+
+ int index = tabFolder.getSelectionIndex();
+ TabItem tab = tabFolder.getItem(index);
+ if (tab == null)
+ return;
+
+ refreshTab(tab);
+ _form.layout();
+ }
+
+ private TabFolder createTabFolder()
+ {
+ TabFolder tabFolder = new TabFolder(_form.getBody(), SWT.NONE);
+ FormData layoutData = new FormData();
+ layoutData.left = new FormAttachment(0);
+ layoutData.top = new FormAttachment(0);
+ layoutData.right = new FormAttachment(100);
+ layoutData.bottom = new FormAttachment(100);
+ tabFolder.setLayoutData(layoutData);
+ tabFolder.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE));
+ tabFolder.setVisible(false);
+
+ createAttributesTab(tabFolder);
+ createOperationTabs(tabFolder);
+ createNotificationsTab(tabFolder);
+
+ tabFolder.addListener(SWT.Selection, new Listener()
+ {
+ public void handleEvent(Event evt)
+ {
+ TabItem tab = (TabItem)evt.item;
+ refreshTab(tab);
+ }
+ });
+
+ tabFolderMap.put(_mbean.getType(), tabFolder);
+ return tabFolder;
+ }
+
+ private void refreshTab(TabItem tab)
+ {
+ // We can avoid refreshing the attributes tab because it's control
+ // already contains the required values. But it is added for now and
+ // will remove if there is any perfornce or any such issue.
+ // The operations control should be refreshed because there is only one
+ // controller for all operations tab.
+ // The Notifications control needs to refresh with latest set of notifications
+
+ if (tab == null)
+ return;
+
+ TabFolder tabFolder = tab.getParent();
+ if (tab.getData() != null && (tab.getData() instanceof OperationData))
+ {
+ // Refresh selected operation tab
+ TabControl control = (TabControl)tabFolder.getData(OPERATIONS_CONTROL);
+ if (control == null)
+ return;
+
+ control.refresh(_mbean, (OperationData)tab.getData());
+ }
+ else if (tab.getText().equals(Constants.NOTIFICATION))
+ {
+ TabControl control = (TabControl)tabFolder.getData(NOTIFICATIONS_CONTROL);
+ if (control == null)
+ return;
+
+ control.refresh(_mbean);
+ }
+ else if (tab.getText().equals(Constants.ATTRIBUTES))
+ {
+ TabControl control = (TabControl)tabFolder.getData(ATTRIBUTES_CONTROL);
+ if (control == null)
+ return;
+
+ control.refresh(_mbean);
+ }
+
+ }
+
+ public void setFocus()
+ {
+ //_form.setFocus();
+ }
+
+ public void dispose()
+ {
+ _toolkit.dispose();
+ super.dispose();
+ }
+
+ private void createAttributesTab(TabFolder tabFolder)
+ {
+ JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(_mbean);
+ if (serverRegistry.getAttributeModel(_mbean).getCount() == 0)
+ {
+ return;
+ }
+
+ TabItem tab = new TabItem(tabFolder, SWT.NONE);
+ tab.setText(Constants.ATTRIBUTES);
+ AttributesTabControl control = new AttributesTabControl(tabFolder);
+ tab.setControl(control.getControl());
+ tabFolder.setData(ATTRIBUTES_CONTROL, control);
+ }
+
+ private void createOperationTabs(TabFolder tabFolder)
+ {
+ JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(_mbean);
+ int operationsCount = serverRegistry.getOperationModel(_mbean).getCount();
+ if (operationsCount == 0)
+ {
+ return;
+ }
+
+ OperationTabControl control = new OperationTabControl(tabFolder);
+ tabFolder.setData(OPERATIONS_CONTROL, control);
+
+ OperationDataModel operationModel = serverRegistry.getOperationModel(_mbean);
+ for (OperationData operationData : operationModel.getOperations())
+ {
+ TabItem operationTab = new TabItem(tabFolder, SWT.NONE);
+ operationTab.setText(ViewUtility.getDisplayText(operationData.getName()));
+ operationTab.setData(operationData);
+ operationTab.setControl(control.getControl());
+ }
+ }
+
+ private void createNotificationsTab(TabFolder tabFolder)
+ {
+ NotificationsTabControl controller = new NotificationsTabControl(tabFolder);
+ tabFolder.setData(NOTIFICATIONS_CONTROL, controller);
+
+ TabItem tab = new TabItem(tabFolder, SWT.NONE);
+ tab.setText(Constants.NOTIFICATION);
+ tab.setControl(controller.getControl());
+ }
+
+ /**
+ * For the EditAttribtue Action. Invoking this from action is same as clicking
+ * "EditAttribute" button from Attribute tab.
+ */
+ public void editAttribute() throws Exception
+ {
+ if (_mbean == null)
+ throw new InfoRequiredException("Please select the managed object and then attribute to be edited");
+
+ String name = (_mbean.getName() != null) ? _mbean.getName() : _mbean.getType();
+ JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(_mbean);
+ if (serverRegistry.getAttributeModel(_mbean).getCount() == 0)
+ {
+ throw new InfoRequiredException("There are no attributes to be edited for " + name);
+ }
+
+ TabFolder tabFolder = tabFolderMap.get(_mbean.getType());
+ int index = tabFolder.getSelectionIndex();
+ if (index != 0)
+ {
+ tabFolder.setSelection(0);
+ throw new InfoRequiredException("Please select the attribute to be edited");
+ }
+
+ AttributesTabControl tabControl = (AttributesTabControl)tabFolder.getData(ATTRIBUTES_CONTROL);
+ AttributeData attribute = tabControl.getSelectionAttribute();
+ if (attribute == null)
+ throw new InfoRequiredException("Please select the attribute to be edited");
+
+ tabControl.createDetailsPopup(attribute);
+ }
+
+
+ /**
+ * hides other folders and makes the given one visible.
+ * @param tabFolder
+ */
+ private void setVisible(TabFolder tabFolder)
+ {
+ for (TabFolder folder : tabFolderMap.values())
+ {
+ if (folder == tabFolder)
+ folder.setVisible(true);
+ else
+ folder.setVisible(false);
+ }
+ }
+
+ private void setInvisible()
+ {
+ for (TabFolder folder : tabFolderMap.values())
+ {
+ folder.setVisible(false);
+ }
+ }
+
+}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NavigationView.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NavigationView.java
new file mode 100644
index 0000000000..4319a4bd10
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NavigationView.java
@@ -0,0 +1,787 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui.views;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectInstance;
+import javax.management.ObjectName;
+
+import org.apache.qpid.management.ui.ApplicationRegistry;
+import org.apache.qpid.management.ui.Constants;
+import org.apache.qpid.management.ui.ManagedBean;
+import org.apache.qpid.management.ui.ManagedServer;
+import org.apache.qpid.management.ui.ServerRegistry;
+import org.apache.qpid.management.ui.exceptions.InfoRequiredException;
+import org.apache.qpid.management.ui.jmx.JMXManagedObject;
+import org.apache.qpid.management.ui.jmx.JMXServerRegistry;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.IFontProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.ITreeViewerListener;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.TreeExpansionEvent;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.part.ViewPart;
+
+
+public class NavigationView extends ViewPart
+{
+ public static final String ID = "org.apache.qpid.management.ui.navigationView";
+ public static final String INI_FILENAME = System.getProperty("user.home") + File.separator + "qpidManagementConsole.ini";
+
+ private TreeViewer _treeViewer = null;
+ private TreeObject _rootNode = null;
+ private TreeObject _serversRootNode = null;
+ // List of all server nodes (connecged or removed)
+ //private List<TreeObject> _serverNodeList = new ArrayList<TreeObject>();
+ // Map of connected servers
+ private HashMap<ManagedServer, TreeObject> _managedServerMap = new HashMap<ManagedServer, TreeObject>();
+
+ private void createTreeViewer(Composite parent)
+ {
+ _treeViewer = new TreeViewer(parent);
+ _treeViewer.setContentProvider(new ContentProviderImpl());
+ _treeViewer.setLabelProvider(new LabelProviderImpl());
+ _treeViewer.setSorter(new ViewerSorterImpl());
+
+ // layout the tree viewer below the label field, to cover the area
+ GridData layoutData = new GridData();
+ layoutData = new GridData();
+ layoutData.grabExcessHorizontalSpace = true;
+ layoutData.grabExcessVerticalSpace = true;
+ layoutData.horizontalAlignment = GridData.FILL;
+ layoutData.verticalAlignment = GridData.FILL;
+ _treeViewer.getControl().setLayoutData(layoutData);
+ _treeViewer.setUseHashlookup(true);
+
+ createListeners();
+ }
+
+ private void createListeners()
+ {
+ _treeViewer.addDoubleClickListener(new IDoubleClickListener()
+ {
+ public void doubleClick(DoubleClickEvent event)
+ {
+ IStructuredSelection ss = (IStructuredSelection)event.getSelection();
+ if (ss == null || ss.getFirstElement() == null)
+ {
+ return;
+ }
+ boolean state = _treeViewer.getExpandedState(ss.getFirstElement());
+ _treeViewer.setExpandedState(ss.getFirstElement(), !state);
+ }
+ });
+
+ _treeViewer.addTreeListener(new ITreeViewerListener()
+ {
+ public void treeExpanded(TreeExpansionEvent event)
+ {
+ _treeViewer.setExpandedState(event.getElement(), true);
+ // Following will cause the selection event to be sent, so commented
+ //_treeViewer.setSelection(new StructuredSelection(event.getElement()));
+ _treeViewer.refresh();
+ }
+
+ public void treeCollapsed(TreeExpansionEvent event)
+ {
+ _treeViewer.setExpandedState(event.getElement(), false);
+ _treeViewer.refresh();
+ }
+ });
+ }
+
+ private void createRMIServerConnection(ManagedServer server) throws Exception
+ {
+ try
+ {
+ // Currently Qpid Management Console only supports JMX MBeanServer
+ JMXServerRegistry serverRegistry = new JMXServerRegistry(server);
+ ApplicationRegistry.addServer(server, serverRegistry);
+ }
+ catch(Exception ex)
+ {
+ throw new Exception("Error in connecting to Qpid broker at " + server.getUrl(), ex);
+ }
+ }
+
+ private String getRMIURL(String host)
+ {
+ return "service:jmx:rmi:///jndi/rmi://" + host + "/jmxrmi";
+ }
+
+
+ public void addNewServer(String transportProtocol, String host, String port, String domain)
+ throws Exception
+ {
+ if ("RMI".equals(transportProtocol))
+ {
+ String serverAddress = host + ":" + port;
+ String url = getRMIURL(serverAddress);
+ List<TreeObject> list = _serversRootNode.getChildren();
+ for (TreeObject node : list)
+ {
+ if (url.equals(node.getUrl()))
+ throw new InfoRequiredException("Server " + serverAddress + " is already added");
+ }
+
+ ManagedServer managedServer = new ManagedServer(url, domain);
+ managedServer.setName(serverAddress);
+ createRMIServerConnection(managedServer);
+
+ // RMI server connection is successful. Now add the server in the tree
+ TreeObject serverNode = new TreeObject(serverAddress, Constants.SERVER);
+ serverNode.setUrl(url);
+ serverNode.setManagedObject(managedServer);
+ _serversRootNode.addChild(serverNode);
+
+ // Add server in the connected server map
+ _managedServerMap.put(managedServer, serverNode);
+ populateServer(serverNode);
+ _treeViewer.refresh();
+
+ // save server address in file
+ addServerAddressInFile(serverAddress);
+ }
+ else
+ {
+ throw new InfoRequiredException(transportProtocol + " transport is not supported");
+ }
+ }
+
+ private void addServerAddressInFile(String serverAddress)
+ {
+ File file = new File(INI_FILENAME);
+ try
+ {
+ if (!file.exists())
+ file.createNewFile();
+
+ BufferedWriter out = new BufferedWriter(new FileWriter(file, true));
+ out.write(serverAddress + "\n");
+ out.close();
+
+ }
+ catch(Exception ex)
+ {
+ System.out.println("Could not write to the file " + INI_FILENAME);
+ System.out.println(ex);
+ }
+ }
+
+
+ private void populateServer(TreeObject serverNode)
+ {
+ ManagedServer server = (ManagedServer)serverNode.getManagedObject();
+ JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(server);
+ String domain = server.getDomain();
+ try
+ {
+ if (!domain.equals("All"))
+ {
+ TreeObject domainNode = new TreeObject(domain, Constants.DOMAIN);
+ domainNode.setParent(serverNode);
+
+ populateDomain(domainNode);
+ }
+ else
+ {
+ List<TreeObject> domainList = new ArrayList<TreeObject>();
+ MBeanServerConnection mbsc = serverRegistry.getServerConnection();
+ String[] domains = mbsc.getDomains();
+ for (int i = 0; i < domains.length; i++)
+ {
+ TreeObject domainNode = new TreeObject(domains[i], Constants.DOMAIN);
+ domainNode.setParent(serverNode);
+
+ domainList.add(domainNode);
+ populateDomain(domainNode);
+ }
+ }
+ }
+ catch(Exception ex)
+ {
+ System.out.println("\nError in connecting to Qpid broker ");
+ System.out.println("\n" + ex.toString());
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private void populateDomain(TreeObject domain) throws IOException, Exception
+ {
+ ManagedServer server = (ManagedServer)domain.getParent().getManagedObject();
+ JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(server);
+
+ String domainName = domain.getName();
+ MBeanServerConnection mbsc = serverRegistry.getServerConnection();
+
+
+ ObjectName objName = new ObjectName(domainName + ":*");
+ Set queryMBeans = mbsc.queryMBeans(objName, null);
+ final Set<ObjectInstance> objectInstances = queryMBeans;
+
+ for (Iterator<ObjectInstance> itr = objectInstances.iterator(); itr.hasNext();)
+ {
+ ObjectInstance instance = itr.next();
+ ManagedBean obj = new JMXManagedObject(instance.getObjectName());
+ obj.setServer(server);
+ addManagedBean(domain, obj);
+ }
+ }
+
+ private TreeObject getIfTypeAlreadyExists(TreeObject domain, String type)
+ {
+ List<TreeObject> types = domain.getChildren();
+
+ for (TreeObject child : types)
+ {
+ if (Constants.TYPE.equals(child.getType()) && type.equals(child.getName()))
+ return child;
+ }
+ return null;
+ }
+
+ private void addManagedBean(TreeObject domain, ManagedBean obj)
+ {
+ ManagedServer server = (ManagedServer)domain.getParent().getManagedObject();
+ JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(server);
+ serverRegistry.addManagedObject(obj);
+
+ String type = obj.getType();
+ String name = obj.getName();
+
+ TreeObject typeChild = getIfTypeAlreadyExists(domain, type);
+ TreeObject mbeanNode = null;
+ if (typeChild != null) // if type is already added as a TreeItem
+ {
+ if (name == null)
+ {
+ System.out.println("Two mbeans can't exist without a name and with same type");
+ return;
+ }
+ mbeanNode = new TreeObject(obj);
+ mbeanNode.setParent(typeChild);
+ }
+ else
+ {
+ if (name != null) // An managedObject with type and name
+ {
+ typeChild = new TreeObject(type, Constants.TYPE);
+ typeChild.setParent(domain);
+ mbeanNode = new TreeObject(obj);
+ mbeanNode.setParent(typeChild);
+ }
+ else // An managedObject with only type
+ {
+ mbeanNode = new TreeObject(obj);
+ mbeanNode.setParent(domain);
+ }
+ }
+
+ // Add notification node
+ // TODO: show this only of the mbean sends any notification
+ TreeObject notificationNode = new TreeObject(Constants.NOTIFICATION, Constants.NOTIFICATION);
+ notificationNode.setParent(mbeanNode);
+ }
+
+ /**
+ * Removes all the child nodes of the given parent node
+ * @param parent
+ */
+ private void removeManagedObject(TreeObject parent)
+ {
+ List<TreeObject> list = parent.getChildren();
+ for (TreeObject child : list)
+ {
+ removeManagedObject(child);
+ }
+
+ list.clear();
+ }
+
+ /**
+ * Removes the mbean from the tree
+ * @param parent
+ * @param mbean
+ */
+ private void removeManagedObject(TreeObject parent, ManagedBean mbean)
+ {
+ List<TreeObject> list = parent.getChildren();
+ TreeObject objectToRemove = null;
+ for (TreeObject child : list)
+ {
+ if (Constants.MBEAN.equals(child.getType()))
+ {
+ String name = mbean.getName() != null ? mbean.getName() : mbean.getType();
+ if (child.getName().equals(name))
+ {
+ objectToRemove = child;
+ break;
+ }
+ }
+ else
+ {
+ removeManagedObject(child, mbean);
+ }
+ }
+
+ if (objectToRemove != null)
+ {
+ list.remove(objectToRemove);
+ }
+
+ }
+
+ public void disconnect() throws Exception
+ {
+ TreeObject selectedNode = getSelectedServerNode();
+ ManagedServer managedServer = (ManagedServer)selectedNode.getManagedObject();
+ if (!_managedServerMap.containsKey(managedServer))
+ return;
+
+ // Close server connection
+ ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(managedServer);
+ if (serverRegistry == null) // server connection is already closed
+ return;
+
+ serverRegistry.closeServerConnection();
+ // Add server to the closed server list and the worker thread will remove the server from required places.
+ ApplicationRegistry.serverConnectionClosed(managedServer);
+ }
+
+ /**
+ * Connects the selected server node
+ * @throws Exception
+ */
+ public void reconnect() throws Exception
+ {
+ TreeObject selectedNode = getSelectedServerNode();
+ ManagedServer managedServer = (ManagedServer)selectedNode.getManagedObject();
+ if(_managedServerMap.containsKey(managedServer))
+ {
+ throw new InfoRequiredException("Server " + managedServer.getName() + " is already connected");
+ }
+ createRMIServerConnection(managedServer);
+ _managedServerMap.put(managedServer, selectedNode);
+ populateServer(selectedNode);
+ _treeViewer.refresh();
+ }
+
+ public void removeServer() throws Exception
+ {
+ disconnect();
+
+ // Remove from the Tree
+ String serverNodeName = getSelectedServerNode().getName();
+ List<TreeObject> list = _serversRootNode.getChildren();
+ TreeObject objectToRemove = null;
+ for (TreeObject child : list)
+ {
+ if (child.getName().equals(serverNodeName))
+ {
+ objectToRemove = child;
+ break;
+ }
+ }
+
+ if (objectToRemove != null)
+ {
+ list.remove(objectToRemove);
+ }
+
+ //_serverNodeList.remove(objectToRemove);
+ _treeViewer.refresh();
+
+ // Remove from the ini file
+ List<String> serversList = getServerListFromFile();
+ serversList.remove(serverNodeName);
+
+ BufferedWriter out = new BufferedWriter(new FileWriter(INI_FILENAME));
+ for (String serverAddress : serversList)
+ {
+ out.write(serverAddress + "\n");
+ }
+ out.close();
+ }
+
+ private List<String> getServerListFromFile() throws Exception
+ {
+ BufferedReader in = new BufferedReader(new FileReader(INI_FILENAME));
+ List<String> serversList = new ArrayList<String>();
+ String str;
+ while ((str = in.readLine()) != null)
+ {
+ serversList.add(str);
+ }
+ in.close();
+
+ return serversList;
+ }
+
+ private TreeObject getSelectedServerNode() throws Exception
+ {
+ IStructuredSelection ss = (IStructuredSelection)_treeViewer.getSelection();
+ TreeObject selectedNode = (TreeObject)ss.getFirstElement();
+ if (ss.isEmpty() || selectedNode == null || (!selectedNode.getType().equals(Constants.SERVER)))
+ {
+ throw new InfoRequiredException("Please select the server");
+ }
+
+ return selectedNode;
+ }
+ /**
+ * This is a callback that will allow us to create the viewer and initialize
+ * it.
+ */
+ public void createPartControl(Composite parent)
+ {
+ Composite composite = new Composite(parent, SWT.NONE);
+ GridLayout gridLayout = new GridLayout();
+ gridLayout.marginHeight = 2;
+ gridLayout.marginWidth = 2;
+ gridLayout.horizontalSpacing = 0;
+ gridLayout.verticalSpacing = 2;
+ composite.setLayout(gridLayout);
+
+ createTreeViewer(composite);
+ _rootNode = new TreeObject("ROOT", "ROOT");
+ _serversRootNode = new TreeObject(Constants.NAVIGATION_ROOT, "ROOT");
+ _serversRootNode.setParent(_rootNode);
+
+ _treeViewer.setInput(_rootNode);
+ // set viewer as selection event provider for MBeanView
+ getSite().setSelectionProvider(_treeViewer);
+
+ // Start worker thread to refresh tree for added or removed objects
+ (new Thread(new Worker())).start();
+
+ try
+ {
+ // load the list of servers already added from file
+ List<String> serversList = getServerListFromFile();
+ for (String serverAddress : serversList)
+ {
+ try
+ {
+ String url = getRMIURL(serverAddress);
+ ManagedServer managedServer = new ManagedServer(url, "org.apache.qpid");
+ managedServer.setName(serverAddress);
+ TreeObject serverNode = new TreeObject(serverAddress, Constants.SERVER);
+ serverNode.setUrl(url);
+ serverNode.setManagedObject(managedServer);
+ _serversRootNode.addChild(serverNode);
+ }
+ catch(Exception ex)
+ {
+ System.out.println(ex);
+ }
+ }
+ _treeViewer.refresh();
+ }
+ catch(Exception ex)
+ {
+ System.out.println(ex);
+ }
+ }
+
+ /**
+ * Passing the focus request to the viewer's control.
+ */
+ public void setFocus()
+ {
+
+ }
+
+ public void refresh()
+ {
+ _treeViewer.refresh();
+ }
+
+ private class ContentProviderImpl implements ITreeContentProvider
+ {
+ public Object[] getElements(Object parent)
+ {
+ return getChildren(parent);
+ }
+
+ public Object[] getChildren(final Object parentElement)
+ {
+ final TreeObject node = (TreeObject)parentElement;
+ return node.getChildren().toArray(new TreeObject[0]);
+ }
+
+ public Object getParent(final Object element)
+ {
+ final TreeObject node = (TreeObject)element;
+ return node.getParent();
+ }
+
+ public boolean hasChildren(final Object element)
+ {
+ final TreeObject node = (TreeObject) element;
+ return !node.getChildren().isEmpty();
+ }
+
+ public void inputChanged(final Viewer viewer, final Object oldInput, final Object newInput)
+ {
+ // Do nothing
+ }
+
+ public void dispose()
+ {
+ // Do nothing
+ }
+ }
+
+ private class LabelProviderImpl extends LabelProvider implements IFontProvider
+ {
+ public Image getImage(Object element)
+ {
+ TreeObject node = (TreeObject)element;
+ if (node.getType().equals(Constants.NOTIFICATION))
+ {
+ return ApplicationRegistry.getImage(Constants.NOTIFICATION_IMAGE);
+ }
+ else if (!node.getType().equals(Constants.MBEAN))
+ {
+ if (_treeViewer.getExpandedState(node))
+ return ApplicationRegistry.getImage(Constants.OPEN_FOLDER_IMAGE);
+ else
+ return ApplicationRegistry.getImage(Constants.CLOSED_FOLDER_IMAGE);
+
+ }
+ else
+ {
+ return ApplicationRegistry.getImage(Constants.MBEAN_IMAGE);
+ }
+ }
+
+ public String getText(Object element)
+ {
+ TreeObject node = (TreeObject)element;
+ return node.getName();
+ }
+
+ public Font getFont(Object element)
+ {
+ TreeObject node = (TreeObject)element;
+ if (node.getType().equals(Constants.SERVER))
+ {
+ if (node.getChildren().isEmpty())
+ return ApplicationRegistry.getFont(Constants.FONT_NORMAL);
+ else
+ return ApplicationRegistry.getFont(Constants.FONT_BOLD);
+ }
+ return ApplicationRegistry.getFont(Constants.FONT_NORMAL);
+ }
+
+ /*
+ public Color getForeground(Object element)
+ {
+ TreeObject node = (TreeObject)element;
+ if (node.getType().equals(Constants.SERVER))
+ {
+ if (!node.getChildren().isEmpty())
+ return Display.getCurrent().getSystemColor(SWT.COLOR_DARK_GREEN);
+ else
+ return Display.getCurrent().getSystemColor(SWT.COLOR_DARK_GRAY);
+ }
+ return Display.getCurrent().getSystemColor(SWT.COLOR_BLACK);
+ }
+ public Color getBackground(Object element)
+ {
+ return _treeViewer.getControl().getBackground();
+ }*/
+ } // End of LabelProviderImpl
+
+
+ private class ViewerSorterImpl extends ViewerSorter
+ {
+ public int category(Object element)
+ {
+ TreeObject node = (TreeObject)element;
+ if (node.getType().equals(Constants.MBEAN))
+ return 1;
+ return 2;
+ }
+ }
+
+ /**
+ * Worker thread, which keeps looking for new ManagedObjects to be added and
+ * unregistered objects to be removed from the tree.
+ * @author Bhupendra Bhardwaj
+ */
+ private class Worker implements Runnable
+ {
+ public void run()
+ {
+ while(true)
+ {
+ if (_managedServerMap.isEmpty())
+ continue;
+
+ try
+ {
+ Thread.sleep(2000);
+ }
+ catch(Exception ex)
+ {
+
+ }
+ refreshAddedObjects();
+ refreshRemovedObjects();
+ refreshClosedServerConnections();
+ }// end of while loop
+ }// end of run method.
+ }// end of Worker class
+
+
+ private void refreshAddedObjects()
+ {
+ for (ManagedServer server : _managedServerMap.keySet())
+ {
+ JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(server);
+ if (serverRegistry == null) // server connection is closed
+ continue;
+
+ final List<ManagedBean> list = serverRegistry.getObjectsToBeAdded();
+ if (list != null)
+ {
+ Display display = getSite().getShell().getDisplay();
+ display.syncExec(new Runnable()
+ {
+ public void run()
+ {
+ for (ManagedBean obj : list)
+ {
+ System.out.println("adding " + obj.getName() + " " + obj.getType());
+ TreeObject treeServerObject = _managedServerMap.get(obj.getServer());
+ List<TreeObject> domains = treeServerObject.getChildren();
+ TreeObject domain = null;
+ for (TreeObject child : domains)
+ {
+ if (child.getName().equals(obj.getDomain()))
+ {
+ domain = child;
+ break;
+ }
+ }
+
+ addManagedBean(domain, obj);
+ }
+ _treeViewer.refresh();
+ }
+ });
+ }
+ }
+ }
+
+ private void refreshRemovedObjects()
+ {
+ for (ManagedServer server : _managedServerMap.keySet())
+ {
+ final JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(server);
+ if (serverRegistry == null) // server connection is closed
+ continue;
+
+ final List<ManagedBean> removalList = serverRegistry.getObjectsToBeRemoved();
+ if (removalList != null)
+ {
+ Display display = getSite().getShell().getDisplay();
+ display.syncExec(new Runnable()
+ {
+ public void run()
+ {
+ for (ManagedBean mbean : removalList)
+ {
+ System.out.println("removing " + mbean.getName() + " " + mbean.getType());
+ TreeObject treeServerObject = _managedServerMap.get(mbean.getServer());
+ List<TreeObject> domains = treeServerObject.getChildren();
+ TreeObject domain = null;
+ for (TreeObject child : domains)
+ {
+ if (child.getName().equals(mbean.getDomain()))
+ {
+ domain = child;
+ break;
+ }
+ }
+ removeManagedObject(domain, mbean);
+ serverRegistry.removeManagedObject(mbean);
+ }
+ _treeViewer.refresh();
+ }
+ });
+ }
+ }
+ }
+
+ /**
+ *
+ *
+ */
+ private void refreshClosedServerConnections()
+ {
+ final List<ManagedServer> closedServers = ApplicationRegistry.getClosedServers();
+ if (closedServers != null)
+ {
+ Display display = getSite().getShell().getDisplay();
+ display.syncExec(new Runnable()
+ {
+ public void run()
+ {
+ for (ManagedServer server : closedServers)
+ {
+ removeManagedObject(_managedServerMap.get(server));
+ _managedServerMap.remove(server);
+ ApplicationRegistry.removeServer(server);
+ }
+
+ _treeViewer.refresh();
+ }
+ });
+ }
+ }
+
+} \ No newline at end of file
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NotificationsTabControl.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NotificationsTabControl.java
new file mode 100644
index 0000000000..c3f42f46aa
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NotificationsTabControl.java
@@ -0,0 +1,708 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui.views;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.qpid.management.ui.ApplicationRegistry;
+import org.apache.qpid.management.ui.Constants;
+import org.apache.qpid.management.ui.ManagedBean;
+import org.apache.qpid.management.ui.ServerRegistry;
+import org.apache.qpid.management.ui.jmx.MBeanUtility;
+import org.apache.qpid.management.ui.model.NotificationInfoModel;
+import org.apache.qpid.management.ui.model.NotificationObject;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.layout.FormLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.TabFolder;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.forms.widgets.Form;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+
+/**
+ *
+ * @author Bhupendra Bhardwaj
+ *
+ */
+public class NotificationsTabControl extends TabControl
+{
+ private FormToolkit _toolkit;
+ private Form _form;
+ private Table table = null;
+ private TableViewer _tableViewer = null;
+
+ private IStructuredContentProvider contentProvider = new ContentProviderImpl();
+ private SelectionListener selectionListener = new SelectionListenerImpl();
+ private SelectionListener comboListener = new ComboSelectionListener();
+
+ private Thread worker = null;
+
+ private List<NotificationObject> _notifications = null;
+ private static final String COLUMN_SEQ = "Sequence No";
+ private static final String COLUMN_TIME = "TimeStamp";
+ private static final String COLUMN_TYPE = "Type";
+ private static final String COLUMN_MSG = "Notification Message";
+ private static final String[] _tableTitles = new String [] {
+ COLUMN_SEQ,
+ COLUMN_TIME,
+ COLUMN_TYPE,
+ COLUMN_MSG
+ };
+
+ private Combo notificationNameCombo = null;
+ private Combo typesCombo = null;
+ private Label descriptionLabel = null;
+ private Button _subscribeButton = null;
+ private Button _unsubscribeButton = null;
+ private Button _clearButton = null;
+ private Button _refreshButton = null;
+
+
+ public NotificationsTabControl(TabFolder tabFolder)
+ {
+ super(tabFolder);
+ _toolkit = new FormToolkit(_tabFolder.getDisplay());
+ _form = _toolkit.createForm(_tabFolder);
+ GridLayout gridLayout = new GridLayout();
+ gridLayout.marginWidth = 0;
+ gridLayout.marginHeight = 0;
+ _form.getBody().setLayout(gridLayout);
+
+ createWidgets();
+ worker = new Thread(new Worker());
+ worker.start();
+ }
+
+ private void createWidgets()
+ {
+ createNotificationInfoComposite();
+ //addFilterComposite();
+ addButtons();
+ createTableViewer();
+ }
+
+ public Control getControl()
+ {
+ return _form;
+ }
+
+ private void createNotificationInfoComposite()
+ {
+ Composite composite = _toolkit.createComposite(_form.getBody(), SWT.NONE);
+ composite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+ composite.setLayout(new FormLayout());
+
+ Label label = _toolkit.createLabel(composite, "Select the notification to subscribe or unsubscribe");
+ label.setFont(ApplicationRegistry.getFont(Constants.FONT_BOLD));
+ FormData formData = new FormData();
+ formData.top = new FormAttachment(0, 10);
+ formData.left = new FormAttachment(0, 10);
+ label.setLayoutData(formData);
+
+ notificationNameCombo = new Combo(composite, SWT.READ_ONLY | SWT.DROP_DOWN);
+ formData = new FormData();
+ formData.top = new FormAttachment(label, 10);
+ formData.left = new FormAttachment(0, 10);
+ formData.right = new FormAttachment(40);
+ notificationNameCombo.setLayoutData(formData);
+ notificationNameCombo.addSelectionListener(comboListener);
+
+ typesCombo = new Combo(composite, SWT.READ_ONLY | SWT.DROP_DOWN);
+ formData = new FormData();
+ formData.top = new FormAttachment(label, 10);
+ formData.left = new FormAttachment(notificationNameCombo, 5);
+ formData.right = new FormAttachment(65);
+ typesCombo.setLayoutData(formData);
+ typesCombo.addSelectionListener(comboListener);
+
+ _subscribeButton = new Button(composite, SWT.PUSH | SWT.CENTER);
+ _subscribeButton.setFont(ApplicationRegistry.getFont(Constants.FONT_BUTTON));
+ _subscribeButton.setText(Constants.SUBSCRIBE_BUTTON);
+ formData = new FormData();
+ formData.top = new FormAttachment(label, 10);
+ formData.left = new FormAttachment(65, 10);
+ formData.width = 80;
+ _subscribeButton.setLayoutData(formData);
+ _subscribeButton.addSelectionListener(selectionListener);
+
+ _unsubscribeButton = new Button(composite, SWT.PUSH | SWT.CENTER);
+ _unsubscribeButton.setFont(ApplicationRegistry.getFont(Constants.FONT_BUTTON));
+ _unsubscribeButton.setText(Constants.UNSUBSCRIBE_BUTTON);
+ formData = new FormData();
+ formData.top = new FormAttachment(label, 10);
+ formData.left = new FormAttachment(_subscribeButton, 10);
+ formData.width = 80;
+ _unsubscribeButton.setLayoutData(formData);
+ _unsubscribeButton.addSelectionListener(selectionListener);
+
+ Label fixedLabel = _toolkit.createLabel(composite, "");
+ formData = new FormData();
+ formData.top = new FormAttachment(notificationNameCombo, 5);
+ formData.left = new FormAttachment(0, 10);
+ fixedLabel.setLayoutData(formData);
+ fixedLabel.setText(Constants.DESCRIPTION);
+ fixedLabel.setFont(ApplicationRegistry.getFont(Constants.FONT_BOLD));
+
+ descriptionLabel = _toolkit.createLabel(composite, "");
+ formData = new FormData();
+ formData.top = new FormAttachment(notificationNameCombo, 5);
+ formData.left = new FormAttachment(fixedLabel, 10);
+ formData.right = new FormAttachment(80);
+ descriptionLabel.setLayoutData(formData);
+ descriptionLabel.setText(" ");
+ descriptionLabel.setFont(ApplicationRegistry.getFont(Constants.FONT_ITALIC));
+ }
+
+ private void addButtons()
+ {
+ Composite composite = _toolkit.createComposite(_form.getBody(), SWT.NONE);
+ composite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+ composite.setLayout(new GridLayout(2, true));
+
+ // Add Clear Button
+ _clearButton = _toolkit.createButton(composite, Constants.BUTTON_CLEAR, SWT.PUSH | SWT.CENTER);
+ _clearButton.setFont(ApplicationRegistry.getFont(Constants.FONT_BUTTON));
+ GridData gridData = new GridData(SWT.LEAD, SWT.TOP, true, false);
+ gridData.widthHint = 80;
+ _clearButton.setLayoutData(gridData);
+ _clearButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ if (_mbean == null)
+ return;
+
+ ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(_mbean);
+ serverRegistry.clearNotifications(_mbean);
+ refresh();
+ }
+ });
+
+ // Add Refresh Button
+ _refreshButton = _toolkit.createButton(composite, Constants.BUTTON_REFRESH, SWT.PUSH | SWT.CENTER);
+ _refreshButton.setFont(ApplicationRegistry.getFont(Constants.FONT_BUTTON));
+ gridData = new GridData(SWT.TRAIL, SWT.TOP, true, false);
+ gridData.widthHint = 80;
+ _refreshButton.setLayoutData(gridData);
+ _refreshButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ if (_mbean == null)
+ return;
+
+ refresh();
+ }
+ });
+ }
+
+ private void createTable()
+ {
+ table = _toolkit.createTable(_form.getBody(), SWT.FULL_SELECTION);
+ table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+
+ TableColumn column = new TableColumn(table, SWT.NONE);
+ column.setText(_tableTitles[0]);
+ column.pack(); //column.setWidth(200);
+
+ column = new TableColumn(table, SWT.NONE);
+ column.setText(_tableTitles[1]);
+ column.setWidth(150);
+
+ column = new TableColumn(table, SWT.NONE);
+ column.setText(_tableTitles[2]);
+ column.setWidth(100);
+
+ column = new TableColumn(table, SWT.NONE);
+ column.setText(_tableTitles[3]);
+ column.setWidth(500);
+
+ table.setHeaderVisible(true);
+ table.setLinesVisible(true);
+ }
+
+ protected void createTableViewer()
+ {
+ createTable();
+ _tableViewer = new TableViewer(table);
+ //_tableViewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ _tableViewer.setUseHashlookup(true);
+ _tableViewer.setContentProvider(contentProvider);
+ _tableViewer.setLabelProvider(new LabelProviderImpl());
+ _tableViewer.setColumnProperties(_tableTitles);
+ /*
+ CellEditor[] cellEditors = new CellEditor[_tableTitles.length];
+ TextCellEditor textEditor = new TextCellEditor(table);
+ cellEditors[0] = textEditor;
+ textEditor = new TextCellEditor(table);
+ cellEditors[1] = textEditor;
+ textEditor = new TextCellEditor(table);
+ cellEditors[2] = textEditor;
+ textEditor = new TextCellEditor(table);
+ cellEditors[3] = textEditor;
+
+ // Assign the cell editors to the viewer
+ _tableViewer.setCellEditors(cellEditors);
+ _tableViewer.setCellModifier(new TableCellModifier());
+ */
+
+ addTableListeners();
+
+ //_tableViewer.addSelectionChangedListener(new );
+
+ //_notificationDetails = new Composite(_tabControl, SWT.BORDER);
+ //_notificationDetails.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ //_tabControl.layout();
+ //viewerComposite.layout();
+ }
+
+ private void addTableListeners()
+ {
+ _tableViewer.addDoubleClickListener(new IDoubleClickListener()
+ {
+ Display display = null;
+ Shell shell = null;
+ public void doubleClick(DoubleClickEvent event)
+ {
+ System.out.println("DoubleClickEvent" + event);
+ display = Display.getCurrent();
+ shell = new Shell(display, SWT.BORDER | SWT.CLOSE | SWT.MIN |
+ SWT.MAX | SWT.RESIZE);
+ shell.setText("Notification");
+
+ int x = display.getBounds().width;
+ int y = display.getBounds().height;
+ shell.setBounds(x/4, y/4, x/2, y/3);
+ StructuredSelection selection = (StructuredSelection)event.getSelection();
+ createPopupContents((NotificationObject)selection.getFirstElement());
+ shell.open();
+ while (!shell.isDisposed()) {
+ if (!display.readAndDispatch()) {
+ display.sleep();
+ }
+ }
+
+ //If you create it, you dispose it.
+ shell.dispose();
+ }
+
+ private void createPopupContents(NotificationObject obj)
+ {
+ shell.setLayout(new GridLayout());
+
+ Composite parent = new Composite(shell, SWT.NONE);
+ parent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ GridLayout layout = new GridLayout(4, true);
+ parent.setLayout(layout);
+
+ Label key = new Label(parent, SWT.TRAIL);
+ key.setText(COLUMN_SEQ);
+ GridData layoutData = new GridData(SWT.TRAIL, SWT.TOP, false, false,1,1);
+ key.setLayoutData(layoutData);
+ Text value = new Text(parent, SWT.BEGINNING | SWT.BORDER |SWT.READ_ONLY);
+ value.setText(""+obj.getSequenceNo());
+ value.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false,3,1));
+
+ // Time row
+ key = new Label(parent, SWT.TRAIL);
+ key.setText(COLUMN_TIME);
+ key.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, true, false,1,1));
+ value = new Text(parent, SWT.BEGINNING | SWT.BORDER | SWT.READ_ONLY);
+ value.setText(""+obj.getTimeStamp());
+ value.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false,3,1));
+
+ key = new Label(parent, SWT.TRAIL);
+ key.setText(COLUMN_TYPE);
+ key.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, true, false,1,1));
+ value = new Text(parent, SWT.BEGINNING | SWT.BORDER | SWT.READ_ONLY);
+ value.setText(""+obj.getType());
+ value.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false,3,1));
+
+ key = new Label(parent, SWT.TRAIL);
+ key.setText(COLUMN_MSG);
+ key.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, true, false,1,1));
+ value = new Text(parent, SWT.MULTI | SWT.WRAP| SWT.BORDER | SWT.V_SCROLL | SWT.READ_ONLY);
+ value.setText(""+obj.getMessage());
+ GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1);
+ gridData.heightHint = 100;
+ value.setLayoutData(gridData);
+ }
+ });
+ }
+
+ @Override
+ public void refresh(ManagedBean mbean)
+ {
+ _mbean = mbean;
+ _notifications = null;
+ _tableViewer.getTable().clearAll();
+
+ if (_mbean == null)
+ {
+ _tableViewer.getTable().clearAll();
+ _subscribeButton.setEnabled(false);
+ _unsubscribeButton.setEnabled(false);
+ return;
+ }
+
+ if (!doesMBeanSendsNotification())
+ {
+ Control[] children = _form.getBody().getChildren();
+ for (int i = 0; i < children.length; i++)
+ {
+ children[i].setVisible(false);
+ }
+
+ String name = (_mbean.getName() != null) ? _mbean.getName() : _mbean.getType();
+ _form.setText(name + " does not send any notification");
+ return;
+ }
+
+ Control[] children = _form.getBody().getChildren();
+ for (int i = 0; i < children.length; i++)
+ {
+ children[i].setVisible(true);
+ }
+
+ populateNotificationInfo();
+ /*
+ ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(_mbean);
+ _notifications = serverRegistry.getNotifications(_mbean);
+ if (_notifications != null)
+ {
+ _tableViewer.setInput(_notifications);
+
+ }*/
+ //_tableViewer.setInput(null);
+ workerRunning = true;
+ _form.layout();
+ }
+
+ private void refresh()
+ {
+ _notifications = null;
+ _tableViewer.getTable().clearAll();
+ }
+
+ private void populateNotificationInfo()
+ {
+ notificationNameCombo.removeAll();
+ NotificationInfoModel[] items = MBeanUtility.getNotificationInfo(_mbean);
+ notificationNameCombo.add("Select Notification");
+ for (int i = 0; i < items.length; i++)
+ {
+ notificationNameCombo.add(items[i].getName());
+ notificationNameCombo.setData(items[i].getName(), items[i]);
+ }
+ notificationNameCombo.select(0);
+
+ typesCombo.removeAll();
+ typesCombo.add("Select Type", 0);
+ typesCombo.select(0);
+ typesCombo.setEnabled(false);
+
+ checkForEnablingButtons();
+ }
+
+ private void checkForEnablingButtons()
+ {
+ int nameIndex = notificationNameCombo.getSelectionIndex();
+ if (nameIndex == 0)
+ {
+ _subscribeButton.setEnabled(false);
+ _unsubscribeButton.setEnabled(false);
+ descriptionLabel.setText("");
+ return;
+ }
+
+ int typeIndex = typesCombo.getSelectionIndex();
+ if (typeIndex == 0)
+ {
+ _subscribeButton.setEnabled(false);
+ _unsubscribeButton.setEnabled(false);
+ return;
+ }
+
+ String type = typesCombo.getItem(typeIndex);
+ String name = notificationNameCombo.getItem(nameIndex);
+ ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(_mbean);
+
+ if (serverRegistry.hasSubscribedForNotifications(_mbean, name, type))
+ {
+ _subscribeButton.setEnabled(false);
+ _unsubscribeButton.setEnabled(true);
+ }
+ else
+ {
+ _subscribeButton.setEnabled(true);
+ _unsubscribeButton.setEnabled(false);
+ }
+ }
+
+ private boolean doesMBeanSendsNotification()
+ {
+ NotificationInfoModel[] items = MBeanUtility.getNotificationInfo(_mbean);
+ if (items == null || items.length == 0)
+ return false;
+ else
+ return true;
+ }
+
+ private class SelectionListenerImpl extends SelectionAdapter
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ if (_mbean == null)
+ return;
+
+ Button source = (Button)e.getSource();
+ String type = typesCombo.getItem(typesCombo.getSelectionIndex());
+ String name = notificationNameCombo.getItem(notificationNameCombo.getSelectionIndex());
+ if (source == _unsubscribeButton)
+ {
+ try
+ {
+ MBeanUtility.removeNotificationListener(_mbean, name, type);
+ }
+ catch(Exception ex)
+ {
+ MBeanUtility.handleException(ex);
+ }
+ }
+ else if (source == _subscribeButton)
+ {
+ try
+ {
+ MBeanUtility.createNotificationlistener(_mbean, name, type);
+ }
+ catch(Exception ex)
+ {
+ MBeanUtility.handleException(ex);
+ }
+ }
+ checkForEnablingButtons();
+ }
+ }
+
+
+ private class ComboSelectionListener extends SelectionAdapter
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ if (_mbean == null)
+ return;
+
+ Combo combo = (Combo)e.getSource();
+ if (combo == notificationNameCombo)
+ {
+ if (combo.getSelectionIndex() == 0)
+ {
+ descriptionLabel.setText("");
+ typesCombo.select(0);
+ typesCombo.setEnabled(false);
+ return;
+ }
+ String index = combo.getItem(combo.getSelectionIndex());
+ NotificationInfoModel data = (NotificationInfoModel)combo.getData(index);
+ descriptionLabel.setText(data.getDescription());
+ typesCombo.removeAll();
+ typesCombo.setItems(data.getTypes());
+ typesCombo.add("Select Type", 0);
+ typesCombo.select(0);
+ typesCombo.setEnabled(true);
+ }
+ checkForEnablingButtons();
+ }
+ }
+
+ private class ContentProviderImpl implements IStructuredContentProvider, INotificationViewer
+ {
+ public void inputChanged(Viewer v, Object oldInput, Object newInput)
+ {
+
+ }
+ public void dispose()
+ {
+
+ }
+ public Object[] getElements(Object parent)
+ {
+ return _notifications.toArray(new NotificationObject[0]);
+ }
+ public void addNotification(NotificationObject notification)
+ {
+ _tableViewer.add(notification);
+ }
+
+ public void addNotification(List<NotificationObject> notificationList)
+ {
+ _tableViewer.add(notificationList.toArray(new NotificationObject[0]));
+ }
+ }
+
+ private class LabelProviderImpl implements ITableLabelProvider
+ {
+ List<ILabelProviderListener> listeners = new ArrayList<ILabelProviderListener>();
+ public void addListener(ILabelProviderListener listener)
+ {
+ listeners.add(listener);
+ }
+
+ public void dispose(){
+
+ }
+
+ public Image getColumnImage(Object element, int columnIndex)
+ {
+ return null;
+ }
+
+ public String getColumnText(Object element, int columnIndex)
+ {
+ String result = null;
+ NotificationObject t = (NotificationObject)element;
+ switch(columnIndex)
+ {
+ case 0 :
+ result = String.valueOf(t.getSequenceNo());
+ break;
+ case 1 :
+ result = String.valueOf(t.getTimeStamp());
+ break;
+ case 2 :
+ result = t.getType();
+ break;
+ case 3 :
+ result = t.getMessage();
+ break;
+ default :
+ result = "";
+ }
+
+ return result;
+ }
+
+ public boolean isLabelProperty(Object element, String property)
+ {
+ return false;
+ }
+
+ public void removeListener(ILabelProviderListener listener)
+ {
+ listeners.remove(listener);
+ }
+ } // end of LabelProviderImpl
+
+ private boolean workerRunning = false;
+ private void setWorkerRunning(boolean running)
+ {
+ workerRunning = running;
+ }
+
+ private class Worker implements Runnable
+ {
+ public void run()
+ {
+ Display display = _tabFolder.getDisplay();
+ while(true)
+ {
+ if (!workerRunning || _mbean == null || display == null)
+ {
+ sleep();
+ continue;
+ }
+
+ display.syncExec(new Runnable()
+ {
+ public void run()
+ {
+ setWorkerRunning(_form.isVisible());
+ if (!workerRunning) return;
+
+ updateTableViewer();
+ }
+ });
+
+ sleep();
+ }
+ }
+
+ private void sleep()
+ {
+ try
+ {
+ Thread.sleep(2000);
+ }
+ catch(Exception ex)
+ {
+
+ }
+ }
+ }
+
+ private void updateTableViewer()
+ {
+ ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(_mbean);
+ List<NotificationObject> newList = serverRegistry.getNotifications(_mbean);
+ if (newList == null)
+ return;
+
+ /*
+ int notificationCount = 0;
+ if (_notifications != null)
+ notificationCount = _notifications.size();
+
+ for (int i = notificationCount; i < newList.size(); i++)
+ {
+ ((INotificationViewer)contentProvider).addNotification(newList.get(i));
+ }*/
+
+ _notifications = newList;
+ _tableViewer.setInput(_notifications);
+ _tableViewer.refresh();
+ }
+}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/OperationTabControl.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/OperationTabControl.java
new file mode 100644
index 0000000000..8563bdb882
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/OperationTabControl.java
@@ -0,0 +1,718 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui.views;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map.Entry;
+
+import javax.management.openmbean.CompositeDataSupport;
+import javax.management.openmbean.TabularDataSupport;
+
+import org.apache.qpid.management.ui.ApplicationRegistry;
+import org.apache.qpid.management.ui.Constants;
+import org.apache.qpid.management.ui.ManagedBean;
+import org.apache.qpid.management.ui.ServerRegistry;
+import org.apache.qpid.management.ui.jmx.MBeanUtility;
+import org.apache.qpid.management.ui.model.OperationData;
+import org.apache.qpid.management.ui.model.ParameterData;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.ScrolledComposite;
+import org.eclipse.swt.events.KeyAdapter;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.events.VerifyEvent;
+import org.eclipse.swt.events.VerifyListener;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.layout.FormLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.TabFolder;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.forms.widgets.Form;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+
+
+/**
+ * Control class for the MBean operations tab. It creates the required widgets
+ * for the selected MBean.
+ * @author Bhupendra Bhardwaj
+ *
+ */
+public class OperationTabControl extends TabControl
+{
+ private int heightForAParameter = 30;
+ private int labelNumerator = 30;
+ private int valueNumerator = labelNumerator + 20;
+
+ private FormToolkit _toolkit;
+ private Form _form;
+ private OperationData _opData;
+
+ private SelectionListener operationExecutionListener = new OperationExecutionListener();
+ private SelectionListener refreshListener = new RefreshListener();
+ private SelectionListener parameterSelectionListener = new ParameterSelectionListener();
+ private SelectionListener bolleanSelectionListener = new BooleanSelectionListener();
+ private VerifyListener verifyListener = new VerifyListenerImpl();
+ private KeyListener keyListener = new KeyListenerImpl();
+ private KeyListener headerBindingListener = new HeaderBindingKeyListener();
+
+ private Composite _headerComposite = null;
+ private Composite _paramsComposite = null;
+ private Composite _resultsComposite = null;
+ private Button _executionButton = null;
+
+ // for customized method in header exchange
+ private HashMap<Text, Text> headerBindingHashMap = null;
+
+ public OperationTabControl(TabFolder tabFolder)
+ {
+ super(tabFolder);
+ _toolkit = new FormToolkit(_tabFolder.getDisplay());
+ _form = _toolkit.createForm(_tabFolder);
+ _form.getBody().setLayout(new GridLayout());
+
+ // Form area is devided in four parts:
+ // Header composite - displays operaiton information
+ // Patameters composite - displays parameters if there
+ // Button - operation execution button
+ // Results composite - displays results for operations, which have
+ // no parameters but have some return value
+ _headerComposite = _toolkit.createComposite(_form.getBody(), SWT.NONE);
+ _headerComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+
+ _paramsComposite = _toolkit.createComposite(_form.getBody(), SWT.NONE);
+ _paramsComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+
+ _executionButton = _toolkit.createButton(_form.getBody(), Constants.BUTTON_EXECUTE, SWT.PUSH | SWT.CENTER);
+ _executionButton.setFont(ApplicationRegistry.getFont(Constants.FONT_BUTTON));
+ GridData layoutData = new GridData(SWT.CENTER, SWT.TOP, true, false);
+ layoutData.verticalIndent = 20;
+ _executionButton.setLayoutData(layoutData);
+
+ _resultsComposite = _toolkit.createComposite(_form.getBody(), SWT.NONE);
+ layoutData = new GridData(SWT.FILL, SWT.FILL, true, true);
+ layoutData.verticalIndent = 20;
+ _resultsComposite.setLayoutData(layoutData);
+ _resultsComposite.setLayout(new GridLayout());
+ }
+
+ public Control getControl()
+ {
+ return _form;
+ }
+
+ public void refresh(ManagedBean mbean)
+ {
+ _mbean = mbean;
+ ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(mbean);
+ _opData = serverRegistry.getOperationModel(mbean).getOperations().get(0);
+ refresh(_mbean, _opData);
+ }
+ public void refresh(ManagedBean mbean, OperationData opData)
+ {
+ _mbean = mbean;
+ _opData = opData;
+
+ // Setting the form to be invisible. Just in case the mbean server connection
+ // is done and it takes time in getting the response, then the ui should be blank
+ // instead of having half the widgets displayed.
+ _form.setVisible(false);
+
+ ViewUtility.disposeChildren(_headerComposite);
+ ViewUtility.disposeChildren(_paramsComposite);
+ ViewUtility.disposeChildren(_resultsComposite);
+
+ setHeader();
+ createParameterWidgets();
+
+ List<ParameterData> params = opData.getParameters();
+ if (params != null && !params.isEmpty())
+ {
+ setButton(Constants.BUTTON_EXECUTE);
+ }
+ else if (opData.getImpact() == Constants.OPERATION_IMPACT_ACTION)
+ {
+ setButton(Constants.BUTTON_EXECUTE);
+ }
+ else if (opData.getImpact() == Constants.OPERATION_IMPACT_INFO)
+ {
+ setButton(Constants.BUTTON_REFRESH);
+ executeAndShowResults();
+ }
+
+ _form.setVisible(true);
+ _form.layout();
+ }
+
+ private void setHeader()
+ {
+ _form.setText(ViewUtility.getDisplayText(_opData.getName()));
+ _headerComposite.setLayout(new GridLayout(2, false));
+ //operation description
+ Label label = _toolkit.createLabel(_headerComposite, Constants.DESCRIPTION);
+ label.setFont(ApplicationRegistry.getFont(Constants.FONT_BOLD));
+ label.setLayoutData(new GridData(SWT.LEAD, SWT.TOP, false, false));
+
+ label = _toolkit.createLabel(_headerComposite, _opData.getDescription());
+ label.setFont(ApplicationRegistry.getFont(Constants.FONT_NORMAL));
+ label.setLayoutData(new GridData(SWT.LEAD, SWT.TOP, true, false));
+
+ _headerComposite.layout();
+ }
+
+ private void createParameterWidgets()
+ {
+ List<ParameterData> params = _opData.getParameters();
+ if (params == null || params.isEmpty())
+ {
+ return;
+ }
+
+ // Customised parameter widgets
+ if (_mbean.getType().equals(Constants.EXCHANGE) &&
+ "headers".equals(_mbean.getProperty(Constants.EXCHANGE_TYPE)) &&
+ _opData.getName().equalsIgnoreCase("createNewBinding"))
+ {
+ customCreateNewBinding();
+ return;
+ }
+ // end of Customised parameter widgets
+
+ _paramsComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+ _paramsComposite.setLayout(new FormLayout());
+ for (ParameterData param : params)
+ {
+ boolean valueInCombo = false;
+ Label label = _toolkit.createLabel(_paramsComposite, ViewUtility.getDisplayText(param.getName()));
+ FormData formData = new FormData();
+ formData.top = new FormAttachment(0, params.indexOf(param) * heightForAParameter + 2);
+ formData.right = new FormAttachment(labelNumerator);
+ label.setLayoutData(formData);
+ label.setToolTipText(param.getDescription());
+
+ formData = new FormData();
+ formData.top = new FormAttachment(0, params.indexOf(param) * heightForAParameter);
+ formData.left = new FormAttachment(label, 5);
+ formData.right = new FormAttachment(valueNumerator);
+ if (param.getName().equals(Constants.QUEUE))
+ {
+ Combo combo = new Combo(_paramsComposite, SWT.READ_ONLY | SWT.DROP_DOWN);
+ String[] items = ApplicationRegistry.getServerRegistry(_mbean).getQueueNames();
+ combo.setItems(items);
+ combo.add("Select Queue", 0);
+ combo.select(0);
+ combo.setLayoutData(formData);
+ combo.setData(param);
+ combo.addSelectionListener(parameterSelectionListener);
+ valueInCombo = true;
+ }
+ else if (param.getName().equals(Constants.EXCHANGE))
+ {
+ Combo combo = new Combo(_paramsComposite, SWT.READ_ONLY | SWT.DROP_DOWN);
+ String[] items = ApplicationRegistry.getServerRegistry(_mbean).getExchangeNames();
+ combo.setItems(items);
+ combo.add("Select Exchange", 0);
+ combo.select(0);
+ combo.setLayoutData(formData);
+ combo.setData(param);
+ combo.addSelectionListener(parameterSelectionListener);
+ valueInCombo = true;
+ }
+ else if (param.getName().equals(Constants.EXCHANGE_TYPE))
+ {
+ Combo combo = new Combo(_paramsComposite, SWT.READ_ONLY | SWT.DROP_DOWN);
+ combo.setItems(Constants.EXCHANGE_TYPE_VALUES);
+ combo.add("Select Exchange Type", 0);
+ combo.select(0);
+ combo.setLayoutData(formData);
+ combo.setData(param);
+ combo.addSelectionListener(parameterSelectionListener);
+ valueInCombo = true;
+ }
+ else if (param.getType().equals("boolean") || param.getType().equals("java.lang.Boolean"))
+ {
+ Combo combo = new Combo(_paramsComposite, SWT.READ_ONLY | SWT.DROP_DOWN);
+ combo.setItems(new String[] {"false", "true"});
+ combo.select(0);
+ param.setValueFromString(combo.getItem(0));
+ combo.setLayoutData(formData);
+ combo.setData(param);
+ combo.addSelectionListener(bolleanSelectionListener);
+ valueInCombo = true;
+ }
+ else
+ {
+ Text text = _toolkit.createText(_paramsComposite, "", SWT.NONE);
+ formData = new FormData();
+ formData.top = new FormAttachment(0, params.indexOf(param) * heightForAParameter);
+ formData.left = new FormAttachment(label, 5);
+ formData.right = new FormAttachment(valueNumerator);
+ text.setLayoutData(formData);
+ text.addKeyListener(keyListener);
+ text.addVerifyListener(verifyListener);
+ text.setData(param);
+ }
+
+ // parameter type (int, String etc)
+ if (valueInCombo)
+ label = _toolkit.createLabel(_paramsComposite, "");
+ else
+ {
+ String str = param.getType() ;
+ if (param.getType().lastIndexOf(".") != -1)
+ str = param.getType().substring(1 + param.getType().lastIndexOf("."));
+
+ label = _toolkit.createLabel(_paramsComposite, "(" + str + ")");
+ }
+ formData = new FormData();
+ formData.top = new FormAttachment(0, params.indexOf(param) * heightForAParameter);
+ formData.left = new FormAttachment(valueNumerator, 5);
+ label.setLayoutData(formData);
+ }
+
+ //_parametersHolder.setMinSize(_parametersComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT));
+ //_parametersComposite.layout();
+ }
+
+ private void customCreateNewBinding()
+ {
+ headerBindingHashMap = new HashMap<Text, Text>();
+
+ _paramsComposite.setLayout(new GridLayout());
+ _paramsComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, true));
+ final ScrolledComposite scrolledComposite = new ScrolledComposite(_paramsComposite, SWT.BORDER | SWT.V_SCROLL);
+ scrolledComposite.setExpandHorizontal(true);
+ scrolledComposite.setExpandVertical(true);
+ GridData layoutData = new GridData(SWT.FILL, SWT.TOP, true, true);
+ scrolledComposite.setLayoutData(layoutData);
+ scrolledComposite.setLayout(new GridLayout());
+
+ final Composite composite = _toolkit.createComposite(scrolledComposite, SWT.NONE);
+ scrolledComposite.setContent(composite);
+ layoutData = new GridData(SWT.FILL, SWT.FILL, true, true);
+ layoutData.verticalIndent = 20;
+ composite.setLayoutData(layoutData);
+ composite.setLayout(new FormLayout());
+
+ List<ParameterData> params = _opData.getParameters();
+ ParameterData param = params.get(0);
+ // Queue selection widget
+ Label label = _toolkit.createLabel(composite, ViewUtility.getDisplayText(param.getName()));
+ FormData formData = new FormData();
+ formData.top = new FormAttachment(0, 2);
+ formData.right = new FormAttachment(labelNumerator);
+ label.setLayoutData(formData);
+ label.setToolTipText(param.getDescription());
+
+ formData = new FormData();
+ formData.top = new FormAttachment(0);
+ formData.left = new FormAttachment(label, 5);
+ formData.right = new FormAttachment(valueNumerator);
+
+ Combo combo = new Combo(composite, SWT.READ_ONLY | SWT.DROP_DOWN);
+ String[] items = ApplicationRegistry.getServerRegistry(_mbean).getQueueNames();
+ combo.setItems(items);
+ combo.add("Select Queue", 0);
+ combo.select(0);
+ combo.setLayoutData(formData);
+ combo.setData(param);
+ combo.addSelectionListener(parameterSelectionListener);
+
+ // Binding creation widgets
+ createARowForCreatingHeadersBinding(composite, 1);
+ createARowForCreatingHeadersBinding(composite, 2);
+ createARowForCreatingHeadersBinding(composite, 3);
+ createARowForCreatingHeadersBinding(composite, 4);
+ createARowForCreatingHeadersBinding(composite, 5);
+ createARowForCreatingHeadersBinding(composite, 6);
+ createARowForCreatingHeadersBinding(composite, 7);
+ createARowForCreatingHeadersBinding(composite, 8);
+
+ final Button addMoreButton = _toolkit.createButton(composite, "Add More", SWT.PUSH);
+ formData = new FormData();
+ formData.top = new FormAttachment(0, heightForAParameter);
+ formData.left = new FormAttachment(70, 5);
+ addMoreButton.setLayoutData(formData);
+ addMoreButton.setData("rowCount", 8);
+ addMoreButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ int count = Integer.parseInt(addMoreButton.getData("rowCount").toString());
+ createARowForCreatingHeadersBinding(composite, ++count);
+ addMoreButton.setData("rowCount", count);
+ scrolledComposite.setMinSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT));
+ composite.layout();
+ _form.layout();
+ }
+ });
+
+ scrolledComposite.setMinSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT));
+ composite.layout();
+ }
+
+ private void createARowForCreatingHeadersBinding(Composite parent, int rowCount)
+ {
+ Label key = _toolkit.createLabel(parent, "Name");
+ FormData formData = new FormData();
+ formData.top = new FormAttachment(0, rowCount * heightForAParameter + 2);
+ formData.right = new FormAttachment(15);
+ key.setLayoutData(formData);
+
+ Text keyText = _toolkit.createText(parent, "", SWT.NONE);
+ formData = new FormData();
+ formData.top = new FormAttachment(0, rowCount * heightForAParameter);
+ formData.left = new FormAttachment(key, 5);
+ formData.right = new FormAttachment(40);
+ keyText.setLayoutData(formData);
+ keyText.addKeyListener(headerBindingListener);
+
+ Label value = _toolkit.createLabel(parent, "Value");
+ formData = new FormData();
+ formData.top = new FormAttachment(0, rowCount * heightForAParameter + 2);
+ formData.right = new FormAttachment(45);
+ value.setLayoutData(formData);
+
+ Text valueText = _toolkit.createText(parent, "", SWT.NONE);
+ formData = new FormData();
+ formData.top = new FormAttachment(0, rowCount * heightForAParameter);
+ formData.left = new FormAttachment(value, 5);
+ formData.right = new FormAttachment(70);
+ valueText.setLayoutData(formData);
+ valueText.addKeyListener(headerBindingListener);
+
+ // Add these to the map, to retrieve the values while setting the parameter value
+ headerBindingHashMap.put(keyText, valueText);
+ }
+
+ private void setButton(String text)
+ {
+ _executionButton.setText(text);
+ _executionButton.removeSelectionListener(refreshListener);
+ _executionButton.removeSelectionListener(operationExecutionListener);
+
+ if (Constants.BUTTON_EXECUTE.equals(text))
+ {
+ _executionButton.addSelectionListener(operationExecutionListener);
+ }
+ else
+ {
+ _executionButton.addSelectionListener(refreshListener);
+ }
+ }
+
+ private void populateResults(Object result)
+ {
+ Display display = Display.getCurrent();
+ int width = 600;
+ int height = 400;
+ Shell shell = ViewUtility.createPopupShell("Result", width, height);
+ populateResults(result, shell);
+
+ shell.open();
+ while (!shell.isDisposed()) {
+ if (!display.readAndDispatch()) {
+ display.sleep();
+ }
+ }
+ shell.dispose();
+ }
+
+ private void populateResults(Object result, Composite parent)
+ {
+ if (result instanceof TabularDataSupport)
+ {
+ ViewUtility.createTabularDataHolder(parent, (TabularDataSupport)result);
+ }
+ else if (result instanceof CompositeDataSupport)
+ {
+ ViewUtility.populateCompositeDataHolder(parent, (CompositeDataSupport)result);
+ }
+ }
+
+ /**
+ * clears the parameter values entered.
+ * @param opName
+
+ private void clearParameterValues()
+ {
+ List<ParameterData> params = _opData.getParameters();
+ if (params != null && !params.isEmpty())
+ {
+ for (ParameterData param : params)
+ {
+ param.setValue(null);
+ }
+
+ Control[] controls = _paramsComposite.getChildren();
+
+ for (int i = 0; i < controls.length; i++)
+ {
+ if (controls[i] instanceof Combo)
+ ((Combo)controls[i]).select(0);
+ else if (controls[i] instanceof Text)
+ ((Text)controls[i]).setText("");
+ }
+ }
+ }*/
+
+ private void clearParameters()
+ {
+ List<ParameterData> params = _opData.getParameters();
+ if (params != null && !params.isEmpty())
+ {
+ for (ParameterData param : params)
+ {
+ param.setValue(null);
+ }
+ }
+ }
+
+ private void clearParameterValues(Composite control)
+ {
+ Control[] controls = control.getChildren();
+ if (controls == null || controls.length == 0)
+ return;
+
+ for (int i = 0; i < controls.length; i++)
+ {
+ if (controls[i] instanceof Combo)
+ ((Combo)controls[i]).select(0);
+ else if (controls[i] instanceof Text)
+ ((Text)controls[i]).setText("");
+ else if (controls[i] instanceof Composite)
+ clearParameterValues((Composite)controls[i]);
+ }
+ }
+
+ /**
+ * Listener class for operation execution events
+ */
+ private class OperationExecutionListener extends SelectionAdapter
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ List<ParameterData> params = _opData.getParameters();
+ if (params != null && !params.isEmpty())
+ {
+ for (ParameterData param : params)
+ {
+ if (param.getValue() == null || param.getValue().toString().length() == 0)
+ {
+ ViewUtility.popupInfoMessage(_form.getText(),
+ "Please select the " + ViewUtility.getDisplayText(param.getName()));
+
+ return;
+ }
+ }
+ }
+
+ if (_opData.getImpact() == Constants.OPERATION_IMPACT_ACTION)
+ {
+ String bean = _mbean.getName() == null ? _mbean.getType() : _mbean.getName();
+ int response = ViewUtility.popupConfirmationMessage(bean,
+ "Do you want to " + _form.getText()+ " ?");
+ if (response == SWT.YES)
+ {
+ executeAndShowResults();
+ }
+ }
+ else
+ {
+ executeAndShowResults();
+ }
+ clearParameters();
+ clearParameterValues(_paramsComposite);
+ }
+ }
+
+ private class RefreshListener extends SelectionAdapter
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ executeAndShowResults();
+ }
+ }
+
+
+ private void executeAndShowResults()
+ {
+ Object result = null;
+ try
+ {
+ result = MBeanUtility.execute(_mbean, _opData);
+ }
+ catch(Exception ex)
+ {
+ MBeanUtility.handleException(_mbean, ex);
+ return;
+ }
+
+ String title = _mbean.getType();
+ if (_mbean.getName() != null && _mbean.getName().length() != 0)
+ {
+ title = _mbean.getName();
+ }
+
+ if (_opData.getReturnType().equals("void") || _opData.getReturnType().equals("java.lang.Void"))
+ {
+ ViewUtility.popupInfoMessage(title, "Operation successful");
+ }
+ else if (_opData.getParameters() != null && !_opData.getParameters().isEmpty())
+ {
+ populateResults(result);
+ }
+ else
+ {
+ ViewUtility.disposeChildren(_resultsComposite);
+ /*
+ if (_resultsComposite == null || _resultsComposite.isDisposed())
+ {
+ _resultsComposite = _toolkit.createComposite(_form.getBody(), SWT.NONE);
+ GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true);
+ layoutData.verticalIndent = 20;
+ _resultsComposite.setLayoutData(layoutData);
+ _resultsComposite.setLayout(new GridLayout());
+ }*/
+ populateResults(result, _resultsComposite);
+ _resultsComposite.layout();
+ _form.layout();
+ }
+
+ }
+
+ /**
+ * Listener class for the operation parameters widget
+ */
+ private class ParameterSelectionListener extends SelectionAdapter
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ Combo combo = (Combo)e.widget;
+ ParameterData parameter = (ParameterData)combo.getData();
+ if (combo.getSelectionIndex() > 0)
+ {
+ String item = combo.getItem(combo.getSelectionIndex());
+ parameter.setValueFromString(item);
+ }
+ else
+ {
+ parameter.setValue(null);
+ }
+ }
+ }
+
+ private class BooleanSelectionListener extends SelectionAdapter
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ Combo combo = (Combo)e.widget;
+ ParameterData parameter = (ParameterData)combo.getData();
+ String item = combo.getItem(combo.getSelectionIndex());
+ parameter.setValueFromString(item);
+ }
+ }
+
+ /**
+ * Listener class for the operation parameter value widget (Text field)
+ */
+ private class KeyListenerImpl extends KeyAdapter
+ {
+ public void keyReleased(KeyEvent e)
+ {
+ if (!(e.widget instanceof Text))
+ return;
+
+ Text text = (Text)e.widget;
+ // Get the parameters widget and assign the text to the parameter
+ String strValue = text.getText();
+ ParameterData parameter = (ParameterData)text.getData();
+ parameter.setValueFromString(strValue);
+ }
+ }
+
+ private class HeaderBindingKeyListener extends KeyAdapter
+ {
+ public void keyReleased(KeyEvent e)
+ {
+ ParameterData param = _opData.getParameters().get(1);
+ StringBuffer paramValue = new StringBuffer();
+ for (Entry<Text, Text> entry : headerBindingHashMap.entrySet())
+ {
+
+ Text nameText = entry.getKey();
+ String name = nameText.getText();
+ Text valueText = entry.getValue();
+ String value = valueText.getText();
+ if ((name != null) && (name.length() != 0) && (value != null) && (value.length() != 0))
+ {
+ if (paramValue.length() != 0)
+ {
+ paramValue.append(",");
+ }
+ paramValue.append(name + "=" + value);
+ }
+ }
+
+ param.setValue(paramValue.toString());
+ }
+ }
+
+ private class VerifyListenerImpl implements VerifyListener
+ {
+ public void verifyText(VerifyEvent event)
+ {
+ Text text = (Text)event.widget;
+ String string = event.text;
+ char [] chars = new char [string.length ()];
+ string.getChars (0, chars.length, chars, 0);
+
+ ParameterData parameter = (ParameterData)text.getData();
+ String type = parameter.getType();
+ if (type.equals("int") || type.equals("java.lang.Integer") ||
+ type.equals("long") || type.equals("java.lang.Long"))
+ {
+ for (int i=0; i<chars.length; i++)
+ {
+ if (!('0' <= chars [i] && chars [i] <= '9'))
+ {
+ event.doit = false;
+ return;
+ }
+ }
+
+ }
+ }
+ }
+
+}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/TabControl.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/TabControl.java
new file mode 100644
index 0000000000..4b89b7ca30
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/TabControl.java
@@ -0,0 +1,57 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui.views;
+
+import org.apache.qpid.management.ui.ManagedBean;
+import org.apache.qpid.management.ui.model.OperationData;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.TabFolder;
+
+public abstract class TabControl
+{
+ protected ManagedBean _mbean = null;
+ protected TabFolder _tabFolder = null;
+
+ public TabControl(TabFolder tabFolder)
+ {
+ _tabFolder = tabFolder;
+ }
+
+ public Control getControl()
+ {
+ return null;
+ }
+
+ public void refresh(ManagedBean mbean)
+ {
+
+ }
+
+ public void refresh(ManagedBean mbean, OperationData opData)
+ {
+
+ }
+
+ public void setFocus()
+ {
+
+ }
+}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/TreeObject.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/TreeObject.java
new file mode 100644
index 0000000000..36dc753a1e
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/TreeObject.java
@@ -0,0 +1,125 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui.views;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.qpid.management.ui.Constants;
+import org.apache.qpid.management.ui.ManagedBean;
+import org.apache.qpid.management.ui.ManagedObject;
+
+public class TreeObject
+{
+ private String _name;
+ private String _type;
+ private String _url;
+ private TreeObject _parent;
+ private List<TreeObject> _children = new ArrayList<TreeObject>();
+ private ManagedObject _object;
+
+ public TreeObject(String name, String type)
+ {
+ this._name = name;
+ this._type = type;
+ }
+
+ public TreeObject(ManagedObject obj)
+ {
+ _name = obj.getName();
+ if (_name == null && (obj instanceof ManagedBean))
+ {
+ _name = ((ManagedBean)obj).getType();
+ }
+ this._type = Constants.MBEAN;
+ this._object = obj;
+ }
+
+ public void addChild(TreeObject child)
+ {
+ _children.add(child);
+ }
+
+ public void addChildren(List<TreeObject> subList)
+ {
+ _children.addAll(subList);
+ }
+
+ public List<TreeObject> getChildren()
+ {
+ return _children;
+ }
+
+ public void setChildren(List<TreeObject> children)
+ {
+ this._children = children;
+ }
+
+ public void setName(String value)
+ {
+ _name = value;
+ }
+
+ public String getName()
+ {
+ return _name;
+ }
+ public String getType()
+ {
+ return _type;
+ }
+
+ public String getUrl()
+ {
+ return _url;
+ }
+
+ public void setUrl(String url)
+ {
+ this._url = url;
+ }
+
+ public ManagedObject getManagedObject()
+ {
+ return _object;
+ }
+
+ public void setManagedObject(ManagedObject obj)
+ {
+ this._object = obj;
+ }
+
+ public TreeObject getParent()
+ {
+ return _parent;
+ }
+
+ public void setParent(TreeObject parent)
+ {
+ this._parent = parent;
+
+ if (parent != null)
+ {
+ this._url = parent.getUrl();
+ parent.addChild(this);
+ }
+ }
+}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/ViewUtility.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/ViewUtility.java
new file mode 100644
index 0000000000..995206f248
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/ViewUtility.java
@@ -0,0 +1,512 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui.views;
+
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.management.openmbean.ArrayType;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.CompositeType;
+import javax.management.openmbean.OpenType;
+import javax.management.openmbean.TabularDataSupport;
+import javax.management.openmbean.TabularType;
+
+import org.apache.qpid.management.ui.ApplicationWorkbenchAdvisor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+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.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.MessageBox;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+public class ViewUtility
+{
+ public static final String OP_NAME = "operation_name";
+ public static final String OP_PARAMS = "parameters";
+ public static final String PARAMS_TEXT = "text";
+
+ public static final String FIRST = "First";
+ public static final String LAST = "Last";
+ public static final String NEXT = "Next";
+ public static final String PREV = "Previous";
+ public static final String INDEX = "Index";
+
+ private static List<String> SUPPORTED_ARRAY_DATATYPES = new ArrayList<String>();
+ static
+ {
+ SUPPORTED_ARRAY_DATATYPES.add("java.lang.String");
+ SUPPORTED_ARRAY_DATATYPES.add("java.lang.Boolean");
+ SUPPORTED_ARRAY_DATATYPES.add("java.lang.Character");
+ SUPPORTED_ARRAY_DATATYPES.add("java.lang.Integer");
+ SUPPORTED_ARRAY_DATATYPES.add("java.lang.Long");
+ SUPPORTED_ARRAY_DATATYPES.add("java.lang.Double");
+ SUPPORTED_ARRAY_DATATYPES.add("java.util.Date");
+ }
+
+ @SuppressWarnings("unchecked")
+ public static void createTabularDataHolder(Composite parent, TabularDataSupport tabularData)
+ {
+ Composite composite = new Composite(parent, SWT.BORDER);
+ //composite.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE));
+ //composite.setBackground(parent.getBackground());
+ GridLayout layout = new GridLayout(4, true);
+ layout.horizontalSpacing = 0;
+ layout.marginWidth = 0;
+ layout.marginHeight = 10;
+ layout.verticalSpacing = 10;
+ composite.setLayout(layout);
+ composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+
+ Set entrySet = tabularData.entrySet();
+ ArrayList<Map.Entry> list = new ArrayList<Map.Entry>(entrySet);
+ if (list.size() == 0)
+ {
+ Text text = new Text(composite, SWT.CENTER | SWT.SINGLE | SWT.READ_ONLY);
+ text.setText(" No records ");
+ //text.setBackground(parent.getBackground());
+ GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true, 4, 1);
+ text.setLayoutData(layoutData);
+ return;
+ }
+ // Attach the tabular record to be retrieve and shown
+ composite.setData(list);
+
+ // Create button and the composite for CompositeData
+ Composite compositeDataHolder = createCompositeDataHolder(composite,
+ tabularData.getTabularType().getRowType());
+
+ // display the first record
+ CompositeData data = (CompositeData)(list.get(0)).getValue();
+ composite.setData(INDEX, 0);
+ populateCompositeDataHolder(compositeDataHolder, data);
+ enableOrDisableTraversalButtons(composite);
+ }
+
+ public static void enableOrDisableTraversalButtons(Composite composite)
+ {
+ int index = (Integer)composite.getData(INDEX);
+ int size = ((List)composite.getData()).size();
+
+ ((Button)composite.getData(FIRST)).setEnabled(true);
+ ((Button)composite.getData(PREV)).setEnabled(true);
+ ((Button)composite.getData(NEXT)).setEnabled(true);
+ ((Button)composite.getData(LAST)).setEnabled(true);
+
+ if (index == 0)
+ {
+ ((Button)composite.getData(FIRST)).setEnabled(false);
+ ((Button)composite.getData(PREV)).setEnabled(false);
+ }
+ if (index == size -1)
+ {
+ ((Button)composite.getData(NEXT)).setEnabled(false);
+ ((Button)composite.getData(LAST)).setEnabled(false);
+ }
+ }
+
+ public static Composite createCompositeDataHolder(final Composite dataHolder, CompositeType compositeType)
+ {
+ Label description = new Label(dataHolder, SWT.CENTER);
+ description.setLayoutData(new GridData(SWT.CENTER, SWT.TOP, true, false, 4, 1));
+ String desc = compositeType.getDescription();
+ // TODO nameLabel.setFont(font);
+ description.setText(desc);
+
+ // Add traversal buttons
+ final Button firstRecordButton = new Button(dataHolder, SWT.PUSH);
+ firstRecordButton.setText(FIRST);
+ GridData layoutData = new GridData (GridData.HORIZONTAL_ALIGN_END);
+ layoutData.widthHint = 80;
+ firstRecordButton.setLayoutData(layoutData);
+
+ final Button nextRecordButton = new Button(dataHolder, SWT.PUSH);
+ nextRecordButton.setText(NEXT);
+ layoutData = new GridData (GridData.HORIZONTAL_ALIGN_END);
+ layoutData.widthHint = 80;
+ nextRecordButton.setLayoutData(layoutData);
+
+ final Button previousRecordButton = new Button(dataHolder, SWT.PUSH);
+ previousRecordButton.setText(PREV);
+ layoutData = new GridData (GridData.HORIZONTAL_ALIGN_BEGINNING);
+ layoutData.widthHint = 80;
+ previousRecordButton.setLayoutData(layoutData);
+
+ final Button lastRecordButton = new Button(dataHolder, SWT.PUSH);
+ lastRecordButton.setText(LAST);
+ layoutData = new GridData (GridData.HORIZONTAL_ALIGN_BEGINNING);
+ layoutData.widthHint = 80;
+ lastRecordButton.setLayoutData(layoutData);
+
+ final Composite composite = new Composite(dataHolder, SWT.NONE);
+ GridLayout layout = new GridLayout();
+ layout.horizontalSpacing = layout.verticalSpacing = 0;
+ layout.marginHeight = layout.marginWidth = 0;
+ composite.setLayout(layout);
+ composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 4, 1));
+
+ // Add button references. These references will be used when buttons
+ // are to enabled or disabled based of record index. e.g. for first record
+ // First and Previous buttons will be disabled.
+ dataHolder.setData(FIRST, firstRecordButton);
+ dataHolder.setData(NEXT, nextRecordButton);
+ dataHolder.setData(PREV, previousRecordButton);
+ dataHolder.setData(LAST, lastRecordButton);
+
+ // Listener for the traversal buttons
+ SelectionListener listener = new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ if (!(e.widget instanceof Button))
+ return;
+
+ Button traverseButton =(Button)e.widget;
+ CompositeData data = getCompositeData(dataHolder, traverseButton.getText());
+ populateCompositeDataHolder(composite, data);
+ enableOrDisableTraversalButtons(dataHolder);
+ }
+ };
+
+ firstRecordButton.addSelectionListener(listener);
+ nextRecordButton.addSelectionListener(listener);
+ previousRecordButton.addSelectionListener(listener);
+ lastRecordButton.addSelectionListener(listener);
+
+ return composite;
+ }
+
+ private static CompositeData getCompositeData(Composite compositeHolder, String dataIndex)
+ {
+ List objectData = (List)compositeHolder.getData();
+ if (objectData == null || objectData.isEmpty())
+ {
+ // TODO
+ }
+
+ // Get the index of record to be shown.
+ int index = 0;
+ if (compositeHolder.getData(INDEX) != null)
+ {
+ index = (Integer)compositeHolder.getData(INDEX);
+ }
+
+ if (FIRST.equals(dataIndex))
+ {
+ index = 0;
+ }
+ else if (NEXT.equals(dataIndex))
+ {
+ index = index + 1;
+ }
+ else if (PREV.equals(dataIndex))
+ {
+ index = (index != 0) ? (index = index - 1) : index;
+ }
+ else if (LAST.equals(dataIndex))
+ {
+ index = objectData.size() -1;
+ }
+
+ // Set the index being shown.
+ compositeHolder.setData(INDEX, index);
+ System.out.println("index :" + index);
+
+ return (CompositeData)((Map.Entry)objectData.get(index)).getValue();
+ }
+
+ @SuppressWarnings("unchecked")
+ public static void populateCompositeDataHolder(Composite parent, CompositeData data/*String dataIndex*/)
+ {
+ Control[] oldControls = parent.getChildren();
+ for (int i = 0; i < oldControls.length; i++)
+ {
+ oldControls[i].dispose();
+ }
+
+ Composite compositeHolder = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout(4, false);
+ layout.horizontalSpacing = 10;
+ compositeHolder.setLayout(layout);
+ compositeHolder.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+
+
+ // ItemNames in composite data
+ List<String> itemNames = new ArrayList<String>(data.getCompositeType().keySet());
+
+ for (String itemName : itemNames)
+ {
+ OpenType itemType = data.getCompositeType().getType(itemName);
+ if (compositeHolder.getData(itemName) == null)
+ {
+ Label keyLabel = new Label(compositeHolder, SWT.TRAIL);
+ keyLabel.setText(itemName);
+ GridData layoutData = new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1);
+ layoutData.minimumWidth = 70;
+ keyLabel.setLayoutData(layoutData);
+ System.out.println(itemType);
+
+ if (itemType.isArray())
+ {
+ OpenType type = ((ArrayType)itemType).getElementOpenType();
+ System.out.println("Array Element type = " + type.getClassName());
+ // If Byte array and mimetype is text, convert to text string
+ if (type.getClassName().equals(Byte.class.getName()))
+ {
+ String mimeType = null;
+ String encoding = null;
+ if (data.containsKey("MimeType"))
+ {
+ mimeType = (String)data.get("MimeType");
+ encoding = (String)data.get("Encoding");
+ if (encoding == null || encoding.length() == 0)
+ {
+ encoding = Charset.defaultCharset().name();
+ }
+
+ if (mimeType.equals("text/plain"))
+ {
+ displayByteArray(compositeHolder, data, itemName, encoding);
+ }
+ }
+ else
+ {
+ displayNotSupportedDataType(compositeHolder);
+ }
+ }
+ // If array of any other supported type, show as a list of String array
+ else if (SUPPORTED_ARRAY_DATATYPES.contains(type.getClassName()))
+ {
+ displayArrayItem(compositeHolder, data, itemName);
+ }
+ else
+ {
+ displayNotSupportedDataType(compositeHolder);
+ }
+ }
+ else if (itemType instanceof TabularType)
+ {
+ Composite composite = new Composite(compositeHolder, SWT.NONE);
+ composite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 3, 1));
+ layout = new GridLayout();
+ layout.marginHeight = 0;
+ layout.marginWidth = 0;
+ composite.setLayout(layout);
+ createTabularDataHolder(composite, (TabularDataSupport)data.get(itemName));
+ }
+ else
+ {
+ Text valueText = new Text(compositeHolder, SWT.READ_ONLY | SWT.BORDER);
+ valueText.setText(String.valueOf(data.get(itemName)));
+ valueText.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 3, 1));
+ }
+ }
+ }
+
+ // layout the composite after creating new widgets.
+ parent.layout();
+ } //end of method
+
+
+ private static void displayByteArray(Composite compositeHolder, CompositeData data, String itemName, String encoding)
+ {
+ Byte[] arrayItems = (Byte[])data.get(itemName);
+ byte[] byteArray = new byte[arrayItems.length];
+
+ for (int i = 0; i < arrayItems.length; i++)
+ {
+ byteArray[i] = arrayItems[i];
+ }
+ try
+ {
+ String textMessage = new String(byteArray, encoding);
+ System.out.println("\nMessage : \n" + textMessage + "\n");
+
+ Text valueText = new Text(compositeHolder, SWT.READ_ONLY | SWT.BORDER |
+ SWT.MULTI | SWT.WRAP | SWT.V_SCROLL);
+ valueText.setText(textMessage);
+ GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1);
+ gridData.heightHint = 300;
+ valueText.setLayoutData(gridData);
+ }
+ catch(Exception ex)
+ {
+ ex.printStackTrace();
+ }
+ }
+
+ public static int popupInfoMessage(String title, String message)
+ {
+ MessageBox messageBox = new MessageBox(Display.getCurrent().getActiveShell(),
+ SWT.ICON_INFORMATION | SWT.OK);
+ messageBox.setMessage(message);
+ messageBox.setText(title);
+ int response = messageBox.open();
+
+ return response;
+ }
+
+ public static int popupErrorMessage(String title, String message)
+ {
+ MessageBox messageBox = new MessageBox(Display.getCurrent().getActiveShell(),
+ SWT.ICON_ERROR | SWT.OK);
+ messageBox.setMessage(message);
+ messageBox.setText(title);
+ int response = messageBox.open();
+
+ return response;
+ }
+
+ public static int popupConfirmationMessage(String title, String message)
+ {
+ MessageBox messageBox = new MessageBox(Display.getCurrent().getActiveShell(),
+ SWT.ICON_QUESTION | SWT.YES | SWT.NO | SWT.CANCEL);
+ messageBox.setMessage(message);
+ messageBox.setText(title);
+ int response = messageBox.open();
+
+ return response;
+ }
+
+ public static void popupError(String title, String message, Exception ex)
+ {
+ IStatus status = new Status(IStatus.ERROR, ApplicationWorkbenchAdvisor.PERSPECTIVE_ID,
+ IStatus.ERROR, ex.getMessage(), ex);
+ ErrorDialog.openError(Display.getCurrent().getActiveShell(), title, message, status);
+
+ }
+
+ public static void popupError(String errorMsg)
+ {
+ Display display = Display.getCurrent();
+ Shell shell = new Shell(display, SWT.BORDER | SWT.CLOSE | SWT.MIN | SWT.MAX);
+ shell.setText("Attribute");
+ shell.setLayout(new GridLayout());
+ int x = display.getBounds().width;
+ int y = display.getBounds().height;
+ int width = 500;
+ int height = 250;
+ shell.setBounds(x/4, y/4, width, height);
+
+ Label label = new Label(shell, SWT.NONE);
+ label.setText(errorMsg);
+ label.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, false, false));
+
+ shell.open();
+ while (!shell.isDisposed()) {
+ if (!display.readAndDispatch()) {
+ display.sleep();
+ }
+ }
+ shell.dispose();
+ }
+
+ public static Shell createPopupShell(String title, int width, int height)
+ {
+ Display display = Display.getCurrent();
+ Shell shell = new Shell(display, SWT.BORDER | SWT.CLOSE | SWT.MIN |SWT.MAX);
+ shell.setText(title);
+ shell.setLayout(new GridLayout());
+ int x = display.getBounds().width;
+ int y = display.getBounds().height;
+ shell.setBounds(x/4, y/4, width, height);
+
+ return shell;
+ }
+
+ private static void displayArrayItem(Composite compositeHolder, CompositeData data, String itemName)
+ {
+ Object[] arrayItems = (Object[])data.get(itemName);
+ String[] items = new String[arrayItems.length];
+ for (int i = 0; i < arrayItems.length; i++)
+ {
+ items[i] = String.valueOf(arrayItems[i]);
+ }
+ org.eclipse.swt.widgets.List list = new org.eclipse.swt.widgets.List(compositeHolder,
+ SWT.MULTI | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL | SWT.READ_ONLY);
+ list.setItems(items);
+ list.setBackground(compositeHolder.getBackground());
+ list.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1));
+ }
+
+ private static void displayNotSupportedDataType(Composite compositeHolder)
+ {
+ Text valueText = new Text(compositeHolder, SWT.READ_ONLY);
+ valueText.setText("Format is not supported to be displayed");
+ valueText.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 3, 1));
+ }
+
+ /**
+ * Converts the input string to displayable format by converting some character case or inserting space
+ * @param input
+ * @return
+ */
+ public static String getDisplayText(String input)
+ {
+ StringBuffer result = new StringBuffer(input);
+ if (Character.isLowerCase(result.charAt(0)))
+ {
+ result.setCharAt(0, Character.toUpperCase(result.charAt(0)));
+ }
+ for (int i = 1; i < input.length(); i++)
+ {
+ if (Character.isUpperCase(result.charAt(i)) && !Character.isWhitespace(result.charAt(i - 1))
+ && Character.isLowerCase(result.charAt(i - 1)))
+ {
+ result.insert(i, " ");
+ i++;
+ }
+ else if (Character.isLowerCase(result.charAt(i)) && Character.isWhitespace(result.charAt(i - 1)))
+ {
+ result.setCharAt(i, Character.toUpperCase(result.charAt(i)));
+ }
+
+ }
+
+ return result.toString();
+ }
+
+ public static void disposeChildren(Composite parent)
+ {
+ if (parent == null || parent.isDisposed())
+ return;
+
+ Control[] oldControls = parent.getChildren();
+ for (int i = 0; i < oldControls.length; i++)
+ {
+ oldControls[i].dispose();
+ }
+ }
+}
diff --git a/java/management/eclipse-plugin/src/main/resources/configuration/config.ini b/java/management/eclipse-plugin/src/main/resources/configuration/config.ini
new file mode 100644
index 0000000000..dbe3f23fe9
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/resources/configuration/config.ini
@@ -0,0 +1,26 @@
+###############################################################################
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+###############################################################################
+
+#Product Runtime Configuration File
+
+osgi.splashPath=platform:/base/plugins/org.apache.qpid.management.ui
+eclipse.product=org.apache.qpid.management.ui.product
+eclipse.application=org.apache.qpid.management.ui.application
+osgi.bundles=org.eclipse.equinox.common@2:start,org.eclipse.core.runtime@start,com.ibm.icu,org.apache.qpid.management.ui,org.eclipse.core.commands,org.eclipse.core.contenttype,org.eclipse.core.expressions,org.eclipse.core.jobs,org.eclipse.core.runtime.compatibility.auth,org.eclipse.core.runtime.compatibility.registry,org.eclipse.equinox.preferences,org.eclipse.equinox.registry,org.eclipse.help,org.eclipse.jface,org.eclipse.swt,org.eclipse.swt.win32.win32.x86,org.eclipse.ui,org.eclipse.ui.forms,org.eclipse.ui.workbench
+osgi.bundles.defaultStartLevel=4
diff --git a/java/management/eclipse-plugin/src/main/resources/configuration/org.eclipse.osgi/bundles/16/1/.cp/swt-win32-3232.dll b/java/management/eclipse-plugin/src/main/resources/configuration/org.eclipse.osgi/bundles/16/1/.cp/swt-win32-3232.dll
new file mode 100644
index 0000000000..f028cec28d
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/resources/configuration/org.eclipse.osgi/bundles/16/1/.cp/swt-win32-3232.dll
Binary files differ
diff --git a/java/management/eclipse-plugin/src/main/resources/license.eclipse.txt b/java/management/eclipse-plugin/src/main/resources/license.eclipse.txt
new file mode 100644
index 0000000000..da433e89f9
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/resources/license.eclipse.txt
@@ -0,0 +1,88 @@
+Eclipse Public License - v 1.0
+
+THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
+
+1. DEFINITIONS
+
+"Contribution" means:
+
+a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and
+b) in the case of each subsequent Contributor:
+
+i) changes to the Program, and
+
+ii) additions to the Program;
+
+where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program.
+
+"Contributor" means any person or entity that distributes the Program.
+
+"Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program.
+
+"Program" means the Contributions distributed in accordance with this Agreement.
+
+"Recipient" means anyone who receives the Program under this Agreement, including all Contributors.
+
+2. GRANT OF RIGHTS
+
+a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form.
+
+b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder.
+
+c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program.
+
+d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement.
+
+3. REQUIREMENTS
+
+A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that:
+
+a) it complies with the terms and conditions of this Agreement; and
+
+b) its license agreement:
+
+i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose;
+
+ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits;
+
+iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and
+
+iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange.
+
+When the Program is made available in source code form:
+
+a) it must be made available under this Agreement; and
+
+b) a copy of this Agreement must be included with each copy of the Program.
+
+Contributors may not remove or alter any copyright notices contained within the Program.
+
+Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution.
+
+4. COMMERCIAL DISTRIBUTION
+
+Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense.
+
+For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages.
+
+5. NO WARRANTY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED 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. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement , including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations.
+
+6. DISCLAIMER OF LIABILITY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+7. GENERAL
+
+If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.
+
+If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed.
+
+All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive.
+
+Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved.
+
+This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation.
+
+
diff --git a/java/management/eclipse-plugin/src/main/resources/qpidmc.exe b/java/management/eclipse-plugin/src/main/resources/qpidmc.exe
new file mode 100644
index 0000000000..7826d1ed80
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/resources/qpidmc.exe
Binary files differ
diff --git a/java/management/eclipse-plugin/src/main/resources/qpidmc.ini b/java/management/eclipse-plugin/src/main/resources/qpidmc.ini
new file mode 100644
index 0000000000..6a4ecb5b5d
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/resources/qpidmc.ini
@@ -0,0 +1,4 @@
+-vmargs
+-Xms40m
+-Xmx256m
+-Declipse.consoleLog=true
diff --git a/java/management/eclipse-plugin/src/main/resources/startup.jar b/java/management/eclipse-plugin/src/main/resources/startup.jar
new file mode 100644
index 0000000000..2f26eceece
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/resources/startup.jar
Binary files differ
diff --git a/java/pom.xml b/java/pom.xml
index e0d1e3154e..dd5280cfde 100644
--- a/java/pom.xml
+++ b/java/pom.xml
@@ -105,6 +105,7 @@
<module>client</module>
<module>cluster</module>
<module>systests</module>
+ <module>management/eclipse-plugin</module>
</modules>
<build>
@@ -226,13 +227,9 @@
<!--downloadSources>true</downloadSources-->
<buildcommands>
<java.lang.String>org.eclipse.jdt.core.javabuilder</java.lang.String>
- <java.lang.String>com.atlassw.tools.eclipse.checkstyle.CheckstyleBuilder</java.lang.String>
- <java.lang.String>net.sourceforge.pmd.runtime.pmdBuilder</java.lang.String>
</buildcommands>
<projectnatures>
<nature>org.eclipse.jdt.core.javanature</nature>
- <nature>com.atlassw.tools.eclipse.checkstyle.CheckstyleNature</nature>
- <nature>net.sourceforge.pmd.runtime.pmdNature</nature>
</projectnatures>
</configuration>
</plugin>
@@ -253,13 +250,11 @@
<dependencyManagement>
<dependencies>
-
<dependency>
<groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId>
<version>1.0</version>
</dependency>
-
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
@@ -270,25 +265,28 @@
<artifactId>commons-collections</artifactId>
<version>3.1</version>
</dependency>
-
<dependency>
<groupId>commons-configuration</groupId>
<artifactId>commons-configuration</artifactId>
<version>1.2</version>
</dependency>
-
<dependency>
-
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.1</version>
+ <exclusions>
+ <!-- this seems to have a junit compile dependency -->
+ <exclusion>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </exclusion>
+ </exclusions>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.0.4</version>
</dependency>
-
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-jms_1.1_spec</artifactId>
@@ -304,12 +302,6 @@
<artifactId>saxon</artifactId>
<version>8.7</version>
</dependency>
-
- <dependency>
- <groupId>jython</groupId>
- <artifactId>jython</artifactId>
- <version>2.1</version>
- </dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
@@ -343,14 +335,9 @@
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
- <version>3.8.2</version>
- </dependency>
- <dependency>
- <groupId>ant</groupId>
- <artifactId>ant-junit</artifactId>
- <version>1.6.5</version>
+ <version>3.8.1</version>
+ <scope>test</scope>
</dependency>
-
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymockclassextension</artifactId>
@@ -412,23 +399,6 @@
<artifactId>maven-javadoc-plugin</artifactId>
<version>${javadoc.version}</version>
</plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-checkstyle-plugin</artifactId>
- <configuration>
- <configLocation>${basedir}/${topDirectoryLocation}/checkstyle.xml</configLocation>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-pmd-plugin</artifactId>
- <configuration>
- <targetJdk>${java.source.version}</targetJdk>
- <rulesets>
- <ruleset>${basedir}/.ruleset</ruleset>
- </rulesets>
- </configuration>
- </plugin>
</plugins>
</reporting>
@@ -468,36 +438,6 @@
</profile>
<profile>
- <!-- default profile enables checkstyle and Xlint stuff -->
- <id>sourcecheck</id>
- <activation>
- <activeByDefault>true</activeByDefault>
- </activation>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-checkstyle-plugin</artifactId>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <configuration>
- <source>1.5</source>
- <target>1.5</target>
- <showDeprecation>false</showDeprecation>
- <compilerArgument>${compile.flags}</compilerArgument>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-pmd-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
- </profile>
-
- <profile>
<id>setup.eclipse</id>
<build>
<defaultGoal>process-test-sources</defaultGoal>
@@ -525,109 +465,6 @@
</execution>
</executions>
</plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-antrun-plugin</artifactId>
- <version>${antrun.version}</version>
- <dependencies>
- <dependency>
- <groupId>ant</groupId>
- <artifactId>ant-nodeps</artifactId>
- <version>1.6.5</version>
- </dependency>
- <dependency>
- <groupId>ant</groupId>
- <artifactId>ant-trax</artifactId>
- <version>1.6.5</version>
- </dependency>
- </dependencies>
- <executions>
- <execution>
- <id>setup.workspace</id>
- <phase>validate</phase>
- <configuration>
- <tasks>
- <path id="ecp.ws.path" location="${eclipse.workspace.dir}"/>
- <property name="full.eclipse.workspace" refid="ecp.ws.path"/>
-
- <mkdir dir="${full.eclipse.workspace}/.metadata/.plugins/org.eclipse.core.runtime/.settings"/>
- <mkdir dir="${full.eclipse.workspace}/.metadata/.plugins/com.atlassw.tools.eclipse.checkstyle"/>
- <mkdir dir="${full.eclipse.workspace}/.metadata/.plugins/net.sourceforge.pmd.eclipse"/>
- <copy file="${basedir}/${topDirectoryLocation}/checkstyle.xml"
- tofile="${full.eclipse.workspace}/qpid-checkstyle.xml"/>
- <copy file="${basedir}/${topDirectoryLocation}/etc/apache-header.txt"
- tofile="${full.eclipse.workspace}/apache-header.txt"/>
-
- <!-- Add checkstyle config -->
- <copy file="${basedir}/${topDirectoryLocation}/etc/eclipse/template.checkstyle-config.xml"
- tofile="${full.eclipse.workspace}/.metadata/.plugins/com.atlassw.tools.eclipse.checkstyle/checkstyle-config.xml"
- overwrite="no">
- <filterset>
- <filter token="CHECKSTYLE_CONFIG_FILE"
- value="${full.eclipse.workspace}/qpid-checkstyle.xml"/>
- <filter token="APACHE_HEADER_FILE"
- value="${full.eclipse.workspace}/apache-header.txt"/>
- </filterset>
- </copy>
-
- <xslt style="${basedir}/${topDirectoryLocation}/etc/eclipse/addcheckstyle.xsl"
- in="${full.eclipse.workspace}/.metadata/.plugins/com.atlassw.tools.eclipse.checkstyle/checkstyle-config.xml"
- out="${full.eclipse.workspace}/.metadata/.plugins/com.atlassw.tools.eclipse.checkstyle/checkstyle-config.xml.new">
- <param name="checkstyleconfig"
- expression="${full.eclipse.workspace}/qpid-checkstyle.xml"/>
- </xslt>
- <copy
- file="${full.eclipse.workspace}/.metadata/.plugins/com.atlassw.tools.eclipse.checkstyle/checkstyle-config.xml.new"
- tofile="${full.eclipse.workspace}/.metadata/.plugins/com.atlassw.tools.eclipse.checkstyle/checkstyle-config.xml"
- overwrite="yes"/>
-
-
- <!-- Add warning flags that we want -->
- <propertyfile
- file="${full.eclipse.workspace}/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.core.prefs">
- <entry key="org.eclipse.jdt.core.compiler.problem.missingSerialVersion"
- value="ignore"/>
- <entry key="org.eclipse.jdt.core.compiler.problem.unusedImport"
- value="ignore"/>
- <entry key="org.eclipse.jdt.core.compiler.problem.annotationSuperInterface"
- value="ignore"/>
- </propertyfile>
-
-
- <!-- Add code format rules -->
- <concat destfile="${full.eclipse.workspace}/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.core.prefs"
- append="true" fixlastline="true">
- <filelist dir="${basedir}/${topDirectoryLocation}/etc/eclipse"
- files="org.eclipse.jdt.core.prefs"/>
- </concat>
- <loadfile property="eclipse.code.format"
- srcFile="${basedir}/${topDirectoryLocation}/etc/eclipse/QpidCodeFormatter.xml"/>
- <loadfile property="eclipse.code.templates"
- srcFile="${basedir}/${topDirectoryLocation}/etc/eclipse/codetemplates.xml"/>
- <propertyfile
- file="${full.eclipse.workspace}/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.ui.prefs">
- <entry key="formatter_profile" value="_Qpid Java Conventions"/>
- <entry key="org.eclipse.jdt.ui.formatterprofiles"
- value="${eclipse.code.format}"/>
- <entry key="org.eclipse.jdt.ui.text.custom_code_templates"
- value="${eclipse.code.templates}"/>
-
- <!-- Add import order -->
- <entry key="org.eclipse.jdt.ui.importorder"
- value="java;javax;org.w3c;org.xml;junit;com;org;"/>
- <!-- Sort order -->
- <entry key="org.eclipse.jdt.ui.visibility.order" value="B,R,D,V,"/>
- <entry key="outlinesortoption" value="T,SF,F,SI,I,C,SM,M,"/>
- <entry key="org.eclipse.jdt.ui.enable.visibility.order" value="true"/>
- </propertyfile>
- </tasks>
- </configuration>
- <goals>
- <goal>run</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
</plugins>
</build>
</profile>
diff --git a/java/systests/pom.xml b/java/systests/pom.xml
index ae6558340f..bf0afa7eef 100644
--- a/java/systests/pom.xml
+++ b/java/systests/pom.xml
@@ -58,11 +58,6 @@
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
- <dependency>
- <groupId>ant</groupId>
- <artifactId>ant-junit</artifactId>
- <scope>test</scope>
- </dependency>
</dependencies>
<build>
diff --git a/java/systests/src/test/java/org/apache/qpid/server/exchange/AbstractHeadersExchangeTest.java b/java/systests/src/test/java/org/apache/qpid/server/exchange/AbstractHeadersExchangeTest.java
index ef9e9f1cd6..aa9c450bf6 100644
--- a/java/systests/src/test/java/org/apache/qpid/server/exchange/AbstractHeadersExchangeTest.java
+++ b/java/systests/src/test/java/org/apache/qpid/server/exchange/AbstractHeadersExchangeTest.java
@@ -21,10 +21,13 @@
package org.apache.qpid.server.exchange;
import junit.framework.TestCase;
-import org.apache.log4j.Logger;
import org.apache.qpid.AMQException;
-import org.apache.qpid.framing.*;
-import org.apache.qpid.server.RequiredDeliveryException;
+import org.apache.qpid.framing.BasicContentHeaderProperties;
+import org.apache.qpid.framing.BasicPublishBody;
+import org.apache.qpid.framing.ContentBody;
+import org.apache.qpid.framing.ContentHeaderBody;
+import org.apache.qpid.framing.FieldTable;
+import org.apache.qpid.framing.FieldTableFactory;
import org.apache.qpid.server.queue.AMQMessage;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.queue.MessageHandleFactory;
@@ -34,6 +37,8 @@ import org.apache.qpid.server.store.SkeletonMessageStore;
import org.apache.qpid.server.store.MemoryMessageStore;
import org.apache.qpid.server.txn.NonTransactionalContext;
import org.apache.qpid.server.txn.TransactionalContext;
+import org.apache.qpid.server.RequiredDeliveryException;
+import org.apache.log4j.Logger;
import java.util.*;
@@ -112,7 +117,7 @@ public class AbstractHeadersExchangeTest extends TestCase
static FieldTable getHeaders(String... entries)
{
- FieldTable headers = new FieldTable();
+ FieldTable headers = FieldTableFactory.newFieldTable();
for (String s : entries)
{
String[] parts = s.split("=", 2);