summaryrefslogtreecommitdiff
path: root/java/management
diff options
context:
space:
mode:
Diffstat (limited to 'java/management')
-rw-r--r--java/management/cli/bin/stac.bat38
-rwxr-xr-xjava/management/cli/bin/stac.sh39
-rw-r--r--java/management/cli/bin/stacDEV.bat41
-rw-r--r--java/management/cli/build-module.xml21
-rw-r--r--java/management/cli/build-old.xml122
-rw-r--r--java/management/cli/lib/jython/jython.jarbin0 -> 719950 bytes
-rw-r--r--java/management/cli/src/org/apache/qpid/stac/Stac.java94
-rw-r--r--java/management/cli/src/org/apache/qpid/stac/StacInterpreter.java31
-rw-r--r--java/management/cli/src/org/apache/qpid/stac/commands/CdCommand.java50
-rw-r--r--java/management/cli/src/org/apache/qpid/stac/commands/InvokeCommand.java31
-rw-r--r--java/management/cli/src/org/apache/qpid/stac/commands/LsCommand.java123
-rw-r--r--java/management/cli/src/org/apache/qpid/stac/jmx/CurrentMBean.java180
-rw-r--r--java/management/cli/src/org/apache/qpid/stac/jmx/MBeanAttributeInfoComparator.java29
-rw-r--r--java/management/cli/src/org/apache/qpid/stac/jmx/MBeanOperationInfoComparator.java29
-rw-r--r--java/management/cli/src/org/apache/qpid/stac/jmx/MBeanServerConnectionContext.java202
-rw-r--r--java/management/cli/src/org/apache/qpid/stac/jmx/MBeanUtils.java35
-rw-r--r--java/management/cli/src/org/apache/qpid/stac/jmx/NotConnectedException.java28
-rw-r--r--java/management/cli/src/python/stac.py190
-rw-r--r--java/management/cli/test/org/apache/qpid/stac/ConnectionTest.java35
-rw-r--r--java/management/core/build-module.xml47
-rw-r--r--java/management/core/build-old.xml189
-rw-r--r--java/management/core/etc/cml-exampleschema.xml51
-rw-r--r--java/management/core/etc/cml.xsd175
-rw-r--r--java/management/core/lib/jakarta-commons/commons-attributes-api.jarbin0 -> 36342 bytes
-rw-r--r--java/management/core/lib/jakarta-commons/commons-attributes-compiler.jarbin0 -> 29216 bytes
-rw-r--r--java/management/core/lib/jakarta-commons/commons-beanutils.jarbin0 -> 188671 bytes
-rw-r--r--java/management/core/lib/jakarta-commons/commons-codec.jarbin0 -> 46725 bytes
-rw-r--r--java/management/core/lib/jakarta-commons/commons-collections.jarbin0 -> 559366 bytes
-rw-r--r--java/management/core/lib/jakarta-commons/commons-dbcp.jarbin0 -> 107631 bytes
-rw-r--r--java/management/core/lib/jakarta-commons/commons-digester.jarbin0 -> 168446 bytes
-rw-r--r--java/management/core/lib/jakarta-commons/commons-discovery.jarbin0 -> 74527 bytes
-rw-r--r--java/management/core/lib/jakarta-commons/commons-fileupload.jarbin0 -> 22379 bytes
-rw-r--r--java/management/core/lib/jakarta-commons/commons-httpclient.jarbin0 -> 279317 bytes
-rw-r--r--java/management/core/lib/jakarta-commons/commons-lang.jarbin0 -> 207723 bytes
-rw-r--r--java/management/core/lib/jakarta-commons/commons-logging.jarbin0 -> 38015 bytes
-rw-r--r--java/management/core/lib/jakarta-commons/commons-pool.jarbin0 -> 42492 bytes
-rw-r--r--java/management/core/lib/jakarta-commons/commons-validator.jarbin0 -> 84462 bytes
-rw-r--r--java/management/core/lib/log4j/log4j-1.2.9.jarbin0 -> 352291 bytes
-rw-r--r--java/management/core/lib/spring/spring-beans.dtd587
-rw-r--r--java/management/core/lib/spring/spring.ftl316
-rw-r--r--java/management/core/lib/spring/spring.tld311
-rw-r--r--java/management/core/lib/spring/spring.vm294
-rw-r--r--java/management/core/lib/xmlbeans/jsr173_api.jarbin0 -> 26396 bytes
-rw-r--r--java/management/core/lib/xmlbeans/resolver.jarbin0 -> 60047 bytes
-rw-r--r--java/management/core/lib/xmlbeans/saxon8.jarbin0 -> 2297989 bytes
-rw-r--r--java/management/core/lib/xmlbeans/xbean.jarbin0 -> 2526707 bytes
-rw-r--r--java/management/core/lib/xmlbeans/xbean_xpath.jarbin0 -> 5182 bytes
-rw-r--r--java/management/core/lib/xmlbeans/xmlpublic.jarbin0 -> 425062 bytes
-rw-r--r--java/management/core/src/log4j.properties6
-rw-r--r--java/management/core/src/org/apache/qpid/management/ManagementConnection.java120
-rw-r--r--java/management/core/src/org/apache/qpid/management/jmx/AMQConsole.java95
-rw-r--r--java/management/core/src/org/apache/qpid/management/jmx/AMQMBeanInfo.java40
-rw-r--r--java/management/core/src/org/apache/qpid/management/jmx/CMLMBean.java298
-rw-r--r--java/management/core/src/org/apache/qpid/management/jmx/JmxConstants.java23
-rw-r--r--java/management/core/src/org/apache/qpid/management/jmx/MBeanInfoRegistry.java201
-rw-r--r--java/management/core/src/org/apache/qpid/management/jmx/MBeanRegistrar.java141
-rw-r--r--java/management/core/src/org/apache/qpid/management/jmx/UnsupportedCMLTypeException.java36
-rw-r--r--java/management/core/src/org/apache/qpid/management/messaging/CMLMessageFactory.java59
-rw-r--r--java/management/core/src/org/apache/qpid/management/messaging/ManagementDestination.java43
-rw-r--r--java/management/core/test/org/apache/qpid/management/harness/SimpleJMXClient.java25
-rw-r--r--java/management/core/test/org/apache/qpid/management/schema/TestParseSchema.java87
-rw-r--r--java/management/mc4j/qpid/BlazeConnections.xml84
-rw-r--r--java/management/mc4j/qpid/BlazeExchanges.xml81
-rw-r--r--java/management/mc4j/qpid/BlazeQueues.xml83
-rw-r--r--java/management/mc4j/qpid/BlazeSingleQueue.xml99
-rw-r--r--java/management/webapp/META-INF/context.xml20
-rw-r--r--java/management/webapp/WEB-INF/web.xml24
67 files changed, 4853 insertions, 0 deletions
diff --git a/java/management/cli/bin/stac.bat b/java/management/cli/bin/stac.bat
new file mode 100644
index 0000000000..156b7792cb
--- /dev/null
+++ b/java/management/cli/bin/stac.bat
@@ -0,0 +1,38 @@
+@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
+
+@echo off
+set COREROOT=..\..\core
+set AMQROOT=..\..\..\clients_java
+
+set CP=..\lib\jython\jython.jar
+set CP=%CP%;..\dist\amqp-stac.jar
+set CP=%CP%;%COREROOT%\dist\amqp-management-common.jar
+set CP=%CP%;%COREROOT%\lib\log4j\log4j-1.2.9.jar
+set CP=%CP%;%COREROOT%\lib\xmlbeans\jsr173_api.jar
+set CP=%CP%;%COREROOT%\lib\xmlbeans\resolver.jar
+set CP=%CP%;%COREROOT%\lib\xmlbeans\xbean.jar
+set CP=%CP%;%COREROOT%\lib\xmlbeans\xbean_xpath.jar
+set CP=%CP%;%COREROOT%\lib\xmlbeans\xmlpublic.jar
+set CP=%CP%;%COREROOT%\lib\xmlbeans\saxon8.jar
+set CP=%CP%;%AMQROOT%\dist\amqp-common.jar
+set CP=%CP%;%AMQROOT%\dist\amqp-jms.jar
+set CP=%CP%;%AMQROOT%\lib\mina\mina-0.7.3.jar
+set CP=%CP%;%AMQROOT%\lib\jms\jms.jar
+set CP=%CP%;%AMQROOT%\lib\util-concurrent\backport-util-concurrent.jar
+set CP=%CP%;%AMQROOT%\lib\jakarta-commons\commons-collections-3.1.jar
+
+%JAVA_HOME%\bin\java -Damqj.logging.level="ERROR" -cp %CP% org.apache.qpid.stac.Stac
diff --git a/java/management/cli/bin/stac.sh b/java/management/cli/bin/stac.sh
new file mode 100755
index 0000000000..8fabe3a606
--- /dev/null
+++ b/java/management/cli/bin/stac.sh
@@ -0,0 +1,39 @@
+#!/bin/sh
+#
+# Copyright (c) 2006 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+
+COREROOT=../../core
+AMQROOT=../../../clients_java
+
+CP=../lib/jython/jython.jar
+CP=$CP:../dist/amqp-stac.jar
+CP=$CP:$COREROOT/dist/amqp-management-common.jar
+CP=$CP:$COREROOT/lib/log4j/log4j-1.2.9.jar
+CP=$CP:$COREROOT/lib/xmlbeans/jsr173_api.jar
+CP=$CP:$COREROOT/lib/xmlbeans/resolver.jar
+CP=$CP:$COREROOT/lib/xmlbeans/xbean.jar
+CP=$CP:$COREROOT/lib/xmlbeans/xbean_xpath.jar
+CP=$CP:$COREROOT/lib/xmlbeans/xmlpublic.jar
+CP=$CP:$COREROOT/lib/xmlbeans/saxon8.jar
+CP=$CP:$AMQROOT/dist/amqp-common.jar
+CP=$CP:$AMQROOT/dist/amqp-jms.jar
+CP=$CP:$AMQROOT/lib/mina/mina-0.7.3.jar
+CP=$CP:$AMQROOT/lib/jms/jms.jar
+CP=$CP:$AMQROOT/lib/util-concurrent/backport-util-concurrent.jar
+CP=$CP:$AMQROOT/lib/jakarta-commons/commons-collections-3.1.jar
+
+$JAVA_HOME/bin/java -Damqj.logging.level="ERROR" -cp $CP org.apache.qpid.stac.Stac
diff --git a/java/management/cli/bin/stacDEV.bat b/java/management/cli/bin/stacDEV.bat
new file mode 100644
index 0000000000..2a5bb88065
--- /dev/null
+++ b/java/management/cli/bin/stacDEV.bat
@@ -0,0 +1,41 @@
+@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
+
+@echo off
+set COREROOT=..\..\core
+set AMQROOT=..\..\..\clients_java
+
+set CP=..\lib\jython\jython.jar
+set CP=%CP%;..\intellijclasses
+set CP=%CP%;%COREROOT%\intellijclasses
+set CP=%CP%;%COREROOT%\classes
+set CP=%CP%;%COREROOT%\lib\log4j\log4j-1.2.9.jar
+set CP=%CP%;%COREROOT%\lib\xmlbeans\jsr173_api.jar
+set CP=%CP%;%COREROOT%\lib\xmlbeans\resolver.jar
+set CP=%CP%;%COREROOT%\lib\xmlbeans\xbean.jar
+set CP=%CP%;%COREROOT%\lib\xmlbeans\xbean_xpath.jar
+set CP=%CP%;%COREROOT%\lib\xmlbeans\xmlpublic.jar
+set CP=%CP%;%COREROOT%\lib\xmlbeans\saxon8.jar
+set CP=%CP%;%AMQROOT%\dist\amqp-common.jar
+set CP=%CP%;%AMQROOT%\dist\amqp-jms.jar
+set CP=%CP%;%AMQROOT%\lib\mina\mina-0.7.3.jar
+set CP=%CP%;%AMQROOT%\lib\jms\jms.jar
+set CP=%CP%;%AMQROOT%\lib\util-concurrent\backport-util-concurrent.jar
+set CP=%CP%;%AMQROOT%\lib\jakarta-commons\commons-collections-3.1.jar
+
+
+@rem %JAVA_HOME%\bin\java -Damqj.logging.level="ERROR" -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005 -cp %CP% org.amqp.blaze.stac.Stac
+%JAVA_HOME%\bin\java -Damqj.logging.level="ERROR" -cp %CP% org.amqp.blaze.stac.Stac \ No newline at end of file
diff --git a/java/management/cli/build-module.xml b/java/management/cli/build-module.xml
new file mode 100644
index 0000000000..2c52418e46
--- /dev/null
+++ b/java/management/cli/build-module.xml
@@ -0,0 +1,21 @@
+<!--
+ -
+ - Copyright (c) 2006 The Apache Software Foundation
+ -
+ - Licensed under the Apache License, Version 2.0 (the "License");
+ - you may not use this file except in compliance with the License.
+ - You may obtain a copy of the License at
+ -
+ - http://www.apache.org/licenses/LICENSE-2.0
+ -
+ - Unless required by applicable law or agreed to in writing, software
+ - distributed under the License is distributed on an "AS IS" BASIS,
+ - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ - See the License for the specific language governing permissions and
+ - limitations under the License.
+ -
+ -->
+<project name="AMQ Management Client" default="build">
+ <property name="module.depends" value="common,client,management/core"/>
+ <import file="../../module.xml"/>
+</project>
diff --git a/java/management/cli/build-old.xml b/java/management/cli/build-old.xml
new file mode 100644
index 0000000000..8445e4484f
--- /dev/null
+++ b/java/management/cli/build-old.xml
@@ -0,0 +1,122 @@
+<?xml version="1.0"?>
+<!--
+ -
+ - Copyright (c) 2006 The Apache Software Foundation
+ -
+ - Licensed under the Apache License, Version 2.0 (the "License");
+ - you may not use this file except in compliance with the License.
+ - You may obtain a copy of the License at
+ -
+ - http://www.apache.org/licenses/LICENSE-2.0
+ -
+ - Unless required by applicable law or agreed to in writing, software
+ - distributed under the License is distributed on an "AS IS" BASIS,
+ - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ - See the License for the specific language governing permissions and
+ - limitations under the License.
+ -
+ -->
+
+<!-- AMQP STAC Java build file -->
+
+<project name="management-stac" default="jar" basedir=".">
+ <property name="lib" value="${basedir}/lib"/>
+ <property name="src" value="${basedir}/src"/>
+ <property name="tests" value="${basedir}/test"/>
+ <property name="classes" value="${basedir}/classes"/>
+ <property name="testclasses" value="${basedir}/testclasses"/>
+ <property name="dist" value="${basedir}/dist"/>
+ <property name="amqp.root" value="${basedir}/../../clients_java"/>
+ <property name="amqp.lib" value="${amqp.root}/lib"/>
+ <property name="amqp.dist" value="${amqp.root}/dist"/>
+ <property name="managementcore.root" value="${basedir}/../core"/>
+ <property name="managementcore.dist" value="${managementcore.root}/dist"/>
+ <property name="managementcore.lib" value="${managementcore.root}/lib"/>
+
+ <!-- Setup details -->
+ <target name="init">
+ <tstamp>
+ <format property="release" pattern="-dMMMyy" locale="en" timezone="GMT"/>
+ </tstamp>
+
+ <mkdir dir="${classes}"/>
+ <mkdir dir="${testclasses}"/>
+ <mkdir dir="${dist}"/>
+ </target>
+
+ <path id="core.classpath">
+ <fileset dir="${lib}">
+ <include name="**/*.jar"/>
+ </fileset>
+ <pathelement path="${classes}"/>
+ <pathelement path="${testclasses}/"/>
+ <fileset dir="${managementcore.dist}">
+ <include name="**/*.jar"/>
+ </fileset>
+ <fileset dir="${managementcore.lib}">
+ <include name="**/*.jar"/>
+ </fileset>
+ <fileset dir="${amqp.dist}">
+ <include name="**/*.jar"/>
+ </fileset>
+ <fileset dir="${amqp.lib}">
+ <include name="**/*.jar"/>
+ </fileset>
+ </path>
+
+ <!-- Remove all built files -->
+ <target name="clean" depends="init">
+ <delete dir="${classes}"/>
+ <delete dir="${dist}"/>
+ <delete dir="${testclasses}"/>
+ </target>
+
+ <!-- Compile Java -->
+ <target name="compile" depends="init">
+ <javac destdir="${classes}" target="1.5" source="1.5" debug="on">
+ <classpath refid="core.classpath"/>
+ <src path="${src}"/>
+ </javac>
+
+ <copy todir="${classes}">
+ <!-- copy any non java src files into the build tree, e.g. log4j.properties -->
+ <fileset dir="${src}">
+ <exclude name="**/*.java"/>
+ <exclude name="**/package.html"/>
+ </fileset>
+ </copy>
+ </target>
+
+
+ <target name="compiletests" depends="compile">
+ <javac destdir="${testclasses}" target="1.5" source="1.5" classpathref="core.classpath"
+ debug="on">
+ <src path="${tests}"/>
+ </javac>
+
+ <copy todir="${testclasses}">
+ <!-- copy any non java src files into the build tree, e.g. log4j.properties -->
+ <fileset dir="${tests}">
+ <exclude name="**/*.java"/>
+ <exclude name="**/package.html"/>
+ </fileset>
+ </copy>
+ </target>
+
+ <!-- Build jar archive -->
+ <target name="jar" depends="compiletests">
+ <mkdir dir="${dist}"/>
+ <jar basedir="${classes}" jarfile="${dist}/amqp-stac.jar"/>
+ <jar basedir="${testclasses}" jarfile="${dist}/amqp-stac-tests.jar"/>
+ </target>
+
+
+ <target name="javadoc" depends="compile, compiletests">
+ <mkdir dir="${dist}/docs/api"/>
+ <javadoc sourcepath="${src}" destdir="${dist}/docs/api"
+ packagenames="org.apache.qpid.*" classpathref="amqp.classpath" author="true"
+ version="true" windowTitle="AMQP STAC API" doctitle="AMQP STAC API"
+ footer="See &lt;a href=&quot;http://www.amqp.org&quot;&gt;www.amqp.org&lt;/a&gt; for more information."
+ use="true" verbose="false"/>
+ </target>
+</project>
diff --git a/java/management/cli/lib/jython/jython.jar b/java/management/cli/lib/jython/jython.jar
new file mode 100644
index 0000000000..517c60dd0e
--- /dev/null
+++ b/java/management/cli/lib/jython/jython.jar
Binary files differ
diff --git a/java/management/cli/src/org/apache/qpid/stac/Stac.java b/java/management/cli/src/org/apache/qpid/stac/Stac.java
new file mode 100644
index 0000000000..98633286fb
--- /dev/null
+++ b/java/management/cli/src/org/apache/qpid/stac/Stac.java
@@ -0,0 +1,94 @@
+/*
+ *
+ * Copyright (c) 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.qpid.stac;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.InputStream;
+
+public class Stac
+{
+ public static void main(String[] args)
+ {
+ BufferedReader terminal = new BufferedReader(new InputStreamReader(System.in));
+ System.out.println("\nInitializing the Scripting Tool for AMQ Console (STAC) ...");
+ String var = System.getProperty("python.verbose");
+ if (var != null)
+ {
+ System.setProperty("python.verbose", var);
+ }
+ else
+ {
+ System.setProperty("python.verbose", "warning");
+ }
+ StacInterpreter interp = new StacInterpreter();
+ InputStream is = Stac.class.getResourceAsStream("/python/stac.py");
+ if (is == null)
+ {
+ System.err.println("Unable to load STAC Python library. Terminating.");
+ System.exit(1);
+ }
+ interp.execfile(is);
+
+ boolean running = true;
+
+ while (running)
+ {
+ interp.write(interp.get("commandPrompt").toString());
+
+ String line = null;
+ try
+ {
+ line = terminal.readLine();
+ if (line != null)
+ {
+ if (line.equalsIgnoreCase("quit") || line.equalsIgnoreCase("exit"))
+ {
+ running = false;
+ line = "quit()";
+ }
+ while (interp.runsource(line))
+ {
+ interp.write("...");
+ try
+ {
+ String s = terminal.readLine();
+ line = line + "\n" + s;
+ }
+ catch (IOException e)
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+ else
+ {
+ System.out.println();
+ running = false;
+ }
+ }
+ catch (IOException ie)
+ {
+ System.err.println("An error occurred: " + ie);
+ ie.printStackTrace(System.err);
+ }
+ }
+ System.exit(0);
+ }
+}
diff --git a/java/management/cli/src/org/apache/qpid/stac/StacInterpreter.java b/java/management/cli/src/org/apache/qpid/stac/StacInterpreter.java
new file mode 100644
index 0000000000..14f9a34504
--- /dev/null
+++ b/java/management/cli/src/org/apache/qpid/stac/StacInterpreter.java
@@ -0,0 +1,31 @@
+/*
+ *
+ * Copyright (c) 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.qpid.stac;
+
+import org.python.util.InteractiveInterpreter;
+import org.python.core.PySystemState;
+
+public class StacInterpreter extends InteractiveInterpreter
+{
+ public StacInterpreter()
+ {
+ PySystemState.initialize();
+ super.set("theInterpreter", this);
+ super.exec("import sys\n");
+ }
+}
diff --git a/java/management/cli/src/org/apache/qpid/stac/commands/CdCommand.java b/java/management/cli/src/org/apache/qpid/stac/commands/CdCommand.java
new file mode 100644
index 0000000000..b21bc450bd
--- /dev/null
+++ b/java/management/cli/src/org/apache/qpid/stac/commands/CdCommand.java
@@ -0,0 +1,50 @@
+/*
+ *
+ * Copyright (c) 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.qpid.stac.commands;
+
+import org.apache.qpid.stac.jmx.MBeanServerConnectionContext;
+import org.apache.qpid.stac.jmx.CurrentMBean;
+import org.apache.qpid.AMQException;
+
+public class CdCommand
+{
+ public static void execute(MBeanServerConnectionContext context, String destination)
+ throws AMQException
+ {
+ // check if it is an absolute path and if so change to the root first
+ if (destination.startsWith("/"))
+ {
+ context.changeBean("/");
+ destination = destination.substring(1);
+ }
+ if (destination.length() == 0)
+ {
+ return;
+ }
+ String[] destinations = destination.split("/");
+ for (String item : destinations)
+ {
+ if ("..".equals(item))
+ {
+ item = CurrentMBean.PARENT_ATTRIBUTE;
+ }
+ context.changeBean(item);
+ }
+ }
+
+}
diff --git a/java/management/cli/src/org/apache/qpid/stac/commands/InvokeCommand.java b/java/management/cli/src/org/apache/qpid/stac/commands/InvokeCommand.java
new file mode 100644
index 0000000000..68b4a6f8aa
--- /dev/null
+++ b/java/management/cli/src/org/apache/qpid/stac/commands/InvokeCommand.java
@@ -0,0 +1,31 @@
+/*
+ *
+ * Copyright (c) 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.qpid.stac.commands;
+
+import org.apache.qpid.stac.jmx.MBeanServerConnectionContext;
+import org.apache.qpid.AMQException;
+
+public class InvokeCommand
+{
+ public static void execute(MBeanServerConnectionContext context, String methodName, Object... args)
+ throws AMQException
+ {
+ // Not used currently
+
+ }
+}
diff --git a/java/management/cli/src/org/apache/qpid/stac/commands/LsCommand.java b/java/management/cli/src/org/apache/qpid/stac/commands/LsCommand.java
new file mode 100644
index 0000000000..4cfa96b030
--- /dev/null
+++ b/java/management/cli/src/org/apache/qpid/stac/commands/LsCommand.java
@@ -0,0 +1,123 @@
+/*
+ *
+ * Copyright (c) 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.qpid.stac.commands;
+
+import org.apache.qpid.AMQException;
+import org.apache.qpid.stac.jmx.CurrentMBean;
+import org.apache.qpid.stac.jmx.MBeanServerConnectionContext;
+import org.apache.qpid.stac.jmx.MBeanUtils;
+
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanParameterInfo;
+import java.util.SortedSet;
+
+public class LsCommand
+{
+ public static void execute(MBeanServerConnectionContext context)
+ throws AMQException
+ {
+ CurrentMBean currentMBean = context.getCurrentMBean();
+
+ SortedSet<MBeanAttributeInfo> directories = currentMBean.getOrderedObjects();
+ System.out.println();
+ for (MBeanAttributeInfo ai : directories)
+ {
+ if (!MBeanUtils.isHidden(ai))
+ {
+ outputAccess(ai);
+ System.out.println(" " + ai.getName());
+ }
+ }
+ System.out.println();
+
+ SortedSet<MBeanAttributeInfo> attributes = currentMBean.getOrderedAttributes();
+ for (MBeanAttributeInfo ai : attributes)
+ {
+ outputAccess(ai);
+ System.out.printf(" %1$-15s%2$-15s %3$s\n", ai.getName(), "[" + convertType(ai.getType()) + "]",
+ currentMBean.getAttributeValue(ai.getName(), ai.getType()));
+ }
+ System.out.println();
+ SortedSet<MBeanOperationInfo> operations = currentMBean.getOrderedOperations();
+
+ for (MBeanOperationInfo oi : operations)
+ {
+ System.out.printf("-r-x %1$-15s", oi.getName());
+ MBeanParameterInfo[] paramInfos = oi.getSignature();
+ System.out.print("[");
+ if (paramInfos.length == 0)
+ {
+ System.out.print("No arguments");
+ }
+
+ for (int i = 0; i < paramInfos.length; i++)
+ {
+ MBeanParameterInfo pi = paramInfos[i];
+ System.out.printf("%1$s:%2$s%3$s", pi.getName(), convertType(pi.getType()),
+ (i < paramInfos.length)?",":"");
+ }
+ System.out.println("]");
+ }
+ System.out.println();
+ }
+
+ private static void outputAccess(MBeanAttributeInfo ai)
+ {
+ boolean isObject = ai.getType().equals("javax.management.ObjectName");
+ System.out.print(isObject?"d":"-");
+ System.out.print(ai.isReadable()?"r":"-");
+ System.out.print(ai.isWritable()?"w":"-");
+ System.out.print("-");
+ }
+
+ /**
+ * Converts the type name to a non-Java type (e.g. java.lang.String -> String)
+ * @param javaType
+ * @return a generic type
+ */
+ private static String convertType(String javaType)
+ {
+ if ("java.lang.String".equals(javaType))
+ {
+ return "String";
+ }
+ else if ("java.lang.Integer".equals(javaType))
+ {
+ return "Integer";
+ }
+ else if ("java.lang.Boolean".equals(javaType))
+ {
+ return "Boolean";
+ }
+ else if ("java.lang.Double".equals(javaType))
+ {
+ return "Double";
+ }
+ else if ("java.util.Date".equals(javaType))
+ {
+ return "Date";
+ }
+ else
+ {
+ return javaType;
+ }
+ }
+
+
+}
diff --git a/java/management/cli/src/org/apache/qpid/stac/jmx/CurrentMBean.java b/java/management/cli/src/org/apache/qpid/stac/jmx/CurrentMBean.java
new file mode 100644
index 0000000000..d378329220
--- /dev/null
+++ b/java/management/cli/src/org/apache/qpid/stac/jmx/CurrentMBean.java
@@ -0,0 +1,180 @@
+/*
+ *
+ * Copyright (c) 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.qpid.stac.jmx;
+
+import org.apache.qpid.AMQException;
+
+import javax.management.*;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+/**
+ * Stores information about the "current" MBean. This data is used when navigating the hierarchy.
+ *
+ * For example, we need to map between a name and an object id, and this stores that link.
+ *
+ */
+public class CurrentMBean
+{
+ private MBeanServerConnection _mbeanServerConnection;
+
+ public static final String PARENT_ATTRIBUTE = "__parent";
+
+ private static final SimpleDateFormat _dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ /**
+ * Maps names to ObjectNames. Used for efficiency to avoid iterating through all names when doing a CD command.
+ */
+ private Map<String, ObjectName> _name2ObjectNameMap = new HashMap<String, ObjectName>();
+
+ private ObjectName _mbeanObjectName;
+
+ private MBeanInfo _mbeanInfo;
+
+ public CurrentMBean(MBeanServerConnection mbeanServerConnection)
+ {
+ _mbeanServerConnection = mbeanServerConnection;
+ }
+
+ public void changeMBean(ObjectName objectName) throws AMQException
+ {
+ try
+ {
+ _mbeanInfo = _mbeanServerConnection.getMBeanInfo(objectName);
+ }
+ catch (Exception e)
+ {
+ throw new AMQException("Unable to look up MBean for object name " + objectName + ": " + e, e);
+ }
+ _mbeanObjectName = objectName;
+ }
+
+ public ObjectName getMBeanObjectName()
+ {
+ return _mbeanObjectName;
+ }
+
+ public MBeanInfo getMBeanInfo()
+ {
+ return _mbeanInfo;
+ }
+
+ public Object getAttributeValue(String name, String type) throws AMQException
+ {
+ // TODO: The type argument is a temporary workaround for a bug (somewhere!) in which
+ // a date is returned as a String
+ try
+ {
+ Object o = _mbeanServerConnection.getAttribute(_mbeanObjectName, name);
+ if ("java.util.Date".equals(type))
+ {
+
+ return _dateFormat.format(new Date(Long.parseLong((String)o)));
+ }
+ else
+ {
+ return o;
+ }
+ }
+ catch (Exception e)
+ {
+ throw new AMQException("Unable to read attribute value for attribute name " + name, e);
+ }
+ }
+
+ /**
+ * Get the objects (i.e. "directories") under the current mbean, ordered alphabetically. This method also
+ * refreshes the cache that maps from name to ObjectName (this saves iterating through the attributes again).
+ * @return a set containing the attribute infos, sorted by name
+ */
+ public SortedSet<MBeanAttributeInfo> getOrderedObjects() throws AMQException
+ {
+ TreeSet<MBeanAttributeInfo> attributes = new TreeSet<MBeanAttributeInfo>(new MBeanAttributeInfoComparator());
+ _name2ObjectNameMap.clear();
+ for (MBeanAttributeInfo ai : _mbeanInfo.getAttributes())
+ {
+ String type = ai.getType();
+
+ if ("javax.management.ObjectName".equals(type))
+ {
+ _name2ObjectNameMap.put(ai.getName(), (ObjectName)getAttributeValue(ai.getName(), type));
+ attributes.add(ai);
+ }
+ }
+ return attributes;
+ }
+
+ public void refreshNameToObjectNameMap() throws AMQException
+ {
+ _name2ObjectNameMap.clear();
+ for (MBeanAttributeInfo ai : _mbeanInfo.getAttributes())
+ {
+ final String type = ai.getType();
+
+ if ("javax.management.ObjectName".equals(type))
+ {
+ _name2ObjectNameMap.put(ai.getName(), (ObjectName)getAttributeValue(ai.getName(), type));
+ }
+ }
+ }
+
+ /**
+ * Gets an object name, given the "display name"
+ * @param name the display name (usually returned to the user when he does an ls()
+ * @return the object name
+ */
+ public ObjectName getObjectNameByName(String name)
+ {
+ return _name2ObjectNameMap.get(name);
+ }
+
+ public SortedSet<MBeanAttributeInfo> getOrderedAttributes()
+ {
+ TreeSet<MBeanAttributeInfo> attributes = new TreeSet<MBeanAttributeInfo>(new MBeanAttributeInfoComparator());
+ for (MBeanAttributeInfo ai : _mbeanInfo.getAttributes())
+ {
+ String type = ai.getType();
+ if (!"javax.management.ObjectName".equals(type))
+ {
+ attributes.add(ai);
+ }
+ }
+ return attributes;
+ }
+
+ public SortedSet<MBeanOperationInfo> getOrderedOperations()
+ {
+ TreeSet<MBeanOperationInfo> operations = new TreeSet<MBeanOperationInfo>(new MBeanOperationInfoComparator());
+ for (MBeanOperationInfo oi : _mbeanInfo.getOperations())
+ {
+ operations.add(oi);
+ }
+ return operations;
+ }
+
+ public void invoke(String methodName, Object... args) throws AMQException
+ {
+ try
+ {
+ _mbeanServerConnection.invoke(_mbeanObjectName, methodName, null, null);
+ }
+ catch (Exception e)
+ {
+ throw new AMQException("Error invoking method " + methodName + ": " + e, e);
+ }
+ }
+}
diff --git a/java/management/cli/src/org/apache/qpid/stac/jmx/MBeanAttributeInfoComparator.java b/java/management/cli/src/org/apache/qpid/stac/jmx/MBeanAttributeInfoComparator.java
new file mode 100644
index 0000000000..b5c2437d58
--- /dev/null
+++ b/java/management/cli/src/org/apache/qpid/stac/jmx/MBeanAttributeInfoComparator.java
@@ -0,0 +1,29 @@
+/*
+ *
+ * Copyright (c) 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.qpid.stac.jmx;
+
+import javax.management.MBeanAttributeInfo;
+import java.util.Comparator;
+
+public class MBeanAttributeInfoComparator implements Comparator<MBeanAttributeInfo>
+{
+ public int compare(MBeanAttributeInfo o1, MBeanAttributeInfo o2)
+ {
+ return o1.getName().compareTo(o2.getName());
+ }
+}
diff --git a/java/management/cli/src/org/apache/qpid/stac/jmx/MBeanOperationInfoComparator.java b/java/management/cli/src/org/apache/qpid/stac/jmx/MBeanOperationInfoComparator.java
new file mode 100644
index 0000000000..4c490d92d5
--- /dev/null
+++ b/java/management/cli/src/org/apache/qpid/stac/jmx/MBeanOperationInfoComparator.java
@@ -0,0 +1,29 @@
+/*
+ *
+ * Copyright (c) 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.qpid.stac.jmx;
+
+import javax.management.MBeanOperationInfo;
+import java.util.Comparator;
+
+public class MBeanOperationInfoComparator implements Comparator<MBeanOperationInfo>
+{
+ public int compare(MBeanOperationInfo o1, MBeanOperationInfo o2)
+ {
+ return o1.getName().compareTo(o2.getName());
+ }
+}
diff --git a/java/management/cli/src/org/apache/qpid/stac/jmx/MBeanServerConnectionContext.java b/java/management/cli/src/org/apache/qpid/stac/jmx/MBeanServerConnectionContext.java
new file mode 100644
index 0000000000..18e5359b8c
--- /dev/null
+++ b/java/management/cli/src/org/apache/qpid/stac/jmx/MBeanServerConnectionContext.java
@@ -0,0 +1,202 @@
+/*
+ *
+ * Copyright (c) 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.qpid.stac.jmx;
+
+import org.apache.qpid.AMQException;
+import org.apache.qpid.management.jmx.JmxConstants;
+import org.apache.qpid.stac.commands.CdCommand;
+import org.apache.qpid.stac.commands.LsCommand;
+import org.apache.log4j.Logger;
+
+import javax.management.MBeanServerConnection;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+import javax.management.ObjectInstance;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXServiceURL;
+import java.lang.management.ManagementFactory;
+import java.util.Hashtable;
+import java.util.Set;
+
+public class MBeanServerConnectionContext
+{
+ private static final Logger _log = Logger.getLogger(MBeanServerConnectionContext.class);
+
+ /**
+ * The connection to the MBean server. Can be remote or local, depending on whether we are proxying.
+ */
+ private MBeanServerConnection _connection;
+
+ /**
+ * The connector used to make the connection to the remote MBean server
+ */
+ private JMXConnector _connector;
+
+ private CurrentMBean _currentMBean;
+
+ /*
+ * Initialize connection to the Domain Runtime MBean Server
+ */
+ public void connect(String host) throws AMQException
+ {
+ if (host == null)
+ {
+ _connection = (MBeanServerConnection) ManagementFactory.getPlatformMBeanServer();
+ }
+ else
+ {
+ String serviceURLString = "service:jmx:local://localhost";
+
+ try
+ {
+ JMXServiceURL serviceURL = new JMXServiceURL(serviceURLString);
+ _connector = JMXConnectorFactory.connect(serviceURL, null);
+ _connection = _connector.getMBeanServerConnection();
+ }
+ catch (Exception e)
+ {
+ throw new AMQException("Unable to connect to remote MBean server with service url " + serviceURLString +
+ ": " + e, e);
+ }
+ }
+ _currentMBean = new CurrentMBean(_connection);
+ changeBean(getRootObjectName());
+ }
+
+ /**
+ * Connect to the local MBean server
+ * @throws AMQException
+ */
+ public void connect() throws AMQException
+ {
+ connect(null);
+ }
+
+ public void disconnect() throws AMQException
+ {
+ if (_connection != null)
+ {
+ try
+ {
+ ObjectName queryName = new ObjectName(JmxConstants.JMX_DOMAIN + ":*");
+ Set<ObjectInstance> beans = _connection.queryMBeans(queryName, null);
+ for (ObjectInstance bean : beans)
+ {
+ _log.debug("Unregistering MBean: " + bean.getObjectName());
+ _connection.unregisterMBean(bean.getObjectName());
+ }
+ }
+ catch (Exception e)
+ {
+ throw new AMQException("Error unregistering MBeans: " + e, e);
+ }
+ }
+ }
+
+ public ObjectName getRootObjectName() throws AMQException
+ {
+ Hashtable<String, String> props = new Hashtable<String, String>();
+ props.put("objectid", "0");
+ props.put("type", "broker");
+ try
+ {
+ return new ObjectName(JmxConstants.JMX_DOMAIN, props);
+ }
+ catch (MalformedObjectNameException e)
+ {
+ throw new AMQException("Cannot construct root MBean object name: " + e, e);
+ }
+ }
+
+ private void changeBean(ObjectName objectName) throws AMQException
+ {
+ _currentMBean.changeMBean(objectName);
+ }
+
+ /**
+ * Change the current bean to the one underneath the current bean, represented by the display name
+ * @param name
+ * @throws AMQException
+ */
+ public void changeBean(String name) throws AMQException
+ {
+ checkConnection();
+ if (name.equals("/"))
+ {
+ changeBean(getRootObjectName());
+ }
+ else
+ {
+ ObjectName objName = _currentMBean.getObjectNameByName(name);
+ if (CurrentMBean.PARENT_ATTRIBUTE.equals(name) && objName == null)
+ {
+ // we have tried to change up a level from the root, so just ignore
+ return;
+ }
+ if (objName == null)
+ {
+ // could be stale cache, so refresh
+ _currentMBean.refreshNameToObjectNameMap();
+ objName = _currentMBean.getObjectNameByName(name);
+ }
+ if (objName == null)
+ {
+ throw new AMQException("Unknown managed object with name: " + name);
+ }
+ else
+ {
+ changeBean(objName);
+ }
+ }
+ }
+
+ public void ls() throws AMQException
+ {
+ checkConnection();
+ LsCommand.execute(this);
+ }
+
+ public void cd(String destination) throws AMQException
+ {
+ CdCommand.execute(this, destination);
+ }
+
+ public void invoke(String methodName, Object... args) throws AMQException
+ {
+ _currentMBean.invoke(methodName, args);
+ }
+
+ public CurrentMBean getCurrentMBean()
+ {
+ return _currentMBean;
+ }
+
+ public MBeanServerConnection getMBeanServerConnection()
+ {
+ return _connection;
+ }
+
+ private void checkConnection() throws NotConnectedException
+ {
+ if (_connection == null)
+ {
+ throw new NotConnectedException();
+ }
+ }
+}
diff --git a/java/management/cli/src/org/apache/qpid/stac/jmx/MBeanUtils.java b/java/management/cli/src/org/apache/qpid/stac/jmx/MBeanUtils.java
new file mode 100644
index 0000000000..57bba9d4d3
--- /dev/null
+++ b/java/management/cli/src/org/apache/qpid/stac/jmx/MBeanUtils.java
@@ -0,0 +1,35 @@
+/*
+ *
+ * Copyright (c) 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.qpid.stac.jmx;
+
+import javax.management.MBeanAttributeInfo;
+
+/**
+ * Useful MBean methods. Also provides functionality for our CMLMBean
+ */
+public class MBeanUtils
+{
+ public static boolean isHidden(MBeanAttributeInfo ai)
+ {
+ /* This is JDK 1.6 only
+ String hidden = (String) ai.getDescriptor().getFieldValue("hidden");
+ return hidden != null && "true".equals(hidden);
+ */
+ return ai.getName().startsWith("__");
+ }
+}
diff --git a/java/management/cli/src/org/apache/qpid/stac/jmx/NotConnectedException.java b/java/management/cli/src/org/apache/qpid/stac/jmx/NotConnectedException.java
new file mode 100644
index 0000000000..2fcb6e5ddf
--- /dev/null
+++ b/java/management/cli/src/org/apache/qpid/stac/jmx/NotConnectedException.java
@@ -0,0 +1,28 @@
+/*
+ *
+ * Copyright (c) 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.qpid.stac.jmx;
+
+import org.apache.qpid.AMQException;
+
+public class NotConnectedException extends AMQException
+{
+ public NotConnectedException()
+ {
+ super("Not connected to JMX server");
+ }
+}
diff --git a/java/management/cli/src/python/stac.py b/java/management/cli/src/python/stac.py
new file mode 100644
index 0000000000..d521dc18c3
--- /dev/null
+++ b/java/management/cli/src/python/stac.py
@@ -0,0 +1,190 @@
+#
+# Copyright (c) 2006 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+"""
+Bridges between Python and Java, to provide a simpler and more Pythonesque environment.
+Certified to be free of dead parrots.
+"""
+# Imports
+from java.lang import *
+import org.amqp.blaze.management.jmx.AMQConsole as AMQConsole
+import org.amqp.blaze.stac.jmx.MBeanServerConnectionContext as MBeanServerConnectionContext
+
+# Globals
+commandPrompt = ""
+proxied = 0
+connected = 0
+amqConsole = None
+connectionContext = None
+
+# Functions
+def connect(url="", username="", password=""):
+ """
+ Connects to an AMQP broker. The URL must be in the form amq://host:port/context
+ """
+ try:
+ global connected
+ global connectionContext
+ if connected==1:
+ print "Already Connected!"
+ return
+
+ try:
+ parsedURL = parseURL(url)
+ except URLFormatError, ufe:
+ print "Invalid URL: " + ufe.msg
+ return
+
+ amqConsole = AMQConsole(parsedURL['host'], parsedURL['port'], username, password, parsedURL['context'])
+
+ amqConsole.initialise()
+ amqConsole.registerAllMBeans()
+ connectionContext = MBeanServerConnectionContext()
+ connectionContext.connect()
+ connected = 1
+ except Exception, e:
+ updateGlobals()
+ print e
+ e.printStackTrace()
+ cause = e.getCause()
+ if cause != None:
+ cause.printStackTrace()
+ else:
+ updateGlobals();
+
+def disconnect():
+ """
+ Disconnects from the broker
+ """
+ global connected
+ global connectionContext
+
+ if connected==0:
+ print "Not connected!"
+ return
+ try:
+ connectionContext.disconnect()
+ connected = 0
+ except Exception, e:
+ updateGlobals()
+ print e
+ else:
+ updateGlobals()
+
+def quit():
+ global connected
+ if connected != 0:
+ disconnect()
+
+def ls():
+ """
+ Lists the current mbean
+ """
+ global connected
+ if connected == 0:
+ print "Not connected!"
+ return
+
+ connectionContext.ls()
+
+def cd(beanName):
+ """
+ Changes the current mbean
+ """
+ global connected
+ global connectionContext
+ if connected == 0:
+ print "Not connected!"
+ return
+
+ try:
+ connectionContext.cd(beanName)
+ except Exception, e:
+ updateGlobals()
+ msg = "Error: " + e.getMessage()
+ print msg
+ else:
+ updateGlobals()
+
+def invoke(methodName):
+ """
+ Invokes an operation of the current mbean
+ """
+ global connected
+ global connectionContext
+
+ if connected == 0:
+ print "Not connected!"
+ return
+
+ try:
+ connectionContext.invoke(methodName, None)
+ except Exception, e:
+ updateGlobals()
+ msg = "Error: " + e.getMessage()
+ print msg
+ else:
+ updateGlobals()
+
+class URLFormatError(Exception):
+ """Exception raised for errors in format of the URL
+
+ Attributes:
+ expression -- input expression in which the error occurred
+ message -- explanation of the error
+ """
+
+ def __init__(self, url, message):
+ self.url = url
+ self.msg = message
+
+def parseURL(url):
+ """
+ Parses an AMQ URL into host, port and context components returning them in a dictionary
+ """
+ idx = url.find("amq://")
+ errorMsg = "Invalid URL - must be format amq://hostname:port/vhost"
+ if idx != 0:
+ raise URLFormatError(url, errorMsg)
+
+ hostEndIdx = url.find(":", 6)
+ if hostEndIdx == -1:
+ raise URLFormatError(url, errorMsg)
+
+ hostname = url[6:hostEndIdx]
+
+ portIdx = url.find("/", hostEndIdx + 1)
+ port = url[hostEndIdx + 1:portIdx]
+ vhost = url[portIdx + 1:]
+ if portIdx == -1:
+ raise URLFormatError(url, errorMsg)
+
+ return {'host':hostname,'port':int(port),'context':vhost}
+
+def updateGlobals():
+ global commandPrompt
+ global connectionContext
+ if connected == 1:
+ commandPrompt = "AMQ:connected#" + connectionContext.getCurrentMBean().getAttributeValue("name", "java.lang.String") + "> "
+ else:
+ commandPrompt = "AMQ:disconnected> "
+# Classes
+
+
+# Global execution
+
+# Update all the global variables - this is called to sync everything at the start
+updateGlobals()
diff --git a/java/management/cli/test/org/apache/qpid/stac/ConnectionTest.java b/java/management/cli/test/org/apache/qpid/stac/ConnectionTest.java
new file mode 100644
index 0000000000..cf728cc6aa
--- /dev/null
+++ b/java/management/cli/test/org/apache/qpid/stac/ConnectionTest.java
@@ -0,0 +1,35 @@
+/*
+ *
+ * Copyright (c) 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.qpid.stac;
+
+import org.apache.qpid.management.jmx.AMQConsole;
+import org.apache.qpid.stac.jmx.MBeanServerConnectionContext;
+
+public class ConnectionTest
+{
+ public static void main(String[] args) throws Exception
+ {
+
+ AMQConsole console = new AMQConsole("localhost", 5672, "guest", "guest", "/test");
+ console.initialise();
+ console.registerAllMBeans();
+ MBeanServerConnectionContext connectionContext = new MBeanServerConnectionContext();
+ connectionContext.connect();
+ connectionContext.ls();
+ }
+}
diff --git a/java/management/core/build-module.xml b/java/management/core/build-module.xml
new file mode 100644
index 0000000000..07e17a44d4
--- /dev/null
+++ b/java/management/core/build-module.xml
@@ -0,0 +1,47 @@
+<!--
+ -
+ - Copyright (c) 2006 The Apache Software Foundation
+ -
+ - Licensed under the Apache License, Version 2.0 (the "License");
+ - you may not use this file except in compliance with the License.
+ - You may obtain a copy of the License at
+ -
+ - http://www.apache.org/licenses/LICENSE-2.0
+ -
+ - Unless required by applicable law or agreed to in writing, software
+ - distributed under the License is distributed on an "AS IS" BASIS,
+ - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ - See the License for the specific language governing permissions and
+ - limitations under the License.
+ -
+ -->
+<project name="AMQ Management Core" default="build">
+
+ <property name="module.depends" value="common,client"/>
+
+ <import file="../../module.xml"/>
+
+ <property name="etc" value="etc"/>
+ <property name="xmlbeans.timestamp" value="${module.dir}/xmlbeans.timestamp"/>
+
+ <fileset id="xmlbeans.schema" dir="${etc}" includes="**/*.xsd"/>
+
+ <uptodate property="xmlbeans.done" targetfile="${xmlbeans.timestamp}">
+ <srcfiles refid="xmlbeans.schema"/>
+ </uptodate>
+
+ <taskdef name="xmlbean" classname="org.apache.xmlbeans.impl.tool.XMLBean" classpathref="module.class.path"/>
+
+ <!-- Generate code from the XML schema -->
+ <target name="xmlbeans" unless="xmlbeans.done">
+ <xmlbean classgendir="${module.classes}" classpathref="module.class.path"
+ failonerror="true" srcgendir="${module.precompiled}"
+ javasource="1.5" source="1.5">
+ <fileset refid="xmlbeans.schema"/>
+ </xmlbean>
+ <touch file="${xmlbeans.timestamp}"/>
+ </target>
+
+ <target name="precompile" depends="xmlbeans"/>
+
+</project>
diff --git a/java/management/core/build-old.xml b/java/management/core/build-old.xml
new file mode 100644
index 0000000000..df00b95bcc
--- /dev/null
+++ b/java/management/core/build-old.xml
@@ -0,0 +1,189 @@
+<?xml version="1.0"?>
+<!--
+ -
+ - Copyright (c) 2006 The Apache Software Foundation
+ -
+ - Licensed under the Apache License, Version 2.0 (the "License");
+ - you may not use this file except in compliance with the License.
+ - You may obtain a copy of the License at
+ -
+ - http://www.apache.org/licenses/LICENSE-2.0
+ -
+ - Unless required by applicable law or agreed to in writing, software
+ - distributed under the License is distributed on an "AS IS" BASIS,
+ - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ - See the License for the specific language governing permissions and
+ - limitations under the License.
+ -
+ -->
+
+<!-- AMQP Management Core Java build file -->
+
+<project name="management-core" default="jar" basedir=".">
+ <property name="lib" value="${basedir}/lib"/>
+ <property name="src" value="${basedir}/src"/>
+ <property name="generated.src" value="${basedir}/generated/src"/>
+ <property name="tests" value="${basedir}/test"/>
+ <property name="etc" value="${basedir}/etc"/>
+ <property name="classes" value="${basedir}/classes"/>
+ <property name="testclasses" value="${basedir}/testclasses"/>
+ <property name="dist" value="${basedir}/dist"/>
+ <property name="apache.root" value="${basedir}/../../clients_java"/>
+ <property name="apache.dist" value="${apache.root}/dist"/>
+ <property name="apache.lib" value="${apache.root}/lib"/>
+
+ <taskdef name="xmlbean" classname="org.apache.xmlbeans.impl.tool.XMLBean" classpathref="core.classpath"/>
+
+ <!-- Setup details -->
+ <target name="init">
+ <tstamp>
+ <format property="release" pattern="-dMMMyy" locale="en" timezone="GMT"/>
+ </tstamp>
+
+ <mkdir dir="${generated.src}"/>
+ <mkdir dir="${classes}"/>
+ <mkdir dir="${testclasses}"/>
+ <mkdir dir="${dist}"/>
+ </target>
+
+ <path id="core.classpath">
+ <fileset dir="${lib}">
+ <include name="**/*.jar"/>
+ </fileset>
+ <pathelement path="${classes}"/>
+ <pathelement path="${testclasses}/"/>
+ <fileset dir="${apache.dist}">
+ <include name="**/*.jar"/>
+ </fileset>
+ <fileset dir="${apache.lib}">
+ <include name="**/*.jar"/>
+ </fileset>
+ </path>
+
+ <!-- Remove all built files -->
+ <target name="clean" depends="init">
+ <delete dir="${generated.src}"/>
+ <delete dir="${classes}"/>
+ <delete dir="${dist}"/>
+ <delete dir="${testclasses}"/>
+ </target>
+
+ <!-- Generate code from the XML schema -->
+ <target name="xmlbeans" depends="init">
+ <xmlbean classgendir="${classes}" classpathref="core.classpath"
+ failonerror="true" srcgendir="${generated.src}"
+ javasource="1.5" source="1.5">
+ <fileset dir="${etc}" includes="**/*.xsd"/>
+ </xmlbean>
+ </target>
+
+ <!-- Compile Java -->
+ <target name="compile" depends="xmlbeans">
+ <javac destdir="${classes}" target="1.5" source="1.5" debug="on">
+ <classpath refid="core.classpath"/>
+ <src path="${src}"/>
+ <src path="${generated.src}"/>
+ </javac>
+
+ <copy todir="${classes}">
+ <!-- copy any non java src files into the build tree, e.g. log4j.properties -->
+ <fileset dir="${src}">
+ <exclude name="**/*.java"/>
+ <exclude name="**/package.html"/>
+ </fileset>
+ </copy>
+ </target>
+
+
+ <target name="compiletests" depends="compile">
+ <javac destdir="${testclasses}" target="1.5" source="1.5" classpathref="core.classpath"
+ debug="on">
+ <src path="${tests}"/>
+ </javac>
+
+ <copy todir="${testclasses}">
+ <!-- copy any non java src files into the build tree, e.g. log4j.properties -->
+ <fileset dir="${tests}">
+ <exclude name="**/*.java"/>
+ <exclude name="**/package.html"/>
+ </fileset>
+ </copy>
+ </target>
+
+ <!-- Build jar archive -->
+ <target name="jar" depends="compiletests">
+ <mkdir dir="${dist}"/>
+ <jar basedir="${classes}" jarfile="${dist}/apache-management-common.jar"/>
+ <jar basedir="${testclasses}" jarfile="${dist}/apache-management-tests.jar"/>
+ </target>
+
+
+ <target name="javadoc" depends="compile, compiletests">
+ <mkdir dir="${dist}/docs/api"/>
+ <javadoc sourcepath="${src}" destdir="${dist}/docs/api"
+ packagenames="org.apache.qpid.*" classpathref="apache.classpath" author="true"
+ version="true" windowTitle="AMQP Client API" doctitle="AMQP Client API"
+ footer="See &lt;a href=&quot;http://www.apache.org&quot;&gt;www.apache.org&lt;/a&gt; for more information."
+ use="true" verbose="false"/>
+ </target>
+
+ <target name="ServiceProvidingClient" depends="compiletests">
+ <java fork="yes" classname="org.apache.qpid.requestreply1.ServiceProvidingClient">
+ <classpath refid="apache.classpath"/>
+ <jvmarg value="-server"/>
+ <jvmarg value="-Damqj.logging.level=INFO"/>
+ <arg value="localhost"/>
+ <arg value="5672"/>
+ <arg value="guest"/>
+ <arg value="guest"/>
+ <arg value="/vpath"/>
+ <arg value="serviceQ1"/>
+ </java>
+ </target>
+
+ <target name="ServiceRequestingClient" depends="compiletests">
+ <java fork="yes" classname="org.apache.qpid.requestreply1.ServiceRequestingClient">
+ <classpath refid="apache.classpath"/>
+ <jvmarg value="-server"/>
+ <jvmarg value="-Damqj.logging.level=INFO"/>
+ <arg value="localhost"/>
+ <arg value="5672"/>
+ <arg value="guest"/>
+ <arg value="guest"/>
+ <arg value="/vpath"/>
+ <arg value="serviceQ1"/>
+ <arg value="5000"/>
+ </java>
+ </target>
+
+ <target name="profile" depends="compile" description="Profile Project">
+ <fail unless="netbeans.home">This target can only run inside the NetBeans IDE.</fail>
+ <nbprofiledirect>
+ <classpath refid="apache.classpath"/>
+ </nbprofiledirect>
+ <java fork="true" classname="org.apache.qpid.requestreply1.ServiceRequestingClient"
+ dir="${profiler.session.working.dir}"
+ jvm="${profiler.info.jvm}">
+ <jvmarg value="${profiler.info.jvmargs.agent}"/>
+ <jvmarg line="${profiler.info.jvmargs}"/>
+ <env key="Path" path="${profiler.info.agentpath}:${env.Path}"/>
+ <classpath refid="apache.classpath"/>
+ <jvmarg value="-server"/>
+ <jvmarg value="-Damqj.logging.level=INFO"/>
+ <arg value="localhost"/>
+ <arg value="5672"/>
+ <arg value="guest"/>
+ <arg value="guest"/>
+ <arg value="/vpath"/>
+ <arg value="serviceQ1"/>
+ <arg value="5000"/>
+ </java>
+ </target>
+
+ <target name="profile-single" depends="compile" description="Profile File">
+ <fail unless="netbeans.home">This target can only run inside the NetBeans IDE.</fail>
+ <nbprofile classname="${profile.class}">
+ <classpath refid="apache.classpath"/>
+ </nbprofile>
+ </target>
+</project>
diff --git a/java/management/core/etc/cml-exampleschema.xml b/java/management/core/etc/cml-exampleschema.xml
new file mode 100644
index 0000000000..bcee38246f
--- /dev/null
+++ b/java/management/core/etc/cml-exampleschema.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0"?>
+<!--
+ -
+ - Copyright (c) 2006 The Apache Software Foundation
+ -
+ - Licensed under the Apache License, Version 2.0 (the "License");
+ - you may not use this file except in compliance with the License.
+ - You may obtain a copy of the License at
+ -
+ - http://www.apache.org/licenses/LICENSE-2.0
+ -
+ - Unless required by applicable law or agreed to in writing, software
+ - distributed under the License is distributed on an "AS IS" BASIS,
+ - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ - See the License for the specific language governing permissions and
+ - limitations under the License.
+ -
+ -->
+<cml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.apache.org/schema/cml cml.xsd"
+ xmlns="http://www.apache.org/schema/cml"
+ version="1.0">
+ <schema-reply name = "qpid.apache.org/kernel" version = "0.1" status = "ok">
+ <class name = "broker">
+ <field name = "started" label = "Date, time broker started" />
+ <field name = "vhost" type = "objref" repeat = "1" />
+ </class>
+ <class name = "vhost">
+ <field name = "name" label = "Virtual host path" />
+ <field name = "exchange" type = "objref" repeat = "1" />
+ <field name = "queue" type = "objref" repeat = "1" />
+ </class>
+ <class name = "exchange">
+ <field name = "name" />
+ <field name = "type" />
+ <field name = "durable" label = "Durable exchange?" type = "bool" />
+ <field name = "auto_delete" label = "Auto-deleted?" type = "bool" />
+ <field name = "bindings" label = "Number of bindings" type = "int" />
+ </class>
+ <class name = "queue">
+ <field name = "scope" />
+ <field name = "name" />
+ <field name = "enabled" label = "Queue accepts new messages?" modify = "1" />
+ <field name = "durable" label = "Durable queue?" type = "bool" />
+ <field name = "exclusive" label = "Exclusive to one connection?" type = "bool" />
+ <field name = "auto_delete" label = "Auto-deleted?" type = "bool" />
+ <field name = "consumers" label = "Number of consumers" type = "int" />
+ <field name = "messages" label = "Number of messages" type = "int" />
+ </class>
+ </schema-reply>
+</cml>
diff --git a/java/management/core/etc/cml.xsd b/java/management/core/etc/cml.xsd
new file mode 100644
index 0000000000..99c21b41f9
--- /dev/null
+++ b/java/management/core/etc/cml.xsd
@@ -0,0 +1,175 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ -
+ - Copyright (c) 2006 The Apache Software Foundation
+ -
+ - Licensed under the Apache License, Version 2.0 (the "License");
+ - you may not use this file except in compliance with the License.
+ - You may obtain a copy of the License at
+ -
+ - http://www.apache.org/licenses/LICENSE-2.0
+ -
+ - Unless required by applicable law or agreed to in writing, software
+ - distributed under the License is distributed on an "AS IS" BASIS,
+ - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ - See the License for the specific language governing permissions and
+ - limitations under the License.
+ -
+ -->
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.apache.org/qpid/schema/cml" xmlns="http://www.apache.org/qpid/schema/cml"
+ elementFormDefault="qualified">
+ <xs:element name="cml">
+ <xs:annotation>
+ <xs:documentation>Defines a CML document as a schema or a...</xs:documentation>
+ </xs:annotation>
+ <xs:complexType>
+ <xs:choice>
+ <xs:element name="schema-request" minOccurs="0"/>
+ <xs:element name="schema-reply" type="schema-reply-type" minOccurs="0" >
+ <!--<xs:key name="classkey">
+ <xs:selector xpath="class"/>
+ <xs:field xpath="@name"/>
+ </xs:key>-->
+ </xs:element>
+ <xs:element name="inspect-request" type="inspect-request-type" minOccurs="0"/>
+ <xs:element name="inspect-reply" type="inspect-reply-type" minOccurs="0" />
+ <xs:element name="method-request" type="method-request-type" minOccurs="0"/>
+ <xs:element name="method-reply" type="method-reply-type" minOccurs="0" />
+ </xs:choice>
+ <xs:attribute name="version" type="xs:string" use="required"/>
+ </xs:complexType>
+ </xs:element>
+ <xs:complexType name="schema-reply-type">
+ <xs:annotation>
+ <xs:documentation>Client request for a schema</xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="class" type="class-type" minOccurs="1" maxOccurs="unbounded"/>
+ </xs:sequence>
+ <xs:attribute name="name" type="xs:string" use="required"/>
+ <xs:attribute name="version" type="xs:string" use="required"/>
+ <xs:attribute name="status">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="ok"/>
+ <xs:enumeration value="not ok"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+ </xs:complexType>
+ <xs:complexType name="class-type">
+ <xs:annotation>
+ <xs:documentation>Defines a class which is a managable object</xs:documentation>
+ </xs:annotation>
+ <xs:choice>
+ <xs:element name="field" type="field-type" minOccurs="0" maxOccurs="unbounded">
+ <xs:unique name="uniqueFieldName">
+ <xs:selector xpath="field"/>
+ <xs:field xpath="@name"/>
+ </xs:unique>
+ </xs:element>
+ <xs:element name="method" type="method-type" minOccurs="0" maxOccurs="unbounded">
+ <xs:unique name="uniqueMethodName">
+ <xs:selector xpath="method"/>
+ <xs:field xpath="@name"/>
+ </xs:unique>
+ </xs:element>
+ </xs:choice>
+ <xs:attribute name="name" type="xs:string" use="required"/>
+ </xs:complexType>
+ <xs:complexType name="field-type">
+ <xs:annotation>
+ <xs:documentation>Defines a field within a class</xs:documentation>
+ </xs:annotation>
+ <xs:simpleContent>
+ <xs:extension base="xs:string">
+ <xs:attribute name="name" type="xs:string" use="required"/>
+ <xs:attribute name="type" use="optional" default="string">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="bool"/>
+ <xs:enumeration value="string"/>
+ <xs:enumeration value="int"/>
+ <xs:enumeration value="objref"/>
+ <xs:enumeration value="time"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+ <xs:attribute name="label" type="xs:string" use="optional"/>
+ <xs:attribute name="repeat" type="xs:boolean" use="optional" default="false"/>
+ <xs:attribute name="modify" type="xs:boolean" use="optional" default="false"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+ <xs:complexType name="method-type">
+ <xs:annotation>
+ <xs:documentation>Defines a method within a class</xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="field" type="field-type" minOccurs="0" maxOccurs="unbounded">
+ <xs:unique name="uniqueArgumentName">
+ <xs:selector xpath="field"/>
+ <xs:field xpath="@name"/>
+ </xs:unique>
+ </xs:element>
+ </xs:sequence>
+ <xs:attribute name="name" type="xs:string" use="required"/>
+ </xs:complexType>
+ <xs:complexType name="inspect-request-type">
+ <xs:annotation>
+ <xs:documentation>A request to get the property values of an instance</xs:documentation>
+ </xs:annotation>
+ <xs:attribute name="object" type="xs:int" use="required"/>
+ </xs:complexType>
+ <xs:complexType name="inspect-reply-type">
+ <xs:annotation>
+ <xs:documentation>A response containing the properties of an instance</xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="field" type="field-type" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="object" type="object-type" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ <xs:attribute name="class" type="xs:string" use="optional"/>
+ <xs:attribute name="status" use="optional">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="ok"/>
+ <xs:enumeration value="notfound"/>
+ <xs:enumeration value="noaccess"/>
+ <xs:enumeration value="invalid"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+ <xs:attribute name="object" type="xs:int" use="required"/>
+ </xs:complexType>
+ <xs:complexType name="object-type">
+ <xs:annotation>
+ <xs:documentation>A reference to an object instance</xs:documentation>
+ </xs:annotation>
+ <xs:attribute name="class" type="xs:string" use="required"/>
+ <xs:attribute name="id" type="xs:int" use="required"/>
+ </xs:complexType>
+ <xs:complexType name="method-request-type">
+ <xs:annotation>
+ <xs:documentation>A request to invoke a method</xs:documentation>
+ </xs:annotation>
+ <xs:attribute name="object" type="xs:int" use="required"/>
+ <xs:attribute name="name" type="xs:string" use="required"/>
+ </xs:complexType>
+ <xs:complexType name="method-reply-type">
+ <xs:annotation>
+ <xs:documentation>A reply to a method invocation request</xs:documentation>
+ </xs:annotation>
+ <xs:attribute name="object" type="xs:int" use="required"/>
+ <xs:attribute name="status" use="required">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="ok"/>
+ <xs:enumeration value="notfound"/>
+ <xs:enumeration value="noaccess"/>
+ <xs:enumeration value="invalid"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+ </xs:complexType>
+</xs:schema>
diff --git a/java/management/core/lib/jakarta-commons/commons-attributes-api.jar b/java/management/core/lib/jakarta-commons/commons-attributes-api.jar
new file mode 100644
index 0000000000..b41cd055bb
--- /dev/null
+++ b/java/management/core/lib/jakarta-commons/commons-attributes-api.jar
Binary files differ
diff --git a/java/management/core/lib/jakarta-commons/commons-attributes-compiler.jar b/java/management/core/lib/jakarta-commons/commons-attributes-compiler.jar
new file mode 100644
index 0000000000..ffd93f79eb
--- /dev/null
+++ b/java/management/core/lib/jakarta-commons/commons-attributes-compiler.jar
Binary files differ
diff --git a/java/management/core/lib/jakarta-commons/commons-beanutils.jar b/java/management/core/lib/jakarta-commons/commons-beanutils.jar
new file mode 100644
index 0000000000..b1b89c9c92
--- /dev/null
+++ b/java/management/core/lib/jakarta-commons/commons-beanutils.jar
Binary files differ
diff --git a/java/management/core/lib/jakarta-commons/commons-codec.jar b/java/management/core/lib/jakarta-commons/commons-codec.jar
new file mode 100644
index 0000000000..957b6752af
--- /dev/null
+++ b/java/management/core/lib/jakarta-commons/commons-codec.jar
Binary files differ
diff --git a/java/management/core/lib/jakarta-commons/commons-collections.jar b/java/management/core/lib/jakarta-commons/commons-collections.jar
new file mode 100644
index 0000000000..41e230feea
--- /dev/null
+++ b/java/management/core/lib/jakarta-commons/commons-collections.jar
Binary files differ
diff --git a/java/management/core/lib/jakarta-commons/commons-dbcp.jar b/java/management/core/lib/jakarta-commons/commons-dbcp.jar
new file mode 100644
index 0000000000..08440c02e5
--- /dev/null
+++ b/java/management/core/lib/jakarta-commons/commons-dbcp.jar
Binary files differ
diff --git a/java/management/core/lib/jakarta-commons/commons-digester.jar b/java/management/core/lib/jakarta-commons/commons-digester.jar
new file mode 100644
index 0000000000..9765493306
--- /dev/null
+++ b/java/management/core/lib/jakarta-commons/commons-digester.jar
Binary files differ
diff --git a/java/management/core/lib/jakarta-commons/commons-discovery.jar b/java/management/core/lib/jakarta-commons/commons-discovery.jar
new file mode 100644
index 0000000000..eff4db19ef
--- /dev/null
+++ b/java/management/core/lib/jakarta-commons/commons-discovery.jar
Binary files differ
diff --git a/java/management/core/lib/jakarta-commons/commons-fileupload.jar b/java/management/core/lib/jakarta-commons/commons-fileupload.jar
new file mode 100644
index 0000000000..1ca4a9cd31
--- /dev/null
+++ b/java/management/core/lib/jakarta-commons/commons-fileupload.jar
Binary files differ
diff --git a/java/management/core/lib/jakarta-commons/commons-httpclient.jar b/java/management/core/lib/jakarta-commons/commons-httpclient.jar
new file mode 100644
index 0000000000..c17584060d
--- /dev/null
+++ b/java/management/core/lib/jakarta-commons/commons-httpclient.jar
Binary files differ
diff --git a/java/management/core/lib/jakarta-commons/commons-lang.jar b/java/management/core/lib/jakarta-commons/commons-lang.jar
new file mode 100644
index 0000000000..87b80ab5db
--- /dev/null
+++ b/java/management/core/lib/jakarta-commons/commons-lang.jar
Binary files differ
diff --git a/java/management/core/lib/jakarta-commons/commons-logging.jar b/java/management/core/lib/jakarta-commons/commons-logging.jar
new file mode 100644
index 0000000000..b73a80fab6
--- /dev/null
+++ b/java/management/core/lib/jakarta-commons/commons-logging.jar
Binary files differ
diff --git a/java/management/core/lib/jakarta-commons/commons-pool.jar b/java/management/core/lib/jakarta-commons/commons-pool.jar
new file mode 100644
index 0000000000..4ba534c90e
--- /dev/null
+++ b/java/management/core/lib/jakarta-commons/commons-pool.jar
Binary files differ
diff --git a/java/management/core/lib/jakarta-commons/commons-validator.jar b/java/management/core/lib/jakarta-commons/commons-validator.jar
new file mode 100644
index 0000000000..bf76e86c29
--- /dev/null
+++ b/java/management/core/lib/jakarta-commons/commons-validator.jar
Binary files differ
diff --git a/java/management/core/lib/log4j/log4j-1.2.9.jar b/java/management/core/lib/log4j/log4j-1.2.9.jar
new file mode 100644
index 0000000000..a6568b01a2
--- /dev/null
+++ b/java/management/core/lib/log4j/log4j-1.2.9.jar
Binary files differ
diff --git a/java/management/core/lib/spring/spring-beans.dtd b/java/management/core/lib/spring/spring-beans.dtd
new file mode 100644
index 0000000000..050f845788
--- /dev/null
+++ b/java/management/core/lib/spring/spring-beans.dtd
@@ -0,0 +1,587 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ Spring XML Beans DTD
+ Authors: Rod Johnson, Juergen Hoeller, Alef Arendsen, Colin Sampaleanu
+
+ This defines a simple and consistent way of creating a namespace
+ of JavaBeans objects, managed by a Spring BeanFactory, read by
+ XmlBeanDefinitionReader (with DefaultXmlBeanDefinitionParser).
+
+ This document type is used by most Spring functionality, including
+ web application contexts, which are based on bean factories.
+
+ Each "bean" element in this document defines a JavaBean.
+ Typically the bean class is specified, along with JavaBean properties
+ and/or constructor arguments.
+
+ Bean instances can be "singletons" (shared instances) or "prototypes"
+ (independent instances). Further scopes are supposed to be built on top
+ of the core BeanFactory infrastructure and are therefore not part of it.
+
+ References among beans are supported, i.e. setting a JavaBean property
+ or a constructor argument to refer to another bean in the same factory
+ (or an ancestor factory).
+
+ As alternative to bean references, "inner bean definitions" can be used.
+ Singleton flags of such inner bean definitions are effectively ignored:
+ Inner beans are typically anonymous prototypes.
+
+ There is also support for lists, sets, maps, and java.util.Properties
+ as bean property types or constructor argument types.
+
+ As the format is simple, a DTD is sufficient, and there's no need
+ for a schema at this point.
+
+ XML documents that conform to this DTD should declare the following doctype:
+
+ <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
+ "http://www.springframework.org/dtd/spring-beans.dtd">
+-->
+
+
+<!--
+ The document root. A document can contain bean definitions only,
+ imports only, or a mixture of both (typically with imports first).
+-->
+<!ELEMENT beans (
+ description?,
+ (import | alias | bean)*
+)>
+
+<!--
+ Default values for all bean definitions. Can be overridden at
+ the "bean" level. See those attribute definitions for details.
+-->
+<!ATTLIST beans default-lazy-init (true | false) "false">
+<!ATTLIST beans default-autowire (no | byName | byType | constructor | autodetect) "no">
+<!ATTLIST beans default-dependency-check (none | objects | simple | all) "none">
+
+<!--
+ Element containing informative text describing the purpose of the enclosing
+ element. Always optional.
+ Used primarily for user documentation of XML bean definition documents.
+-->
+<!ELEMENT description (#PCDATA)>
+
+
+<!--
+ Specifies an XML bean definition resource to import.
+-->
+<!ELEMENT import EMPTY>
+
+<!--
+ The relative resource location of the XML bean definition file to import,
+ for example "myImport.xml" or "includes/myImport.xml" or "../myImport.xml".
+-->
+<!ATTLIST import resource CDATA #REQUIRED>
+
+
+<!--
+ Defines an alias for a bean, which can reside in a different definition file.
+-->
+<!ELEMENT alias EMPTY>
+
+<!--
+ The name of the bean to define an alias for.
+-->
+<!ATTLIST alias name CDATA #REQUIRED>
+
+<!--
+ The alias name to define for the bean.
+-->
+<!ATTLIST alias alias CDATA #REQUIRED>
+
+
+<!--
+ Defines a single (usually named) bean.
+
+ A bean definition may contain nested tags for constructor arguments,
+ property values, lookup methods, and replaced methods. Mixing constructor
+ injection and setter injection on the same bean is explicitly supported.
+-->
+<!ELEMENT bean (
+ description?,
+ (constructor-arg | property | lookup-method | replaced-method)*
+)>
+
+<!--
+ Beans can be identified by an id, to enable reference checking.
+
+ There are constraints on a valid XML id: if you want to reference your bean
+ in Java code using a name that's illegal as an XML id, use the optional
+ "name" attribute. If neither is given, the bean class name is used as id
+ (with an appended counter like "#2" if there is already a bean with that name).
+-->
+<!ATTLIST bean id ID #IMPLIED>
+
+<!--
+ Optional. Can be used to create one or more aliases illegal in an id.
+ Multiple aliases can be separated by any number of spaces or commas.
+-->
+<!ATTLIST bean name CDATA #IMPLIED>
+
+<!--
+ Each bean definition must specify the fully qualified name of the class,
+ except if it pure serves as parent for child bean definitions.
+-->
+<!ATTLIST bean class CDATA #IMPLIED>
+
+<!--
+ Optionally specify a parent bean definition.
+
+ Will use the bean class of the parent if none specified, but can
+ also override it. In the latter case, the child bean class must be
+ compatible with the parent, i.e. accept the parent's property values
+ and constructor argument values, if any.
+
+ A child bean definition will inherit constructor argument values,
+ property values and method overrides from the parent, with the option
+ to add new values. If init method, destroy method, factory bean and/or factory
+ method are specified, they will override the corresponding parent settings.
+
+ The remaining settings will always be taken from the child definition:
+ depends on, autowire mode, dependency check, singleton, lazy init.
+-->
+<!ATTLIST bean parent CDATA #IMPLIED>
+
+<!--
+ Is this bean "abstract", i.e. not meant to be instantiated itself but
+ rather just serving as parent for concrete child bean definitions.
+ Default is "false". Specify "true" to tell the bean factory to not try to
+ instantiate that particular bean in any case.
+-->
+<!ATTLIST bean abstract (true | false) "false">
+
+<!--
+ Is this bean a "singleton" (one shared instance, which will
+ be returned by all calls to getBean() with the id),
+ or a "prototype" (independent instance resulting from each call to
+ getBean(). Default is singleton.
+
+ Singletons are most commonly used, and are ideal for multi-threaded
+ service objects.
+-->
+<!ATTLIST bean singleton (true | false) "true">
+
+<!--
+ If this bean should be lazily initialized.
+ If false, it will get instantiated on startup by bean factories
+ that perform eager initialization of singletons.
+-->
+<!ATTLIST bean lazy-init (true | false | default) "default">
+
+<!--
+ Optional attribute controlling whether to "autowire" bean properties.
+ This is an automagical process in which bean references don't need to be coded
+ explicitly in the XML bean definition file, but Spring works out dependencies.
+
+ There are 5 modes:
+
+ 1. "no"
+ The traditional Spring default. No automagical wiring. Bean references
+ must be defined in the XML file via the <ref> element. We recommend this
+ in most cases as it makes documentation more explicit.
+
+ 2. "byName"
+ Autowiring by property name. If a bean of class Cat exposes a dog property,
+ Spring will try to set this to the value of the bean "dog" in the current factory.
+ If there is no matching bean by name, nothing special happens;
+ use dependency-check="objects" to raise an error in that case.
+
+ 3. "byType"
+ Autowiring if there is exactly one bean of the property type in the bean factory.
+ If there is more than one, a fatal error is raised, and you can't use byType
+ autowiring for that bean. If there is none, nothing special happens;
+ use dependency-check="objects" to raise an error in that case.
+
+ 4. "constructor"
+ Analogous to "byType" for constructor arguments. If there isn't exactly one bean
+ of the constructor argument type in the bean factory, a fatal error is raised.
+
+ 5. "autodetect"
+ Chooses "constructor" or "byType" through introspection of the bean class.
+ If a default constructor is found, "byType" gets applied.
+
+ The latter two are similar to PicoContainer and make bean factories simple to
+ configure for small namespaces, but doesn't work as well as standard Spring
+ behaviour for bigger applications.
+
+ Note that explicit dependencies, i.e. "property" and "constructor-arg" elements,
+ always override autowiring. Autowire behaviour can be combined with dependency
+ checking, which will be performed after all autowiring has been completed.
+-->
+<!ATTLIST bean autowire (no | byName | byType | constructor | autodetect | default) "default">
+
+<!--
+ Optional attribute controlling whether to check whether all this
+ beans dependencies, expressed in its properties, are satisfied.
+ Default is no dependency checking.
+
+ "simple" type dependency checking includes primitives and String
+ "object" includes collaborators (other beans in the factory)
+ "all" includes both types of dependency checking
+-->
+<!ATTLIST bean dependency-check (none | objects | simple | all | default) "default">
+
+<!--
+ The names of the beans that this bean depends on being initialized.
+ The bean factory will guarantee that these beans get initialized before.
+
+ Note that dependencies are normally expressed through bean properties or
+ constructor arguments. This property should just be necessary for other kinds
+ of dependencies like statics (*ugh*) or database preparation on startup.
+-->
+<!ATTLIST bean depends-on CDATA #IMPLIED>
+
+<!--
+ Optional attribute for the name of the custom initialization method
+ to invoke after setting bean properties. The method must have no arguments,
+ but may throw any exception.
+-->
+<!ATTLIST bean init-method CDATA #IMPLIED>
+
+<!--
+ Optional attribute for the name of the custom destroy method to invoke
+ on bean factory shutdown. The method must have no arguments,
+ but may throw any exception. Note: Only invoked on singleton beans!
+-->
+<!ATTLIST bean destroy-method CDATA #IMPLIED>
+
+<!--
+ Optional attribute specifying the name of a factory method to use to
+ create this object. Use constructor-arg elements to specify arguments
+ to the factory method, if it takes arguments. Autowiring does not apply
+ to factory methods.
+
+ If the "class" attribute is present, the factory method will be a static
+ method on the class specified by the "class" attribute on this bean
+ definition. Often this will be the same class as that of the constructed
+ object - for example, when the factory method is used as an alternative
+ to a constructor. However, it may be on a different class. In that case,
+ the created object will *not* be of the class specified in the "class"
+ attribute. This is analogous to FactoryBean behavior.
+
+ If the "factory-bean" attribute is present, the "class" attribute is not
+ used, and the factory method will be an instance method on the object
+ returned from a getBean call with the specified bean name. The factory
+ bean may be defined as a singleton or a prototype.
+
+ The factory method can have any number of arguments. Autowiring is not
+ supported. Use indexed constructor-arg elements in conjunction with the
+ factory-method attribute.
+
+ Setter Injection can be used in conjunction with a factory method.
+ Method Injection cannot, as the factory method returns an instance,
+ which will be used when the container creates the bean.
+-->
+<!ATTLIST bean factory-method CDATA #IMPLIED>
+
+<!--
+ Alternative to class attribute for factory-method usage.
+ If this is specified, no class attribute should be used.
+ This should be set to the name of a bean in the current or
+ ancestor factories that contains the relevant factory method.
+ This allows the factory itself to be configured using Dependency
+ Injection, and an instance (rather than static) method to be used.
+-->
+<!ATTLIST bean factory-bean CDATA #IMPLIED>
+
+
+<!--
+ Bean definitions can specify zero or more constructor arguments.
+ This is an alternative to "autowire constructor".
+ Arguments correspond to either a specific index of the constructor argument
+ list or are supposed to be matched generically by type.
+
+ Note: A single generic argument value will just be used once, rather than
+ potentially matched multiple times (as of Spring 1.1).
+
+ constructor-arg elements are also used in conjunction with the factory-method
+ element to construct beans using static or instance factory methods.
+-->
+<!ELEMENT constructor-arg (
+ description?,
+ (bean | ref | idref | value | null | list | set | map | props)?
+)>
+
+<!--
+ The constructor-arg tag can have an optional index attribute,
+ to specify the exact index in the constructor argument list. Only needed
+ to avoid ambiguities, e.g. in case of 2 arguments of the same type.
+-->
+<!ATTLIST constructor-arg index CDATA #IMPLIED>
+
+<!--
+ The constructor-arg tag can have an optional type attribute,
+ to specify the exact type of the constructor argument. Only needed
+ to avoid ambiguities, e.g. in case of 2 single argument constructors
+ that can both be converted from a String.
+-->
+<!ATTLIST constructor-arg type CDATA #IMPLIED>
+
+<!--
+ A short-cut alternative to a child element "ref bean=".
+-->
+<!ATTLIST constructor-arg ref CDATA #IMPLIED>
+
+<!--
+ A short-cut alternative to a child element "value".
+-->
+<!ATTLIST constructor-arg value CDATA #IMPLIED>
+
+
+<!--
+ Bean definitions can have zero or more properties.
+ Property elements correspond to JavaBean setter methods exposed
+ by the bean classes. Spring supports primitives, references to other
+ beans in the same or related factories, lists, maps and properties.
+-->
+<!ELEMENT property (
+ description?,
+ (bean | ref | idref | value | null | list | set | map | props)?
+)>
+
+<!--
+ The property name attribute is the name of the JavaBean property.
+ This follows JavaBean conventions: a name of "age" would correspond
+ to setAge()/optional getAge() methods.
+-->
+<!ATTLIST property name CDATA #REQUIRED>
+
+<!--
+ A short-cut alternative to a child element "ref bean=".
+-->
+<!ATTLIST property ref CDATA #IMPLIED>
+
+<!--
+ A short-cut alternative to a child element "value".
+-->
+<!ATTLIST property value CDATA #IMPLIED>
+
+
+<!--
+ A lookup method causes the IoC container to override the given method and return
+ the bean with the name given in the bean attribute. This is a form of Method Injection.
+ It's particularly useful as an alternative to implementing the BeanFactoryAware
+ interface, in order to be able to make getBean() calls for non-singleton instances
+ at runtime. In this case, Method Injection is a less invasive alternative.
+-->
+<!ELEMENT lookup-method EMPTY>
+
+<!--
+ Name of a lookup method. This method should take no arguments.
+-->
+<!ATTLIST lookup-method name CDATA #IMPLIED>
+
+<!--
+ Name of the bean in the current or ancestor factories that the lookup method
+ should resolve to. Often this bean will be a prototype, in which case the
+ lookup method will return a distinct instance on every invocation. This
+ is useful for single-threaded objects.
+-->
+<!ATTLIST lookup-method bean CDATA #IMPLIED>
+
+
+<!--
+ Similar to the lookup method mechanism, the replaced-method element is used to control
+ IoC container method overriding: Method Injection. This mechanism allows the overriding
+ of a method with arbitrary code.
+-->
+<!ELEMENT replaced-method (
+ (arg-type)*
+)>
+
+<!--
+ Name of the method whose implementation should be replaced by the IoC container.
+ If this method is not overloaded, there's no need to use arg-type subelements.
+ If this method is overloaded, arg-type subelements must be used for all
+ override definitions for the method.
+-->
+<!ATTLIST replaced-method name CDATA #IMPLIED>
+
+<!--
+ Bean name of an implementation of the MethodReplacer interface
+ in the current or ancestor factories. This may be a singleton or prototype
+ bean. If it's a prototype, a new instance will be used for each method replacement.
+ Singleton usage is the norm.
+-->
+<!ATTLIST replaced-method replacer CDATA #IMPLIED>
+
+<!--
+ Subelement of replaced-method identifying an argument for a replaced method
+ in the event of method overloading.
+-->
+<!ELEMENT arg-type (#PCDATA)>
+
+<!--
+ Specification of the type of an overloaded method argument as a String.
+ For convenience, this may be a substring of the FQN. E.g. all the
+ following would match "java.lang.String":
+ - java.lang.String
+ - String
+ - Str
+
+ As the number of arguments will be checked also, this convenience can often
+ be used to save typing.
+-->
+<!ATTLIST arg-type match CDATA #IMPLIED>
+
+
+<!--
+ Defines a reference to another bean in this factory or an external
+ factory (parent or included factory).
+-->
+<!ELEMENT ref EMPTY>
+
+<!--
+ References must specify a name of the target bean.
+ The "bean" attribute can reference any name from any bean in the context,
+ to be checked at runtime.
+ Local references, using the "local" attribute, have to use bean ids;
+ they can be checked by this DTD, thus should be preferred for references
+ within the same bean factory XML file.
+-->
+<!ATTLIST ref bean CDATA #IMPLIED>
+<!ATTLIST ref local IDREF #IMPLIED>
+<!ATTLIST ref parent CDATA #IMPLIED>
+
+
+<!--
+ Defines a string property value, which must also be the id of another
+ bean in this factory or an external factory (parent or included factory).
+ While a regular 'value' element could instead be used for the same effect,
+ using idref in this case allows validation of local bean ids by the xml
+ parser, and name completion by helper tools.
+-->
+<!ELEMENT idref EMPTY>
+
+<!--
+ ID refs must specify a name of the target bean.
+ The "bean" attribute can reference any name from any bean in the context,
+ potentially to be checked at runtime by bean factory implementations.
+ Local references, using the "local" attribute, have to use bean ids;
+ they can be checked by this DTD, thus should be preferred for references
+ within the same bean factory XML file.
+-->
+<!ATTLIST idref bean CDATA #IMPLIED>
+<!ATTLIST idref local IDREF #IMPLIED>
+
+
+<!--
+ Contains a string representation of a property value.
+ The property may be a string, or may be converted to the
+ required type using the JavaBeans PropertyEditor
+ machinery. This makes it possible for application developers
+ to write custom PropertyEditor implementations that can
+ convert strings to objects.
+
+ Note that this is recommended for simple objects only.
+ Configure more complex objects by populating JavaBean
+ properties with references to other beans.
+-->
+<!ELEMENT value (#PCDATA)>
+
+<!--
+ The value tag can have an optional type attribute, to specify the
+ exact type that the value should be converted to. Only needed
+ if the type of the target property or constructor argument is
+ too generic: for example, in case of a collection element.
+-->
+<!ATTLIST value type CDATA #IMPLIED>
+
+<!--
+ Denotes a Java null value. Necessary because an empty "value" tag
+ will resolve to an empty String, which will not be resolved to a
+ null value unless a special PropertyEditor does so.
+-->
+<!ELEMENT null (#PCDATA)>
+
+
+<!--
+ A list can contain multiple inner bean, ref, collection, or value elements.
+ Java lists are untyped, pending generics support in Java 1.5,
+ although references will be strongly typed.
+ A list can also map to an array type. The necessary conversion
+ is automatically performed by the BeanFactory.
+-->
+<!ELEMENT list (
+ (bean | ref | idref | value | null | list | set | map | props)*
+)>
+
+<!--
+ A set can contain multiple inner bean, ref, collection, or value elements.
+ Java sets are untyped, pending generics support in Java 1.5,
+ although references will be strongly typed.
+-->
+<!ELEMENT set (
+ (bean | ref | idref | value | null | list | set | map | props)*
+)>
+
+
+<!--
+ A Spring map is a mapping from a string key to object.
+ Maps may be empty.
+-->
+<!ELEMENT map (
+ (entry)*
+)>
+
+<!--
+ A map entry can be an inner bean, ref, value, or collection.
+ The key of the entry is given by the "key" attribute or child element.
+-->
+<!ELEMENT entry (
+ key?,
+ (bean | ref | idref | value | null | list | set | map | props)?
+)>
+
+<!--
+ Each map element must specify its key as attribute or as child element.
+ A key attribute is always a String value.
+-->
+<!ATTLIST entry key CDATA #IMPLIED>
+
+<!--
+ A short-cut alternative to a "key" element with a "ref bean=" child element.
+-->
+<!ATTLIST entry key-ref CDATA #IMPLIED>
+
+<!--
+ A short-cut alternative to a child element "value".
+-->
+<!ATTLIST entry value CDATA #IMPLIED>
+
+<!--
+ A short-cut alternative to a child element "ref bean=".
+-->
+<!ATTLIST entry value-ref CDATA #IMPLIED>
+
+<!--
+ A key element can contain an inner bean, ref, value, or collection.
+-->
+<!ELEMENT key (
+ (bean | ref | idref | value | null | list | set | map | props)
+)>
+
+
+<!--
+ Props elements differ from map elements in that values must be strings.
+ Props may be empty.
+-->
+<!ELEMENT props (
+ (prop)*
+)>
+
+<!--
+ Element content is the string value of the property.
+ Note that whitespace is trimmed off to avoid unwanted whitespace
+ caused by typical XML formatting.
+-->
+<!ELEMENT prop (#PCDATA)>
+
+<!--
+ Each property element must specify its key.
+-->
+<!ATTLIST prop key CDATA #REQUIRED>
+
diff --git a/java/management/core/lib/spring/spring.ftl b/java/management/core/lib/spring/spring.ftl
new file mode 100644
index 0000000000..45d8ad0b39
--- /dev/null
+++ b/java/management/core/lib/spring/spring.ftl
@@ -0,0 +1,316 @@
+<#--
+ * spring.ftl
+ *
+ * This file consists of a collection of FreeMarker macros aimed at easing
+ * some of the common requirements of web applications - in particular
+ * handling of forms.
+ *
+ * Spring's FreeMarker support will automatically make this file and therefore
+ * all macros within it available to any application using Spring's
+ * FreeMarkerConfigurer.
+ *
+ * To take advantage of these macros, the "exposeSpringMacroHelpers" property
+ * of the FreeMarker class needs to be set to "true". This will expose a
+ * RequestContext under the name "springMacroRequestContext", as needed by
+ * the macros in this library.
+ *
+ * @author Darren Davison
+ * @author Juergen Hoeller
+ * @since 1.1
+ -->
+
+<#--
+ * message
+ *
+ * Macro to translate a message code into a message.
+ -->
+<#macro message code>${springMacroRequestContext.getMessage(code)}</#macro>
+
+<#--
+ * messageText
+ *
+ * Macro to translate a message code into a message,
+ * using the given default text if no message found.
+ -->
+<#macro messageText code, text>${springMacroRequestContext.getMessage(code, text)}</#macro>
+
+<#--
+ * url
+ *
+ * Takes a relative URL and makes it absolute from the server root by
+ * adding the context root for the web application.
+ -->
+<#macro url relativeUrl>${springMacroRequestContext.getContextPath()}${relativeUrl}</#macro>
+
+<#--
+ * bind
+ *
+ * Exposes a BindStatus object for the given bind path, which can be
+ * a bean (e.g. "person") to get global errors, or a bean property
+ * (e.g. "person.name") to get field errors. Can be called multiple times
+ * within a form to bind to multiple command objects and/or field names.
+ *
+ * This macro will participate in the default HTML escape setting for the given
+ * RequestContext. This can be customized by calling "setDefaultHtmlEscape"
+ * on the "springMacroRequestContext" context variable, or via the
+ * "defaultHtmlEscape" context-param in web.xml (same as for the JSP bind tag).
+ * Also regards a "htmlEscape" variable in the namespace of this library.
+ *
+ * Producing no output, the following context variable will be available
+ * each time this macro is referenced (assuming you import this library in
+ * your templates with the namespace 'spring'):
+ *
+ * spring.status : a BindStatus instance holding the command object name,
+ * expression, value, and error messages and codes for the path supplied
+ *
+ * @param path : the path (string value) of the value required to bind to.
+ * Spring defaults to a command name of "command" but this can be overridden
+ * by user config.
+ -->
+<#macro bind path>
+ <#if htmlEscape?exists>
+ <#assign status = springMacroRequestContext.getBindStatus(path, htmlEscape)>
+ <#else>
+ <#assign status = springMacroRequestContext.getBindStatus(path)>
+ </#if>
+ <#-- assign a temporary value, forcing a string representation for any
+ kind of variable. This temp value is only used in this macro lib -->
+ <#if status.value?exists && status.value?is_boolean>
+ <#assign stringStatusValue=status.value?string>
+ <#else>
+ <#assign stringStatusValue=status.value?default("")>
+ </#if>
+</#macro>
+
+<#--
+ * bindEscaped
+ *
+ * Similar to spring:bind, but takes an explicit HTML escape flag rather
+ * than relying on the default HTML escape setting.
+ -->
+<#macro bindEscaped path, htmlEscape>
+ <#assign status = springMacroRequestContext.getBindStatus(path, htmlEscape)>
+ <#-- assign a temporary value, forcing a string representation for any
+ kind of variable. This temp value is only used in this macro lib -->
+ <#if status.value?exists && status.value?is_boolean>
+ <#assign stringStatusValue=status.value?string>
+ <#else>
+ <#assign stringStatusValue=status.value?default("")>
+ </#if>
+</#macro>
+
+<#--
+ * formInput
+ *
+ * Display a form input field of type 'text' and bind it to an attribute
+ * of a command or bean.
+ *
+ * @param path the name of the field to bind to
+ * @param attributes any additional attributes for the element (such as class
+ * or CSS styles or size
+ -->
+<#macro formInput path attributes="" fieldType="text" >
+ <@bind path/>
+ <input type="${fieldType}" name="${status.expression}" value="<#if fieldType!="password">${stringStatusValue}</#if>" ${attributes}
+ <@closeTag/>
+</#macro>
+
+<#--
+ * formPasswordInput
+ *
+ * Display a form input field of type 'password' and bind it to an attribute
+ * of a command or bean. No value will ever be displayed. This functionality
+ * can also be obtained by calling the formInput macro with a 'type' parameter
+ * of 'password'
+ *
+ * @param path the name of the field to bind to
+ * @param attributes any additional attributes for the element (such as class
+ * or CSS styles or size
+ -->
+<#macro formPasswordInput path attributes="" >
+ <@formInput path, attributes, "password"/>
+</#macro>
+
+<#--
+ * formHiddenInput
+ *
+ * Generate a form input field of type 'hidden' and bind it to an attribute
+ * of a command or bean. This functionality can also be obtained by calling
+ * the formInput macro with a 'type' parameter of 'hidden'
+ *
+ * @param path the name of the field to bind to
+ * @param attributes any additional attributes for the element (such as class
+ * or CSS styles or size
+ -->
+<#macro formHiddenInput path attributes="" >
+ <@formInput path, attributes, "hidden"/>
+</#macro>
+
+<#--
+ * formTextarea
+ *
+ * Display a text area and bind it to an attribute of a command or bean.
+ *
+ * @param path the name of the field to bind to
+ * @param attributes any additional attributes for the element (such as class
+ * or CSS styles or size
+ -->
+<#macro formTextarea path attributes="" >
+ <@bind path/>
+ <textarea name="${status.expression}" ${attributes}>${stringStatusValue}</textarea>
+</#macro>
+
+<#--
+ * formSingleSelect
+ *
+ * Show a selectbox (dropdown) input element allowing a single value to be chosen
+ * from a list of options.
+ *
+ * @param path the name of the field to bind to
+ * @param options a map (value=label) of all the available options
+ * @param attributes any additional attributes for the element (such as class
+ * or CSS styles or size
+-->
+<#macro formSingleSelect path options attributes="">
+ <@bind path/>
+ <select name="${status.expression}" ${attributes}>
+ <#list options?keys as value>
+ <option value="${value}"<@checkSelected value/>>${options[value]}</option>
+ </#list>
+ </select>
+</#macro>
+
+<#--
+ * formMultiSelect
+ *
+ * Show a listbox of options allowing the user to make 0 or more choices from
+ * the list of options.
+ *
+ * @param path the name of the field to bind to
+ * @param options a map (value=label) of all the available options
+ * @param attributes any additional attributes for the element (such as class
+ * or CSS styles or size
+-->
+<#macro formMultiSelect path options attributes="">
+ <@bind path/>
+ <select multiple="multiple" name="${status.expression}" ${attributes}>
+ <#list options?keys as value>
+ <#assign isSelected = contains(status.value?default([""]), value)>
+ <option value="${value}" <#if isSelected>selected="selected"</#if>>${options[value]}</option>
+ </#list>
+ </select>
+</#macro>
+
+<#--
+ * formRadioButtons
+ *
+ * Show radio buttons.
+ *
+ * @param path the name of the field to bind to
+ * @param options a map (value=label) of all the available options
+ * @param separator the html tag or other character list that should be used to
+ * separate each option. Typically '&nbsp;' or '<br>'
+ * @param attributes any additional attributes for the element (such as class
+ * or CSS styles or size
+-->
+<#macro formRadioButtons path options separator attributes="">
+ <@bind path/>
+ <#list options?keys as value>
+ <input type="radio" name="${status.expression}" value="${value}"
+ <#if stringStatusValue == value>checked="checked"</#if> ${attributes}
+ <@closeTag/>
+ ${options[value]}${separator}
+ </#list>
+</#macro>
+
+<#--
+ * formCheckboxes
+ *
+ * Show checkboxes.
+ *
+ * @param path the name of the field to bind to
+ * @param options a map (value=label) of all the available options
+ * @param separator the html tag or other character list that should be used to
+ * separate each option. Typically '&nbsp;' or '<br>'
+ * @param attributes any additional attributes for the element (such as class
+ * or CSS styles or size
+-->
+<#macro formCheckboxes path options separator attributes="">
+ <@bind path/>
+ <#list options?keys as value>
+ <#assign isSelected = contains(status.value?default([""]), value)>
+ <input type="checkbox" name="${status.expression}" value="${value}"
+ <#if isSelected>checked="checked"</#if> ${attributes}
+ <@closeTag/>
+ ${options[value]}${separator}
+ </#list>
+</#macro>
+
+<#--
+ * showErrors
+ *
+ * Show validation errors for the currently bound field, with
+ * optional style attributes.
+ *
+ * @param separator the html tag or other character list that should be used to
+ * separate each option. Typically '<br>'.
+ * @param classOrStyle either the name of a CSS class element (which is defined in
+ * the template or an external CSS file) or an inline style. If the value passed in here
+ * contains a colon (:) then a 'style=' attribute will be used, else a 'class=' attribute
+ * will be used.
+-->
+<#macro showErrors separator classOrStyle="">
+ <#list status.errorMessages as error>
+ <#if classOrStyle == "">
+ <b>${error}</b>
+ <#else>
+ <#if classOrStyle?index_of(":") == -1><#assign attr="class"><#else><#assign attr="style"></#if>
+ <span ${attr}="${classOrStyle}">${error}</span>
+ </#if>
+ <#if error_has_next>${separator}</#if>
+ </#list>
+</#macro>
+
+<#--
+ * checkSelected
+ *
+ * Check a value in a list to see if it is the currently selected value.
+ * If so, add the 'selected="selected"' text to the output.
+ * Handles values of numeric and string types.
+ * This function is used internally but can be accessed by user code if required.
+ *
+ * @param value the current value in a list iteration
+-->
+<#macro checkSelected value>
+ <#if stringStatusValue?is_number && stringStatusValue == value?number>selected="selected"</#if>
+ <#if stringStatusValue?is_string && stringStatusValue == value>selected="selected"</#if>
+</#macro>
+
+<#--
+ * contains
+ *
+ * Macro to return true if the list contains the scalar, false if not.
+ * Surprisingly not a FreeMarker builtin.
+ * This function is used internally but can be accessed by user code if required.
+ *
+ * @param list the list to search for the item
+ * @param item the item to search for in the list
+ * @return true if item is found in the list, false otherwise
+-->
+<#function contains list item>
+ <#list list as nextInList>
+ <#if nextInList == item><#return true></#if>
+ </#list>
+ <#return false>
+</#function>
+
+<#--
+ * closeTag
+ *
+ * Simple macro to close an HTML tag that has no body with '>' or '/>',
+ * depending on the value of a 'xhtmlCompliant' variable in the namespace
+ * of this library.
+-->
+<#macro closeTag>
+ <#if xhtmlCompliant?exists && xhtmlCompliant>/><#else>></#if>
+</#macro>
diff --git a/java/management/core/lib/spring/spring.tld b/java/management/core/lib/spring/spring.tld
new file mode 100644
index 0000000000..1bc7091f03
--- /dev/null
+++ b/java/management/core/lib/spring/spring.tld
@@ -0,0 +1,311 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
+
+<taglib>
+
+ <tlib-version>1.1.1</tlib-version>
+
+ <jsp-version>1.2</jsp-version>
+
+ <short-name>Spring</short-name>
+
+ <uri>http://www.springframework.org/tags</uri>
+
+ <description>Spring Framework JSP Tag Library. Authors: Rod Johnson, Juergen Hoeller</description>
+
+
+ <tag>
+
+ <name>htmlEscape</name>
+ <tag-class>org.springframework.web.servlet.tags.HtmlEscapeTag</tag-class>
+ <body-content>JSP</body-content>
+
+ <description>
+ Sets default HTML escape value for the current page.
+ Overrides a "defaultHtmlEscape" context-param in web.xml, if any.
+ </description>
+
+ <attribute>
+ <name>defaultHtmlEscape</name>
+ <required>true</required>
+ <rtexprvalue>true</rtexprvalue>
+ </attribute>
+
+ </tag>
+
+
+ <tag>
+
+ <name>escapeBody</name>
+ <tag-class>org.springframework.web.servlet.tags.EscapeBodyTag</tag-class>
+ <body-content>JSP</body-content>
+
+ <description>
+ Escapes its enclosed body content, applying HTML escaping and/or JavaScript escaping.
+ The HTML escaping flag participates in a page-wide or application-wide setting
+ (i.e. by HtmlEscapeTag or a "defaultHtmlEscape" context-param in web.xml).
+ </description>
+
+ <attribute>
+ <name>htmlEscape</name>
+ <required>false</required>
+ <rtexprvalue>true</rtexprvalue>
+ </attribute>
+
+ <attribute>
+ <name>javaScriptEscape</name>
+ <required>false</required>
+ <rtexprvalue>true</rtexprvalue>
+ </attribute>
+
+ </tag>
+
+
+ <tag>
+
+ <name>message</name>
+ <tag-class>org.springframework.web.servlet.tags.MessageTag</tag-class>
+ <body-content>JSP</body-content>
+
+ <description>
+ Retrieves the message with the given code, or text if code isn't resolvable.
+ The HTML escaping flag participates in a page-wide or application-wide setting
+ (i.e. by HtmlEscapeTag or a "defaultHtmlEscape" context-param in web.xml).
+ </description>
+
+ <attribute>
+ <name>code</name>
+ <required>false</required>
+ <rtexprvalue>true</rtexprvalue>
+ </attribute>
+
+ <attribute>
+ <name>arguments</name>
+ <required>false</required>
+ <rtexprvalue>true</rtexprvalue>
+ </attribute>
+
+ <attribute>
+ <name>text</name>
+ <required>false</required>
+ <rtexprvalue>true</rtexprvalue>
+ </attribute>
+
+ <attribute>
+ <name>var</name>
+ <required>false</required>
+ <rtexprvalue>true</rtexprvalue>
+ </attribute>
+
+ <attribute>
+ <name>scope</name>
+ <required>false</required>
+ <rtexprvalue>true</rtexprvalue>
+ </attribute>
+
+ <attribute>
+ <name>htmlEscape</name>
+ <required>false</required>
+ <rtexprvalue>true</rtexprvalue>
+ </attribute>
+
+ <attribute>
+ <name>javaScriptEscape</name>
+ <required>false</required>
+ <rtexprvalue>true</rtexprvalue>
+ </attribute>
+
+ </tag>
+
+
+ <tag>
+
+ <name>theme</name>
+ <tag-class>org.springframework.web.servlet.tags.ThemeTag</tag-class>
+ <body-content>JSP</body-content>
+
+ <description>
+ Retrieves the theme message with the given code, or text if code isn't resolvable.
+ The HTML escaping flag participates in a page-wide or application-wide setting
+ (i.e. by HtmlEscapeTag or a "defaultHtmlEscape" context-param in web.xml).
+ </description>
+
+ <attribute>
+ <name>code</name>
+ <required>false</required>
+ <rtexprvalue>true</rtexprvalue>
+ </attribute>
+
+ <attribute>
+ <name>arguments</name>
+ <required>false</required>
+ <rtexprvalue>true</rtexprvalue>
+ </attribute>
+
+ <attribute>
+ <name>text</name>
+ <required>false</required>
+ <rtexprvalue>true</rtexprvalue>
+ </attribute>
+
+ <attribute>
+ <name>var</name>
+ <required>false</required>
+ <rtexprvalue>true</rtexprvalue>
+ </attribute>
+
+ <attribute>
+ <name>scope</name>
+ <required>false</required>
+ <rtexprvalue>true</rtexprvalue>
+ </attribute>
+
+ <attribute>
+ <name>htmlEscape</name>
+ <required>false</required>
+ <rtexprvalue>true</rtexprvalue>
+ </attribute>
+
+ <attribute>
+ <name>javaScriptEscape</name>
+ <required>false</required>
+ <rtexprvalue>true</rtexprvalue>
+ </attribute>
+
+ </tag>
+
+
+ <tag>
+
+ <name>hasBindErrors</name>
+ <tag-class>org.springframework.web.servlet.tags.BindErrorsTag</tag-class>
+ <body-content>JSP</body-content>
+
+ <description>
+ Provides Errors instance in case of bind errors.
+ The HTML escaping flag participates in a page-wide or application-wide setting
+ (i.e. by HtmlEscapeTag or a "defaultHtmlEscape" context-param in web.xml).
+ </description>
+
+ <variable>
+ <name-given>errors</name-given>
+ <variable-class>org.springframework.validation.Errors</variable-class>
+ </variable>
+
+ <attribute>
+ <name>name</name>
+ <required>true</required>
+ <rtexprvalue>true</rtexprvalue>
+ </attribute>
+
+ <attribute>
+ <name>htmlEscape</name>
+ <required>false</required>
+ <rtexprvalue>true</rtexprvalue>
+ </attribute>
+
+ </tag>
+
+
+ <tag>
+
+ <name>nestedPath</name>
+ <tag-class>org.springframework.web.servlet.tags.NestedPathTag</tag-class>
+ <body-content>JSP</body-content>
+
+ <description>
+ Sets a nested path to be used by the bind tag's path.
+ </description>
+
+ <variable>
+ <name-given>nestedPath</name-given>
+ <variable-class>java.lang.String</variable-class>
+ </variable>
+
+ <attribute>
+ <name>path</name>
+ <required>true</required>
+ <rtexprvalue>true</rtexprvalue>
+ </attribute>
+
+ </tag>
+
+
+ <tag>
+
+ <name>bind</name>
+ <tag-class>org.springframework.web.servlet.tags.BindTag</tag-class>
+ <body-content>JSP</body-content>
+
+ <description>
+ Provides BindStatus object for the given bind path.
+ The HTML escaping flag participates in a page-wide or application-wide setting
+ (i.e. by HtmlEscapeTag or a "defaultHtmlEscape" context-param in web.xml).
+ </description>
+
+ <variable>
+ <name-given>status</name-given>
+ <variable-class>org.springframework.web.servlet.support.BindStatus</variable-class>
+ </variable>
+
+ <attribute>
+ <name>path</name>
+ <required>true</required>
+ <rtexprvalue>true</rtexprvalue>
+ </attribute>
+
+ <attribute>
+ <name>ignoreNestedPath</name>
+ <required>false</required>
+ <rtexprvalue>true</rtexprvalue>
+ </attribute>
+
+ <attribute>
+ <name>htmlEscape</name>
+ <required>false</required>
+ <rtexprvalue>true</rtexprvalue>
+ </attribute>
+
+ </tag>
+
+
+ <tag>
+
+ <name>transform</name>
+ <tag-class>org.springframework.web.servlet.tags.TransformTag</tag-class>
+ <body-content>JSP</body-content>
+
+ <description>
+ Provides transformation of variables to Strings, using an appropriate
+ custom PropertyEditor from BindTag (can only be used inside BindTag).
+ The HTML escaping flag participates in a page-wide or application-wide setting
+ (i.e. by HtmlEscapeTag or a "defaultHtmlEscape" context-param in web.xml).
+ </description>
+
+ <attribute>
+ <name>value</name>
+ <required>true</required>
+ <rtexprvalue>true</rtexprvalue>
+ </attribute>
+
+ <attribute>
+ <name>var</name>
+ <required>false</required>
+ <rtexprvalue>true</rtexprvalue>
+ </attribute>
+
+ <attribute>
+ <name>scope</name>
+ <required>false</required>
+ <rtexprvalue>true</rtexprvalue>
+ </attribute>
+
+ <attribute>
+ <name>htmlEscape</name>
+ <required>false</required>
+ <rtexprvalue>true</rtexprvalue>
+ </attribute>
+
+ </tag>
+
+</taglib>
diff --git a/java/management/core/lib/spring/spring.vm b/java/management/core/lib/spring/spring.vm
new file mode 100644
index 0000000000..50e104328c
--- /dev/null
+++ b/java/management/core/lib/spring/spring.vm
@@ -0,0 +1,294 @@
+#**
+ * spring.vm
+ *
+ * This file consists of a collection of Velocity macros aimed at easing
+ * some of the common requirements of web applications - in particular
+ * handling of forms.
+ *
+ * Spring's Velocity support will automatically make this file and therefore
+ * all macros within it available to any application using Spring's
+ * VelocityConfigurer.
+ *
+ * To take advantage of these macros, the "exposeSpringMacroHelpers" property
+ * of the VelocityView class needs to be set to "true". This will expose a
+ * RequestContext under the name "springMacroRequestContext", as needed by
+ * the macros in this library.
+ *
+ * @author Darren Davison
+ * @author Juergen Hoeller
+ * @since 1.1
+ *#
+
+#**
+ * springMessage
+ *
+ * Macro to translate a message code into a message.
+ *#
+#macro( springMessage $code )$springMacroRequestContext.getMessage($code)#end
+
+#**
+ * springMessageText
+ *
+ * Macro to translate a message code into a message,
+ * using the given default text if no message found.
+ *#
+#macro( springMessageText $code $text )$springMacroRequestContext.getMessage($code, $text)#end
+
+#**
+ * springUrl
+ *
+ * Takes a relative URL and makes it absolute from the server root by
+ * adding the context root for the web application.
+ *#
+#macro( springUrl $relativeUrl )$springMacroRequestContext.getContextPath()${relativeUrl}#end
+
+#**
+ * springBind
+ *
+ * Exposes a BindStatus object for the given bind path, which can be
+ * a bean (e.g. "person") to get global errors, or a bean property
+ * (e.g. "person.name") to get field errors. Can be called multiple times
+ * within a form to bind to multiple command objects and/or field names.
+ *
+ * This macro will participate in the default HTML escape setting for the given
+ * RequestContext. This can be customized by calling "setDefaultHtmlEscape"
+ * on the "springMacroRequestContext" context variable, or via the
+ * "defaultHtmlEscape" context-param in web.xml (same as for the JSP bind tag).
+ * Also regards a "springHtmlEscape" variable in the template context.
+ *
+ * Producing no output, the following context variable will be available
+ * each time this macro is referenced:
+ *
+ * $status : a BindStatus instance holding the command object name,
+ * expression, value, and error codes and messages for the path supplied
+ *
+ * @param $path : the path (string value) of the value required to bind to.
+ * Spring defaults to a command name of "command" but this can be overridden
+ * by user config.
+ *#
+#macro( springBind $path )
+ #if("$!springHtmlEscape" != "")
+ #set( $status = $springMacroRequestContext.getBindStatus($path, $springHtmlEscape) )
+ #else
+ #set( $status = $springMacroRequestContext.getBindStatus($path) )
+ #end
+#end
+
+#**
+ * springBindEscaped
+ *
+ * Similar to springBind, but takes an explicit HTML escape flag rather
+ * than relying on the default HTML escape setting.
+ *#
+#macro( springBindEscaped $path $htmlEscape )
+ #set( $status = $springMacroRequestContext.getBindStatus($path, $htmlEscape) )
+#end
+
+#**
+ * springFormInput
+ *
+ * Display a form input field of type 'text' and bind it to an attribute
+ * of a command or bean.
+ *
+ * @param path the name of the field to bind to
+ * @param attributes any additional attributes for the element (such as class
+ * or CSS styles or size
+ *
+ *#
+#macro( springFormInput $path $attributes )
+ #springBind($path)
+ <input type="text" name="${status.expression}" value="$!status.value" ${attributes}#springCloseTag()
+#end
+
+#**
+ * springFormPasswordInput
+ *
+ * Display a form input field of type 'password' and bind it to an attribute
+ * of a command or bean. No value will ever be specified for this field regardless
+ * of whether one exists or not. For hopefully obvious reasons!
+ *
+ * @param path the name of the field to bind to
+ * @param attributes any additional attributes for the element (such as class
+ * or CSS styles or size
+ *
+ *#
+#macro( springFormPasswordInput $path $attributes )
+ #springBind($path)
+ <input type="password" name="${status.expression}" value="" ${attributes}#springCloseTag()
+#end
+
+#**
+ * springFormHiddenInput
+ *
+ * Generate a form input field of type 'hidden' and bind it to an attribute
+ * of a command or bean.
+ *
+ * @param path the name of the field to bind to
+ * @param attributes any additional attributes for the element (such as class
+ * or CSS styles or size
+ *
+ *#
+#macro( springFormHiddenInput $path $attributes )
+ #springBind($path)
+ <input type="hidden" name="${status.expression}" value="$!status.value" ${attributes}#springCloseTag()
+#end
+
+#**
+ * formTextArea
+ *
+ * display a text area and bind it to an attribute
+ * of a command or bean
+ *
+ * @param path the name of the field to bind to
+ * @param attributes any additional attributes for the element (such as class
+ * or CSS styles or size
+ *
+ *#
+#macro( springFormTextarea $path $attributes )
+ #springBind($path)
+ <textarea name="${status.expression}" ${attributes}>$!status.value</textarea>
+#end
+
+#**
+ * springFormSingleSelect
+ *
+ * Show a selectbox (dropdown) input element allowing a single value to be chosen
+ * from a list of options.
+ *
+ * The null check for $status.value leverages Velocity's 'quiet' notation rather
+ * than the more common #if($status.value) since this method evaluates to the
+ * boolean 'false' if the content of $status.value is the String "false" - not
+ * what we want.
+ *
+ * @param path the name of the field to bind to
+ * @param options a map (value=label) of all the available options
+ * @param attributes any additional attributes for the element (such as class
+ * or CSS styles or size
+*#
+#macro( springFormSingleSelect $path $options $attributes )
+ #springBind($path)
+ <select name="${status.expression}" ${attributes}>
+ #foreach($option in $options.keySet())
+ <option value="${option}"
+ #if("$!status.value" == "$option")
+ selected="selected"
+ #end>
+ ${options.get($option)}</option>
+ #end
+ </select>
+#end
+
+#**
+ * springFormMultiSelect
+ *
+ * Show a listbox of options allowing the user to make 0 or more choices from
+ * the list of options.
+ *
+ * @param path the name of the field to bind to
+ * @param options a map (value=label) of all the available options
+ * @param attributes any additional attributes for the element (such as class
+ * or CSS styles or size
+*#
+#macro( springFormMultiSelect $path $options $attributes )
+ #springBind($path)
+ <select multiple="multiple" name="${status.expression}" ${attributes}>
+ #foreach($option in $options.keySet())
+ <option value="${option}"
+ #foreach($item in $status.value)
+ #if($item == $option)
+ selected="selected"
+ #end
+ #end
+ >${options.get($option)}</option>
+ #end
+ </select>
+#end
+
+#**
+ * springFormRadioButtons
+ *
+ * Show radio buttons.
+ *
+ * @param path the name of the field to bind to
+ * @param options a map (value=label) of all the available options
+ * @param separator the html tag or other character list that should be used to
+ * separate each option. Typically '&nbsp;' or '<br>'
+ * @param attributes any additional attributes for the element (such as class
+ * or CSS styles or size
+*#
+#macro( springFormRadioButtons $path $options $separator $attributes )
+ #springBind($path)
+ #foreach($option in $options.keySet())
+ <input type="radio" name="${status.expression}" value="${option}"
+ #if("$!status.value" == "$option")
+ checked="checked"
+ #end
+ ${attributes}
+ #springCloseTag()
+ ${options.get($option)} ${separator}
+ #end
+#end
+
+#**
+ * springFormCheckboxes
+ *
+ * Show checkboxes.
+ *
+ * @param path the name of the field to bind to
+ * @param options a map (value=label) of all the available options
+ * @param separator the html tag or other character list that should be used to
+ * separate each option. Typically '&nbsp;' or '<br>'
+ * @param attributes any additional attributes for the element (such as class
+ * or CSS styles or size
+*#
+#macro( springFormCheckboxes $path $options $separator $attributes )
+ #springBind($path)
+ #foreach($option in $options.keySet())
+ <input type="checkbox" name="${status.expression}" value="${option}"
+ #foreach($item in $status.value)
+ #if($item == $option)
+ checked="checked"
+ #end
+ #end
+ ${attributes} #springCloseTag()
+ ${options.get($option)} ${separator}
+ #end
+#end
+
+#**
+ * springShowErrors
+ *
+ * Show validation errors for the currently bound field, with
+ * optional style attributes.
+ *
+ * @param separator the html tag or other character list that should be used to
+ * separate each option. Typically '<br>'.
+ * @param classOrStyle either the name of a CSS class element (which is defined in
+ * the template or an external CSS file) or an inline style. If the value passed in here
+ * contains a colon (:) then a 'style=' attribute will be used, else a 'class=' attribute
+ * will be used.
+*#
+#macro( springShowErrors $separator $classOrStyle )
+ #foreach($error in $status.errorMessages)
+ #if($classOrStyle == "")
+ <b>${error}</b>
+ #else
+ #if($classOrStyle.indexOf(":") == -1)
+ #set($attr="class")
+ #else
+ #set($attr="style")
+ #end
+ <span ${attr}="${classOrStyle}">${error}</span>
+ #end
+ ${separator}
+ #end
+#end
+
+#**
+ * springCloseTag
+ *
+ * Simple macro to close an HTML tag that has no body with '>' or '/>',
+ * depending on the value of a 'springXhtmlCompliant' variable in the
+ * template context.
+ *#
+#macro( springCloseTag )#if($springXhtmlCompliant)/>#else>#end #end
diff --git a/java/management/core/lib/xmlbeans/jsr173_api.jar b/java/management/core/lib/xmlbeans/jsr173_api.jar
new file mode 100644
index 0000000000..d6fdfad49b
--- /dev/null
+++ b/java/management/core/lib/xmlbeans/jsr173_api.jar
Binary files differ
diff --git a/java/management/core/lib/xmlbeans/resolver.jar b/java/management/core/lib/xmlbeans/resolver.jar
new file mode 100644
index 0000000000..073d789675
--- /dev/null
+++ b/java/management/core/lib/xmlbeans/resolver.jar
Binary files differ
diff --git a/java/management/core/lib/xmlbeans/saxon8.jar b/java/management/core/lib/xmlbeans/saxon8.jar
new file mode 100644
index 0000000000..f3a2484882
--- /dev/null
+++ b/java/management/core/lib/xmlbeans/saxon8.jar
Binary files differ
diff --git a/java/management/core/lib/xmlbeans/xbean.jar b/java/management/core/lib/xmlbeans/xbean.jar
new file mode 100644
index 0000000000..08c72cd5b7
--- /dev/null
+++ b/java/management/core/lib/xmlbeans/xbean.jar
Binary files differ
diff --git a/java/management/core/lib/xmlbeans/xbean_xpath.jar b/java/management/core/lib/xmlbeans/xbean_xpath.jar
new file mode 100644
index 0000000000..c3366ebc8b
--- /dev/null
+++ b/java/management/core/lib/xmlbeans/xbean_xpath.jar
Binary files differ
diff --git a/java/management/core/lib/xmlbeans/xmlpublic.jar b/java/management/core/lib/xmlbeans/xmlpublic.jar
new file mode 100644
index 0000000000..8c79b44c47
--- /dev/null
+++ b/java/management/core/lib/xmlbeans/xmlpublic.jar
Binary files differ
diff --git a/java/management/core/src/log4j.properties b/java/management/core/src/log4j.properties
new file mode 100644
index 0000000000..367153b2d9
--- /dev/null
+++ b/java/management/core/src/log4j.properties
@@ -0,0 +1,6 @@
+log4j.rootCategory=${amqj.logging.level}, console
+
+log4j.appender.console=org.apache.log4j.ConsoleAppender
+log4j.appender.console.Threshold=DEBUG
+log4j.appender.console.layout=org.apache.log4j.PatternLayout
+log4j.appender.console.layout.ConversionPattern=%t %d %p [%c{4}] %m%n
diff --git a/java/management/core/src/org/apache/qpid/management/ManagementConnection.java b/java/management/core/src/org/apache/qpid/management/ManagementConnection.java
new file mode 100644
index 0000000000..1dbfe6826c
--- /dev/null
+++ b/java/management/core/src/org/apache/qpid/management/ManagementConnection.java
@@ -0,0 +1,120 @@
+/*
+ *
+ * Copyright (c) 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.qpid.management;
+
+import org.apache.qpid.AMQException;
+import org.apache.qpid.url.URLSyntaxException;
+import org.apache.qpid.management.messaging.ManagementDestination;
+import org.apache.qpid.jms.Session;
+import org.apache.qpid.jms.MessageProducer;
+import org.apache.qpid.client.AMQConnection;
+import org.apache.qpid.client.AMQQueue;
+import org.apache.log4j.Logger;
+
+import javax.jms.*;
+
+public class ManagementConnection
+{
+ private static final Logger _log = Logger.getLogger(ManagementConnection.class);
+
+ private String _brokerHost;
+
+ private int _brokerPort;
+
+ private String _username;
+
+ private String _password;
+
+ private String _virtualPath;
+
+ private AMQConnection _connection;
+
+ private Session _session;
+
+ private MessageConsumer _consumer;
+
+ private MessageProducer _producer;
+
+ private AMQQueue _replyQueue;
+
+ public ManagementConnection(String brokerHost, int brokerPort, String username,
+ String password, String virtualPath)
+ {
+ _brokerHost = brokerHost;
+ _brokerPort = brokerPort;
+ _username = username;
+ _password = password;
+ _virtualPath = virtualPath;
+ }
+
+ public void connect() throws AMQException, JMSException, URLSyntaxException
+ {
+ _connection = new AMQConnection(_brokerHost, _brokerPort, _username, _password,
+ "clientName" + System.currentTimeMillis(), _virtualPath);
+ _connection.setExceptionListener(new ExceptionListener()
+ {
+ public void onException(JMSException jmsException)
+ {
+ _log.error("Error occurred: " + jmsException, jmsException);
+ try
+ {
+ _connection.close();
+ }
+ catch (JMSException e)
+ {
+ _log.error("Error closing connection: " + e, e);
+ }
+ }
+ });
+ _session = (Session)_connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
+ _replyQueue = new AMQQueue("response", true)
+ {
+ public String getEncodedName()
+ {
+ return getQueueName();
+ }
+ };
+ _consumer = _session.createConsumer(_replyQueue, 100, true, true, null);
+
+ _producer = (MessageProducer) _session.createProducer(new ManagementDestination());
+ _connection.start();
+ }
+
+ /**
+ * Send a request and wait for a response.
+ * @param xmlRequest the request to send
+ * @return the response received from the broker
+ * @throws AMQException when an AMQ error occurs
+ * @throws JMSException when a JMS error occurs
+ */
+ public TextMessage sendRequest(String xmlRequest) throws AMQException, JMSException
+ {
+ TextMessage requestMsg = _session.createTextMessage(xmlRequest);
+ requestMsg.setJMSReplyTo(_replyQueue);
+ _producer.send(requestMsg);
+ return (TextMessage) _consumer.receive();
+ }
+
+ public void close() throws AMQException, JMSException
+ {
+ if (_connection != null)
+ {
+ _connection.close();
+ }
+ }
+}
diff --git a/java/management/core/src/org/apache/qpid/management/jmx/AMQConsole.java b/java/management/core/src/org/apache/qpid/management/jmx/AMQConsole.java
new file mode 100644
index 0000000000..c312ef63bf
--- /dev/null
+++ b/java/management/core/src/org/apache/qpid/management/jmx/AMQConsole.java
@@ -0,0 +1,95 @@
+/*
+ *
+ * Copyright (c) 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.qpid.management.jmx;
+
+import org.apache.log4j.Logger;
+import org.apache.xmlbeans.XmlException;
+import org.apache.qpid.AMQException;
+import org.apache.qpid.url.URLSyntaxException;
+import org.apache.qpid.management.ManagementConnection;
+import org.apache.qpid.management.messaging.CMLMessageFactory;
+import org.apache.qpid.schema.cml.CmlDocument;
+
+import javax.jms.JMSException;
+import javax.jms.TextMessage;
+import javax.management.MBeanServer;
+import java.lang.management.ManagementFactory;
+
+/**
+ * Main entry point for AMQ console implementation.
+ *
+ */
+public class AMQConsole
+{
+ private static final Logger _log = Logger.getLogger(AMQConsole.class);
+
+ private ManagementConnection _connection;
+
+ private MBeanInfoRegistry _mbeanInfoRegistry;
+
+ private MBeanRegistrar _mbeanRegistrar;
+
+ private MBeanServer _mbeanServer;
+
+ public AMQConsole(String host, int port, String username, String password,
+ String context)
+ {
+ _connection = new ManagementConnection(host, port, username, password, context);
+ }
+
+ public void initialise() throws AMQException, JMSException, XmlException, URLSyntaxException
+ {
+ _connection.connect();
+ createMBeanInfo();
+ _mbeanServer = ManagementFactory.getPlatformMBeanServer();
+ _mbeanRegistrar = new MBeanRegistrar(_mbeanServer, _connection, _mbeanInfoRegistry);
+ }
+
+ public void registerAllMBeans() throws JMSException, AMQException
+ {
+ _mbeanRegistrar.registerAllMBeans();
+ }
+
+ private void createMBeanInfo() throws JMSException, AMQException, XmlException
+ {
+ TextMessage tm = _connection.sendRequest(CMLMessageFactory.createSchemaRequest());
+ if (_log.isDebugEnabled())
+ {
+ _log.debug("Response document: \n" + tm.getText());
+ }
+ CmlDocument cmlDoc = CmlDocument.Factory.parse(tm.getText());
+ _mbeanInfoRegistry = new MBeanInfoRegistry(cmlDoc);
+ }
+
+ public static void main(String[] args)
+ {
+ AMQConsole console = new AMQConsole(args[0], Integer.parseInt(args[1]), args[2], args[3],
+ args[4]);
+ try
+ {
+ console.initialise();
+ _log.info("Registering all MBeans...");
+ console.registerAllMBeans();
+ _log.info("MBean registration completed successfully");
+ }
+ catch (Exception e)
+ {
+ _log.error("Console initialisation error: " + e, e);
+ }
+ }
+}
diff --git a/java/management/core/src/org/apache/qpid/management/jmx/AMQMBeanInfo.java b/java/management/core/src/org/apache/qpid/management/jmx/AMQMBeanInfo.java
new file mode 100644
index 0000000000..9663a7f783
--- /dev/null
+++ b/java/management/core/src/org/apache/qpid/management/jmx/AMQMBeanInfo.java
@@ -0,0 +1,40 @@
+/*
+ *
+ * Copyright (c) 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.qpid.management.jmx;
+
+import javax.management.openmbean.OpenMBeanAttributeInfo;
+import java.util.Map;
+import java.util.HashMap;
+
+public class AMQMBeanInfo
+{
+ private Map<String, OpenMBeanAttributeInfo> _name2AttributeInfoMap = new HashMap<String, OpenMBeanAttributeInfo>();
+
+ public AMQMBeanInfo(OpenMBeanAttributeInfo[] attributeInfos)
+ {
+ for (OpenMBeanAttributeInfo attributeInfo: attributeInfos)
+ {
+ _name2AttributeInfoMap.put(attributeInfo.getName(), attributeInfo);
+ }
+ }
+
+ public OpenMBeanAttributeInfo getAttributeInfo(String name)
+ {
+ return _name2AttributeInfoMap.get(name);
+ }
+}
diff --git a/java/management/core/src/org/apache/qpid/management/jmx/CMLMBean.java b/java/management/core/src/org/apache/qpid/management/jmx/CMLMBean.java
new file mode 100644
index 0000000000..2d1dafb9f0
--- /dev/null
+++ b/java/management/core/src/org/apache/qpid/management/jmx/CMLMBean.java
@@ -0,0 +1,298 @@
+/*
+ *
+ * Copyright (c) 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.qpid.management.jmx;
+
+import org.apache.log4j.Logger;
+import org.apache.qpid.AMQException;
+import org.apache.qpid.management.ManagementConnection;
+import org.apache.qpid.management.messaging.CMLMessageFactory;
+import org.apache.qpid.schema.cml.CmlDocument;
+import org.apache.qpid.schema.cml.FieldType;
+import org.apache.qpid.schema.cml.InspectReplyType;
+import org.apache.qpid.schema.cml.MethodReplyType;
+
+import javax.jms.JMSException;
+import javax.jms.TextMessage;
+import javax.management.*;
+import javax.management.openmbean.OpenMBeanAttributeInfo;
+import javax.management.openmbean.OpenMBeanInfoSupport;
+import javax.management.openmbean.OpenType;
+import javax.management.openmbean.SimpleType;
+import java.util.Hashtable;
+
+public class CMLMBean implements DynamicMBean
+{
+ private static final Logger _log = Logger.getLogger(CMLMBean.class);
+
+ /**
+ * The number of milliseconds after which data values are considered "stale" and will be
+ * refreshed by querying the broker. This is a way of ensure that reading attributes
+ * repeatedly does not hit the broker heavily.
+ */
+ private static final long REFRESH_IN_MILLIS = 2000;
+
+ /**
+ * Name of the attribute for the parent MBean
+ */
+ public static final String PARENT_ATTRIBUTE = "__parent";
+
+ private OpenMBeanInfoSupport _mbeanInfo;
+
+ private AMQMBeanInfo _extraMbeanInfo;
+
+ /**
+ * The cached inspect reply. This is used to read attribute values and is refreshed automatically
+ * if a request for an attribute is made after the time interval specified in REFRESH_IN_MILLIS
+ */
+ private InspectReplyType _inspectReply;
+
+ private CMLMBean _parent;
+
+ private ObjectName _objectName;
+
+ private ManagementConnection _connection;
+
+ private int _objectId;
+
+ private long _lastRefreshTime = System.currentTimeMillis();
+
+ public CMLMBean(CMLMBean parent, OpenMBeanInfoSupport mbeanInfo, AMQMBeanInfo extraMbeanInfo,
+ InspectReplyType inspectReply, ManagementConnection connection, int objectId)
+ {
+ _mbeanInfo = mbeanInfo;
+ _extraMbeanInfo = extraMbeanInfo;
+ _inspectReply = inspectReply;
+ _parent = parent;
+ _connection = connection;
+ _objectId = objectId;
+ }
+
+ /**
+ * Utility method that populates all the type infos up to the root. Used when
+ * constructing the ObjectName.
+ * We end up with properties of the form "className", "objectId" in the map.
+ * @param leaf the child node. Must not be null. Note that the child types are not populated since the
+ * convention is different for the child where instead of "className" the word "type" is
+ * used. See the JMX Best Practices document on the Sun JMX website for details.
+ * @param properties
+ */
+ public static void populateAllTypeInfo(Hashtable<String, String> properties, CMLMBean leaf)
+ {
+ CMLMBean current = leaf.getParent();
+ while (current != null)
+ {
+ properties.put(current.getType(), Integer.toString(current.getObjectId()));
+ current = current.getParent();
+ }
+ }
+
+ public String getType()
+ {
+ return _inspectReply.getClass1();
+ }
+
+ public int getObjectId()
+ {
+ return _inspectReply.getObject2();
+ }
+
+ public InspectReplyType getInspectReply()
+ {
+ return _inspectReply;
+ }
+
+ public CMLMBean getParent()
+ {
+ return _parent;
+ }
+
+ public ObjectName getObjectName()
+ {
+ return _objectName;
+ }
+
+ public void setObjectName(ObjectName objectName)
+ {
+ _objectName = objectName;
+ }
+
+ public Object getAttribute(String attribute)
+ throws AttributeNotFoundException, MBeanException, ReflectionException
+ {
+ if (PARENT_ATTRIBUTE.equals(attribute))
+ {
+ if (_parent == null)
+ {
+ return null;
+ }
+ else
+ {
+ return _parent.getObjectName();
+ }
+ }
+ if (needRefresh())
+ {
+ refreshValues();
+ }
+ String nsDecl = "declare namespace cml='http://www.amqp.org/schema/cml';";
+ FieldType[] fields = (FieldType[]) _inspectReply.selectPath(nsDecl + "$this/cml:field[@name='" +
+ attribute + "']");
+ if (fields == null || fields.length == 0)
+ {
+ throw new AttributeNotFoundException("Attribute " + attribute + " not found");
+ }
+ else
+ {
+ OpenMBeanAttributeInfo attrInfo = _extraMbeanInfo.getAttributeInfo(attribute);
+ OpenType openType = attrInfo.getOpenType();
+ String value = fields[0].getStringValue();
+ try
+ {
+ return createAttributeValue(openType, value, attrInfo.getName());
+ }
+ catch (MalformedObjectNameException e)
+ {
+ throw new MBeanException(e);
+ }
+ }
+ }
+
+ private boolean needRefresh()
+ {
+ return ((System.currentTimeMillis() - _lastRefreshTime) > REFRESH_IN_MILLIS);
+ }
+
+ private void refreshValues() throws MBeanException
+ {
+ _log.debug("Refreshing values...");
+ try
+ {
+ TextMessage response = _connection.sendRequest(CMLMessageFactory.createInspectRequest(_objectId));
+
+ CmlDocument cmlDoc = CmlDocument.Factory.parse(response.getText());
+ _inspectReply = cmlDoc.getCml().getInspectReply();
+ _lastRefreshTime = System.currentTimeMillis();
+ }
+ catch (Exception e)
+ {
+ throw new MBeanException(e);
+ }
+ }
+
+ private Object createAttributeValue(OpenType openType, String value, String mbeanType)
+ throws MalformedObjectNameException
+ {
+ if (openType.equals(SimpleType.STRING))
+ {
+ return value;
+ }
+ else if (openType.equals(SimpleType.BOOLEAN))
+ {
+ return Boolean.valueOf(value);
+ }
+ else if (openType.equals(SimpleType.INTEGER))
+ {
+ return Integer.valueOf(value);
+ }
+ else if (openType.equals(SimpleType.DOUBLE))
+ {
+ return Double.valueOf(value);
+ }
+ else if (openType.equals(SimpleType.OBJECTNAME))
+ {
+ Hashtable<String, String> props = new Hashtable<String, String>();
+ props.put("objectid", value);
+ props.put("type", mbeanType);
+ // this populates all type info for parents
+ populateAllTypeInfo(props, this);
+ // add in type info for this level. This information is available from the inspect reply xml fragment
+ props.put(_inspectReply.getClass1(), Integer.toString(_inspectReply.getObject2()));
+ return new ObjectName(JmxConstants.JMX_DOMAIN, props);
+ }
+ else
+ {
+ _log.warn("Unsupported open type: " + openType + " - returning string value");
+ return value;
+ }
+ }
+
+ public void setAttribute(Attribute attribute) throws AttributeNotFoundException, InvalidAttributeValueException,
+ MBeanException, ReflectionException
+ {
+
+ }
+
+ public AttributeList getAttributes(String[] attributes)
+ {
+ AttributeList al = new AttributeList(attributes.length);
+ for (String name : attributes)
+ {
+ try
+ {
+ Object value = getAttribute(name);
+ final Attribute attr = new Attribute(name, value);
+ al.add(attr);
+ }
+ catch (Exception e)
+ {
+ _log.error("Unable to get value for attribute: " + name, e);
+ }
+ }
+ return al;
+ }
+
+ public AttributeList setAttributes(AttributeList attributes)
+ {
+ return null;
+ }
+
+ public Object invoke(String actionName, Object params[], String signature[]) throws MBeanException,
+ ReflectionException
+ {
+ _log.debug("Invoke called on action " + actionName);
+ try
+ {
+ TextMessage response = _connection.sendRequest(CMLMessageFactory.createMethodRequest(_objectId, actionName));
+ CmlDocument cmlDoc = CmlDocument.Factory.parse(response.getText());
+ CmlDocument.Cml cml = cmlDoc.getCml();
+ MethodReplyType methodReply = cml.getMethodReply();
+ if (methodReply.getStatus() != MethodReplyType.Status.OK)
+ {
+ throw new MBeanException(new Exception("Response code from method: " + methodReply.getStatus()));
+ }
+ return null;
+ }
+ catch (AMQException e)
+ {
+ throw new MBeanException(e);
+ }
+ catch (JMSException e)
+ {
+ throw new MBeanException(e);
+ }
+ catch (org.apache.xmlbeans.XmlException e)
+ {
+ throw new MBeanException(e);
+ }
+ }
+
+ public MBeanInfo getMBeanInfo()
+ {
+ return _mbeanInfo;
+ }
+}
diff --git a/java/management/core/src/org/apache/qpid/management/jmx/JmxConstants.java b/java/management/core/src/org/apache/qpid/management/jmx/JmxConstants.java
new file mode 100644
index 0000000000..a1944bfeb1
--- /dev/null
+++ b/java/management/core/src/org/apache/qpid/management/jmx/JmxConstants.java
@@ -0,0 +1,23 @@
+/*
+ *
+ * Copyright (c) 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.qpid.management.jmx;
+
+public interface JmxConstants
+{
+ String JMX_DOMAIN = "org.apache.qpid";
+}
diff --git a/java/management/core/src/org/apache/qpid/management/jmx/MBeanInfoRegistry.java b/java/management/core/src/org/apache/qpid/management/jmx/MBeanInfoRegistry.java
new file mode 100644
index 0000000000..f6abb5028b
--- /dev/null
+++ b/java/management/core/src/org/apache/qpid/management/jmx/MBeanInfoRegistry.java
@@ -0,0 +1,201 @@
+/*
+ *
+ * Copyright (c) 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.qpid.management.jmx;
+
+import org.apache.qpid.AMQException;
+import org.apache.qpid.schema.cml.CmlDocument;
+import org.apache.qpid.schema.cml.FieldType;
+import org.apache.qpid.schema.cml.MethodType;
+import org.apache.qpid.schema.cml.SchemaReplyType;
+
+import javax.management.modelmbean.DescriptorSupport;
+import javax.management.openmbean.*;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Stores all OpenMBeanInfo instances.
+ * <p/>
+ * Builds MBeanInfo instances from the CML schema (which is parsed by XMLBeans) and
+ * stores these indexed by CML class name.
+ * <p/>
+ * When constructing a DynamicMBean this registry is consulted for the MBeanInfo.
+ *
+ */
+public class MBeanInfoRegistry
+{
+ private Map<String, OpenMBeanInfoSupport> _cmlClass2OpenMBeanInfoMap = new HashMap<String, OpenMBeanInfoSupport>();
+
+ private Map<String, AMQMBeanInfo> _cmlClass2AMQMBeanInfoMap = new HashMap<String, AMQMBeanInfo>();
+
+ public MBeanInfoRegistry(CmlDocument cmlDocument) throws AMQException
+ {
+ initialise(cmlDocument);
+ }
+
+ private void initialise(CmlDocument cmlDocument) throws AMQException
+ {
+ CmlDocument.Cml cml = cmlDocument.getCml();
+ SchemaReplyType schema = cml.getSchemaReply();
+ for (org.apache.qpid.schema.cml.ClassType c : schema.getClass1List())
+ {
+ OpenMBeanAttributeInfo[] attributes = createAttributeInfos(c.getFieldList());
+ OpenMBeanOperationInfo[] operations = createOperationInfos(c.getMethodList());
+ String className = c.getName();
+ OpenMBeanInfoSupport support = new OpenMBeanInfoSupport(className, null, attributes,
+ null, operations, null);
+ // we need to store the extra information separately since we cannot subclass
+ // OpenMBeanInfoSupport. Doing so means we need to have an AMQMBeanInfo class on each client
+ // which defeats the point of OpenMBeans. The extra info is only used by the CMLBean implementation
+ // to assist with runtime value lookups.
+ AMQMBeanInfo extra = new AMQMBeanInfo(attributes);
+ _cmlClass2OpenMBeanInfoMap.put(className, support);
+ _cmlClass2AMQMBeanInfoMap.put(className, extra);
+ }
+ }
+
+ public OpenMBeanInfoSupport getOpenMBeanInfo(String cmlType)
+ {
+ return _cmlClass2OpenMBeanInfoMap.get(cmlType);
+ }
+
+ public AMQMBeanInfo getAMQMBeanInfo(String cmlType)
+ {
+ return _cmlClass2AMQMBeanInfoMap.get(cmlType);
+ }
+
+ private OpenMBeanAttributeInfo[] createAttributeInfos(List<FieldType> fields)
+ throws AMQException
+ {
+ OpenMBeanAttributeInfo[] attributes = new OpenMBeanAttributeInfo[fields.size() + 1];
+
+ // we up the parent attribute which is always present
+ try
+ {
+ DescriptorSupport descriptor = new DescriptorSupport(new String[]{"hidden=true"});
+ attributes[attributes.length - 1] = new OpenMBeanAttributeInfoSupport(CMLMBean.PARENT_ATTRIBUTE,
+ "Parent", SimpleType.OBJECTNAME,
+ true, false, false);
+ //descriptor); JDK 1.6 only
+ }
+ catch (Exception e)
+ {
+ // should never happen
+ throw new AMQException("Unable to create Parent attribute", e);
+ }
+ // add all the type-specific attributes
+ for (int i = 0; i < attributes.length - 1; i++)
+ {
+ FieldType field = fields.get(i);
+ OpenType openType = getOpenType(field.getType(), field.getModify());
+ String description = field.getLabel();
+ attributes[i] = new OpenMBeanAttributeInfoSupport(field.getName(),
+ description != null ? description:"No description",
+ openType,
+ true,
+ field.getModify(),
+ openType == SimpleType.BOOLEAN);
+ }
+
+ return attributes;
+ }
+
+ private static OpenType getOpenType(FieldType.Type.Enum type, boolean isArray)
+ throws UnsupportedCMLTypeException, AMQException
+ {
+ SimpleType simpleType;
+ boolean primitive;
+ switch (type.intValue())
+ {
+ // the constants are not public (bug in xmlbeans) so we cannot use
+ // the constants that are defined
+ // TODO: raise defect with xmlbeans projects
+ case 1:
+ simpleType = SimpleType.BOOLEAN;
+ primitive = true;
+ break;
+ case 2:
+ simpleType = SimpleType.STRING;
+ primitive = false;
+ break;
+ case 3:
+ simpleType = SimpleType.INTEGER;
+ primitive = true;
+ break;
+ case 4:
+ simpleType = SimpleType.OBJECTNAME;
+ primitive = false;
+ break;
+ case 5:
+ simpleType = SimpleType.DATE;
+ primitive = false;
+ break;
+ default:
+ throw new UnsupportedCMLTypeException(type.toString());
+ }
+ if (isArray)
+ {
+ try
+ {
+ //return new ArrayType(simpleType, primitive);
+ return new ArrayType(1, simpleType);
+ }
+ catch (OpenDataException e)
+ {
+ throw new AMQException("Error constructing array type: " + e, e);
+ }
+ }
+ else
+ {
+ return simpleType;
+ }
+ }
+
+ private OpenMBeanOperationInfo[] createOperationInfos(List<MethodType> methods)
+ throws AMQException
+ {
+ OpenMBeanOperationInfo[] methodInfos = new OpenMBeanOperationInfo[methods.size()];
+ for (int i = 0; i < methodInfos.length; i++)
+ {
+ MethodType methodType = methods.get(i);
+ OpenMBeanParameterInfo[] parameters = createParameterInfos(methodType.getFieldList());
+ methodInfos[i] = new OpenMBeanOperationInfoSupport(methodType.getName(), "No description",
+ parameters, SimpleType.VOID,
+ OpenMBeanOperationInfoSupport.ACTION);
+ }
+ return methodInfos;
+ }
+
+ private OpenMBeanParameterInfo[] createParameterInfos(List<FieldType> parameters)
+ throws AMQException
+ {
+ OpenMBeanParameterInfo[] paramInfos = new OpenMBeanParameterInfo[parameters.size()];
+ for (int i = 0; i < paramInfos.length; i++)
+ {
+ FieldType field = parameters.get(i);
+ String description = field.getLabel();
+ OpenType openType = getOpenType(field.getType(), field.getModify());
+ paramInfos[i] = new OpenMBeanParameterInfoSupport(field.getName(),
+ description==null?"No description":description,
+ openType);
+ }
+ return paramInfos;
+ }
+}
+
diff --git a/java/management/core/src/org/apache/qpid/management/jmx/MBeanRegistrar.java b/java/management/core/src/org/apache/qpid/management/jmx/MBeanRegistrar.java
new file mode 100644
index 0000000000..bdc3772553
--- /dev/null
+++ b/java/management/core/src/org/apache/qpid/management/jmx/MBeanRegistrar.java
@@ -0,0 +1,141 @@
+/*
+ *
+ * Copyright (c) 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.qpid.management.jmx;
+
+import org.apache.log4j.Logger;
+import org.apache.xmlbeans.XmlException;
+import org.apache.qpid.AMQException;
+import org.apache.qpid.management.ManagementConnection;
+import org.apache.qpid.management.messaging.CMLMessageFactory;
+import org.apache.qpid.schema.cml.CmlDocument;
+import org.apache.qpid.schema.cml.FieldType;
+import org.apache.qpid.schema.cml.InspectReplyType;
+
+import javax.jms.JMSException;
+import javax.jms.TextMessage;
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import javax.management.openmbean.OpenMBeanAttributeInfo;
+import javax.management.openmbean.SimpleType;
+import javax.management.openmbean.OpenMBeanInfoSupport;
+import java.util.Hashtable;
+
+/**
+ * Responsible for registering MBeans. This class will navigate through
+ * our hierarchy of MBeans, registering them with the appropriate ObjectNames.
+ *
+ */
+public class MBeanRegistrar
+{
+ private static final Logger _log = Logger.getLogger(MBeanRegistrar.class);
+
+ /** The MBean server with which all MBeans will be registered. */
+ private MBeanServer _targetMBeanServer;
+
+ /** The connection used to communicate with the broker */
+ private ManagementConnection _connection;
+
+ private MBeanInfoRegistry _mbeanInfoRegistry;
+
+ /**
+ * Create a registrar for the specified MBean server
+ * @param targetMBeanServer the MBean server with which all MBeans will be registered
+ */
+ public MBeanRegistrar(MBeanServer targetMBeanServer, ManagementConnection connection,
+ MBeanInfoRegistry mbeanInfoRegistry)
+ {
+ _targetMBeanServer = targetMBeanServer;
+ _connection = connection;
+ _mbeanInfoRegistry = mbeanInfoRegistry;
+ }
+
+ public void registerAllMBeans() throws AMQException, JMSException
+ {
+ registerMBean(null, 0);
+ }
+
+ /**
+ * Asks the broker for details of a particular object id then creates and registers an
+ * MBean with the MBeanServer.
+ * @param objectId id of the object we want to inspect
+ * @return the registered bean, from which the underlying inspect response can be retrieved if required
+ * @throws AMQException
+ * @throws JMSException
+ */
+ private CMLMBean registerMBean(CMLMBean parent, int objectId) throws AMQException, JMSException
+ {
+ TextMessage response = _connection.sendRequest(CMLMessageFactory.createInspectRequest(objectId));
+ try
+ {
+ CmlDocument cmlDoc = CmlDocument.Factory.parse(response.getText());
+ CmlDocument.Cml cml = cmlDoc.getCml();
+ InspectReplyType inspect = cml.getInspectReply();
+ if (_log.isDebugEnabled())
+ {
+ _log.debug("Inspect reply: " + inspect);
+ }
+ OpenMBeanInfoSupport mbeanInfo = _mbeanInfoRegistry.getOpenMBeanInfo(inspect.getClass1());
+ AMQMBeanInfo extraMbeanInfo = _mbeanInfoRegistry.getAMQMBeanInfo(inspect.getClass1());
+ CMLMBean mbean = new CMLMBean(parent, mbeanInfo, extraMbeanInfo, inspect, _connection, objectId);
+ Hashtable<String, String> props = new Hashtable<String, String>();
+ props.put("objectid", Integer.toString(objectId));
+ props.put("type", mbean.getType());
+ CMLMBean.populateAllTypeInfo(props, mbean);
+ ObjectName mbeanObjectName = new ObjectName("org.apache.qpid", props);
+ mbean.setObjectName(mbeanObjectName);
+ _targetMBeanServer.registerMBean(mbean, mbeanObjectName);
+
+ // recursively register all beans
+ String nsDecl = "declare namespace cml='http://www.amqp.org/schema/cml';";
+ for (MBeanAttributeInfo attributeInfo: mbeanInfo.getAttributes())
+ {
+ OpenMBeanAttributeInfo openAttributeInfo = (OpenMBeanAttributeInfo) attributeInfo;
+ if (openAttributeInfo.getOpenType().equals(SimpleType.OBJECTNAME) &&
+ !"__parent".equals(openAttributeInfo.getName()))
+ {
+ if (_log.isDebugEnabled())
+ {
+ _log.debug("Searching for fields with name: " + openAttributeInfo.getName());
+ }
+ FieldType[] fields = (FieldType[]) inspect.selectPath(nsDecl + "$this/cml:field[@name='" +
+ openAttributeInfo.getName() + "']");
+ if (fields == null || fields.length == 0)
+ {
+ throw new AMQException("inspect xml did not contain field value for field " +
+ attributeInfo.getName());
+ }
+ for (FieldType field : fields)
+ {
+ registerMBean(mbean, Integer.parseInt(field.getStringValue()));
+ }
+ }
+ }
+ return mbean;
+ }
+ catch (XmlException e)
+ {
+ throw new AMQException(_log, "Error parsing broker response: " + e, e);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ throw new AMQException(_log, "Error registering MBean: " + e, e);
+ }
+ }
+}
diff --git a/java/management/core/src/org/apache/qpid/management/jmx/UnsupportedCMLTypeException.java b/java/management/core/src/org/apache/qpid/management/jmx/UnsupportedCMLTypeException.java
new file mode 100644
index 0000000000..bb866f8d17
--- /dev/null
+++ b/java/management/core/src/org/apache/qpid/management/jmx/UnsupportedCMLTypeException.java
@@ -0,0 +1,36 @@
+/*
+ *
+ * Copyright (c) 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.qpid.management.jmx;
+
+import org.apache.qpid.AMQException;
+
+public class UnsupportedCMLTypeException extends AMQException
+{
+ private String _type;
+
+ public UnsupportedCMLTypeException(String type)
+ {
+ super("CML type " + type + " is unsupported by the JMX layer");
+ _type = type;
+ }
+
+ public String getType()
+ {
+ return _type;
+ }
+}
diff --git a/java/management/core/src/org/apache/qpid/management/messaging/CMLMessageFactory.java b/java/management/core/src/org/apache/qpid/management/messaging/CMLMessageFactory.java
new file mode 100644
index 0000000000..e47eb66c65
--- /dev/null
+++ b/java/management/core/src/org/apache/qpid/management/messaging/CMLMessageFactory.java
@@ -0,0 +1,59 @@
+/*
+ *
+ * Copyright (c) 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.qpid.management.messaging;
+
+import org.apache.qpid.schema.cml.CmlDocument;
+import org.apache.qpid.schema.cml.InspectRequestType;
+import org.apache.qpid.schema.cml.MethodRequestType;
+
+public class CMLMessageFactory
+{
+ public static String createSchemaRequest()
+ {
+ CmlDocument cmlDoc = CmlDocument.Factory.newInstance();
+ CmlDocument.Cml cml = createStandardCml(cmlDoc);
+ cml.addNewSchemaRequest();
+ return cmlDoc.toString();
+ }
+
+ public static String createInspectRequest(int objectId)
+ {
+ CmlDocument cmlDoc = CmlDocument.Factory.newInstance();
+ CmlDocument.Cml cml = createStandardCml(cmlDoc);
+ InspectRequestType inspect = cml.addNewInspectRequest();
+ inspect.setObject(objectId);
+ return cmlDoc.toString();
+ }
+
+ public static String createMethodRequest(int objectId, String methodName)
+ {
+ CmlDocument cmlDoc = CmlDocument.Factory.newInstance();
+ CmlDocument.Cml cml = createStandardCml(cmlDoc);
+ MethodRequestType methodReq = cml.addNewMethodRequest();
+ methodReq.setObject(objectId);
+ methodReq.setName(methodName);
+ return cmlDoc.toString();
+ }
+
+ private static CmlDocument.Cml createStandardCml(CmlDocument cmlDoc)
+ {
+ CmlDocument.Cml cml = cmlDoc.addNewCml();
+ cml.setVersion("1.0");
+ return cml;
+ }
+}
diff --git a/java/management/core/src/org/apache/qpid/management/messaging/ManagementDestination.java b/java/management/core/src/org/apache/qpid/management/messaging/ManagementDestination.java
new file mode 100644
index 0000000000..f6edb9394a
--- /dev/null
+++ b/java/management/core/src/org/apache/qpid/management/messaging/ManagementDestination.java
@@ -0,0 +1,43 @@
+/*
+ *
+ * Copyright (c) 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.qpid.management.messaging;
+
+import org.apache.qpid.client.AMQDestination;
+
+public class ManagementDestination extends AMQDestination
+{
+ public ManagementDestination()
+ {
+ super("amq.system", "system", "amq.console");
+ }
+
+ public boolean isNameRequired()
+ {
+ return false;
+ }
+
+ public String getEncodedName()
+ {
+ return null;
+ }
+
+ public String getRoutingKey()
+ {
+ return getDestinationName();
+ }
+}
diff --git a/java/management/core/test/org/apache/qpid/management/harness/SimpleJMXClient.java b/java/management/core/test/org/apache/qpid/management/harness/SimpleJMXClient.java
new file mode 100644
index 0000000000..68e1325b1d
--- /dev/null
+++ b/java/management/core/test/org/apache/qpid/management/harness/SimpleJMXClient.java
@@ -0,0 +1,25 @@
+/*
+ *
+ * Copyright (c) 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.qpid.management.harness;
+
+public class SimpleJMXClient
+{
+
+
+
+}
diff --git a/java/management/core/test/org/apache/qpid/management/schema/TestParseSchema.java b/java/management/core/test/org/apache/qpid/management/schema/TestParseSchema.java
new file mode 100644
index 0000000000..8672207e59
--- /dev/null
+++ b/java/management/core/test/org/apache/qpid/management/schema/TestParseSchema.java
@@ -0,0 +1,87 @@
+/*
+ *
+ * Copyright (c) 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.qpid.management.schema;
+
+import org.apache.log4j.Logger;
+import org.apache.qpid.management.ManagementConnection;
+import org.apache.qpid.management.messaging.CMLMessageFactory;
+import org.apache.qpid.schema.cml.CmlDocument;
+
+import javax.jms.TextMessage;
+
+public class TestParseSchema
+{
+ private static final Logger _logger = Logger.getLogger(TestParseSchema.class);
+
+ private static ManagementConnection _con;
+
+ private static void parseCMLSchema(String xml) throws Exception
+ {
+ CmlDocument cmlDoc = CmlDocument.Factory.parse(xml);
+ CmlDocument.Cml cml = cmlDoc.getCml();
+ /*SchemaReplyDocument.SchemaReply schema = cml.getSchemaReply();
+ for (ClassDocument.Class classDefn: schema.getClass1List())
+ {
+ System.out.println("Class: " + classDefn.getName());
+ } */
+ }
+
+ public static void main(String[] args)
+ {
+ _logger.info("Starting...");
+
+ if (args.length != 5)
+ {
+ System.out.println("Usage: host port username password vhost");
+ System.exit(1);
+ }
+ try
+ {
+ _con = new ManagementConnection(args[0], Integer.parseInt(args[1]), args[2], args[3],
+ args[4]);
+
+ _con.connect();
+ TextMessage tm = _con.sendRequest(CMLMessageFactory.createSchemaRequest());
+ parseCMLSchema(tm.getText());
+ _logger.info("Closing management connection");
+ _con.close();
+
+ //_logger.info("Waiting...");
+ }
+ catch (Throwable t)
+ {
+ _logger.error("Fatal error: " + t, t);
+ }
+ finally
+ {
+ if (_con != null)
+ {
+ _logger.info("Closing connection");
+ try
+ {
+ _con.close();
+ }
+ catch (Exception e)
+ {
+ _logger.error("Error closing connection: " + e);
+ }
+ }
+ }
+
+ }
+}
diff --git a/java/management/mc4j/qpid/BlazeConnections.xml b/java/management/mc4j/qpid/BlazeConnections.xml
new file mode 100644
index 0000000000..b75f49d95b
--- /dev/null
+++ b/java/management/mc4j/qpid/BlazeConnections.xml
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ -
+ - Copyright (c) 2006 The Apache Software Foundation
+ -
+ - Licensed under the Apache License, Version 2.0 (the "License");
+ - you may not use this file except in compliance with the License.
+ - You may obtain a copy of the License at
+ -
+ - http://www.apache.org/licenses/LICENSE-2.0
+ -
+ - Unless required by applicable law or agreed to in writing, software
+ - distributed under the License is distributed on an "AS IS" BASIS,
+ - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ - See the License for the specific language governing permissions and
+ - limitations under the License.
+ -
+ -->
+<!DOCTYPE Dashboard PUBLIC "-//MC4J//DTD Dashboard 1.0//EN" "http://mc4j.sourceforge.net/Dashboard_1_0.dtd">
+
+<Dashboard version="1.0" name="Qpid AMQ Connections Statistics">
+
+ <Description>This dashboard shows the statistics of all Qpid Client Connections.</Description>
+
+ <DashboardMatch type="Global" location="/Qpid/Connections">
+ <BeanMatch id="ConnectionBeanList" type="Multiple">
+ <Condition type="BeanObjectNameCondition" filter="type=Connection"/>
+ </BeanMatch>
+ </DashboardMatch>
+
+ <LayoutManager type="java.awt.BorderLayout"/>
+ <Content>
+
+ <!-- *** The header section displays title and a refresh control *** -->
+ <Component type="javax.swing.JPanel">
+ <Constraint type="BorderConstraints" direction="NORTH"/>
+ <LayoutManager type="java.awt.BorderLayout"/>
+ <Border type="javax.swing.border.EmptyBorder" top="(Literal)2" left="(Literal)5" bottom="(Literal)2" right="(Literal)5"/>
+ <Content>
+ <Component type="javax.swing.JPanel">
+ <Constraint type="BorderConstraints" direction="CENTER"/>
+ <LayoutManager type="java.awt.BorderLayout"/>
+ <Content>
+ <Component type="javax.swing.JLabel" id="titleLable">
+ <Constraint type="BorderConstraints" direction="CENTER"/>
+ <Attribute name="text" value="DashboardName"/>
+ <Attribute name="font" value="(Literal)SansSerif bold 20"/>
+ <Attribute name="foreground" value="(Literal)0x666666"/>
+ </Component>
+ <Component type="javax.swing.JTextArea">
+ <Constraint type="BorderConstraints" direction="SOUTH"/>
+ <Attribute name="text" value="DashboardDescription"/>
+ <Attribute name="font" value="(Literal)DialogInput bold 14"/>
+ <Attribute name="opaque" value="(Literal)false"/>
+ <Attribute name="editable" value="(Literal)false"/>
+ </Component>
+ </Content>
+ </Component>
+ <Component type="org.mc4j.console.dashboard.components.RefreshControlComponent">
+ <Constraint type="BorderConstraints" direction="EAST"/>
+ <Attribute name="refreshDelay" value="(Literal)1000"/>
+ </Component>
+ </Content>
+ </Component>
+
+
+ <Component type="org.mc4j.console.dashboard.components.AttributeTableComponent">
+ <Attribute name="beanList" value="ConnectionBeanList"/>
+ <Constraint type="BorderConstraints" direction="CENTER"/>
+
+ <Attribute name="background" value="(Literal)0xFFFFFF"/>
+ <Attribute name="preferredSize" value="100,100"/>
+
+
+
+ <Attribute name="AttributeName" value="(Literal)RemoteAddress"/>
+ <Attribute name="AttributeName" value="(Literal)ReadBytes"/>
+ <Attribute name="AttributeName" value="(Literal)WrittenBytes"/>
+ <Attribute name="AttributeName" value="(Literal)LastIoTime"/>
+ </Component>
+
+
+ </Content>
+</Dashboard>
diff --git a/java/management/mc4j/qpid/BlazeExchanges.xml b/java/management/mc4j/qpid/BlazeExchanges.xml
new file mode 100644
index 0000000000..6612c711c3
--- /dev/null
+++ b/java/management/mc4j/qpid/BlazeExchanges.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ -
+ - Copyright (c) 2006 The Apache Software Foundation
+ -
+ - Licensed under the Apache License, Version 2.0 (the "License");
+ - you may not use this file except in compliance with the License.
+ - You may obtain a copy of the License at
+ -
+ - http://www.apache.org/licenses/LICENSE-2.0
+ -
+ - Unless required by applicable law or agreed to in writing, software
+ - distributed under the License is distributed on an "AS IS" BASIS,
+ - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ - See the License for the specific language governing permissions and
+ - limitations under the License.
+ -
+ -->
+<!DOCTYPE Dashboard PUBLIC "-//MC4J//DTD Dashboard 1.0//EN" "http://mc4j.sourceforge.net/Dashboard_1_0.dtd">
+
+<Dashboard version="1.0" name="Qpid AMQ Exchanges">
+
+ <Description>This dashboard shows the statistics of all Qpid Exchanges.</Description>
+
+ <DashboardMatch type="Global" location="/Qpid/Exchanges">
+ <BeanMatch id="ConnectionBeanList" type="Multiple">
+ <Condition type="BeanObjectNameCondition" filter="type=Exchange"/>
+ </BeanMatch>
+ </DashboardMatch>
+
+ <LayoutManager type="java.awt.BorderLayout"/>
+ <Content>
+
+ <!-- *** The header section displays title and a refresh control *** -->
+ <Component type="javax.swing.JPanel">
+ <Constraint type="BorderConstraints" direction="NORTH"/>
+ <LayoutManager type="java.awt.BorderLayout"/>
+ <Border type="javax.swing.border.EmptyBorder" top="(Literal)2" left="(Literal)5" bottom="(Literal)2" right="(Literal)5"/>
+ <Content>
+ <Component type="javax.swing.JPanel">
+ <Constraint type="BorderConstraints" direction="CENTER"/>
+ <LayoutManager type="java.awt.BorderLayout"/>
+ <Content>
+ <Component type="javax.swing.JLabel" id="titleLable">
+ <Constraint type="BorderConstraints" direction="CENTER"/>
+ <Attribute name="text" value="DashboardName"/>
+ <Attribute name="font" value="(Literal)SansSerif bold 20"/>
+ <Attribute name="foreground" value="(Literal)0x666666"/>
+ </Component>
+ <Component type="javax.swing.JTextArea">
+ <Constraint type="BorderConstraints" direction="SOUTH"/>
+ <Attribute name="text" value="DashboardDescription"/>
+ <Attribute name="font" value="(Literal)DialogInput bold 14"/>
+ <Attribute name="opaque" value="(Literal)false"/>
+ <Attribute name="editable" value="(Literal)false"/>
+ </Component>
+ </Content>
+ </Component>
+ <Component type="org.mc4j.console.dashboard.components.RefreshControlComponent">
+ <Constraint type="BorderConstraints" direction="EAST"/>
+ <Attribute name="refreshDelay" value="(Literal)1000"/>
+ </Component>
+ </Content>
+ </Component>
+
+
+ <Component type="org.mc4j.console.dashboard.components.AttributeTableComponent">
+ <Attribute name="beanList" value="ConnectionBeanList"/>
+ <Constraint type="BorderConstraints" direction="CENTER"/>
+
+ <Attribute name="background" value="(Literal)0xFFFFFF"/>
+ <Attribute name="preferredSize" value="100,100"/>
+
+ <Attribute name="AttributeName" value="(Literal)Name"/>
+ <Attribute name="AttributeName" value="(Literal)Durable"/>
+ <Attribute name="AttributeName" value="(Literal)Bindings"/>
+ </Component>
+
+
+ </Content>
+</Dashboard>
diff --git a/java/management/mc4j/qpid/BlazeQueues.xml b/java/management/mc4j/qpid/BlazeQueues.xml
new file mode 100644
index 0000000000..4a6e55cdb7
--- /dev/null
+++ b/java/management/mc4j/qpid/BlazeQueues.xml
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ -
+ - Copyright (c) 2006 The Apache Software Foundation
+ -
+ - Licensed under the Apache License, Version 2.0 (the "License");
+ - you may not use this file except in compliance with the License.
+ - You may obtain a copy of the License at
+ -
+ - http://www.apache.org/licenses/LICENSE-2.0
+ -
+ - Unless required by applicable law or agreed to in writing, software
+ - distributed under the License is distributed on an "AS IS" BASIS,
+ - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ - See the License for the specific language governing permissions and
+ - limitations under the License.
+ -
+ -->
+<!DOCTYPE Dashboard PUBLIC "-//MC4J//DTD Dashboard 1.0//EN" "http://mc4j.sourceforge.net/Dashboard_1_0.dtd">
+
+<Dashboard version="1.0" name="Qpid AMQ Queues">
+
+ <Description>This dashboard shows the statistics of all Qpid Queues.</Description>
+
+ <DashboardMatch type="Global" location="/Qpid/Queues">
+ <BeanMatch id="ConnectionBeanList" type="Multiple">
+ <Condition type="BeanObjectNameCondition" filter="type=Queue"/>
+ </BeanMatch>
+ </DashboardMatch>
+
+ <LayoutManager type="java.awt.BorderLayout"/>
+ <Content>
+
+ <!-- *** The header section displays title and a refresh control *** -->
+ <Component type="javax.swing.JPanel">
+ <Constraint type="BorderConstraints" direction="NORTH"/>
+ <LayoutManager type="java.awt.BorderLayout"/>
+ <Border type="javax.swing.border.EmptyBorder" top="(Literal)2" left="(Literal)5" bottom="(Literal)2" right="(Literal)5"/>
+ <Content>
+ <Component type="javax.swing.JPanel">
+ <Constraint type="BorderConstraints" direction="CENTER"/>
+ <LayoutManager type="java.awt.BorderLayout"/>
+ <Content>
+ <Component type="javax.swing.JLabel" id="titleLable">
+ <Constraint type="BorderConstraints" direction="CENTER"/>
+ <Attribute name="text" value="DashboardName"/>
+ <Attribute name="font" value="(Literal)SansSerif bold 20"/>
+ <Attribute name="foreground" value="(Literal)0x666666"/>
+ </Component>
+ <Component type="javax.swing.JTextArea">
+ <Constraint type="BorderConstraints" direction="SOUTH"/>
+ <Attribute name="text" value="DashboardDescription"/>
+ <Attribute name="font" value="(Literal)DialogInput bold 14"/>
+ <Attribute name="opaque" value="(Literal)false"/>
+ <Attribute name="editable" value="(Literal)false"/>
+ </Component>
+ </Content>
+ </Component>
+ <Component type="org.mc4j.console.dashboard.components.RefreshControlComponent">
+ <Constraint type="BorderConstraints" direction="EAST"/>
+ <Attribute name="refreshDelay" value="(Literal)1000"/>
+ </Component>
+ </Content>
+ </Component>
+
+
+ <Component type="org.mc4j.console.dashboard.components.AttributeTableComponent">
+ <Attribute name="beanList" value="ConnectionBeanList"/>
+ <Constraint type="BorderConstraints" direction="CENTER"/>
+
+ <Attribute name="background" value="(Literal)0xFFFFFF"/>
+ <Attribute name="preferredSize" value="100,100"/>
+
+ <Attribute name="AttributeName" value="(Literal)Name"/>
+ <Attribute name="AttributeName" value="(Literal)AutoDelete"/>
+ <Attribute name="AttributeName" value="(Literal)Durable"/>
+ <Attribute name="AttributeName" value="(Literal)Owner"/>
+ <Attribute name="AttributeName" value="(Literal)MessageCount"/>
+ </Component>
+
+
+ </Content>
+</Dashboard>
diff --git a/java/management/mc4j/qpid/BlazeSingleQueue.xml b/java/management/mc4j/qpid/BlazeSingleQueue.xml
new file mode 100644
index 0000000000..0879801746
--- /dev/null
+++ b/java/management/mc4j/qpid/BlazeSingleQueue.xml
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ -
+ - Copyright (c) 2006 The Apache Software Foundation
+ -
+ - Licensed under the Apache License, Version 2.0 (the "License");
+ - you may not use this file except in compliance with the License.
+ - You may obtain a copy of the License at
+ -
+ - http://www.apache.org/licenses/LICENSE-2.0
+ -
+ - Unless required by applicable law or agreed to in writing, software
+ - distributed under the License is distributed on an "AS IS" BASIS,
+ - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ - See the License for the specific language governing permissions and
+ - limitations under the License.
+ -
+ -->
+<!DOCTYPE Dashboard PUBLIC "-//MC4J//DTD Dashboard 1.0//EN" "http://mc4j.sourceforge.net/Dashboard_1_0.dtd">
+
+<Dashboard version="1.0" name="Qpid Queue Statistics Graph">
+
+ <Description>This dashboard shows the statistics of a Qpid Queue</Description>
+
+ <DashboardMatch type="Bean">
+ <BeanMatch id="QueueNode" type="Single">
+ <Condition type="BeanObjectNameCondition" filter="type=Queue"/>
+ </BeanMatch>
+ </DashboardMatch>
+
+ <LayoutManager type="java.awt.BorderLayout"/>
+ <Content>
+
+ <!-- *** The header section displays title and a refresh control *** -->
+ <Component type="javax.swing.JPanel">
+ <Constraint type="BorderConstraints" direction="NORTH"/>
+ <LayoutManager type="java.awt.BorderLayout"/>
+ <Border type="javax.swing.border.EmptyBorder" top="(Literal)2" left="(Literal)5" bottom="(Literal)2" right="(Literal)5"/>
+ <Content>
+ <Component type="javax.swing.JPanel">
+ <Constraint type="BorderConstraints" direction="CENTER"/>
+ <LayoutManager type="java.awt.BorderLayout"/>
+ <Content>
+ <Component type="javax.swing.JLabel" id="titleLable">
+ <Constraint type="BorderConstraints" direction="CENTER"/>
+ <Attribute name="text" value="DashboardName"/>
+ <Attribute name="font" value="(Literal)SansSerif bold 20"/>
+ <Attribute name="foreground" value="(Literal)0x666666"/>
+ </Component>
+ <Component type="javax.swing.JTextArea">
+ <Constraint type="BorderConstraints" direction="SOUTH"/>
+ <Attribute name="text" value="DashboardDescription"/>
+ <Attribute name="font" value="(Literal)DialogInput bold 14"/>
+ <Attribute name="opaque" value="(Literal)false"/>
+ <Attribute name="editable" value="(Literal)false"/>
+ </Component>
+ </Content>
+ </Component>
+ </Content>
+ </Component>
+
+
+ <!-- *** Scroll pane of info *** -->
+ <Component type="javax.swing.JScrollPane">
+ <Attribute name="background" value="(Literal)0xFFFFFF"/>
+ <Content>
+ <Component type="javax.swing.JPanel">
+ <Attribute name="background" value="(Literal)0xFFFFFF"/>
+ <Constraint type="BorderConstraints" direction="CENTER"/>
+ <Attribute name="preferredSize" value="100,100"/>
+ <LayoutManager type="java.awt.BoxLayout" axis="Y_AXIS"/>
+ <Content>
+
+ <Component type="org.mc4j.console.swing.SectionHolder">
+ <Attribute name="title" value="(Literal)Queue Depth"/>
+ <Attribute name="background" value="(Literal)0xFFFFFF"/>
+ <LayoutManager type="java.awt.GridLayout" rows="1" cols="1"/>
+ <Content>
+ <Component type="org.mc4j.console.dashboard.components.NumericAttributeGraph">
+ <Attribute name="beanNode" value="QueueNode"/>
+
+ <Attribute name="preferredSize" value="(Literal)400,150"/>
+ <Attribute name="attributeName" value="(Literal)MessageCount"/>
+ </Component>
+ </Content>
+ </Component>
+
+ <Component type="org.mc4j.console.dashboard.components.FillerComponent">
+ <Attribute name="type" value="(Literal)VERTICAL_GLUE_SHAPE"/>
+ </Component>
+ </Content>
+
+ </Component>
+ </Content>
+ </Component>
+
+
+ </Content>
+</Dashboard>
diff --git a/java/management/webapp/META-INF/context.xml b/java/management/webapp/META-INF/context.xml
new file mode 100644
index 0000000000..1d3d5683b9
--- /dev/null
+++ b/java/management/webapp/META-INF/context.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ -
+ - Copyright (c) 2006 The Apache Software Foundation
+ -
+ - Licensed under the Apache License, Version 2.0 (the "License");
+ - you may not use this file except in compliance with the License.
+ - You may obtain a copy of the License at
+ -
+ - http://www.apache.org/licenses/LICENSE-2.0
+ -
+ - Unless required by applicable law or agreed to in writing, software
+ - distributed under the License is distributed on an "AS IS" BASIS,
+ - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ - See the License for the specific language governing permissions and
+ - limitations under the License.
+ -
+ -->
+<Context path="/">
+</Context>
diff --git a/java/management/webapp/WEB-INF/web.xml b/java/management/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000000..db467779bf
--- /dev/null
+++ b/java/management/webapp/WEB-INF/web.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ -
+ - Copyright (c) 2006 The Apache Software Foundation
+ -
+ - Licensed under the Apache License, Version 2.0 (the "License");
+ - you may not use this file except in compliance with the License.
+ - You may obtain a copy of the License at
+ -
+ - http://www.apache.org/licenses/LICENSE-2.0
+ -
+ - Unless required by applicable law or agreed to in writing, software
+ - distributed under the License is distributed on an "AS IS" BASIS,
+ - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ - See the License for the specific language governing permissions and
+ - limitations under the License.
+ -
+ -->
+
+<web-app version="2.4"
+ xmlns="http://java.sun.com/xml/ns/j2ee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" >
+</web-app>