git-svn-id: https://svn.apache.org/repos/asf/incubator/felix/trunk@423855 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/pom.xml b/org.apache.felix.mosgi.jmx.httpconnector/pom.xml
new file mode 100644
index 0000000..68fcf51
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/pom.xml
@@ -0,0 +1,68 @@
+<project>
+ <parent>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>felix</artifactId>
+ <version>0.8.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <packaging>osgi-bundle</packaging>
+ <name>MOSGi JMX httpconnector</name>
+ <artifactId>org.apache.felix.mosgi.jmx.httpconnector</artifactId>
+ <dependencies>
+ <dependency>
+ <groupId>${pom.groupId}</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ <version>${pom.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${pom.groupId}</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>${pom.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${pom.groupId}</groupId>
+ <artifactId>org.apache.felix.framework</artifactId>
+ <version>${pom.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${pom.groupId}</groupId>
+ <artifactId>org.apache.felix.mosgi.jmx.agent</artifactId>
+ <version>${pom.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix.plugins</groupId>
+ <artifactId>maven-osgi-plugin</artifactId>
+ <version>${pom.version}</version>
+ <extensions>true</extensions>
+ <configuration>
+ <osgiManifest>
+ <bundleName>MOSGi JMX-MX4J http connector</bundleName>
+ <bundleDescription>MOSGi JMX-MX4J http connector</bundleDescription>
+ <bundleActivator>auto-detect</bundleActivator>
+ <bundleDocUrl>http://oscar-osgi.sf.net/obr2/${pom.artifactId}/</bundleDocUrl>
+ <bundleUrl>http://oscar-osgi.sf.net/obr2/${pom.artifactId}/${pom.artifactId}-${pom.version}.jar</bundleUrl>
+ <bundleSource>http://oscar-osgi.sf.net/obr2/${pom.artifactId}/${pom.artifactId}-${pom.version}-src.jar</bundleSource>
+ <bundleSymbolicName>${pom.artifactId}</bundleSymbolicName>
+ <importPackage>
+ org.osgi.service.log;specification-version="1.0.0",
+ org.osgi.framework;specification-version="1.0.0",
+ javax.management;specification-version="1.0.0",
+ org.w3c.dom;specification-version="1.0.0",
+ javax.xml.parsers;specification-version="1.0.0",
+ javax.xml.transform;specification-version="1.0.0",
+ javax.xml.transform.stream;specification-version="1.0.0",
+ javax.xml.transform.dom;specification-version="1.0.0"
+ </importPackage>
+ </osgiManifest>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/HttpConnectorActivator.java b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/HttpConnectorActivator.java
new file mode 100644
index 0000000..2da4556
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/HttpConnectorActivator.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2005 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.felix.mosgi.jmx.httpconnector;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.BundleException;
+
+import org.osgi.service.log.LogService;
+
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+
+import org.apache.felix.mosgi.jmx.httpconnector.mx4j.tools.adaptor.http.HttpAdaptor;
+import org.apache.felix.mosgi.jmx.httpconnector.mx4j.tools.adaptor.http.XSLTProcessor;
+
+
+public class HttpConnectorActivator implements BundleActivator{
+ public static BundleContext bc;
+ private HttpAdaptor http;
+ private ObjectName httpName;
+ private ObjectName processorName;
+ private String version=null;
+
+ public void start(BundleContext bc) throws Exception{
+ this.version=(String)bc.getBundle().getHeaders().get(Constants.BUNDLE_VERSION);
+ ServiceReference sr = bc.getServiceReference(javax.management.MBeanServer.class.getName());
+ if (sr!=null){
+ HttpConnectorActivator.bc=bc;
+
+ HttpConnectorActivator.log(LogService.LOG_INFO, "Starting JMX Http Connector "+version,null);
+ MBeanServer server= (MBeanServer)bc.getService(sr);
+
+ String httpPort = bc.getProperty("insa.jmx.httpconnector.port");
+ if (httpPort==null){
+ httpPort="8080";
+ }
+
+ httpName = new ObjectName("HtmlAdaptor:name=HttpAdaptor,port=" + httpPort);
+ http = new HttpAdaptor();
+
+ http.setPort((new Integer(httpPort)).intValue());
+ http.setHost("0.0.0.0"); //For external access
+
+ processorName = new ObjectName("HtmlAdaptor:name=XSLTProcessor");
+ XSLTProcessor processor=new XSLTProcessor();
+
+ server.registerMBean(processor, processorName);
+ server.registerMBean(http, httpName);
+
+ http.setProcessorName(processorName);
+ http.start();
+ HttpConnectorActivator.log(LogService.LOG_INFO, "Started JMX Http Connector "+version,null);
+ }else {
+ throw new BundleException("No JMX Agent found");
+ }
+ }
+
+ public void stop(BundleContext bc) throws Exception {
+ HttpConnectorActivator.log(LogService.LOG_INFO, "Stopping JMX Http connector "+version,null);
+ this.http.stop();
+ ServiceReference sr = bc.getServiceReference(javax.management.MBeanServer.class.getName());
+ if (sr!=null){
+ MBeanServer server= (MBeanServer)bc.getService(sr);
+ server.unregisterMBean(processorName);
+ server.unregisterMBean(httpName);
+ }
+ HttpConnectorActivator.log(LogService.LOG_INFO, "JMX Http Connector stopped "+version,null);
+ HttpConnectorActivator.bc=null;
+ }
+
+ private static void log(int prio, String message, Throwable t){
+ if (HttpConnectorActivator.bc!=null){
+ ServiceReference logSR=HttpConnectorActivator.bc.getServiceReference(LogService.class.getName());
+ if (logSR!=null){
+ ((LogService)HttpConnectorActivator.bc.getService(logSR)).log(prio, message, t);
+ }else{
+ System.out.println("No Log Service");
+ }
+ }else{
+ System.out.println(org.apache.felix.mosgi.jmx.httpconnector.HttpConnectorActivator.class.getName()+": No bundleContext");
+ }
+ }
+
+}
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/AdaptorServerSocketFactory.java b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/AdaptorServerSocketFactory.java
new file mode 100644
index 0000000..945d69c
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/AdaptorServerSocketFactory.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) MX4J.
+ * All rights reserved.
+ *
+ * This software is distributed under the terms of the MX4J License version 1.0.
+ * See the terms of the MX4J License in the documentation provided with this software.
+ */
+/*
+ * Copyright 2005 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.felix.mosgi.jmx.httpconnector.mx4j.tools.adaptor;
+
+import java.net.ServerSocket;
+import java.io.IOException;
+
+/**
+ * The ServerSocket factory interface. <p>
+ * It allows to create ServerSocket for JMX adaptors
+ *
+ * @author <a href="mailto:tibu@users.sourceforge.net">Carlos Quiroz</a>
+ * @author <a href="mailto:biorn_steedom@users.sourceforge.net">Simone Bordet</a>
+ * @version $Revision: 1.1.1.1 $
+ */
+public interface AdaptorServerSocketFactory
+{
+ /**
+ * Creates a new ServerSocket on the specified port, with the specified backlog and on the given host. <br>
+ * The last parameter is useful for hosts with more than one IP address.
+ */
+ public ServerSocket createServerSocket(int port, int backlog, String host) throws IOException;
+}
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/PlainAdaptorServerSocketFactory.java b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/PlainAdaptorServerSocketFactory.java
new file mode 100644
index 0000000..705c608
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/PlainAdaptorServerSocketFactory.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) MX4J.
+ * All rights reserved.
+ *
+ * This software is distributed under the terms of the MX4J License version 1.0.
+ * See the terms of the MX4J License in the documentation provided with this software.
+ */
+/*
+ * Copyright 2005 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.felix.mosgi.jmx.httpconnector.mx4j.tools.adaptor;
+
+import java.net.ServerSocket;
+import java.net.InetAddress;
+import java.io.IOException;
+
+/**
+ * Creates plain ServerSockets.
+ *
+ * @author <a href="mailto:tibu@users.sourceforge.net">Carlos Quiroz</a>
+ * @author <a href="mailto:biorn_steedom@users.sourceforge.net">Simone Bordet</a>
+ * @version $Revision: 1.1.1.1 $
+ */
+public class PlainAdaptorServerSocketFactory implements AdaptorServerSocketFactory
+{
+ public ServerSocket createServerSocket(int port, int backlog, String host) throws IOException
+ {
+ return new ServerSocket(port, backlog, InetAddress.getByName(host));
+ }
+}
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/CommandProcessorUtil.java b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/CommandProcessorUtil.java
new file mode 100644
index 0000000..41871a8
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/CommandProcessorUtil.java
@@ -0,0 +1,350 @@
+/*
+ * Copyright (C) MX4J.
+ * All rights reserved.
+ *
+ * This software is distributed under the terms of the MX4J License version 1.0.
+ * See the terms of the MX4J License in the documentation provided with this software.
+ */
+/*
+ * Copyright 2005 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.felix.mosgi.jmx.httpconnector.mx4j.tools.adaptor.http;
+
+import java.lang.reflect.Constructor;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.util.Comparator;
+import java.util.Date;
+
+import javax.management.ObjectInstance;
+
+//SFR import javax.management.openmbean.OpenType;
+
+/**
+ * Contains utilities common to CommandProcessor objects
+ *
+ * @author <a href="mailto:tibu@users.sourceforge.net">Carlos Quiroz</a>
+ * @author <a href="mailto:l.dobrev@lsnsoft.com">Lachezar Dobrev</a>
+ * @version $Revision: 1.2 $
+ */
+public class CommandProcessorUtil
+{
+ // contains all date and date time format instances
+ // for the current locale
+ private static final DateFormat[] allFormats = new DateFormat[] {
+ DateFormat.getDateInstance(),
+ DateFormat.getTimeInstance(),
+ DateFormat.getDateTimeInstance(),
+ // first pure date format
+ DateFormat.getDateInstance(DateFormat.SHORT),
+ DateFormat.getDateInstance(DateFormat.MEDIUM),
+ DateFormat.getDateInstance(DateFormat.LONG),
+ DateFormat.getDateInstance(DateFormat.FULL),
+ // pure time format
+ DateFormat.getTimeInstance(DateFormat.SHORT),
+ DateFormat.getTimeInstance(DateFormat.MEDIUM),
+ DateFormat.getTimeInstance(DateFormat.LONG),
+ DateFormat.getTimeInstance(DateFormat.FULL),
+ // combinations
+ DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT),
+ DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM),
+ DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.LONG),
+ DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.FULL),
+
+ DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.SHORT),
+ DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM),
+ DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.LONG),
+ DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.FULL),
+
+ DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.SHORT),
+ DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.MEDIUM),
+ DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG),
+ DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.FULL),
+
+ DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.SHORT),
+ DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.MEDIUM),
+ DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.LONG),
+ DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL)
+ };
+
+ private static final String[] BASIC_TYPES = new String[] {
+ "int", "long", "short", "byte", "float", "double", "boolean"
+ };
+
+ /**
+ * Creates a parameter object of the given type containing a given value.
+ * If the type is unknown null is returned
+ *
+ * @param parameterType Indicates the type of the parameter, for instance java.lang.String
+ * @param parameterValue The value of the parameter as a String
+ * @return an object of parameterType type and value parameterValue or null if the type is unknown
+ * @exception Thrown in case there is a data conversion error
+ */
+ protected static Object createParameterValue(String parameterType, String parameterValue)
+ throws Exception
+ {
+ if (parameterType.equals("java.lang.String"))
+ {
+ return parameterValue;
+ }
+ else if (parameterType.equals("java.lang.Integer") || parameterType.equals("int"))
+ {
+ return Integer.valueOf(parameterValue);
+ }
+ else if (parameterType.equals("java.lang.Long") || parameterType.equals("long"))
+ {
+ return Long.valueOf(parameterValue);
+ }
+ else if (parameterType.equals("java.lang.Short") || parameterType.equals("short"))
+ {
+ return Short.valueOf(parameterValue);
+ }
+ else if (parameterType.equals("java.lang.Byte") || parameterType.equals("byte"))
+ {
+ return Byte.valueOf(parameterValue);
+ }
+ else if (parameterType.equals("java.lang.Float") || parameterType.equals("float"))
+ {
+ return Float.valueOf(parameterValue);
+ }
+ // changed java.lang.dobule to java.lang.double bronwen
+ else if (parameterType.equals("java.lang.Double") || parameterType.equals("double"))
+ {
+ return Double.valueOf(parameterValue);
+ }
+ else if (parameterType.equals("java.lang.Boolean") || parameterType.equals("boolean"))
+ {
+ return Boolean.valueOf(parameterValue);
+ }
+ else if (parameterType.equals("java.lang.Void"))
+ {
+ return Void.TYPE;
+ }
+ else if (parameterType.equals("java.util.Date"))
+ {
+ // this is tricky since Date can be written in many formats
+ // will use the Date format with current locale and several
+ // different formats
+ Date value = null;
+ for (int i=0;i<allFormats.length;i++) {
+ synchronized (allFormats[i]) {
+ try {
+ System.out.println(parameterValue + " " + allFormats[i]);
+ value = allFormats[i].parse(parameterValue);
+ // if succeful then break
+ break;
+ } catch (ParseException e) {
+ // ignore, the format wasn't appropriate
+ }
+ }
+ }
+ if (value == null) {
+ throw new ParseException("Not possible to parse", 0);
+ }
+ return value;
+ }
+ else if (parameterType.equals("java.lang.Number"))
+ {
+ Number value = null;
+ // try first as a long
+ try
+ {
+ value = Long.valueOf(parameterValue);
+ }
+ catch (NumberFormatException e)
+ {
+ }
+ // if not try as a double
+ if (value == null) {
+ try {
+ value = Double.valueOf(parameterValue);
+ }
+ catch (NumberFormatException e)
+ {
+ }
+ }
+ if (value == null) {
+ throw new NumberFormatException("Not possible to parse");
+ }
+ return value;
+ }
+ if (parameterType.equals("java.lang.Character") || parameterType.equals("char"))
+ {
+ if ( parameterValue.length() > 0 )
+ {
+ return new Character(parameterValue.charAt(0));
+ }
+ else
+ {
+ throw new NumberFormatException("Can not initialize Character from empty String");
+ }
+ }
+ // tests whether the classes have a single string parameter value
+ // constructor. That covers the classes
+ // javax.management.ObjectName
+ // java.math.BigInteger
+ // java.math.BigDecimal
+
+ Class cls = null;
+ java.lang.reflect.Constructor ctor = null;
+ try
+ {
+ cls = Class.forName(parameterType);
+ ctor = cls.getConstructor(new Class[] {String.class});
+ return ctor.newInstance(new Object[] {parameterValue});
+ }
+ catch (ClassNotFoundException cnfe)
+ {
+ // Can not find class. Not in our ClassLoader?
+ /** @todo Ask the MBeanServer to instantiate this class??? */
+ throw new IllegalArgumentException("Invalid parameter type: " + parameterType);
+ }
+ catch (NoSuchMethodException nsme)
+ {
+ // No public String constructor.
+ throw new IllegalArgumentException("Invalid parameter type: " + parameterType);
+ }
+ catch (Exception ex)
+ {
+ // Constructor might have thrown an exception?
+ // Security Exception ?
+ // IllegalAccessException? .... etc.
+ // Just rethrow. We can do little here <shrug>
+ /** @todo Log the exception */
+ throw ex;
+ }
+ }
+
+ /**
+ * Checks if the given type is primitive of can be initialized from String.<br>
+ * This is done by trying to load the class and checking if there is a public String
+ * only constructor.
+ *
+ * @param parameterType Indicates the type of the parameter, for instance java.lang.String
+ * @return true if the type is primitive or String initializable
+ * @exception Thrown in case there is a data conversion error
+ */
+
+ protected static boolean canCreateParameterValue(String parameterType)
+ {
+ int count;
+ /*
+ count = OpenType.ALLOWED_CLASSNAMES.length;
+ for (int i=0;i<count;i++)
+ {
+ if (OpenType.ALLOWED_CLASSNAMES[i].equals(parameterType))
+ {
+ return true;
+ }
+ }
+ */
+ count = BASIC_TYPES.length;
+ for (int i=0;i<count;i++)
+ {
+ if (BASIC_TYPES[i].equals(parameterType))
+ {
+ return true;
+ }
+ }
+
+ Class cls = null ;
+ try
+ {
+ cls = Class.forName(parameterType);
+ cls.getConstructor(new Class[] {String.class});
+ // Yes we can load the class and it has a public String constructor.
+ return true;
+ }
+ catch (ClassNotFoundException cnfe)
+ {
+ // Can not find class. Not in our ClassLoader?
+ return false;
+ }
+ catch (NoSuchMethodException nsme)
+ {
+ // No public String constructor.
+ return false;
+ }
+ catch (Exception ex)
+ {
+ // Constructor might have thrown an exception?
+ // Security Exception ?
+ // IllegalAccessException? .... etc.
+ // Just rethrow. We can do little here <shrug>
+ return false;
+ }
+ }
+
+ public static Comparator createObjectNameComparator()
+ {
+ return new ToStringComparator();
+ }
+
+ public static Comparator createObjectInstanceComparator()
+ {
+ return new ObjectInstanceComparator();
+ }
+
+ public static Comparator createConstructorComparator()
+ {
+ return new ConstructorComparator();
+ }
+
+ public static Comparator createClassComparator()
+ {
+ return new ToStringComparator();
+ }
+
+ private static class ToStringComparator implements Comparator {
+ public int compare(Object o1, Object o2) {
+ return o1.toString().compareTo(o2.toString());
+ }
+ }
+
+ private static class ObjectInstanceComparator implements Comparator {
+ private ToStringComparator comp = new ToStringComparator();
+ public int compare(Object o1, Object o2) {
+ ObjectInstance oi1 = (ObjectInstance)o1;
+ ObjectInstance oi2 = (ObjectInstance)o2;
+ return comp.compare(oi1.getObjectName(), oi2.getObjectName());
+ }
+ }
+
+ private static class ConstructorComparator implements Comparator {
+ public int compare(Object o1, Object o2) {
+ Constructor c1 = (Constructor)o1;
+ Constructor c2 = (Constructor)o2;
+ // sort them by the parameter types;
+ Class[] params1 = c1.getParameterTypes();
+ Class[] params2 = c2.getParameterTypes();
+ if (params1.length == params2.length)
+ {
+ for (int i=0;i<params1.length;i++)
+ {
+ if (!params1[i].equals(params2[i])) {
+ return params2[i].toString().compareTo(params1[i].toString());
+ }
+ }
+ return 0;
+ }
+ else
+ {
+ return params1.length - params2.length;
+ }
+ }
+ }
+
+}
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/ConstructorsCommandProcessor.java b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/ConstructorsCommandProcessor.java
new file mode 100644
index 0000000..e3dc2db
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/ConstructorsCommandProcessor.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) MX4J.
+ * All rights reserved.
+ *
+ * This software is distributed under the terms of the MX4J License version 1.0.
+ * See the terms of the MX4J License in the documentation provided with this software.
+ */
+/*
+ * Copyright 2005 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.felix.mosgi.jmx.httpconnector.mx4j.tools.adaptor.http;
+
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.util.Arrays;
+
+import javax.management.JMException;
+import javax.management.loading.DefaultLoaderRepository;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * ConstructorsCommandProcessor, processes a request to query the available
+ * constructors for a classname
+ *
+ * @author <a href="mailto:tibu@users.sourceforge.net">Carlos Quiroz</a>
+ * @author <a href="mailto:l.dobrev@lsnsoft.com">Lachezar Dobrev</a>
+ * @version $Revision: 1.1.1.1 $
+ */
+public class ConstructorsCommandProcessor extends HttpCommandProcessorAdaptor
+{
+ public ConstructorsCommandProcessor()
+ {
+ }
+
+ public Document executeRequest(HttpInputStream in) throws IOException, JMException
+ {
+ Document document = builder.newDocument();
+
+ String classname = in.getVariable("classname");
+ if (classname == null || classname.trim().length() == 0)
+ {
+ return createException(document, "", "classname parameter required");
+ }
+ else
+ {
+ // look class in default classloader
+ Class targetClass = null;
+ try
+ {
+ targetClass = DefaultLoaderRepository.loadClass(classname);
+ }
+ catch (ClassNotFoundException e) {}
+ try
+ {
+ if (targetClass == null)
+ {
+ targetClass = ClassLoader.getSystemClassLoader().loadClass(classname);
+ }
+ }
+ catch (ClassNotFoundException e) {}
+ try
+ {
+ if (targetClass == null)
+ {
+ targetClass = getClass().getClassLoader().loadClass(classname);
+ }
+ }
+ catch (ClassNotFoundException e) {}
+
+ if (targetClass == null) {
+ return createException(document, classname, "class " + classname + " not found");
+ }
+
+ Element root = document.createElement("Class");
+ root.setAttribute("classname", classname);
+ document.appendChild(root);
+ Constructor[] constructors = targetClass.getConstructors();
+ Arrays.sort(constructors, CommandProcessorUtil.createConstructorComparator());
+ for (int i=0;i<constructors.length;i++)
+ {
+ System.out.println("Constructor " + constructors[i]);
+ Element constructor = document.createElement("Constructor");
+ constructor.setAttribute("name", constructors[i].getName());
+ addParameters(constructor, document, constructors[i].getParameterTypes());
+ root.appendChild(constructor);
+ }
+ }
+ return document;
+ }
+
+ protected void addParameters(Element node, Document document, Class[] parameters)
+ {
+ for (int j=0;j<parameters.length;j++)
+ {
+ Element parameter = document.createElement("Parameter");
+ parameter.setAttribute("type", parameters[j].getName());
+ parameter.setAttribute("strinit", String.valueOf(CommandProcessorUtil.canCreateParameterValue(parameters[j].getName())));
+ // add id since order is relevant
+ parameter.setAttribute("id", ""+j);
+ node.appendChild(parameter);
+ }
+ }
+
+ private Document createException(Document document, String classname, String message)
+ {
+ Element exceptionElement = document.createElement("Exception");
+ document.appendChild(exceptionElement);
+ exceptionElement.setAttribute("classname", classname);
+ exceptionElement.setAttribute("errorMsg", message);
+ return document;
+ }
+
+}
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/CreateMBeanCommandProcessor.java b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/CreateMBeanCommandProcessor.java
new file mode 100644
index 0000000..131813d
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/CreateMBeanCommandProcessor.java
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) MX4J.
+ * All rights reserved.
+ *
+ * This software is distributed under the terms of the MX4J License version 1.0.
+ * See the terms of the MX4J License in the documentation provided with this software.
+ */
+/*
+ * Copyright 2005 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.felix.mosgi.jmx.httpconnector.mx4j.tools.adaptor.http;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.management.JMException;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * CreateMBeanCommandProcessor, processes a request for creating and registering
+ * an MBean
+ *
+ * @author <a href="mailto:tibu@users.sourceforge.net">Carlos Quiroz</a>
+ * @version $Revision: 1.1.1.1 $
+ */
+public class CreateMBeanCommandProcessor extends HttpCommandProcessorAdaptor
+{
+
+ /**
+ * Constructs a new CreateMBeanCommandProcessor
+ *
+ */
+ public CreateMBeanCommandProcessor()
+ {
+ }
+
+
+ public Document executeRequest(HttpInputStream in)
+ throws IOException, JMException
+ {
+ Document document = builder.newDocument();
+
+ Element root = document.createElement("MBeanOperation");
+ document.appendChild(root);
+ Element operationElement = document.createElement("Operation");
+ operationElement.setAttribute("name", "create");
+ root.appendChild(operationElement);
+
+ String objectVariable = in.getVariable("objectname");
+ String classVariable = in.getVariable("class");
+ if (objectVariable == null || objectVariable.equals("")
+ || classVariable == null || classVariable.equals(""))
+ {
+ operationElement.setAttribute("result", "error");
+ operationElement.setAttribute("errorMsg", "Incorrect parameters in the request");
+ return document;
+ }
+ operationElement.setAttribute("objectname", objectVariable);
+ List types = new ArrayList();
+ List values = new ArrayList();
+ int i = 0;
+ boolean unmatchedParameters = false;
+ boolean valid = false;
+ do
+ {
+ String parameterType = in.getVariable("type" + i);
+ String parameterValue = in.getVariable("value" + i);
+ valid = (parameterType != null && parameterValue != null);
+ if (valid)
+ {
+ types.add(parameterType);
+ Object value = null;
+ try
+ {
+ value = CommandProcessorUtil.createParameterValue(parameterType, parameterValue);
+ }
+ catch (Exception e)
+ {
+ operationElement.setAttribute("result", "error");
+ operationElement.setAttribute("errorMsg", "Parameter " + i + ": " + parameterValue + " cannot be converted to type " + parameterType);
+ return document;
+ }
+ if (value != null)
+ {
+ values.add(value);
+ }
+ }
+ if (parameterType == null ^ parameterValue == null)
+ {
+ unmatchedParameters = true;
+ break;
+ }
+ i++;
+ } while (valid);
+ if (objectVariable == null || objectVariable.equals(""))
+ {
+ operationElement.setAttribute("result", "error");
+ operationElement.setAttribute("errorMsg", "Incorrect parameters in the request");
+ return document;
+ }
+ if (unmatchedParameters)
+ {
+ operationElement.setAttribute("result", "error");
+ operationElement.setAttribute("errorMsg", "count of parameter types doesn't match count of parameter values");
+ return document;
+ }
+ ObjectName name = null;
+ try
+ {
+ name = new ObjectName(objectVariable);
+ }
+ catch (MalformedObjectNameException e)
+ {
+ operationElement.setAttribute("result", "error");
+ operationElement.setAttribute("errorMsg", "Malformed object name");
+ return document;
+ }
+
+ if (server.isRegistered(name))
+ {
+ operationElement.setAttribute("result", "error");
+ operationElement.setAttribute("errorMsg", "A MBean with name " + name + " is already registered");
+ return document;
+ }
+ else
+ {
+ try
+ {
+ if (types.size() > 0)
+ {
+ Object[] params = values.toArray();
+ String[] signature = new String[types.size()];
+ types.toArray(signature);
+ server.createMBean(classVariable, name, null, params, signature);
+ }
+ else
+ {
+ server.createMBean(classVariable, name, null);
+ }
+ operationElement.setAttribute("result", "success");
+ }
+ catch (Exception e)
+ {
+ operationElement.setAttribute("result", "error");
+ operationElement.setAttribute("errorMsg", e.getMessage());
+ }
+ }
+ return document;
+ }
+
+}
+
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/DefaultProcessor.java b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/DefaultProcessor.java
new file mode 100644
index 0000000..44dfb89
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/DefaultProcessor.java
@@ -0,0 +1,336 @@
+/*
+ * Copyright (C) MX4J.
+ * All rights reserved.
+ *
+ * This software is distributed under the terms of the MX4J License version 1.0.
+ * See the terms of the MX4J License in the documentation provided with this software.
+ */
+/*
+ * Copyright 2005 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.felix.mosgi.jmx.httpconnector.mx4j.tools.adaptor.http;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.log.LogService;
+
+import org.apache.felix.mosgi.jmx.httpconnector.HttpConnectorActivator;
+
+
+/**
+ * DefaultPostProcessor doesn't alter the result, just publising the xml file
+ *
+ * @author <a href="mailto:tibu@users.sourceforge.net">Carlos Quiroz</a>
+ * @version $Revision: 1.1.1.1 $
+ */
+
+public class DefaultProcessor implements ProcessorMBean
+{
+
+ private final static String ENCODING = "UTF-8";
+ private boolean canonical = false;
+ public String getName()
+ {
+ return "Default XML Processor";
+ }
+
+ public void writeResponse(HttpOutputStream out, HttpInputStream in, Document document)
+ throws IOException
+ {
+ out.setCode(HttpConstants.STATUS_OKAY);
+ out.setHeader("Content-Type", "text/xml");
+ out.sendHeaders();
+ print(new PrintWriter(out), document);
+ ByteArrayOutputStream o = new ByteArrayOutputStream();
+ print(new PrintWriter(o), document);
+ DefaultProcessor.log(LogService.LOG_INFO,new String(o.toByteArray()),null);
+ }
+
+ public void writeError(HttpOutputStream out, HttpInputStream in, Exception e)
+ throws IOException
+ {
+ if (e instanceof HttpException)
+ {
+ out.setCode(((HttpException)e).getCode());
+ out.setHeader("Content-Type", "text/xml");
+ out.sendHeaders();
+ print(new PrintWriter(out), ((HttpException)e).getResponseDoc());
+ }
+ }
+
+ public String preProcess(String path)
+ {
+ // The only special case. The root is routed to the the server request
+ if (path.equals("/"))
+ {
+ path = "/server";
+ }
+ return path;
+ }
+
+ public String notFoundElement(String path, HttpOutputStream out, HttpInputStream in)
+ throws IOException, HttpException
+ {
+ // no processing. Unknown elements are not found
+ throw new HttpException(HttpConstants.STATUS_NOT_FOUND, "Path " + path + " not found");
+ }
+
+ // ripped from Xerces samples
+ protected void print(PrintWriter out, Node node)
+ {
+ // is there anything to do?
+ if (node == null)
+ {
+ return;
+ }
+ int type = node.getNodeType();
+ switch (type)
+ {
+ // print document
+ case Node.DOCUMENT_NODE:
+ {
+ if (!canonical)
+ {
+ out.println("<?xml version=\"1.0\" encoding=\"" + ENCODING + "\"?>");
+ }
+ NodeList children = node.getChildNodes();
+ for (int iChild = 0; iChild < children.getLength(); iChild++)
+ {
+ print(out, children.item(iChild));
+ }
+ out.flush();
+ break;
+ }
+ // print element with attributes
+ case Node.ELEMENT_NODE:
+ {
+ out.print('<');
+ out.print(node.getNodeName());
+ Attr attrs[] = sortAttributes(node.getAttributes());
+ for (int i = 0; i < attrs.length; i++)
+ {
+ Attr attr = attrs[i];
+ out.print(' ');
+ out.print(attr.getNodeName());
+ out.print("=\"");
+ out.print(normalize(attr.getNodeValue()));
+ out.print('"');
+ }
+ out.print('>');
+ NodeList children = node.getChildNodes();
+ if (children != null)
+ {
+ int len = children.getLength();
+ for (int i = 0; i < len; i++)
+ {
+ print(out, children.item(i));
+ }
+ }
+ break;
+ }
+ // handle entity reference nodes
+ case Node.ENTITY_REFERENCE_NODE:
+ {
+ if (canonical)
+ {
+ NodeList children = node.getChildNodes();
+ if (children != null)
+ {
+ int len = children.getLength();
+ for (int i = 0; i < len; i++)
+ {
+ print(out, children.item(i));
+ }
+ }
+ }
+ else
+ {
+ out.print('&');
+ out.print(node.getNodeName());
+ out.print(';');
+ }
+ break;
+ }
+ // print cdata sections
+ case Node.CDATA_SECTION_NODE:
+ {
+ if (canonical)
+ {
+ out.print(normalize(node.getNodeValue()));
+ }
+ else
+ {
+ out.print("<![CDATA[");
+ out.print(node.getNodeValue());
+ out.print("]]>");
+ }
+ break;
+ }
+ // print text
+ case Node.TEXT_NODE:
+ {
+ out.print(normalize(node.getNodeValue()));
+ break;
+ }
+ // print processing instruction
+ case Node.PROCESSING_INSTRUCTION_NODE:
+ {
+ out.print("<?");
+ out.print(node.getNodeName());
+ String data = node.getNodeValue();
+ if (data != null && data.length() > 0)
+ {
+ out.print(' ');
+ out.print(data);
+ }
+ out.println("?>");
+ break;
+ }
+ }
+ if (type == Node.ELEMENT_NODE)
+ {
+ out.print("</");
+ out.print(node.getNodeName());
+ out.print('>');
+ }
+ out.flush();
+ }
+ // print(Node)
+
+ /**
+ * Returns a sorted list of attributes.
+ *
+ * @param attrs Description of Parameter
+ * @return Description of the Returned Value
+ * @since
+ */
+
+ protected Attr[] sortAttributes(NamedNodeMap attrs)
+ {
+ int len = (attrs != null) ? attrs.getLength() : 0;
+ Attr array[] = new Attr[len];
+ for (int i = 0; i < len; i++)
+ {
+ array[i] = (Attr)attrs.item(i);
+ }
+ for (int i = 0; i < len - 1; i++)
+ {
+ String name = array[i].getNodeName();
+ int index = i;
+ for (int j = i + 1; j < len; j++)
+ {
+ String curName = array[j].getNodeName();
+ if (curName.compareTo(name) < 0)
+ {
+ name = curName;
+ index = j;
+ }
+ }
+ if (index != i)
+ {
+ Attr temp = array[i];
+ array[i] = array[index];
+ array[index] = temp;
+ }
+ }
+ return (array);
+ }
+
+ /**
+ * Normalizes the given string.
+ *
+ * @param s Description of Parameter
+ * @return Description of the Returned Value
+ * @since
+ */
+
+ protected String normalize(String s)
+ {
+ StringBuffer str = new StringBuffer();
+ int len = (s != null) ? s.length() : 0;
+ for (int i = 0; i < len; i++)
+ {
+ char ch = s.charAt(i);
+ switch (ch)
+ {
+ case '<':
+ {
+ str.append("<");
+ break;
+ }
+ case '>':
+ {
+ str.append(">");
+ break;
+ }
+ case '&':
+ {
+ str.append("&");
+ break;
+ }
+ case '"':
+ {
+ str.append(""");
+ break;
+ }
+ case '\'':
+ {
+ str.append("'");
+ break;
+ }
+ case '\r':
+ case '\n':
+ {
+ if (canonical)
+ {
+ str.append("&#");
+ str.append(Integer.toString(ch));
+ str.append(';');
+ break;
+ }
+ // else, default append char
+ }
+ default:
+ {
+ str.append(ch);
+ }
+ }
+ }
+ return (str.toString());
+ }
+
+ private static void log(int prio, String message, Throwable t){
+ if (HttpConnectorActivator.bc!=null){
+ ServiceReference logSR=HttpConnectorActivator.bc.getServiceReference(LogService.class.getName());
+ if (logSR!=null){
+ ((LogService)HttpConnectorActivator.bc.getService(logSR)).log(prio, message, t);
+ }else{
+ System.out.println("No Log Service");
+ }
+ }else{
+ System.out.println(DefaultProcessor.class.getName()+".log: No bundleContext");
+ }
+ }
+}
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/DeleteMBeanCommandProcessor.java b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/DeleteMBeanCommandProcessor.java
new file mode 100644
index 0000000..7a59391
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/DeleteMBeanCommandProcessor.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) MX4J.
+ * All rights reserved.
+ *
+ * This software is distributed under the terms of the MX4J License version 1.0.
+ * See the terms of the MX4J License in the documentation provided with this software.
+ */
+/*
+ * Copyright 2005 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.felix.mosgi.jmx.httpconnector.mx4j.tools.adaptor.http;
+
+import java.io.IOException;
+
+import javax.management.JMException;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * DeleteMBeanCommandProcessor, processes a request for unregistering an MBean
+ *
+ * @author <a href="mailto:tibu@users.sourceforge.net">Carlos Quiroz</a>
+ * @version $Revision: 1.1.1.1 $
+ */
+public class DeleteMBeanCommandProcessor extends HttpCommandProcessorAdaptor
+{
+
+ public DeleteMBeanCommandProcessor()
+ {
+ }
+
+
+ public Document executeRequest(HttpInputStream in)
+ throws IOException, JMException
+ {
+ Document document = builder.newDocument();
+
+ Element root = document.createElement("MBeanOperation");
+ document.appendChild(root);
+ Element operationElement = document.createElement("Operation");
+ operationElement.setAttribute("operation", "delete");
+ root.appendChild(operationElement);
+
+ String objectVariable = in.getVariable("objectname");
+ operationElement.setAttribute("objectname", objectVariable);
+ if (objectVariable == null || objectVariable.equals(""))
+ {
+ operationElement.setAttribute("result", "error");
+ operationElement.setAttribute("errorMsg", "Incorrect parameters in the request");
+ return document;
+ }
+ ObjectName name = null;
+ try
+ {
+ name = new ObjectName(objectVariable);
+ }
+ catch (MalformedObjectNameException e)
+ {
+ operationElement.setAttribute("result", "error");
+ operationElement.setAttribute("errorMsg", "Malformed object name");
+ return document;
+ }
+
+ if (server.isRegistered(name))
+ {
+ try
+ {
+ server.unregisterMBean(name);
+ operationElement.setAttribute("result", "success");
+ }
+ catch (Exception e)
+ {
+ operationElement.setAttribute("result", "error");
+ operationElement.setAttribute("errorMsg", e.getMessage());
+ }
+ }
+ else
+ {
+ if (name != null)
+ {
+ operationElement.setAttribute("result", "error");
+ operationElement.setAttribute("errorMsg", "MBean " + name + " not registered");
+ }
+ }
+ return document;
+ }
+
+}
+
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/EmptyCommandProcessor.java b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/EmptyCommandProcessor.java
new file mode 100644
index 0000000..9344800
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/EmptyCommandProcessor.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) MX4J.
+ * All rights reserved.
+ *
+ * This software is distributed under the terms of the MX4J License version 1.0.
+ * See the terms of the MX4J License in the documentation provided with this software.
+ */
+/*
+ * Copyright 2005 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.felix.mosgi.jmx.httpconnector.mx4j.tools.adaptor.http;
+
+import java.io.IOException;
+
+import javax.management.JMException;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * EmptyCommandProcessor, returns an empty xml tree
+ *
+ * @author <a href="mailto:tibu@users.sourceforge.net">Carlos Quiroz</a>
+ * @version $Revision: 1.2 $
+ */
+public class EmptyCommandProcessor extends HttpCommandProcessorAdaptor
+{
+
+ /**
+ * Constructs a new EmptyCommandProcessor
+ *
+ */
+ public EmptyCommandProcessor()
+ {
+ }
+
+
+ public Document executeRequest(HttpInputStream in)
+ throws IOException, JMException
+ {
+ Document document = builder.newDocument();
+
+ Element root = document.createElement("empty");
+ document.appendChild(root);
+
+ return document;
+ }
+
+}
+
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/GetAttributeCommandProcessor.java b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/GetAttributeCommandProcessor.java
new file mode 100644
index 0000000..0e6dcda
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/GetAttributeCommandProcessor.java
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) MX4J.
+ * All rights reserved.
+ *
+ * This software is distributed under the terms of the MX4J License version 1.0.
+ * See the terms of the MX4J License in the documentation provided with this software.
+ */
+/*
+ * Copyright 2005 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.felix.mosgi.jmx.httpconnector.mx4j.tools.adaptor.http;
+
+import java.io.IOException;
+import java.lang.reflect.Array;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.management.JMException;
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanInfo;
+import javax.management.ObjectName;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * GetAttributeCommandProcessor, processes a request for getting one attribute
+ * of a specific MBean. It also support some formats for types like Arrays
+ *
+ * @author <a href="mailto:tibu@users.sourceforge.net">Carlos Quiroz</a>
+ * @version $Revision: 1.1.1.1 $
+ */
+public class GetAttributeCommandProcessor extends HttpCommandProcessorAdaptor
+{
+ public GetAttributeCommandProcessor()
+ {
+ }
+
+ public Document executeRequest(HttpInputStream in) throws IOException, JMException
+ {
+ Document document = builder.newDocument();
+
+ String name = in.getVariable("objectname");
+ String attributeVariable = in.getVariable("attribute");
+ String formatVariable = in.getVariable("format");
+ ObjectName objectName = null;
+ MBeanAttributeInfo targetAttribute = null;
+ // special case
+ boolean validMBean = false;
+ if (name != null)
+ {
+ objectName = new ObjectName(name);
+ if (server.isRegistered(objectName))
+ {
+ validMBean = true;
+ }
+ }
+ if (validMBean && attributeVariable != null)
+ {
+ validMBean = false;
+ MBeanInfo info = server.getMBeanInfo(objectName);
+ MBeanAttributeInfo[] attributes = info.getAttributes();
+
+ if (attributes != null)
+ {
+ for (int i=0;i<attributes.length;i++)
+ {
+ if (attributes[i].getName().equals(attributeVariable))
+ {
+ targetAttribute = attributes[i];
+ validMBean = true;
+ break;
+ }
+ }
+ }
+ }
+ if (validMBean)
+ {
+ Element root = document.createElement("MBean");
+ document.appendChild(root);
+
+ root.setAttribute("objectname", objectName.toString());
+ MBeanInfo info = server.getMBeanInfo(objectName);
+ root.setAttribute("classname", info.getClassName());
+ root.setAttribute("description", info.getDescription());
+
+ Element attribute = document.createElement("Attribute");
+ attribute.setAttribute("name", attributeVariable);
+ attribute.setAttribute("classname", targetAttribute.getType());
+ Object attributeValue = server.getAttribute(objectName, attributeVariable);
+ attribute.setAttribute("isnull", (attributeValue==null)?"true":"false");
+ root.appendChild(attribute);
+
+ if ("array".equals(formatVariable) && attributeValue.getClass().isArray())
+ {
+ Element array = document.createElement("Array");
+ array.setAttribute("componentclass", attributeValue.getClass().getComponentType().getName());
+ int length = Array.getLength(attributeValue);
+ array.setAttribute("length", "" + length);
+ for (int i=0;i<length;i++) {
+ Element arrayElement = document.createElement("Element");
+ arrayElement.setAttribute("index", "" + i);
+ if (Array.get(attributeValue, i) != null)
+ {
+ arrayElement.setAttribute("element", Array.get(attributeValue, i).toString());
+ arrayElement.setAttribute("isnull", "false");
+ }
+ else
+ {
+ arrayElement.setAttribute("element", "null");
+ arrayElement.setAttribute("isnull", "true");
+ }
+ array.appendChild(arrayElement);
+ }
+ attribute.appendChild(array);
+ }
+ else if ("collection".equals(formatVariable) && attributeValue instanceof Collection)
+ {
+ Collection collection = (Collection)attributeValue;
+ Element collectionElement = document.createElement("Collection");
+ collectionElement.setAttribute("length", "" + collection.size());
+ Iterator i=collection.iterator();
+ int j=0;
+ while (i.hasNext())
+ {
+ Element collectionEntry = document.createElement("Element");
+ collectionEntry.setAttribute("index", "" + j++);
+ Object obj = i.next();
+ if (obj != null)
+ {
+ collectionEntry.setAttribute("elementclass", obj.getClass().getName());
+ collectionEntry.setAttribute("element", obj.toString());
+ }
+ else
+ {
+ collectionEntry.setAttribute("elementclass", "null");
+ collectionEntry.setAttribute("element", "null");
+ }
+ collectionElement.appendChild(collectionEntry);
+ }
+ attribute.appendChild(collectionElement);
+ }
+ else if ("map".equals(formatVariable) && attributeValue instanceof Map)
+ {
+ Map map = (Map)attributeValue;
+ Element mapElement = document.createElement("Map");
+ mapElement.setAttribute("length", "" + map.size());
+ Iterator i=map.keySet().iterator();
+ int j=0;
+ while (i.hasNext())
+ {
+ Element mapEntry = document.createElement("Element");
+ mapEntry.setAttribute("index", "" + j++);
+ Object key = i.next();
+ Object entry = map.get(key);
+ if (entry != null && key != null)
+ {
+ mapEntry.setAttribute("keyclass", key.getClass().getName());
+ mapEntry.setAttribute("key", key.toString());
+ mapEntry.setAttribute("elementclass", entry.getClass().getName());
+ mapEntry.setAttribute("element", entry.toString());
+ }
+ else
+ {
+ mapEntry.setAttribute("keyclass", "null");
+ mapEntry.setAttribute("key", "null");
+ mapEntry.setAttribute("elementclass", "null");
+ mapEntry.setAttribute("element", "null");
+ }
+ mapElement.appendChild(mapEntry);
+ }
+ attribute.appendChild(mapElement);
+ }
+ else
+ {
+ attribute.setAttribute("value", attributeValue.toString());
+ }
+
+ }
+ return document;
+ }
+}
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/HttpAdaptor.java b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/HttpAdaptor.java
new file mode 100644
index 0000000..41da1bc
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/HttpAdaptor.java
@@ -0,0 +1,1019 @@
+/*
+ * Copyright (C) MX4J.
+ * All rights reserved.
+ *
+ * This software is distributed under the terms of the MX4J License version 1.0.
+ * See the terms of the MX4J License in the documentation provided with this software.
+ */
+/*
+ * Copyright 2005 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.felix.mosgi.jmx.httpconnector.mx4j.tools.adaptor.http;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InterruptedIOException;
+import java.io.OutputStream;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.StringTokenizer;
+import javax.management.JMException;
+import javax.management.MBeanRegistration;
+import javax.management.MBeanServer;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.w3c.dom.Document;
+
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.log.LogService;
+
+import org.apache.felix.mosgi.jmx.httpconnector.mx4j.tools.adaptor.AdaptorServerSocketFactory;
+import org.apache.felix.mosgi.jmx.httpconnector.mx4j.tools.adaptor.PlainAdaptorServerSocketFactory;
+
+import org.apache.felix.mosgi.jmx.agent.mx4j.util.Base64Codec;
+
+import org.apache.felix.mosgi.jmx.httpconnector.HttpConnectorActivator;
+
+/**
+ * HttpAdaptor sets the basic adaptor listening for HTTP requests
+ *
+ * @author <a href="mailto:tibu@users.sourceforge.net">Carlos Quiroz</a>
+ * @version $Revision: 1.1.1.1 $
+ */
+public class HttpAdaptor implements HttpAdaptorMBean, MBeanRegistration
+{
+ private static final String VERSION = "2.0 Beta 1";
+
+ /** Port to listen for connections */
+ private int port = 8080;
+
+ /** Host where to set the server socket */
+ private String host = "localhost";
+
+ /** Target server */
+ private MBeanServer server;
+
+ /** Server socket */
+ private ServerSocket serverSocket;
+
+ /** Indicates whether the server is running */
+ private boolean alive;
+
+ /** Map of commands indexed by the request path */
+ private Map commands = new HashMap();
+
+ /** Target processor */
+ private ProcessorMBean processor = null;
+
+ /** Target processor name */
+ private ObjectName processorName = null;
+
+ /** Default processor */
+ private ProcessorMBean defaultProcessor = new DefaultProcessor();
+
+ private String authenticationMethod = "none";
+
+ // Should be dependant on the server?
+ private String realm="MX4J";
+
+ private Map authorizations = new HashMap();
+
+ private AdaptorServerSocketFactory socketFactory = null;
+
+ private ObjectName factoryName;
+
+ private String processorClass;
+
+ private Date startDate;
+
+ private long requestsCount;
+
+ private String[][] defaultCommandProcessors = {
+ {"server", "mx4j.tools.adaptor.http.ServerCommandProcessor"},
+ {"serverbydomain", "mx4j.tools.adaptor.http.ServerByDomainCommandProcessor"},
+ {"mbean", "mx4j.tools.adaptor.http.MBeanCommandProcessor"},
+ {"setattributes", "mx4j.tools.adaptor.http.SetAttributesCommandProcessor"},
+ {"setattribute", "mx4j.tools.adaptor.http.SetAttributeCommandProcessor"},
+ {"getattribute", "mx4j.tools.adaptor.http.GetAttributeCommandProcessor"},
+ {"delete", "mx4j.tools.adaptor.http.DeleteMBeanCommandProcessor"},
+ {"invoke", "mx4j.tools.adaptor.http.InvokeOperationCommandProcessor"},
+ {"create", "mx4j.tools.adaptor.http.CreateMBeanCommandProcessor"},
+ {"constructors", "mx4j.tools.adaptor.http.ConstructorsCommandProcessor"},
+ {"empty", "mx4j.tools.adaptor.http.EmptyCommandProcessor"}};
+
+// {"relation", "mx4j.tools.adaptor.http.RelationCommandProcessor"},
+
+ private DocumentBuilder builder;
+
+ /**
+ * Default Constructor added so that we can have some additional
+ * constructors as well.
+ */
+ public HttpAdaptor()
+ {
+ }
+
+ /**
+ * Overloaded constructor to allow the port to be set.
+ * The reason this was added was to allow the loading of this adaptor by
+ * the dynamic loading service of the MBean server and have the port set
+ * from a param in the mlet file. Example: (replaced lt & gt symbol with [])
+ * <br>[mlet code="mx4j.tools.adaptor.http.HttpAdaptor"
+ * <br> archive="mx4j.jar"
+ * <br> name="Server:name=HttpAdaptor"]
+ * <br> [arg type="int" value="12345"]
+ * <br>[/mlet]
+ *
+ * <p>This constructor uses the default host or the host must be set later.
+ * @param port The port on which the HttpAdaptor should listen
+ */
+ public HttpAdaptor(int port)
+ {
+ this.port = port;
+ }
+
+
+ /**
+ * Overloaded constructor to allow the host to be set.
+ * The reason this was added was to allow the loading of this adaptor by
+ * the dynamic loading service of the MBean server and have the host set
+ * from a param in the mlet file. Example: (replaced lt & gt symbol with [])
+ * <br>[mlet code="mx4j.tools.adaptor.http.HttpAdaptor"
+ * <br> archive="mx4j.jar"
+ * <br> name="Server:name=HttpAdaptor"]
+ * <br> [arg type="java.lang.String" value="someserver.somehost.com"]
+ * <br>[/mlet]
+ *
+ * <p>This constructor uses the default port or the port must be set later.
+ * @param host The host on which the HttpAdaptor should listen
+ */
+ public HttpAdaptor(String host)
+ {
+ this.host = host;
+ }
+
+
+ /**
+ * Overloaded constructor to allow the port to be set.
+ * The reason this was added was to allow the loading of this adaptor by
+ * the dynamic loading service of the MBean server and have the port set
+ * from a param in the mlet file. Example: (replaced lt & gt symbol with [])
+ * NOTE that the port must come before the host in the arg list of the mlet
+ * <br>[mlet code="mx4j.tools.adaptor.http.HttpAdaptor"
+ * <br> archive="mx4j.jar"
+ * <br> name="Server:name=HttpAdaptor"]
+ * <br> [arg type="int" value="12345"]
+ * <br> [arg type="java.lang.String" value="someserver.somehost.com"]
+ * <br>[/mlet]
+ *
+ * @param port The port on which the HttpAdaptor should listen
+ * @param host The host on which the HttpAdaptor should listen
+ */
+ public HttpAdaptor(int port, String host)
+ {
+ this.port = port;
+ this.host = host;
+ }
+
+
+ /**
+ * Sets the value of the server's port
+ *
+ * @param port the new port's value
+ */
+ public void setPort(int port)
+ {
+ if (alive)
+ {
+ throw new IllegalArgumentException("Not possible to change port with the server running");
+ }
+ this.port = port;
+ }
+
+
+ /**
+ * Returns the port where the server is running on. Default is 8080
+ *
+ * @return HTTPServer's port
+ */
+ public int getPort()
+ {
+ return port;
+ }
+
+
+ /**
+ * Sets the host name where the server will be listening
+ *
+ * @param host Server's host
+ */
+ public void setHost(String host)
+ {
+ if (alive)
+ {
+ throw new IllegalArgumentException("Not possible to change port with the server running");
+ }
+ this.host = host;
+ }
+
+
+ /**
+ * Return the host name the server will be listening to. If null the server
+ * listen at the localhost
+ *
+ * @return the current hostname
+ */
+ public String getHost()
+ {
+ return host;
+ }
+
+
+ /**
+ * Sets the Authentication Method.
+ *
+ * @param method none/basic/digest
+ */
+ public void setAuthenticationMethod(String method) {
+ if (alive)
+ {
+ throw new IllegalArgumentException("Not possible to change authentication method with the server running");
+ }
+ if (method == null || !(method.equals("none") || method.equals("basic") || method.equals("digest")))
+ {
+ throw new IllegalArgumentException("Only accept methods none/basic/digest");
+ }
+ this.authenticationMethod = method;
+ }
+
+
+ /**
+ * Authentication Method
+ *
+ * @return authentication method
+ */
+ public String getAuthenticationMethod()
+ {
+ return authenticationMethod;
+ }
+
+
+ /**
+ * Sets the object which will post process the XML results. The last value set
+ * between the setPostProcessor and setPostProcessorName will be the valid one
+ *
+ * @param processor a Post processor object
+ */
+ public void setProcessor(ProcessorMBean processor)
+ {
+ this.processor = processor;
+ this.processorName = null;
+ }
+
+
+ /**
+ * Sets the classname of the object which will post process the XML results. The adaptor
+ * will try to build the object and use the processor name ObjectName to register it
+ * The class name has to implements mx4j.tools.adaptor.http.ProcessorMBean and be MBean
+ * compliant
+ * @param processorClass a Post processor object
+ */
+ public void setProcessorClass(String processorClass)
+ {
+ this.processorClass = processorClass;
+ }
+
+
+ /**
+ * Sets the object name of the PostProcessor MBean. If ProcessorClass is set the processor
+ * will be created
+ * @param processorName a Post processor object
+ */
+ public void setProcessorNameString(String processorName) throws MalformedObjectNameException
+ {
+ this.processorName = new ObjectName(processorName);
+ }
+
+
+ /**
+ * Sets the object name which will post process the XML result. The last value
+ * set between the setPostProcessor and setPostProcessorName will be the valid
+ * one. The MBean will be verified to be of instance HttpPostProcessor
+ * @param processorName The new processorName value
+ */
+ public void setProcessorName(ObjectName processorName)
+ {
+ this.processor = null;
+ this.processorName = processorName;
+ }
+
+ public ProcessorMBean getProcessor()
+ {
+ return this.processor;
+ }
+
+ public ObjectName getProcessorName()
+ {
+ return this.processorName;
+ }
+
+ /**
+ * Sets the object which create the server sockets
+ *
+ * @param factory the socket factory
+ */
+ public void setSocketFactory(AdaptorServerSocketFactory factory)
+ {
+ this.factoryName = null;
+ this.socketFactory = factory;
+ }
+
+
+ /**
+ * Sets the factory's object name which will create the server sockets
+ *
+ * @param factoryName the socket factory
+ */
+ public void setSocketFactoryName(ObjectName factoryName)
+ {
+ this.socketFactory = null;
+ this.factoryName = factoryName;
+ }
+
+
+ /**
+ * Sets the factory's object name which will create the server sockets
+ *
+ * @param factoryName the socket factory
+ */
+ public void setSocketFactoryNameString(String factoryName) throws MalformedObjectNameException
+ {
+ this.socketFactory = null;
+ this.factoryName = new ObjectName(factoryName);
+ }
+
+
+ /**
+ * Indicates whether the server's running
+ *
+ * @return The active value
+ */
+ public boolean isActive()
+ {
+ return alive;
+ }
+
+
+ /**
+ * Starting date
+ *
+ * @return The date when the server was started
+ */
+ public Date getStartDate()
+ {
+ return startDate;
+ }
+
+
+ /**
+ * Requests count
+ *
+ * @return The total of requests served so far
+ */
+ public long getRequestsCount()
+ {
+ return requestsCount;
+ }
+
+
+ /**
+ * Gets the HttpAdaptor version
+ *
+ * @return HttpAdaptor's version
+ */
+ public String getVersion()
+ {
+ return VERSION;
+ }
+
+
+ /**
+ * Adds a command processor object
+ */
+ public void addCommandProcessor(String path, HttpCommandProcessor processor)
+ {
+ commands.put(path, processor);
+ if (alive)
+ {
+ processor.setMBeanServer(server);
+ processor.setDocumentBuilder(builder);
+ }
+ }
+
+
+ /**
+ * Adds a command processor object by class
+ */
+ public void addCommandProcessor(String path, String processorClass)
+ {
+ try
+ {
+ HttpCommandProcessor processor = (HttpCommandProcessor)Class.forName(processorClass).newInstance();
+ addCommandProcessor(path, processor);
+ }
+ catch (Exception e)
+ {
+ HttpAdaptor.log(LogService.LOG_ERROR,
+ "Exception creating Command Processor of class " + processorClass,
+ e);
+ }
+ }
+
+
+ /**
+ * Removes a command processor object by class
+ */
+ public void removeCommandProcessor(String path)
+ {
+ if (commands.containsKey(path))
+ {
+ commands.remove(path);
+ }
+ }
+
+
+ /**
+ * Starts the server
+ */
+ public void start()
+ throws IOException
+ {
+
+ if (server != null)
+ {
+ serverSocket = createServerSocket();
+
+ if (serverSocket == null)
+ {
+ HttpAdaptor.log(LogService.LOG_ERROR, "Server socket is null", null);
+ return;
+ }
+
+ if (processorClass != null && processorName != null)
+ {
+ HttpAdaptor.log(LogService.LOG_INFO,"Building processor class of type " + processorClass + " and name " + processorName, null);
+ try {
+ server.createMBean(processorClass, processorName, null);
+ } catch (JMException e) {
+ HttpAdaptor.log(LogService.LOG_INFO, "Exception creating processor class", e);
+ }
+ }
+
+ Iterator i = commands.values().iterator();
+ while (i.hasNext())
+ {
+ HttpCommandProcessor processor = (HttpCommandProcessor)i.next();
+ processor.setMBeanServer(server);
+ processor.setDocumentBuilder(builder);
+ }
+
+ HttpAdaptor.log(LogService.LOG_INFO, "HttpAdaptor server listening on port " + port, null);
+ alive = true;
+ Thread serverThread = new Thread(
+ new Runnable() {
+ public void run() {
+ HttpAdaptor.log(LogService.LOG_INFO, "HttpAdaptor version " + VERSION + " started",null);
+
+ startDate = new Date();
+ requestsCount = 0;
+
+ while (alive)
+ {
+ try
+ {
+ Socket client = null;
+ client = serverSocket.accept();
+ if (!alive)
+ {
+ break;
+ }
+ requestsCount++;
+ new HttpClient(client).start();
+ }
+ catch (InterruptedIOException e)
+ {
+ continue;
+ }
+ catch (IOException e)
+ {
+ continue;
+ }
+ catch (Exception e)
+ {
+ HttpAdaptor.log(LogService.LOG_WARNING, "Exception during request processing", e);
+ continue;
+ }
+ catch (Error e)
+ {
+ HttpAdaptor.log(LogService.LOG_ERROR, "Error during request processing", e);
+ continue;
+ }
+ }
+ try {
+ serverSocket.close();
+ } catch (IOException e) {
+ HttpAdaptor.log(LogService.LOG_WARNING, "Exception closing the server", e);
+ }
+ serverSocket = null;
+ alive = false;
+ HttpAdaptor.log(LogService.LOG_INFO, "Server stopped", null);
+ }
+ });
+ serverThread.start();
+ }
+ else
+ {
+ HttpAdaptor.log(LogService.LOG_INFO,"Start failed, no server target server has been set",null);
+ }
+ }
+
+
+ /**
+ * Restarts the server. Useful when changing the Server parameters
+ *
+ * @deprecated as of RC 1
+ */
+ public void restart()
+ throws IOException
+ {
+ stop();
+ start();
+ }
+
+
+ /**
+ * Stops the HTTP daemon
+ */
+ public void stop()
+ {
+ try
+ {
+ if (alive)
+ {
+ alive = false;
+ // force the close with a socket call
+ new Socket(host, port);
+ }
+ }
+ catch (IOException e)
+ {
+ HttpAdaptor.log(LogService.LOG_WARNING,e.getMessage(),e);
+ }
+ try {
+ if (serverSocket != null)
+ {
+ serverSocket.close();
+ }
+ }
+ catch (IOException e)
+ {
+ HttpAdaptor.log(LogService.LOG_WARNING,e.getMessage(),e);
+ }
+ }
+
+
+ /**
+ * Adds an authorization pair as username/password
+ */
+ public void addAuthorization(String username, String password)
+ {
+ if (username == null || password == null)
+ {
+ throw new IllegalArgumentException("username and passwords cannot be null");
+ }
+ authorizations.put(username, password);
+ }
+
+
+ /**
+ * Gathers some basic data
+ */
+ public ObjectName preRegister(MBeanServer server, ObjectName name)
+ throws java.lang.Exception
+ {
+ this.server = server;
+ buildCommands();
+ return name;
+ }
+
+
+ public void postRegister(Boolean registrationDone) { }
+
+
+ public void preDeregister()
+ throws java.lang.Exception
+ {
+ // stop the server
+ stop();
+ }
+
+ public void postDeregister() { }
+
+ private ServerSocket createServerSocket() throws IOException
+ {
+ if (socketFactory == null)
+ {
+ if (factoryName == null)
+ {
+ socketFactory = new PlainAdaptorServerSocketFactory();
+ return socketFactory.createServerSocket(port, 50, host);
+ }
+ else
+ {
+ try
+ {
+ return (ServerSocket)server.invoke(factoryName, "createServerSocket", new Object[] {new Integer(port), new Integer(50), host}, new String[] {"int", "int", "java.lang.String"});
+ }
+ catch (Exception x)
+ {
+ HttpAdaptor.log(LogService.LOG_ERROR,"Exception invoking AdaptorServerSocketFactory via MBeanServer", x);
+ }
+ }
+ }
+ else
+ {
+ return socketFactory.createServerSocket(port, 50, host);
+ }
+
+ return null;
+ }
+
+
+ private boolean isUsernameValid(String username, String password)
+ {
+ if (authorizations.containsKey(username))
+ {
+ return password.equals(authorizations.get(username));
+ }
+ return false;
+ }
+
+
+ protected HttpCommandProcessor getProcessor(String path)
+ {
+ return (HttpCommandProcessor)commands.get(path);
+ }
+
+
+ /**
+ * Build the commands
+ */
+ protected void buildCommands()
+ {
+ try
+ {
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ builder = factory.newDocumentBuilder();
+ for (int i=0;i<defaultCommandProcessors.length;i++)
+ {
+ try
+ {
+ HttpCommandProcessor processor = (HttpCommandProcessor)Class.forName(defaultCommandProcessors[i][1]).newInstance();
+ commands.put(defaultCommandProcessors[i][0], processor);
+ } catch (Exception e) {
+ HttpAdaptor.log(LogService.LOG_WARNING,"Exception building command procesor", e);
+ }
+ }
+ }
+ catch (ParserConfigurationException e)
+ {
+ HttpAdaptor.log(LogService.LOG_ERROR,"Exception building the Document Factories", e);
+ }
+ }
+
+
+ protected void postProcess(HttpOutputStream out, HttpInputStream in, Document document)
+ throws IOException, JMException
+ {
+ boolean processed = false;
+ // inefficient but handles modifications at runtime
+ if (processorName != null)
+ {
+ if (server.isRegistered(processorName) &&
+ server.isInstanceOf(processorName, "mx4j.tools.adaptor.http.ProcessorMBean"))
+ {
+ server.invoke(processorName,
+ "writeResponse",
+ new Object[]{out, in, document},
+ new String[]{"mx4j.tools.adaptor.http.HttpOutputStream", "mx4j.tools.adaptor.http.HttpInputStream", "org.w3c.dom.Document"});
+ processed = true;
+ }
+ else
+ {
+ HttpAdaptor.log(LogService.LOG_DEBUG,processorName + " not found",null);
+ }
+ }
+ if (!processed && processor != null)
+ {
+ processor.writeResponse(out, in, document);
+ processed = true;
+ }
+ if (!processed)
+ {
+ defaultProcessor.writeResponse(out, in, document);
+ }
+ }
+
+
+ protected void findUnknownElement(String path, HttpOutputStream out, HttpInputStream in)
+ throws IOException, JMException
+ {
+ boolean processed = false;
+ // inefficient but handles modifications at runtime
+ if (processorName != null)
+ {
+ if (server.isRegistered(processorName) &&
+ server.isInstanceOf(processorName, "mx4j.tools.adaptor.http.ProcessorMBean"))
+ {
+ server.invoke(processorName,
+ "notFoundElement",
+ new Object[]{path, out, in},
+ new String[]{"java.lang.String", "mx4j.tools.adaptor.http.HttpOutputStream", "mx4j.tools.adaptor.http.HttpInputStream"});
+ processed = true;
+ }
+ else
+ {
+ HttpAdaptor.log(LogService.LOG_DEBUG,processorName + " not found",null);
+ }
+ }
+ if (!processed && processor != null)
+ {
+ processor.notFoundElement(path, out, in);
+ processed = true;
+ }
+ if (!processed)
+ {
+ defaultProcessor.notFoundElement(path, out, in);
+ }
+ }
+
+
+ protected String preProcess(String path)
+ throws IOException, JMException
+ {
+ boolean processed = false;
+ // inefficient but handles modifications at runtime
+ if (processorName != null)
+ {
+ HttpAdaptor. log(LogService.LOG_DEBUG,"Preprocess using " + processorName,null);
+ if (server.isRegistered(processorName) &&
+ server.isInstanceOf(processorName, "mx4j.tools.adaptor.http.ProcessorMBean"))
+ {
+ HttpAdaptor.log(LogService.LOG_DEBUG,"Preprocessing",null);
+ path = (String)server.invoke(processorName,
+ "preProcess",
+ new Object[]{path},
+ new String[]{"java.lang.String"});
+ processed = true;
+ }
+ else
+ {
+ HttpAdaptor.log(LogService.LOG_DEBUG,processorName + " not found",null);
+ }
+ }
+ if (!processed && processor != null)
+ {
+ path = processor.preProcess(path);
+ processed = true;
+ }
+ if (!processed)
+ {
+ path = defaultProcessor.preProcess(path);
+ }
+ return path;
+ }
+
+
+ protected void postProcess(HttpOutputStream out, HttpInputStream in, Exception e)
+ throws IOException, JMException
+ {
+ boolean processed = false;
+ // inefficient but handles modifications at runtime
+ if (processorName != null)
+ {
+ if (server.isRegistered(processorName) &&
+ server.isInstanceOf(processorName, "mx4j.tools.adaptor.http.ProcessorMBean"))
+ {
+ server.invoke(processorName,
+ "writeError",
+ new Object[]{out, in, e},
+ new String[]{"mx4j.tools.adaptor.http.HttpOutputStream", "mx4j.tools.adaptor.http.HttpInputStream", "java.lang.Exception"});
+ processed = true;
+ }
+ else
+ {
+ HttpAdaptor.log(LogService.LOG_DEBUG,processorName + " not found",null);
+ }
+ }
+ if (!processed && processor != null)
+ {
+ processor.writeError(out, in, e);
+ processed = true;
+ }
+ if (!processed)
+ {
+ defaultProcessor.writeError(out, in, e);
+ }
+ }
+
+
+ private class HttpClient extends Thread
+ {
+ private Socket client;
+
+
+ HttpClient(Socket client)
+ {
+ this.client = client;
+ }
+
+ public boolean isValid(String authorizationString) {
+ if (authenticationMethod.startsWith("basic"))
+ {
+ authorizationString = authorizationString.substring(5,authorizationString.length());
+ String decodeString = new String(Base64Codec.decodeBase64(authorizationString.getBytes()));
+ if (decodeString.indexOf(":")>0)
+ {
+ try
+ {
+ StringTokenizer tokens = new StringTokenizer(decodeString, ":");
+ String username = tokens.nextToken();
+ String password = tokens.nextToken();
+ return isUsernameValid(username, password);
+ }
+ catch (Exception e)
+ {
+ return false;
+ }
+ }
+ }
+ return false;
+ }
+
+
+ private boolean handleAuthentication(HttpInputStream in, HttpOutputStream out) throws IOException {
+ if (authenticationMethod.equals("basic"))
+ {
+ String result = in.getHeader("authorization");
+ if (result != null)
+ {
+ if (isValid(result))
+ {
+ return true;
+ }
+ throw new HttpException(HttpConstants.STATUS_FORBIDDEN, "Authentication failed");
+ }
+
+ out.setCode(HttpConstants.STATUS_AUTHENTICATE);
+ out.setHeader("WWW-Authenticate", "Basic realm=\"" + realm + "\"");
+ out.sendHeaders();
+ out.flush();
+ return false;
+ }
+ if (authenticationMethod.equals("digest"))
+ {
+ // not implemented
+ }
+ return true;
+ }
+
+
+ public void run()
+ {
+ HttpInputStream httpIn = null;
+ HttpOutputStream httpOut = null;
+ try
+ {
+ // get input streams
+ InputStream in = client.getInputStream();
+ httpIn = new HttpInputStream(in);
+ httpIn.readRequest();
+
+ // Find a suitable command processor
+ String path = httpIn.getPath();
+ String queryString = httpIn.getQueryString();
+ HttpAdaptor.log(LogService.LOG_INFO,"Request " + path + ((queryString == null) ? "" : ("?" + queryString)), null);
+ String postPath = preProcess(path);
+ if (!postPath.equals(path))
+ {
+ HttpAdaptor.log(LogService.LOG_INFO,"Processor replaced path " + path + " with the path " + postPath,null);
+ path = postPath;
+ }
+ OutputStream out = client.getOutputStream();
+ httpOut = new HttpOutputStream(out, httpIn);
+ if (!handleAuthentication(httpIn, httpOut)) {
+ return;
+ }
+ HttpCommandProcessor processor = getProcessor(path.substring(1, path.length()));
+ if (processor == null)
+ {
+ HttpAdaptor.log(LogService.LOG_INFO,"No suitable command processor found, requesting from processor path " + path, null);
+ findUnknownElement(path, httpOut, httpIn);
+ }
+ else
+ {
+ Document document = processor.executeRequest(httpIn);
+ postProcess(httpOut, httpIn, document);
+ }
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ HttpAdaptor.log(LogService.LOG_WARNING,"Exception during http request", ex);
+ if (httpOut != null)
+ {
+ try
+ {
+ postProcess(httpOut, httpIn, ex);
+ }
+ catch (IOException e)
+ {
+ HttpAdaptor.log(LogService.LOG_WARNING,"IOException during http request", e);
+ }
+ catch (JMException e)
+ {
+ HttpAdaptor.log(LogService.LOG_WARNING,"JMException during http request", e);
+ }
+ catch (RuntimeException rte)
+ {
+ HttpAdaptor.log(LogService.LOG_ERROR,"RuntimeException during http request", rte);
+ }
+ catch (Error er)
+ {
+ HttpAdaptor.log(LogService.LOG_ERROR,"Error during http request ", er);
+ }
+ catch (Throwable t)
+ {
+ HttpAdaptor.log(LogService.LOG_ERROR,"Throwable during http request ", t);
+ }
+ }
+ }
+ catch (Error ex)
+ {
+ HttpAdaptor.log(LogService.LOG_ERROR,"Error during http request ", ex);
+ }
+ finally
+ {
+ try
+ {
+ if (httpOut != null)
+ {
+ httpOut.flush();
+ }
+ // always close the socket
+ client.close();
+ }
+ catch (IOException e)
+ {
+ HttpAdaptor.log(LogService.LOG_WARNING,"Exception during request processing", e);
+ }
+ }
+ }
+ }
+
+
+ private static void log(int prio, String message, Throwable t){
+ if (HttpConnectorActivator.bc!=null){
+ ServiceReference logSR=HttpConnectorActivator.bc.getServiceReference(LogService.class.getName());
+ if (logSR!=null){
+ ((LogService)HttpConnectorActivator.bc.getService(logSR)).log(prio, message, t);
+ }else{
+ System.out.println("No Log Service");
+ }
+ }else{
+ System.out.println("mx4j.tools.adapatoir.http.HttpAdaptor.log: No bundleContext");
+ }
+ }
+}
+
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/HttpAdaptorMBean.java b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/HttpAdaptorMBean.java
new file mode 100644
index 0000000..c073d58
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/HttpAdaptorMBean.java
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) MX4J.
+ * All rights reserved.
+ *
+ * This software is distributed under the terms of the MX4J License version 1.0.
+ * See the terms of the MX4J License in the documentation provided with this software.
+ */
+/*
+ * Copyright 2005 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.felix.mosgi.jmx.httpconnector.mx4j.tools.adaptor.http;
+
+import java.util.Date;
+import java.io.IOException;
+
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+
+import org.apache.felix.mosgi.jmx.httpconnector.mx4j.tools.adaptor.AdaptorServerSocketFactory;
+
+/**
+ * Management interface for the HttpAdaptor MBean.
+ * @author <a href="mailto:tibu@users.sourceforge.net">Carlos Quiroz</a>
+ * @version $Revision: 1.1.1.1 $
+ */
+public interface HttpAdaptorMBean
+{
+ /**
+ * Sets the value of the server's port
+ * @param port the new port's value
+ */
+ public void setPort(int port);
+
+ /**
+ * Returns the port where the server is running on. Default is 8080
+ * @return HTTPServer's port
+ */
+ public int getPort();
+
+ /**
+ * Sets the host name where the server will be listening
+ * @param host Server's host
+ */
+ public void setHost(java.lang.String host);
+
+ /**
+ * Return the host name the server will be listening to. If null the server listen at the localhost
+ * @return the current hostname
+ */
+ java.lang.String getHost();
+
+ /**
+ * Sets the Authentication Method.
+ * @param method none/basic/digest
+ */
+ public void setAuthenticationMethod(String method);
+
+ /**
+ * Authentication Method
+ * @return authentication method
+ */
+ public String getAuthenticationMethod();
+
+ /**
+ * Sets the object which will post process the XML results.
+ * The last value set between the setPostProcessor and setPostProcessorName will be the valid one
+ * @param processor a Post processor object
+ */
+ public void setProcessor(ProcessorMBean processor);
+
+ /**
+ * Returns the Processor set by {@link #setProcessor}
+ */
+ public ProcessorMBean getProcessor();
+
+ /**
+ * Sets the classname of the object which will post process the XML results.
+ * The adaptor will try to build the object and use the processor name ObjectName to register it.
+ * The class name has to implements mx4j.tools.adaptor.http.ProcessorMBean and be MBean compliant
+ * @param processorClass a Post processor object
+ */
+ public void setProcessorClass(String processorClass);
+
+ /**
+ * Sets the object name of the PostProcessor MBean. If ProcessorClass is set the processor will be created
+ * @param processorName a Post processor object
+ */
+ public void setProcessorNameString(String processorName) throws MalformedObjectNameException;
+
+ /**
+ * Sets the object name which will post process the XML result. The last value set between the setPostProcessor and setPostProcessorName will be the valid one. The MBean will be verified to be of instance HttpPostProcessor
+ * @param processorName The new processorName value
+ */
+ public void setProcessorName(ObjectName processorName);
+
+ /**
+ * Returns the ObjectName of the processor set by {@link #setProcessorName}
+ */
+ public ObjectName getProcessorName();
+
+ /**
+ * Sets the object which create the server sockets
+ * @param factory the socket factory
+ */
+ public void setSocketFactory(AdaptorServerSocketFactory factory);
+
+ /**
+ * Sets the factory's object name which will create the server sockets
+ * @param factoryName the socket factory
+ */
+ public void setSocketFactoryName(ObjectName factoryName);
+
+ /**
+ * Sets the factory's object name which will create the server sockets
+ * @param factoryName the socket factory
+ */
+ public void setSocketFactoryNameString(String factoryName) throws MalformedObjectNameException;
+
+ /**
+ * Indicates whether the server's running
+ * @return The active value
+ */
+ public boolean isActive();
+
+ /**
+ * Starting date
+ * @return The date when the server was started
+ */
+ public Date getStartDate();
+
+ /**
+ * Requests count
+ * @return The total of requests served so far
+ */
+ public long getRequestsCount();
+
+ /**
+ * Gets the HttpAdaptor version
+ * @return HttpAdaptor's version
+ */
+ public String getVersion();
+
+ /**
+ * Adds a command processor object
+ */
+ public void addCommandProcessor(String path, HttpCommandProcessor processor);
+
+ /**
+ * Adds a command processor object by class
+ */
+ public void addCommandProcessor(String path, String processorClass);
+
+ /**
+ * Removes a command processor object by class
+ */
+ public void removeCommandProcessor(String path);
+
+ /**
+ * Starts the server
+ */
+ public void start() throws IOException;
+
+ /**
+ * Stops the HTTP daemon
+ */
+ public void stop();
+
+ /**
+ * Adds an authorization pair as username/password
+ */
+ public void addAuthorization(String username, String password);
+}
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/HttpCommandProcessor.java b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/HttpCommandProcessor.java
new file mode 100644
index 0000000..5e19952
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/HttpCommandProcessor.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) MX4J.
+ * All rights reserved.
+ *
+ * This software is distributed under the terms of the MX4J License version 1.0.
+ * See the terms of the MX4J License in the documentation provided with this software.
+ */
+/*
+ * Copyright 2005 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.felix.mosgi.jmx.httpconnector.mx4j.tools.adaptor.http;
+
+
+import java.io.IOException;
+import javax.management.JMException;
+import javax.management.MBeanServer;
+import javax.xml.parsers.DocumentBuilder;
+
+import org.w3c.dom.Document;
+
+/**
+ * HttpCommandProcessor sets the structure of a command processor
+ *
+ * @author <a href="mailto:tibu@users.sourceforge.net">Carlos Quiroz</a>
+ * @version $Revision: 1.1.1.1 $
+ */
+
+public interface HttpCommandProcessor
+{
+
+ /**
+ * Executes an HTTP request. It assumes the request is well formed
+ *
+ * @param out Input request
+ * @return An XML Document
+ * @exception IOException
+ */
+ public Document executeRequest(HttpInputStream in) throws IOException, JMException;
+
+ /**
+ * Sets the target MBeanServer
+ */
+ public void setMBeanServer(MBeanServer server);
+
+ /**
+ * Sets the Document Builder factory
+ */
+ public void setDocumentBuilder(DocumentBuilder builder);
+
+}
+
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/HttpCommandProcessorAdaptor.java b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/HttpCommandProcessorAdaptor.java
new file mode 100644
index 0000000..e7d46f9
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/HttpCommandProcessorAdaptor.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) MX4J.
+ * All rights reserved.
+ *
+ * This software is distributed under the terms of the MX4J License version 1.0.
+ * See the terms of the MX4J License in the documentation provided with this software.
+ */
+/*
+ * Copyright 2005 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.felix.mosgi.jmx.httpconnector.mx4j.tools.adaptor.http;
+
+
+import java.io.IOException;
+import javax.management.JMException;
+import javax.management.MBeanServer;
+import javax.xml.parsers.DocumentBuilder;
+import org.w3c.dom.Document;
+
+/**
+ * HttpCommandProcessor sets the structure of a command processor
+ *
+ * @author <a href="mailto:tibu@users.sourceforge.net">Carlos Quiroz</a>
+ * @version $Revision: 1.1.1.1 $
+ */
+public abstract class HttpCommandProcessorAdaptor implements HttpCommandProcessor
+{
+ protected MBeanServer server;
+
+ protected DocumentBuilder builder;
+
+ public abstract Document executeRequest(HttpInputStream in) throws IOException, JMException;
+
+ /**
+ * Sets the target MBeanServer
+ */
+ public void setMBeanServer(MBeanServer server) {
+ this.server = server;
+ }
+
+ /**
+ * Sets the Document Builder factory
+ */
+ public void setDocumentBuilder(DocumentBuilder builder) {
+ this.builder = builder;
+ }
+}
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/HttpConstants.java b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/HttpConstants.java
new file mode 100644
index 0000000..e9b609b
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/HttpConstants.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) MX4J.
+ * All rights reserved.
+ *
+ * This software is distributed under the terms of the MX4J License version 1.0.
+ * See the terms of the MX4J License in the documentation provided with this software.
+ */
+/*
+ * Copyright 2005 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.felix.mosgi.jmx.httpconnector.mx4j.tools.adaptor.http;
+
+/**
+ * Define constants for the HTTP request processing
+ *
+ * @author <a href="mailto:tibu@users.sourceforge.net">Carlos Quiroz</a>
+ * @version $Revision: 1.1.1.1 $
+ */
+public class HttpConstants
+{
+ /**
+ * Server info header
+ */
+ public final static String SERVER_INFO = "MX4J-HTTPD/1.0";
+
+ /**
+ * HTTP implemented version
+ */
+ public final static String HTTP_VERSION = "HTTP/1.0 ";
+
+ /**
+ * Get method header
+ */
+ public final static String METHOD_GET = "GET";
+
+ /**
+ * Post method header
+ */
+ public final static String METHOD_POST = "POST";
+
+ /**
+ * Status code OK
+ */
+ public final static int STATUS_OKAY = 200;
+
+ /**
+ * Status code NO CONTENT
+ */
+ public final static int STATUS_NO_CONTENT = 204;
+
+ /**
+ * Status code MOVED PERMANENTLY
+ */
+ public final static int STATUS_MOVED_PERMANENTLY = 301;
+
+ /**
+ * Status code MOVED TEMPORARILY
+ */
+ public final static int STATUS_MOVED_TEMPORARILY = 302;
+
+ /**
+ * Status code BAD REQUEST
+ */
+ public final static int STATUS_BAD_REQUEST = 400;
+
+ /**
+ * Status code AUTHENTICATE
+ */
+ public final static int STATUS_AUTHENTICATE = 401;
+
+ /**
+ * Status code FORBIDDEN
+ */
+ public final static int STATUS_FORBIDDEN = 403;
+
+ /**
+ * Status code NOT FOUND
+ */
+ public final static int STATUS_NOT_FOUND = 404;
+
+ /**
+ * Status code NOT ALLOWED
+ */
+ public final static int STATUS_NOT_ALLOWED = 405;
+
+ /**
+ * Status code INTERNAL ERROR
+ */
+ public final static int STATUS_INTERNAL_ERROR = 500;
+
+ /**
+ * Status code NOT IMPLEMENTED
+ */
+ public final static int STATUS_NOT_IMPLEMENTED = 501;
+
+}
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/HttpException.java b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/HttpException.java
new file mode 100644
index 0000000..d1c40b5
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/HttpException.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) MX4J.
+ * All rights reserved.
+ *
+ * This software is distributed under the terms of the MX4J License version 1.0.
+ * See the terms of the MX4J License in the documentation provided with this software.
+ */
+/*
+ * Copyright 2005 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.felix.mosgi.jmx.httpconnector.mx4j.tools.adaptor.http;
+
+
+import java.io.IOException;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+
+/**
+ * HttpException is emitted when an error parsing an HTTP request appears
+ *
+ * @author <a href="mailto:tibu@users.sourceforge.net">Carlos Quiroz</a>
+ * @version $Revision: 1.1.1.1 $
+ */
+
+public class HttpException extends IOException
+{
+ /** Error code */
+ protected int code;
+
+ /**
+ * Constructor for the HttpException object
+ *
+ * @param code Error code
+ * @param description Description
+ */
+
+ public HttpException(int code, String description)
+ {
+ super(description);
+ this.code = code;
+ }
+
+ /**
+ * Return the exception code
+ */
+ public int getCode()
+ {
+ return code;
+ }
+
+ public Document getResponseDoc() {
+ try
+ {
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ DocumentBuilder builder = factory.newDocumentBuilder();
+ Document document = builder.newDocument();
+ Element root = document.createElement("HttpException");
+ root.setAttribute("code", Integer.toString(code));
+ root.setAttribute("description", getMessage());
+ document.appendChild(root);
+ return document;
+ }
+ catch (ParserConfigurationException e)
+ {
+ return null;
+ }
+ }
+}
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/HttpInputStream.java b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/HttpInputStream.java
new file mode 100644
index 0000000..ca4645c
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/HttpInputStream.java
@@ -0,0 +1,427 @@
+/*
+ * Copyright (C) MX4J.
+ * All rights reserved.
+ *
+ * This software is distributed under the terms of the MX4J License version 1.0.
+ * See the terms of the MX4J License in the documentation provided with this software.
+ */
+/*
+ * Copyright 2005 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.felix.mosgi.jmx.httpconnector.mx4j.tools.adaptor.http;
+
+import java.io.BufferedInputStream;
+import java.io.InputStream;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.StringTokenizer;
+import java.util.NoSuchElementException;
+import java.net.URLDecoder;
+
+/**
+ * HttpInputStream processes an HTTP request
+ *
+ * @author <a href="mailto:tibu@users.sourceforge.net">Carlos Quiroz</a>
+ * @version $Revision: 1.1.1.1 $
+ */
+
+public class HttpInputStream extends BufferedInputStream {
+ /** Http method. only GET, POST implemented */
+ private String method;
+
+ /** Path of the request */
+ private String path;
+
+ /** Query string */
+ private String queryString;
+
+ /** Request version */
+ private float version;
+
+ /** Current headers */
+ private Map headers = new HashMap();
+
+ private Map variables = new HashMap();
+
+ /**
+ * Constructs a new HttpInputStream
+ *
+ * @param in InputStream
+ */
+ public HttpInputStream(InputStream in)
+ {
+ super(in);
+ }
+
+ /**
+ * Returns the method of the request
+ *
+ * @return the method of the request GET/POST
+ */
+ public String getMethod()
+ {
+ return method;
+ }
+
+ /**
+ * Returns the path of the request
+ *
+ * @return the path of the request
+ */
+
+ public String getPath()
+ {
+ return path;
+ }
+
+ /**
+ * Returns the query string
+ *
+ * @return The queryString value
+ */
+ public String getQueryString()
+ {
+ return queryString;
+ }
+
+ /**
+ * Returns the version of the request
+ *
+ * @return The version value 1.0/1.1
+ */
+ public float getVersion()
+ {
+ return version;
+ }
+
+ /**
+ * Returns a given header by name, assumes lower case
+ *
+ * @param name Name of the header
+ * @return The header value
+ */
+ public String getHeader(String name)
+ {
+ return (String) headers.get(name);
+ }
+
+ /**
+ * Returns a given header by name, assumes lower case
+ *
+ * @param name Name of the header
+ * @return The header value
+ */
+ public Map getHeaders()
+ {
+ return headers;
+ }
+
+ /**
+ * Reads the request parsing the headers
+ *
+ * @exception IOException Description of Exception
+ */
+ public void readRequest() throws IOException
+ {
+ String request = readLine();
+ if (request == null)
+ {
+ throw new HttpException(HttpConstants.STATUS_BAD_REQUEST, "Null query");
+ }
+ // Parses the request
+ StringTokenizer parts = new StringTokenizer(request);
+ try
+ {
+ parseMethod(parts.nextToken());
+ parseRequest(parts.nextToken());
+ }
+ catch (NoSuchElementException ex)
+ {
+ throw new HttpException(HttpConstants.STATUS_BAD_REQUEST, request);
+ }
+ if (parts.hasMoreTokens())
+ {
+ parseVersion(parts.nextToken());
+ }
+ else
+ {
+ version = 0.9f;
+ }
+ if (version >= 1.0f)
+ {
+ readHeaders();
+ parseVariables();
+ }
+ }
+
+ /**
+ * Reads an HTTP line
+ *
+ * @return A read line
+ * @exception IOException Emmited in case of errors reading the stream
+ */
+ public String readLine() throws IOException
+ {
+ StringBuffer line = new StringBuffer(64);
+ line.delete(0, line.length());
+ int c;
+ while (((c = read()) != -1) && (c != '\n') && (c != '\r'))
+ {
+ line.append((char) c);
+ }
+ if ((c == '\r') && ((c = read()) != '\n') && (c != -1))
+ {
+ --pos;
+ }
+ if ((c == -1) && (line.length() == 0))
+ {
+ return null;
+ }
+ else
+ {
+ return line.toString();
+ }
+ }
+
+ /**
+ * Returns a map with the variables passed in the request.
+ *
+ * @return A map containing variables/value pairs. If a variable is
+ * present only once in the request the value will be a String.
+ * If it is present many times the variable will be a String[]
+ */
+ public Map getVariables()
+ {
+ return variables;
+ }
+ /**
+ * Returns one variable value. If the variable is present many times, the first
+ * instance will be returned
+ *
+ * @return A String with the variable value
+ */
+ public String getVariable(String name)
+ {
+ if (variables.containsKey(name))
+ {
+ Object variable = variables.get(name);
+ if (variable instanceof String)
+ {
+ return (String)variable;
+ }
+ else if (variable instanceof String[])
+ {
+ return ((String[])variable)[0];
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns one variable values.
+ *
+ * @return A String array with all variable instances
+ */
+ public String[] getVariableValues(String name)
+ {
+ if (variables.containsKey(name))
+ {
+ Object variable = variables.get(name);
+ if (variable instanceof String[])
+ {
+ return (String[])variable;
+ } else if (variable instanceof String)
+ {
+ String[] result = new String[1];
+ result[0] = (String)variable;
+ return result;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Parses the request parameters
+ */
+ protected void parseVariables() throws HttpException
+ {
+ try
+ {
+ // get request variables
+ String variableHolder = "";
+ if (method.equals(HttpConstants.METHOD_POST) && "application/x-www-form-urlencoded".equals(headers.get("content-type"))
+ && (headers.get("content-length") != null))
+ {
+ if ("chunked".equals(headers.get("transfer-encoding")))
+ {
+ throw new HttpException(HttpConstants.STATUS_BAD_REQUEST, "Sorry I don't understand chunked requests");
+ }
+ StringBuffer buffer = new StringBuffer();
+ int size = Integer.parseInt((String)headers.get("content-length"));
+ mark(size);
+ for (int i=0;i<size;i++)
+ {
+ int j=read();
+ if (j>=0)
+ {
+ buffer.append((char)j);
+ }
+ else
+ {
+ throw new HttpException(HttpConstants.STATUS_BAD_REQUEST, "Request not understood");
+ }
+ }
+ variableHolder = buffer.toString();
+ reset();
+ }
+ else if (method.equals(HttpConstants.METHOD_GET))
+ {
+ variableHolder = getQueryString();
+ }
+ else
+ {
+ throw new HttpException(HttpConstants.STATUS_BAD_REQUEST, "Request not understood");
+ }
+ StringTokenizer parser = new StringTokenizer(variableHolder, "&");
+ while (parser.hasMoreTokens())
+ {
+ String command = parser.nextToken();
+ int equalIndex = command.indexOf('=');
+ if (equalIndex > 0)
+ {
+ String variableName = URLDecoder.decode(command.substring(0, equalIndex));
+ String variableValue = URLDecoder.decode(command.substring(equalIndex + 1, command.length()));
+ variableValue = new String(variableValue.getBytes(), "UTF-8");
+ if (variables.get(variableName) != null) {
+ Object value = variables.get(variableName);
+ String[] newValue = null;
+ if (value instanceof String)
+ {
+ newValue = new String[2];
+ newValue[0] = variableValue;
+ newValue[1] = (String)value;
+ }
+ else
+ {
+ String[] oldValue = (String[])value;
+ newValue = new String[oldValue.length+1];
+ System.arraycopy(oldValue, 0, newValue, 1, oldValue.length);
+ newValue[0] = variableValue;
+ }
+ variables.put(variableName, newValue);
+ }
+ else
+ {
+ variables.put(variableName, variableValue);
+ }
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ throw new HttpException(HttpConstants.STATUS_BAD_REQUEST, getQueryString());
+ }
+ }
+
+ /**
+ * Parses the connection method. GET/POST are allowed
+ *
+ * @param method Description of Parameter
+ * @exception HttpException Description of Exception
+ */
+ protected void parseMethod(String method) throws HttpException
+ {
+ if (method.equals(HttpConstants.METHOD_GET))
+ {
+ this.method = HttpConstants.METHOD_GET;
+ }
+ else if (method.equals(HttpConstants.METHOD_POST))
+ {
+ this.method = HttpConstants.METHOD_POST;
+ }
+ else
+ {
+ throw new HttpException(HttpConstants.STATUS_NOT_IMPLEMENTED, method);
+ }
+ }
+
+ /**
+ * Parses the request
+ *
+ * @param request Request string
+ * @exception HttpException Thrown if an error ocurr
+ */
+ protected void parseRequest(String request) throws HttpException
+ {
+ if (!request.startsWith("/"))
+ {
+ throw new HttpException(HttpConstants.STATUS_BAD_REQUEST, request);
+ }
+ int queryIdx = request.indexOf('?');
+ if (queryIdx == -1)
+ {
+ path = HttpUtil.canonicalizePath(request);
+ queryString = "";
+ }
+ else
+ {
+ path = HttpUtil.canonicalizePath(request.substring(0, queryIdx));
+ queryString = request.substring(queryIdx + 1);
+ }
+ }
+
+ /**
+ * Parses the request HttpConstants version
+ *
+ * @param verStr String containing the HTTP version
+ * @exception HttpException
+ */
+ protected void parseVersion(String verStr) throws HttpException
+ {
+ if (!verStr.startsWith("HTTP/"))
+ {
+ throw new HttpException(HttpConstants.STATUS_BAD_REQUEST, verStr);
+ }
+ try
+ {
+ version = Float.valueOf(verStr.substring(5)).floatValue();
+ }
+ catch (NumberFormatException ex)
+ {
+ throw new HttpException(HttpConstants.STATUS_BAD_REQUEST, verStr);
+ }
+ }
+
+ /**
+ * Reads the headers
+ *
+ * @exception IOException
+ */
+ protected void readHeaders() throws IOException
+ {
+ String header;
+ while (((header = readLine()) != null) && !header.equals(""))
+ {
+ int colonIdx = header.indexOf(':');
+ {
+ String name = header.substring(0, colonIdx);
+ String value = header.substring(colonIdx + 1);
+ headers.put(name.toLowerCase(), value.trim());
+ }
+ }
+ }
+}
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/HttpOutputStream.java b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/HttpOutputStream.java
new file mode 100644
index 0000000..5e940b1
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/HttpOutputStream.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) MX4J.
+ * All rights reserved.
+ *
+ * This software is distributed under the terms of the MX4J License version 1.0.
+ * See the terms of the MX4J License in the documentation provided with this software.
+ */
+/*
+ * Copyright 2005 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.felix.mosgi.jmx.httpconnector.mx4j.tools.adaptor.http;
+
+import java.io.BufferedOutputStream;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Iterator;
+
+/**
+ * HttpAdaptor sets the basic adaptor listening for HTTP requests
+ *
+ * @author <a href="mailto:tibu@users.sourceforge.net">Carlos Quiroz</a>
+ * @version $Revision: 1.1.1.1 $
+ */
+public class HttpOutputStream extends BufferedOutputStream
+{
+ /** Answer code */
+ protected int code;
+ /** whether to send the headers*/
+ protected boolean sendHeaders;
+ /** Headers to be sent */
+ protected Map headers = new HashMap(7);
+ /**
+ * Creates a new HttpOutputStream with a given OutputStream and an InputStream
+ *
+ * @param out The OutputStream normally associated with the output socket
+ * stream of the incoming connection
+ * @param in HttpInputStream containing the incoming request
+ */
+ public HttpOutputStream(OutputStream out, HttpInputStream in)
+ {
+ super(out);
+ code = HttpConstants.STATUS_OKAY;
+ setHeader("Server", HttpConstants.SERVER_INFO);
+ sendHeaders = (in.getVersion() >= 1.0);
+ }
+ /**
+ * Sets the answer code
+ *
+ * @param code The new code value
+ */
+ public void setCode(int code)
+ {
+ this.code = code;
+ }
+ /**
+ * Sets a given header code
+ *
+ * @param attr The new header name
+ * @param value The new header value
+ */
+ public void setHeader(String attr, String value)
+ {
+ headers.put(attr, value);
+ }
+ /**
+ * Sends the headers
+ *
+ * @return Description of the Returned Value
+ * @exception IOException Description of Exception
+ */
+ public boolean sendHeaders() throws IOException
+ {
+ if (sendHeaders)
+ {
+ StringBuffer buffer = new StringBuffer(512);
+ buffer.append(HttpConstants.HTTP_VERSION);
+ buffer.append(code);
+ buffer.append(" ");
+ buffer.append(HttpUtil.getCodeMessage(code));
+ buffer.append("\r\n");
+ Iterator attrs = headers.keySet().iterator();
+ int size = headers.size();
+ for (int i = 0; i < size; i++)
+ {
+ String attr = (String) attrs.next();
+ buffer.append(attr);
+ buffer.append(": ");
+ buffer.append(headers.get(attr));
+ buffer.append("\r\n");
+ }
+ buffer.append("\r\n");
+ write(buffer.toString());
+ }
+ return sendHeaders;
+ }
+ /**
+ * Writes a given message line
+ *
+ * @param msg The message to be written
+ * @exception IOException
+ */
+ public void write(String msg) throws IOException
+ {
+ write(msg.getBytes("latin1"));
+ }
+ /**
+ * Writes the content of the input stream to the output stream
+ *
+ * @param in The input stream
+ * @exception IOException
+ */
+ public void write(InputStream in) throws IOException
+ {
+ int n;
+ int length = buf.length;
+ while ((n = in.read(buf, count, length - count)) >= 0)
+ {
+ if ((count += n) >= length)
+ {
+ out.write(buf, count = 0, length);
+ }
+ }
+ }
+}
+
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/HttpUtil.java b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/HttpUtil.java
new file mode 100644
index 0000000..23281d8
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/HttpUtil.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) MX4J.
+ * All rights reserved.
+ *
+ * This software is distributed under the terms of the MX4J License version 1.0.
+ * See the terms of the MX4J License in the documentation provided with this software.
+ */
+/*
+ * Copyright 2005 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.felix.mosgi.jmx.httpconnector.mx4j.tools.adaptor.http;
+
+/**
+ * Utility methods for the HTTP adaptor
+ *
+ * @author <a href="mailto:tibu@users.sourceforge.net">Carlos Quiroz</a>
+ * @version $Revision: 1.1.1.1 $
+ */
+public class HttpUtil
+{
+
+ /**
+ * Gets a message apropriate for a give HTTP code
+ *
+ * @param code Reference Code
+ * @return The result message
+ * @see HttpConstants
+ */
+ public static String getCodeMessage(int code) {
+ switch (code) {
+ case HttpConstants.STATUS_OKAY:
+ return "OK";
+ case HttpConstants.STATUS_NO_CONTENT:
+ return "No Content";
+ case HttpConstants.STATUS_MOVED_PERMANENTLY:
+ return "Moved Permanently";
+ case HttpConstants.STATUS_MOVED_TEMPORARILY:
+ return "Moved Temporarily";
+ case HttpConstants.STATUS_BAD_REQUEST:
+ return "Bad Request";
+ case HttpConstants.STATUS_FORBIDDEN:
+ return "Forbidden";
+ case HttpConstants.STATUS_NOT_FOUND:
+ return "Not Found";
+ case HttpConstants.STATUS_NOT_ALLOWED:
+ return "Method Not Allowed";
+ case HttpConstants.STATUS_INTERNAL_ERROR:
+ return "Internal Server Error";
+ case HttpConstants.STATUS_AUTHENTICATE:
+ return "Authentication requested";
+ case HttpConstants.STATUS_NOT_IMPLEMENTED:
+ return "Not Implemented";
+ default:
+ return "Unknown Code (" + code + ")";
+ }
+ }
+
+
+ /**
+ * Makes a path canonical
+ *
+ * @param path Target path
+ * @return The canonicalized path
+ */
+ public static String canonicalizePath(String path) {
+ char[] chars = path.toCharArray();
+ int length = chars.length;
+ int idx;
+ int odx = 0;
+ while ((idx = indexOf(chars, length, '/', odx)) < length - 1)
+ {
+ int ndx = indexOf(chars, length, '/', idx + 1);
+ int kill = -1;
+ if (ndx == idx + 1)
+ {
+ kill = 1;
+ }
+ else if ((ndx >= idx + 2) && (chars[idx + 1] == '.'))
+ {
+ if (ndx == idx + 2)
+ {
+ kill = 2;
+ }
+ else if ((ndx == idx + 3) && (chars[idx + 2] == '.'))
+ {
+ kill = 3;
+ while ((idx > 0) && (chars[--idx] != '/'))
+ {
+ ++kill;
+ }
+ }
+ }
+ if (kill == -1)
+ {
+ odx = ndx;
+ }
+ else if (idx + kill >= length)
+ {
+ length = odx = idx + 1;
+ }
+ else
+ {
+ length -= kill;
+ System.arraycopy(chars, idx + 1 + kill,
+ chars, idx + 1, length - idx - 1);
+ odx = idx;
+ }
+ }
+ return new String(chars, 0, length);
+ }
+
+
+ protected static int indexOf(char[] chars, int length, char chr, int from)
+ {
+ while ((from < length) && (chars[from] != chr))
+ {
+ ++from;
+ }
+ return from;
+ }
+
+ /**
+ * Returns whether a boolean variable is in the variables. It tries to find
+ * it. If not found the the default is used. If found is tested to check if
+ * it is <code>true</code> or <code>1</code> and the answer is true.
+ * Otherwise is false
+ */
+ public static boolean booleanVariableValue(HttpInputStream in, String variable, boolean defaultValue)
+ {
+ if (in.getVariables().containsKey(variable))
+ {
+ String result = (String)in.getVariables().get(variable);
+ return result.equals("true") || result.equals("1");
+ }
+ return defaultValue;
+ }
+}
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/InvokeOperationCommandProcessor.java b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/InvokeOperationCommandProcessor.java
new file mode 100644
index 0000000..5dfe218
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/InvokeOperationCommandProcessor.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) MX4J.
+ * All rights reserved.
+ *
+ * This software is distributed under the terms of the MX4J License version 1.0.
+ * See the terms of the MX4J License in the documentation provided with this software.
+ */
+/*
+ * Copyright 2005 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.felix.mosgi.jmx.httpconnector.mx4j.tools.adaptor.http;
+
+import javax.management.ObjectName;
+import javax.management.JMException;
+import javax.management.MalformedObjectNameException;
+import javax.management.MBeanInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanParameterInfo;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Iterator;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * InvokeOperationCommandProcessor, processes a request for unregistering an MBean
+ *
+ * @author <a href="mailto:tibu@users.sourceforge.net">Carlos Quiroz</a>
+ * @version $Revision: 1.1.1.1 $
+ */
+public class InvokeOperationCommandProcessor extends HttpCommandProcessorAdaptor
+{
+ public InvokeOperationCommandProcessor()
+ {
+ }
+
+ public Document executeRequest(HttpInputStream in) throws IOException, JMException
+ {
+ Document document = builder.newDocument();
+
+ Element root = document.createElement("MBeanOperation");
+ document.appendChild(root);
+ Element operationElement = document.createElement("Operation");
+ operationElement.setAttribute("operation", "invoke");
+ root.appendChild(operationElement);
+
+ String objectVariable = in.getVariable("objectname");
+ String operationVariable = in.getVariable("operation");
+ if (objectVariable == null || objectVariable.equals("")
+ || operationVariable == null || operationVariable.equals(""))
+ {
+ operationElement.setAttribute("result", "error");
+ operationElement.setAttribute("errorMsg", "Incorrect parameters in the request");
+ return document;
+ }
+ operationElement.setAttribute("objectname", objectVariable);
+ List types = new ArrayList();
+ List values = new ArrayList();
+ int i=0;
+ boolean unmatchedParameters = false;
+ boolean valid = false;
+ do
+ {
+ String parameterType = in.getVariable("type"+i);
+ String parameterValue = in.getVariable("value"+i);
+ valid = (parameterType != null && parameterValue != null);
+ if (valid)
+ {
+ types.add(parameterType);
+ Object value = null;
+ try
+ {
+ value = CommandProcessorUtil.createParameterValue(parameterType, parameterValue);
+ }
+
+ catch (Exception e)
+ {
+ operationElement.setAttribute("result", "error");
+ operationElement.setAttribute("errorMsg", "Parameter " + i + ": " + parameterValue + " cannot be converted to type " + parameterType);
+ return document;
+ }
+ if (value != null)
+ {
+ values.add(value);
+ }
+ }
+ if (parameterType == null ^ parameterValue == null)
+ {
+ unmatchedParameters = true;
+ break;
+ }
+ i++;
+ }
+ while (valid);
+ if (objectVariable == null || objectVariable.equals("") ||
+ operationVariable == null || operationVariable.equals(""))
+ {
+ operationElement.setAttribute("result", "error");
+ operationElement.setAttribute("errorMsg", "Incorrect parameters in the request");
+ return document;
+ }
+ if (unmatchedParameters)
+ {
+ operationElement.setAttribute("result", "error");
+ operationElement.setAttribute("errorMsg", "count of parameter types doesn't match count of parameter values");
+ return document;
+ }
+ ObjectName name = null;
+ try
+ {
+ name = new ObjectName(objectVariable);
+ }
+ catch (MalformedObjectNameException e)
+ {
+ operationElement.setAttribute("result", "error");
+ operationElement.setAttribute("errorMsg", "Malformed object name");
+ return document;
+ }
+
+ if (server.isRegistered(name))
+ {
+ MBeanInfo info = server.getMBeanInfo(name);
+ MBeanOperationInfo[] operations = info.getOperations();
+ boolean match = false;
+ if (operations != null)
+ {
+ for (int j=0;j<operations.length;j++)
+ {
+ if (operations[j].getName().equals(operationVariable))
+ {
+ MBeanParameterInfo[] parameters = operations[j].getSignature();
+ if (parameters.length != types.size())
+ {
+ continue;
+ }
+ Iterator k = types.iterator();
+ boolean signatureMatch = true;
+ for (int p = 0;p<types.size();p++)
+ {
+ if (!parameters[p].getType().equals(k.next()))
+ {
+ signatureMatch = false;
+ break;
+ }
+ }
+ match = signatureMatch;
+ }
+ if (match)
+ {
+ break;
+ }
+ }
+ }
+ if (!match)
+ {
+ operationElement.setAttribute("result", "error");
+ operationElement.setAttribute("errorMsg", "Operation singature has no match in the MBean");
+ }
+ else
+ {
+ try
+ {
+ Object[] params = values.toArray();
+ String[] signature = new String[types.size()];
+ types.toArray(signature);
+ Object returnValue = server.invoke(name, operationVariable, params, signature);
+ operationElement.setAttribute("result", "success");
+ if (returnValue != null)
+ {
+ operationElement.setAttribute("returnclass", returnValue.getClass().getName());
+ operationElement.setAttribute("return", returnValue.toString());
+ } else
+ {
+ operationElement.setAttribute("returnclass", null);
+ operationElement.setAttribute("return", null);
+ }
+ }
+ catch (Exception e)
+ {
+ operationElement.setAttribute("result", "error");
+ operationElement.setAttribute("errorMsg", e.getMessage());
+ }
+ }
+ }
+ else
+ {
+ if (name != null)
+ {
+ operationElement.setAttribute("result", "error");
+ operationElement.setAttribute("errorMsg", new StringBuffer("MBean ").append(name).append(" not registered").toString());
+ }
+ }
+ return document;
+ }
+
+}
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/MBeanCommandProcessor.java b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/MBeanCommandProcessor.java
new file mode 100644
index 0000000..0fde55c
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/MBeanCommandProcessor.java
@@ -0,0 +1,259 @@
+/*
+ * Copyright (C) MX4J.
+ * All rights reserved.
+ *
+ * This software is distributed under the terms of the MX4J License version 1.0.
+ * See the terms of the MX4J License in the documentation provided with this software.
+ */
+/*
+ * Copyright 2005 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.felix.mosgi.jmx.httpconnector.mx4j.tools.adaptor.http;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.Comparator;
+import java.util.TreeSet;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import javax.management.JMException;
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanConstructorInfo;
+import javax.management.MBeanInfo;
+import javax.management.MBeanNotificationInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanParameterInfo;
+import javax.management.ObjectName;
+//import javax.management.modelmbean.ModelMBeanInfo;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * MBeanCommandProcessor, processes a request for getting data about a MBean
+ *
+ * @author <a href="mailto:tibu@users.sourceforge.net">Carlos Quiroz</a>
+ * @author <a href="mailto:l.dobrev@lsnsoft.com">Lachezar Dobrev</a>
+ * @version $Revision: 1.1.1.1 $
+ */
+public class MBeanCommandProcessor extends HttpCommandProcessorAdaptor
+{
+ public MBeanCommandProcessor()
+ {
+ }
+
+ public Document executeRequest(HttpInputStream in) throws IOException, JMException
+ {
+ Document document = builder.newDocument();
+
+ String name = in.getVariable("objectname");
+ ObjectName objectName = null;
+
+ if (name != null)
+ {
+ objectName = new ObjectName(name);
+ if (!objectName.isPattern())
+ {
+ // not a pattern - assume a single MBean
+ if (server.isRegistered(objectName))
+ {
+ Element mb = createMBeanElement(document, objectName, in);
+ document.appendChild(mb);
+ }
+ }
+ else
+ {
+ // A pattern - return all matching MBeans
+ Set names = new TreeSet(CommandProcessorUtil.createObjectNameComparator());
+ names.addAll(server.queryNames(objectName, null));
+ Element root = document.createElement("Server");
+ root.setAttribute("pattern", objectName.toString());
+ for (Iterator it = names.iterator(); it.hasNext();)
+ {
+ Element mb = createMBeanElement(document, (ObjectName)it.next(), in);
+ root.appendChild(mb);
+ }
+ document.appendChild(root);
+ }
+ }
+ return document;
+ }
+
+ private Element createMBeanElement(Document document, ObjectName objectName, HttpInputStream in)
+ throws JMException
+ {
+ Element root = document.createElement("MBean");
+
+ MBeanInfo info = server.getMBeanInfo(objectName);
+ root.setAttribute("description", info.getDescription());
+ root.setAttribute("classname", info.getClassName());
+ root.setAttribute("objectname", objectName.toString());
+/*
+ if (info instanceof ModelMBeanInfo)
+ {
+ root.setAttribute("model", "true");
+ }
+*/
+ if (HttpUtil.booleanVariableValue(in, "attributes", true)) {
+ MBeanAttributeInfo[] attributes = info.getAttributes();
+ if (attributes != null)
+ {
+ SortedMap sortedAttributes = new TreeMap();
+ for (int i=0;i<attributes.length;i++)
+ {
+ Element attribute = document.createElement("Attribute");
+ attribute.setAttribute("name", attributes[i].getName());
+ attribute.setAttribute("type", attributes[i].getType());
+ attribute.setAttribute("description", attributes[i].getDescription());
+ attribute.setAttribute("strinit", String.valueOf(CommandProcessorUtil.canCreateParameterValue(attributes[i].getType())));
+ if (attributes[i].isReadable() && attributes[i].isWritable())
+ {
+ attribute.setAttribute("availability", "RW");
+ }
+ if (attributes[i].isReadable() && !attributes[i].isWritable())
+ {
+ attribute.setAttribute("availability", "RO");
+ }
+ if (!attributes[i].isReadable() && attributes[i].isWritable())
+ {
+ attribute.setAttribute("availability", "WO");
+ }
+ try
+ {
+ Object attributeValue = server.getAttribute(objectName, attributes[i].getName());
+ attribute.setAttribute("isnull", (attributeValue==null)?"true":"false");
+ if (attributeValue != null)
+ {
+ attribute.setAttribute("value", attributeValue.toString());
+ if (attributeValue.getClass().isArray())
+ {
+ attribute.setAttribute("aggregation", "array");
+ }
+ if (attributeValue instanceof java.util.Collection)
+ {
+ attribute.setAttribute("aggregation", "collection");
+ }
+ if (attributeValue instanceof java.util.Map)
+ {
+ attribute.setAttribute("aggregation", "map");
+ }
+ }
+ else
+ {
+ attribute.setAttribute("value", "null");
+ }
+
+ }
+ catch (JMException e)
+ {
+ attribute.setAttribute("value", e.getMessage());
+ }
+ sortedAttributes.put(attributes[i].getName(), attribute);
+ }
+ Iterator keys = sortedAttributes.keySet().iterator();
+ while (keys.hasNext())
+ {
+ root.appendChild((Element)sortedAttributes.get(keys.next()));
+ }
+ }
+ }
+ if (HttpUtil.booleanVariableValue(in, "constructors", true))
+ {
+ MBeanConstructorInfo[] constructors = info.getConstructors();
+ if (constructors != null)
+ {
+ // How to order contructors?
+ for (int i=0;i<constructors.length;i++)
+ {
+ Element constructor = document.createElement("Constructor");
+ constructor.setAttribute("name", constructors[i].getName());
+ constructor.setAttribute("description", constructors[i].getDescription());
+ addParameters(constructor, document, constructors[i].getSignature());
+ root.appendChild(constructor);
+ }
+ }
+ }
+ if (HttpUtil.booleanVariableValue(in, "operations", true))
+ {
+ MBeanOperationInfo[] operations = info.getOperations();
+ if (operations != null)
+ {
+ for (int i=0;i<operations.length;i++)
+ {
+ Element operation = document.createElement("Operation");
+ operation.setAttribute("name", operations[i].getName());
+ operation.setAttribute("description", operations[i].getDescription());
+ operation.setAttribute("return", operations[i].getReturnType());
+ switch (operations[i].getImpact())
+ {
+ case MBeanOperationInfo.UNKNOWN:
+ operation.setAttribute("impact", "unknown");
+ break;
+ case MBeanOperationInfo.ACTION:
+ operation.setAttribute("impact", "action");
+ break;
+ case MBeanOperationInfo.INFO:
+ operation.setAttribute("impact", "info");
+ break;
+ case MBeanOperationInfo.ACTION_INFO:
+ operation.setAttribute("impact", "action_info");
+ break;
+ }
+ addParameters(operation, document, operations[i].getSignature());
+ root.appendChild(operation);
+ }
+ }
+ }
+ if (HttpUtil.booleanVariableValue(in, "notifications", true))
+ {
+ MBeanNotificationInfo[] notifications = info.getNotifications();
+ if (notifications != null)
+ {
+ for (int i=0;i<notifications.length;i++)
+ {
+ Element notification = document.createElement("Notification");
+ notification.setAttribute("name", notifications[i].getName());
+ notification.setAttribute("description", notifications[i].getDescription());
+ String[] types = notifications[i].getNotifTypes();
+ for (int j=0;j<types.length;j++)
+ {
+ Element type = document.createElement("Type");
+ type.setAttribute("name", types[j]);
+ notification.appendChild(type);
+ }
+ root.appendChild(notification);
+ }
+ }
+ }
+ return root;
+ }
+
+ protected void addParameters(Element node, Document document, MBeanParameterInfo[] parameters)
+ {
+ for (int j=0;j<parameters.length;j++)
+ {
+ Element parameter = document.createElement("Parameter");
+ parameter.setAttribute("name", parameters[j].getName());
+ parameter.setAttribute("description", parameters[j].getDescription());
+ parameter.setAttribute("type", parameters[j].getType());
+ parameter.setAttribute("strinit", String.valueOf(CommandProcessorUtil.canCreateParameterValue(parameters[j].getType())));
+ // add id since order is relevant
+ parameter.setAttribute("id", ""+j);
+ node.appendChild(parameter);
+ }
+ }
+
+}
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/ProcessorMBean.java b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/ProcessorMBean.java
new file mode 100644
index 0000000..63133b1
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/ProcessorMBean.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) MX4J.
+ * All rights reserved.
+ *
+ * This software is distributed under the terms of the MX4J License version 1.0.
+ * See the terms of the MX4J License in the documentation provided with this software.
+ */
+/*
+ * Copyright 2005 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.felix.mosgi.jmx.httpconnector.mx4j.tools.adaptor.http;
+
+import java.io.IOException;
+import org.w3c.dom.Document;
+
+/**
+ * Processor ManagementBean, just defines a generic description
+ *
+ * @author <a href="mailto:tibu@users.sourceforge.net">Carlos Quiroz</a>
+ * @version $Revision: 1.1.1.1 $
+ */
+public interface ProcessorMBean
+{
+ public String getName();
+
+ /**
+ * The method will process the result string and produce an output. The
+ * implementor is also responsible to set the mime type, response code and
+ * send the headers before answering as follow:
+ * <code>
+ * out.setCode(HttpConstants.STATUS_OKAY);
+ * out.setHeader("Content-type", "text/html");
+ * out.sendHeaders();
+ * out.write("some text");
+ * </code>
+ *
+ * @param out The output stream
+ * @param in The input stream
+ * @param document A document containing the data
+ */
+ public void writeResponse(HttpOutputStream out, HttpInputStream in, Document document) throws IOException;
+
+ /**
+ * The method will process the result exception and produce output. The
+ * implementor is also responsible to set the mime type, response code and
+ * send the headers before answering as follow:
+ * <code>
+ * out.setCode(HttpConstants.STATUS_OKAY);
+ * out.setHeader("Content-type", "text/html");
+ * out.sendHeaders();
+ * out.write("some text");
+ * </code>
+ *
+ * @param out The output stream
+ * @param in The input stream
+ * @param e The exception to be reported
+ */
+ public void writeError(HttpOutputStream out, HttpInputStream in, Exception e) throws IOException;
+
+ /**
+ * Preprocess a path and return a replacement path. For instance the / path
+ * could be replaced by the server path
+ *
+ * @param path The original path
+ * @return the replacement path. If not modification the path param should
+ * be returned
+ */
+ public String preProcess(String path);
+
+ /**
+ * Let the processor load internally a not found element. This can be used
+ * to load images, stylesheets and so on. If return is not null, the path is
+ * processed
+ *
+ * @param path The request element
+ * @param out The output stream
+ * @param in The input stream
+ */
+ public String notFoundElement(String path, HttpOutputStream out, HttpInputStream in) throws IOException, HttpException;
+}
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/ServerByDomainCommandProcessor.java b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/ServerByDomainCommandProcessor.java
new file mode 100644
index 0000000..3ead0d7
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/ServerByDomainCommandProcessor.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) MX4J.
+ * All rights reserved.
+ *
+ * This software is distributed under the terms of the MX4J License version 1.0.
+ * See the terms of the MX4J License in the documentation provided with this software.
+ */
+/*
+ * Copyright 2005 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.felix.mosgi.jmx.httpconnector.mx4j.tools.adaptor.http;
+
+import javax.management.ObjectInstance;
+import javax.management.ObjectName;
+import javax.management.MalformedObjectNameException;
+import javax.management.JMException;
+import javax.management.MBeanInfo;
+import java.io.IOException;
+import java.util.Set;
+import java.util.HashMap;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import java.util.Map;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ArrayList;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * ServerByDomainCommandProcessor, processes a request for getting all the
+ * MBeans of the current server grouped by domains
+ *
+ * @author <a href="mailto:tibu@users.sourceforge.net">Carlos Quiroz</a>
+ * @version $Revision: 1.1.1.1 $
+ */
+public class ServerByDomainCommandProcessor extends HttpCommandProcessorAdaptor
+{
+ public ServerByDomainCommandProcessor()
+ {
+ }
+
+ public Document executeRequest(HttpInputStream in) throws IOException, JMException
+ {
+ Document document = builder.newDocument();
+
+ Element root = document.createElement("Server");
+ document.appendChild(root);
+
+ String targetClass = in.getVariable("instanceof");
+ String queryNames = in.getVariable("querynames");
+ ObjectName query = null;
+ if (queryNames != null)
+ {
+ try
+ {
+ query = new ObjectName(queryNames);
+ }
+ catch (MalformedObjectNameException e)
+ {
+ Element exceptionElement = document.createElement("Exception");
+ exceptionElement.setAttribute("errorMsg", e.getMessage());
+ root.appendChild(exceptionElement);
+ return document;
+ }
+ }
+ Set mbeans = server.queryMBeans(query, null);
+ Iterator i = mbeans.iterator();
+ // this will order the domains
+ Map domains = new TreeMap();
+ while (i.hasNext())
+ {
+ ObjectInstance instance = (ObjectInstance)i.next();
+ ObjectName name = instance.getObjectName();
+ String domain = name.getDomain();
+ if (domains.containsKey(domain))
+ {
+ ((Set)domains.get(domain)).add(name);
+ }
+ else
+ {
+ Set objects = new TreeSet(CommandProcessorUtil.createObjectNameComparator());
+ objects.add(name);
+ domains.put(domain, objects);
+ }
+ }
+ i = domains.keySet().iterator();
+ while (i.hasNext())
+ {
+ String domain = (String)i.next();
+ Element domainElement = document.createElement("Domain");
+ root.appendChild(domainElement);
+ domainElement.setAttribute("name", domain);
+ Set names = (Set)domains.get(domain);
+ Iterator j = names.iterator();
+ while (j.hasNext())
+ {
+ ObjectName targetName = (ObjectName)j.next();
+ if (targetClass != null && !server.isInstanceOf(targetName, targetClass))
+ {
+ continue;
+ }
+ Element mBeanElement = document.createElement("MBean");
+ mBeanElement.setAttribute("objectname", targetName.toString());
+ MBeanInfo info = server.getMBeanInfo(targetName);
+ mBeanElement.setAttribute("description", info.getDescription());
+ mBeanElement.setAttribute("classname", info.getClassName());
+ domainElement.appendChild(mBeanElement);
+ }
+ }
+ return document;
+ }
+
+}
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/ServerCommandProcessor.java b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/ServerCommandProcessor.java
new file mode 100644
index 0000000..94a607c
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/ServerCommandProcessor.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) MX4J.
+ * All rights reserved.
+ *
+ * This software is distributed under the terms of the MX4J License version 1.0.
+ * See the terms of the MX4J License in the documentation provided with this software.
+ */
+/*
+ * Copyright 2005 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.felix.mosgi.jmx.httpconnector.mx4j.tools.adaptor.http;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.TreeSet;
+import javax.management.JMException;
+import javax.management.MBeanInfo;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectInstance;
+import javax.management.ObjectName;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * ServerCommandProcessor, processes a request for getting all the
+ * MBeans of the current server
+ *
+ * @author <a href="mailto:tibu@users.sourceforge.net">Carlos Quiroz</a>
+ * @version $Revision: 1.1.1.1 $
+ */
+public class ServerCommandProcessor extends HttpCommandProcessorAdaptor
+{
+ public ServerCommandProcessor()
+ {
+ }
+
+ public Document executeRequest(HttpInputStream in) throws IOException, JMException
+ {
+ Document document = builder.newDocument();
+
+ Element root = document.createElement("Server");
+ document.appendChild(root);
+
+ String classVariable = in.getVariable("instanceof");
+ String queryNames = in.getVariable("querynames");
+ Set mbeans = null;
+ ObjectName query = null;
+ if (queryNames != null)
+ {
+ try
+ {
+ query = new ObjectName(queryNames);
+ mbeans = new TreeSet(CommandProcessorUtil.createObjectInstanceComparator());
+ mbeans.addAll(server.queryMBeans(query, null));
+ }
+ catch (MalformedObjectNameException e)
+ {
+ Element exceptionElement = document.createElement("Exception");
+ exceptionElement.setAttribute("errorMsg", e.getMessage());
+ root.appendChild(exceptionElement);
+ return document;
+ }
+ } else {
+ mbeans = new TreeSet(CommandProcessorUtil.createObjectInstanceComparator());
+ mbeans.addAll(server.queryMBeans(null, null));
+ }
+ Iterator i = mbeans.iterator();
+ while (i.hasNext())
+ {
+ ObjectInstance instance = (ObjectInstance)i.next();
+ if (classVariable != null && !classVariable.equals(instance.getClassName()))
+ {
+ continue;
+ }
+ Element mBeanElement = document.createElement("MBean");
+ mBeanElement.setAttribute("objectname", instance.getObjectName().toString());
+ mBeanElement.setAttribute("classname", instance.getClassName());
+ MBeanInfo info = server.getMBeanInfo(instance.getObjectName());
+ mBeanElement.setAttribute("description", info.getDescription());
+ root.appendChild(mBeanElement);
+ }
+ return document;
+ }
+
+}
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/SetAttributeCommandProcessor.java b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/SetAttributeCommandProcessor.java
new file mode 100644
index 0000000..12285f2
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/SetAttributeCommandProcessor.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) MX4J.
+ * All rights reserved.
+ *
+ * This software is distributed under the terms of the MX4J License version 1.0.
+ * See the terms of the MX4J License in the documentation provided with this software.
+ */
+/*
+ * Copyright 2005 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.felix.mosgi.jmx.httpconnector.mx4j.tools.adaptor.http;
+
+import javax.management.ObjectName;
+import javax.management.JMException;
+import javax.management.MalformedObjectNameException;
+import javax.management.MBeanInfo;
+import javax.management.Attribute;
+import javax.management.MBeanAttributeInfo;
+import java.io.IOException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * SetAttributeCommandProcessor, processes a request for setting one attribute
+ * in one MBean
+ *
+ * @author <a href="mailto:tibu@users.sourceforge.net">Carlos Quiroz</a>
+ * @version $Revision: 1.1.1.1 $
+ */
+public class SetAttributeCommandProcessor extends HttpCommandProcessorAdaptor
+{
+
+ public SetAttributeCommandProcessor()
+ {
+ }
+
+ public Document executeRequest(HttpInputStream in) throws IOException, JMException
+ {
+ Document document = builder.newDocument();
+
+ Element root = document.createElement("MBeanOperation");
+ document.appendChild(root);
+ Element operationElement = document.createElement("Operation");
+ operationElement.setAttribute("operation", "setattribute");
+ root.appendChild(operationElement);
+
+ String objectVariable = in.getVariable("objectname");
+ String attributeVariable = in.getVariable("attribute");
+ String valueVariable = in.getVariable("value");
+ if (objectVariable == null || objectVariable.equals("") ||
+ attributeVariable == null || attributeVariable.equals("") ||
+ valueVariable == null)
+ {
+ operationElement.setAttribute("result", "error");
+ operationElement.setAttribute("errorMsg", "Incorrect parameters in the request");
+ return document;
+ }
+ operationElement.setAttribute("objectname", objectVariable);
+ ObjectName name = null;
+ try
+ {
+ name = new ObjectName(objectVariable);
+ }
+ catch (MalformedObjectNameException e)
+ {
+ operationElement.setAttribute("result", "error");
+ operationElement.setAttribute("errorMsg", "Malformed object name");
+ return document;
+ }
+
+ if (server.isRegistered(name))
+ {
+ MBeanInfo info = server.getMBeanInfo(name);
+ MBeanAttributeInfo[] attributes = info.getAttributes();
+ MBeanAttributeInfo targetAttribute = null;
+ if (attributes != null)
+ {
+ for (int i=0;i<attributes.length;i++)
+ {
+ if (attributes[i].getName().equals(attributeVariable))
+ {
+ targetAttribute = attributes[i];
+ break;
+ }
+ }
+ }
+ if (targetAttribute != null)
+ {
+ String type = targetAttribute.getType();
+ Object value = null;
+ if (valueVariable != null)
+ {
+ try
+ {
+ value = CommandProcessorUtil.createParameterValue(type, valueVariable);
+ }
+ catch (Exception e)
+ {
+ operationElement.setAttribute("result", "error");
+ operationElement.setAttribute("errorMsg", "Value: " + valueVariable + " could not be converted to " + type);
+ }
+ if (value != null)
+ {
+ try
+ {
+ server.setAttribute(name, new Attribute(attributeVariable, value));
+ operationElement.setAttribute("result", "success");
+ }
+ catch (Exception e)
+ {
+ operationElement.setAttribute("result", "error");
+ operationElement.setAttribute("errorMsg", e.getMessage());
+ }
+ }
+ }
+ }
+ else
+ {
+ operationElement.setAttribute("result", "error");
+ operationElement.setAttribute("errorMsg", "Attribute " + attributeVariable + " not found");
+ }
+ }
+ else
+ {
+ if (name != null)
+ {
+ operationElement.setAttribute("result", "error");
+ operationElement.setAttribute("errorMsg", "MBean " + name + " not registered");
+ }
+ }
+ return document;
+ }
+
+}
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/SetAttributesCommandProcessor.java b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/SetAttributesCommandProcessor.java
new file mode 100644
index 0000000..86242cf
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/SetAttributesCommandProcessor.java
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) MX4J.
+ * All rights reserved.
+ *
+ * This software is distributed under the terms of the MX4J License version 1.0.
+ * See the terms of the MX4J License in the documentation provided with this software.
+ */
+/*
+ * Copyright 2005 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.felix.mosgi.jmx.httpconnector.mx4j.tools.adaptor.http;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import javax.management.Attribute;
+import javax.management.JMException;
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanInfo;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * SetAttributesCommandProcessor, processes a request for setting one or more attributes
+ * in one MBean. it uses th facility of havin multiple submit buttons in a web page
+ * if the set_all=Set variable is passed all attributes will be set, if a set_XXX varialbe
+ * is passed only the specific attribute will be set
+ *
+ * @author <a href="mailto:tibu@users.sourceforge.net">Carlos Quiroz</a>
+ * @version $Revision: 1.1.1.1 $
+ */
+public class SetAttributesCommandProcessor extends HttpCommandProcessorAdaptor
+{
+
+ public SetAttributesCommandProcessor()
+ {
+ }
+
+ public Document executeRequest(HttpInputStream in) throws IOException, JMException
+ {
+ Document document = builder.newDocument();
+
+ Element root = document.createElement("MBeanOperation");
+ document.appendChild(root);
+ Element operationElement = document.createElement("Operation");
+ operationElement.setAttribute("operation", "setattributes");
+ root.appendChild(operationElement);
+
+ String objectVariable = in.getVariable("objectname");
+ if (objectVariable == null || objectVariable.equals(""))
+ {
+ operationElement.setAttribute("result", "error");
+ operationElement.setAttribute("errorMsg", "Missing objectname in the request");
+ return document;
+ }
+ operationElement.setAttribute("objectname", objectVariable);
+ ObjectName name = null;
+ try
+ {
+ name = new ObjectName(objectVariable);
+ }
+ catch (MalformedObjectNameException e)
+ {
+ operationElement.setAttribute("result", "error");
+ operationElement.setAttribute("errorMsg", "Malformed object name");
+ return document;
+ }
+ if (server.isRegistered(name))
+ {
+ Map variables = in.getVariables();
+ if (variables.containsKey("setall"))
+ {
+ Iterator keys = variables.keySet().iterator();
+ SortedMap allAttributes = new TreeMap();
+ while (keys.hasNext()) {
+ String key = (String)keys.next();
+ if (key.startsWith("value_"))
+ {
+ String attributeVariable = key.substring(6, key.length());
+ String valueVariable = in.getVariable(key);
+ Element attributeElement = setAttribute(document, attributeVariable, valueVariable, name);
+ allAttributes.put(attributeVariable, attributeElement);
+ operationElement.appendChild(attributeElement);
+ }
+ }
+ keys = allAttributes.keySet().iterator();
+ while (keys.hasNext()) {
+ Element attributeElement = (Element)allAttributes.get(keys.next());
+ operationElement.appendChild(attributeElement);
+ }
+ }
+ else
+ {
+ Iterator keys = variables.keySet().iterator();
+ SortedMap allAttributes = new TreeMap();
+ while (keys.hasNext())
+ {
+ String key = (String)keys.next();
+ if (key.startsWith("set_"))
+ {
+ String attributeVariable = key.substring(4, key.length());
+ String valueVariable = in.getVariable("value_" + attributeVariable);
+ Element attributeElement = setAttribute(document, attributeVariable, valueVariable, name);
+ allAttributes.put(attributeVariable, attributeElement);
+ }
+ }
+ keys = allAttributes.keySet().iterator();
+ while (keys.hasNext()) {
+ Element attributeElement = (Element)allAttributes.get(keys.next());
+ operationElement.appendChild(attributeElement);
+ }
+ }
+ //operationElement.setAttribute("result", "success");
+ }
+ else
+ {
+ if (name != null)
+ {
+ operationElement.setAttribute("result", "error");
+ operationElement.setAttribute("errorMsg", "MBean " + name + " not registered");
+ }
+ }
+ return document;
+ }
+
+ private Element setAttribute(Document document, String attributeVariable, String valueVariable, ObjectName name) throws JMException
+ {
+ Element attributeElement = document.createElement("Attribute");
+ attributeElement.setAttribute("attribute", attributeVariable);
+ MBeanInfo info = server.getMBeanInfo(name);
+ MBeanAttributeInfo[] attributes = info.getAttributes();
+ MBeanAttributeInfo targetAttribute = null;
+ if (attributes != null)
+ {
+ for (int i=0;i<attributes.length;i++)
+ {
+ if (attributes[i].getName().equals(attributeVariable))
+ {
+ targetAttribute = attributes[i];
+ break;
+ }
+ }
+ }
+ if (targetAttribute != null)
+ {
+ String type = targetAttribute.getType();
+ Object value = null;
+ if (valueVariable != null)
+ {
+ try
+ {
+ value = CommandProcessorUtil.createParameterValue(type, valueVariable);
+ }
+ catch (Exception e)
+ {
+ attributeElement.setAttribute("result", "error");
+ attributeElement.setAttribute("errorMsg", "Value: " + valueVariable + " could not be converted to " + type);
+ }
+ if (value != null)
+ {
+ try
+ {
+ server.setAttribute(name, new Attribute(attributeVariable, value));
+ attributeElement.setAttribute("result", "success");
+ attributeElement.setAttribute("value", valueVariable);
+ }
+ catch (Exception e)
+ {
+ attributeElement.setAttribute("result", "error");
+ attributeElement.setAttribute("errorMsg", e.getMessage());
+ }
+ }
+ }
+ }
+ else
+ {
+ attributeElement.setAttribute("result", "error");
+ attributeElement.setAttribute("errorMsg", "Attribute " + attributeVariable + " not found");
+ }
+ return attributeElement;
+ }
+
+}
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/XSLTProcessor.java b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/XSLTProcessor.java
new file mode 100644
index 0000000..111d5da
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/XSLTProcessor.java
@@ -0,0 +1,527 @@
+/*
+ * Copyright (C) MX4J.
+ * All rights reserved.
+ *
+ * This software is distributed under the terms of the MX4J License version 1.0.
+ * See the terms of the MX4J License in the documentation provided with this software.
+ */
+/*
+ * Copyright 2005 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.felix.mosgi.jmx.httpconnector.mx4j.tools.adaptor.http;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import javax.management.MBeanException;
+import javax.management.ReflectionException;
+import javax.management.RuntimeMBeanException;
+import javax.xml.transform.Source;
+import javax.xml.transform.Templates;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.URIResolver;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+
+import org.w3c.dom.Document;
+
+import org.osgi.framework.ServiceReference;
+
+import org.osgi.service.log.LogService;
+
+import org.apache.felix.mosgi.jmx.httpconnector.HttpConnectorActivator;
+
+
+/**
+ * XSLTPostProcessor pass the document through an XSLT transformation
+ *
+ * @author <a href="mailto:tibu@users.sourceforge.net">Carlos Quiroz</a>
+ * @version $Revision: 1.1.1.1 $
+ * the HttpAdaptor through a XSL transformation" extends="mx4j.tools.adaptor.http.ProcessorMBean"
+ */
+public class XSLTProcessor
+ implements ProcessorMBean, XSLTProcessorMBean, URIResolver
+{
+ TransformerFactory factory = null;
+
+ private Map templatesCache = new HashMap();
+
+ private String path = "mx4j/tools/adaptor/http/xsl";
+
+ private File root = null;
+
+ private Map mimeTypes = new HashMap();
+
+ /** Indicated whether the file are read from a file */
+ private boolean useJar = true;
+
+ private boolean useCache = true;
+
+ private ClassLoader targetClassLoader = ClassLoader.getSystemClassLoader();
+
+ private String defaultPage = "serverbydomain";
+
+ /**
+ * The locale is set with the default as en_US since it is the
+ * one bundled
+ */
+ private Locale locale = new Locale("en", "");
+
+ public XSLTProcessor()
+ {
+ factory = TransformerFactory.newInstance();
+ factory.setURIResolver(this);
+ mimeTypes.put(".gif", "image/gif");
+ mimeTypes.put(".jpg", "image/jpg");
+ mimeTypes.put(".png", "image/png");
+ mimeTypes.put(".tif", "image/tiff");
+ mimeTypes.put(".tiff", "image/tiff");
+ mimeTypes.put(".ico", "image/ico");
+ mimeTypes.put(".html", "text/html");
+ mimeTypes.put(".htm", "text/html");
+ mimeTypes.put(".txt", "text/plain");
+ mimeTypes.put(".xml", "text/xml");
+ mimeTypes.put(".xsl", "text/xsl");
+ mimeTypes.put(".css", "text/css");
+ mimeTypes.put(".js", "text/x-javascript");
+ mimeTypes.put(".jar", "application/java-archive");
+ }
+
+ public void writeResponse(HttpOutputStream out, HttpInputStream in, Document document) throws IOException
+ {
+ out.setCode(HttpConstants.STATUS_OKAY);
+ out.setHeader("Content-Type", "text/html");
+ // added some caching attributes to fornce not to cache
+ out.setHeader("Cache-Control", "no-cache");
+ out.setHeader("expires", "now");
+ out.setHeader("pragma", "no-cache");
+ out.sendHeaders();
+ Transformer transformer = null;
+ String path = preProcess(in.getPath());
+
+ if (in.getVariable("template") != null)
+ {
+ transformer = createTransformer(in.getVariable("template") + ".xsl");
+ }
+ else
+ {
+ transformer = createTransformer(path + ".xsl");
+ }
+
+ if (transformer != null)
+ {
+ // added so that the document() function works
+ transformer.setURIResolver(this);
+ // The variables are passed to the XSLT as (param.name, value)
+ Map variables = in.getVariables();
+ Iterator j = variables.keySet().iterator();
+ while (j.hasNext())
+ {
+ String key = (String)j.next();
+ Object value = variables.get(key);
+ if (value instanceof String) {
+ transformer.setParameter("request." + key, value);
+ }
+ if (value instanceof String[]) {
+ String[] allvalues = (String[])value;
+ // not a good solution, only the first one is presented
+ transformer.setParameter("request." + key, allvalues[0]);
+ }
+
+ }
+ if (!variables.containsKey("locale"))
+ {
+ transformer.setParameter("request.locale", locale.toString());
+ }
+ try
+ {
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ XSLTProcessor.log(LogService.LOG_DEBUG,"transforming " + path,null);
+ transformer.transform(new DOMSource(document), new StreamResult(output));
+ output.writeTo(out);
+ }
+ catch (TransformerException e)
+ {
+ XSLTProcessor.log(LogService.LOG_ERROR,"Transformation exception ", e);
+ }
+ }
+ else
+ {
+ XSLTProcessor.log(LogService.LOG_WARNING,"Transformer for path " + path + " not found",null);
+ }
+ }
+
+ protected Transformer createTransformer(String path)
+ {
+ Transformer transformer = null;
+ try
+ {
+ if (useCache && templatesCache.containsKey(path))
+ {
+ transformer = ((Templates)templatesCache.get(path)).newTransformer();
+ }
+ else
+ {
+ InputStream file = getInputStream(path);
+ if (file != null)
+ {
+ XSLTProcessor.log(LogService.LOG_INFO,"Creating template for path "+path, null);
+ Templates template = factory.newTemplates(new StreamSource(file));
+ transformer = template.newTransformer();
+ if (useCache)
+ {
+ templatesCache.put(path, template);
+ }
+ }
+ else
+ {
+ XSLTProcessor.log(LogService.LOG_WARNING,"template for path "+path+" not found", null);
+ }
+ }
+ }
+ catch (TransformerConfigurationException e)
+ {
+ XSLTProcessor.log(LogService.LOG_ERROR,"Exception during template construction", e);
+ }
+ return transformer;
+ }
+
+ protected void processHttpException(HttpInputStream in, HttpOutputStream out, HttpException e) throws IOException
+ {
+ out.setCode(e.getCode());
+ out.setHeader("Content-Type", "text/html");
+ out.sendHeaders();
+ // hardcoded dir :-P
+ Transformer transformer = createTransformer("error.xsl");
+ transformer.setURIResolver(this);
+ Document doc = e.getResponseDoc();
+ if (doc != null)
+ {
+ try
+ {
+ if (!in.getVariables().containsKey("locale"))
+ {
+ transformer.setParameter("request.locale", locale.toString());
+ }
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ transformer.transform(new DOMSource(doc), new StreamResult(output));
+ output.writeTo(out);
+ }
+ catch (TransformerException ex)
+ {
+ XSLTProcessor.log(LogService.LOG_ERROR,"Exception during error output", ex);
+ }
+ }
+ }
+
+ public void writeError(HttpOutputStream out, HttpInputStream in, Exception e) throws IOException
+ {
+ Exception t = e;
+ if (e instanceof RuntimeMBeanException)
+ {
+ t = ((RuntimeMBeanException)e).getTargetException();
+ }
+ XSLTProcessor.log(LogService.LOG_INFO,"Processing error " + t.getMessage(),null);
+ if (t instanceof HttpException)
+ {
+ processHttpException(in, out, (HttpException)e);
+ }
+ else if ((t instanceof MBeanException) && (((MBeanException)t).getTargetException() instanceof HttpException))
+ {
+ processHttpException(in, out, (HttpException)((MBeanException)t).getTargetException());
+ }
+ else if ((t instanceof ReflectionException) && (((ReflectionException)t).getTargetException() instanceof HttpException))
+ {
+ processHttpException(in, out, (HttpException)((ReflectionException)t).getTargetException());
+ }
+ else
+ {
+ out.setCode(HttpConstants.STATUS_INTERNAL_ERROR);
+ out.setHeader("Content-Type", "text/html");
+ out.sendHeaders();
+ }
+ }
+
+ public String preProcess(String path) {
+ if (path.equals("/"))
+ {
+ path = "/" + defaultPage;
+ }
+ return path;
+ }
+
+ public String notFoundElement(String path, HttpOutputStream out, HttpInputStream in) throws IOException, HttpException
+ {
+ File file = new File(this.path, path);
+ XSLTProcessor.log(LogService.LOG_INFO,"Processing file request " + file,null);
+ String name = file.getName();
+ int extensionIndex = name.lastIndexOf('.');
+ String mime = null;
+ if (extensionIndex < 0)
+ {
+ XSLTProcessor.log(LogService.LOG_WARNING,"Filename has no extensions " + file.toString(),null);
+ mime = "text/plain";
+ }
+ else
+ {
+ String extension = name.substring(extensionIndex, name.length());
+ if (mimeTypes.containsKey(extension))
+ {
+ mime = (String)mimeTypes.get(extension);
+ } else {
+ XSLTProcessor.log(LogService.LOG_WARNING,"MIME type not found " + extension,null);
+ mime = "text/plain";
+ }
+ }
+ try
+ {
+ XSLTProcessor.log(LogService.LOG_DEBUG,"Trying to read file " + file,null);
+ BufferedInputStream fileIn = new BufferedInputStream(getInputStream(path));
+ ByteArrayOutputStream outArray = new ByteArrayOutputStream();
+ BufferedOutputStream outBuffer = new BufferedOutputStream(outArray);
+ int piece = 0;
+ while ((piece = fileIn.read()) >= 0)
+ {
+ outBuffer.write(piece);
+ }
+ outBuffer.flush();
+ out.setCode(HttpConstants.STATUS_OKAY);
+ out.setHeader("Content-type", mime);
+ out.sendHeaders();
+ XSLTProcessor.log(LogService.LOG_DEBUG,"File output " + mime,null);
+ outArray.writeTo(out);
+ fileIn.close();
+ }
+ catch (Exception e)
+ {
+ XSLTProcessor.log(LogService.LOG_WARNING,"Exception loading file " + file, e);
+ throw new HttpException(HttpConstants.STATUS_NOT_FOUND, "file " + file + " not found");
+ }
+ return null;
+ }
+
+ protected InputStream getInputStream(String path)
+ {
+ InputStream file = null;
+ if (!useJar)
+ {
+ try
+ {
+ // load from a dir
+ file = new FileInputStream(new File(this.root, path));
+ }
+ catch (FileNotFoundException e)
+ {
+ XSLTProcessor.log(LogService.LOG_ERROR,"File not found", e);
+ }
+ }
+ else
+ {
+ // load from a jar
+ String targetFile = this.path;
+ // workaround, should tought of somehting better
+ if (path.startsWith("/"))
+ {
+ targetFile += path;
+ } else {
+ targetFile += "/" + path;
+ }
+ if (root != null)
+ {
+ file = targetClassLoader.getResourceAsStream(targetFile);
+ }
+ if (file == null)
+ {
+ ClassLoader cl=getClass().getClassLoader();
+ if (cl == null)
+ {
+ file = ClassLoader.getSystemClassLoader().getResourceAsStream(targetFile);
+ }
+ else
+ {
+ file = getClass().getClassLoader().getResourceAsStream(targetFile);
+ }
+ file = getClass().getClassLoader().getResourceAsStream(targetFile);
+ }
+ }
+
+ return file;
+ }
+
+ public Source resolve(String href, String base)
+ {
+ StreamSource source = new StreamSource(getInputStream(href));
+ // this works with saxon7/saxon6.5.2/xalan
+ source.setSystemId(href);
+ return source;
+ }
+
+ public void setFile(String file)
+ {
+ if (file != null)
+ {
+
+ File target = new File(file);
+ if (!target.exists())
+ {
+ XSLTProcessor.log(LogService.LOG_WARNING,"Target file " + file + " does not exist, defaulting to previous",null);
+ return;
+ }
+ if (target.isDirectory())
+ {
+ useJar = false;
+ XSLTProcessor.log(LogService.LOG_INFO, "Using " + file + " as the root dir", null);
+ this.root = target;
+ return;
+ }
+ if (target.isFile() && (target.getName().endsWith(".jar") ||
+ (target.getName().endsWith(".zip"))))
+ {
+ try {
+ URL url = target.toURL();
+ targetClassLoader = new URLClassLoader(new URL[] {url});
+ XSLTProcessor.log(LogService.LOG_INFO,"Using compressed file " + url + " as the root file",null);
+ this.root = target;
+ useJar = true;
+ } catch (MalformedURLException e) {
+ XSLTProcessor.log(LogService.LOG_WARNING,"Unable to create class loader", e);
+ }
+ }
+ else
+ {
+ XSLTProcessor.log(LogService.LOG_WARNING,"Target file " + file + " does not exist, defaulting to previous",null);
+ }
+ }
+ }
+
+ public String getFile()
+ {
+ return (root != null)?root.getName():null;
+ }
+
+ public String getPathInJar()
+ {
+ return path;
+ }
+
+ public void setPathInJar(String path)
+ {
+ this.path = path;
+ }
+
+ public String getDefaultPage()
+ {
+ return defaultPage;
+ }
+
+ public void setDefaultPage(String defaultPage)
+ {
+ this.defaultPage = defaultPage;
+ }
+
+ public boolean isUseJar()
+ {
+ return useJar;
+ }
+
+ public boolean isUsePath()
+ {
+ return !useJar;
+ }
+
+ public void addMimeType(String extension, String type)
+ {
+ if (extension != null && type != null)
+ {
+ XSLTProcessor.log(LogService.LOG_INFO,"Added MIME type " + type + " for extension " + extension,null);
+ mimeTypes.put(extension, type);
+ }
+ }
+
+ public void setUseCache(boolean useCache)
+ {
+ this.useCache = useCache;
+ }
+
+ public boolean isUseCache()
+ {
+ return useCache;
+ }
+
+ public String getName()
+ {
+ return "XSLT Processor";
+ }
+
+ public Locale getLocale() {
+ return locale;
+ }
+
+ public void setLocale(Locale locale) {
+ this.locale = locale;
+ }
+
+ public void setLocaleString(String locale) {
+ if (locale == null || locale.length()==0) {
+ this.locale = new Locale("en", "");
+ }
+ else
+ {
+ // split locale based on underbar
+ StringTokenizer tknzr = new StringTokenizer(locale,"_");
+ String language = tknzr.nextToken();
+ String country = "";
+ String variant = "";
+ if (tknzr.hasMoreTokens())
+ country = tknzr.nextToken();
+ if (tknzr.hasMoreTokens())
+ variant = tknzr.nextToken();
+ this.locale = new Locale(language,country,variant);
+ }
+ }
+
+ private static void log(int prio, String message, Throwable t){
+ if (HttpConnectorActivator.bc!=null){
+ ServiceReference logSR=HttpConnectorActivator.bc.getServiceReference(LogService.class.getName());
+ if (logSR!=null){
+ ((LogService)HttpConnectorActivator.bc.getService(logSR)).log(prio, message, t);
+ }else{
+ System.out.println("No Log Service");
+ }
+ }else{
+ System.out.println("mx4j.tools.adapatoir.http.XSLTProcessor.log: No bundleContext");
+ }
+ }
+
+}
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/XSLTProcessorMBean.java b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/XSLTProcessorMBean.java
new file mode 100644
index 0000000..dfe4d8f
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/XSLTProcessorMBean.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) MX4J.
+ * All rights reserved.
+ *
+ * This software is distributed under the terms of the MX4J License version 1.0.
+ * See the terms of the MX4J License in the documentation provided with this software.
+ */
+/*
+ * Copyright 2005 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.felix.mosgi.jmx.httpconnector.mx4j.tools.adaptor.http;
+
+import java.util.Locale;
+
+/**
+ * Management interface for the XSLTProcessor MBean.
+ * @author <a href="mailto:tibu@users.sourceforge.net">Carlos Quiroz</a>
+ * @version $Revision: 1.1.1.1 $
+ */
+public interface XSLTProcessorMBean extends ProcessorMBean
+{
+ /**
+ * Sets the jar/zip file or the directory where to find the XSL files
+ * @see #getFile
+ */
+ public void setFile(String file);
+
+ /**
+ * Returns the jar/zip file or the directory where XSL files are loaded
+ * @see #setFile
+ */
+ public String getFile();
+
+ /**
+ * Returns the path of the XSL templates inside a jar file.
+ * @see #setPathInJar
+ */
+ public String getPathInJar();
+
+ /**
+ * Specifies the path of the XSL templates inside a jar file.
+ * @see #getPathInJar
+ */
+ public void setPathInJar(String path);
+
+ /**
+ * Returns the default start page
+ * @see #setDefaultPage
+ */
+ public String getDefaultPage();
+
+ /**
+ * Sets the default start page, serverbydomain as a default
+ * @see #getDefaultPage
+ */
+ public void setDefaultPage(String defaultPage);
+
+ /**
+ * Returns if the XSL files are contained in a jar/zip file.
+ * @see #isUsePath
+ * @see #setFile
+ */
+ boolean isUseJar();
+
+ /**
+ * Returns if the XSL files are contained in a path.
+ * @see #isUseJar
+ * @see #setFile
+ */
+ boolean isUsePath();
+
+ /**
+ * Maps a given extension with a specified MIME type
+ */
+ public void addMimeType(String extension, String type);
+
+ /**
+ * Sets the caching of the XSL Templates.
+ */
+ public void setUseCache(boolean useCache);
+
+ /**
+ * Returns if the XSL Templates are cached
+ */
+ boolean isUseCache();
+
+ /**
+ * Returns the Locale used to internationalize the output
+ */
+ public Locale getLocale();
+
+ /**
+ * Sets the locale used to internationalize the output
+ */
+ public void setLocale(Locale locale);
+
+ /**
+ * Sets the locale used to internationalize the output, as a string
+ */
+ public void setLocaleString(String locale);
+}
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/about.xsl b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/about.xsl
new file mode 100644
index 0000000..4333217
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/about.xsl
@@ -0,0 +1,115 @@
+<?xml version="1.0"?>
+<!--
+ Copyright (C) MX4J.
+ All rights reserved.
+
+ This software is distributed under the terms of the MX4J License version 1.0.
+ See the terms of the MX4J License in the documentation provided with this software.
+
+ Author: Carlos Quiroz (tibu@users.sourceforge.net)
+ Revision: $Revision: 1.1.1.1 $
+ -->
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+ <xsl:output method="html" indent="yes" encoding="ISO-8859-1"/>
+ <xsl:include href="common.xsl"/>
+ <xsl:include href="xalan-ext.xsl"/>
+
+ <xsl:param name="html.stylesheet">stylesheet.css</xsl:param>
+ <xsl:param name="html.stylesheet.type">text/css</xsl:param>
+ <xsl:param name="head.title">about.title</xsl:param>
+
+ <!-- Main template -->
+ <xsl:template match="/MBean">
+ <html>
+ <xsl:call-template name="head"/>
+ <body>
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
+ <tr width="100%">
+ <td>
+ <xsl:call-template name="toprow"/>
+ <xsl:call-template name="tabs">
+ <xsl:with-param name="selection">about</xsl:with-param>
+ </xsl:call-template>
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
+ <tr class="about">
+ <td colspan="2">
+ <h1 align="center" class="about">
+ <xsl:variable name="str.url">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">about.main.url</xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">about.main.title</xsl:with-param>
+ <xsl:with-param name="p0"><a href="{$str.url}">MX4J</a></xsl:with-param>
+ </xsl:call-template>
+ </h1>
+ </td>
+ </tr>
+ <tr class="about">
+ <td colspan="2">
+ <h2 align="center" class="about">
+ <xsl:variable name="str.url">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">about.main.url2</xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">about.main.line1</xsl:with-param>
+ <xsl:with-param name="p0"><a href="{$str.url}">JMX</a></xsl:with-param>
+ </xsl:call-template>
+ </h2>
+ </td>
+ </tr>
+ <tr class="about">
+ <td>
+ <h3 align="right" class="about">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">about.main.implementation</xsl:with-param>
+ </xsl:call-template>
+ </h3>
+ </td>
+ <td>
+ <h3 align="left" class="about">
+ <xsl:value-of select="./Attribute[@name='ImplementationName']/@value"/>
+ </h3>
+ </td>
+ </tr>
+ <tr class="about">
+ <td>
+ <h3 align="right" class="about">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">about.main.implementationversion</xsl:with-param>
+ </xsl:call-template>
+ </h3>
+ </td>
+ <td>
+ <h3 align="left" class="about">
+ <xsl:value-of select="./Attribute[@name='ImplementationVersion']/@value"/>
+ </h3>
+ </td>
+ </tr>
+ <tr class="about">
+ <td>
+ <h3 align="right" class="about">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">about.main.serverid</xsl:with-param>
+ </xsl:call-template>
+ </h3>
+ </td>
+ <td>
+ <h3 align="left" class="about">
+ <xsl:value-of select="./Attribute[@name='MBeanServerId']/@value"/>
+ </h3>
+ </td>
+ </tr>
+ </table>
+ <xsl:call-template name="bottom"/>
+ </td>
+ </tr>
+ </table>
+ </body>
+ </html>
+ </xsl:template>
+</xsl:stylesheet>
+
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/common.xsl b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/common.xsl
new file mode 100644
index 0000000..ab6f754
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/common.xsl
@@ -0,0 +1,441 @@
+<?xml version="1.0"?>
+<!--
+ Copyright (C) MX4J.
+ All rights reserved.
+
+ This software is distributed under the terms of the MX4J License version 1.0.
+ See the terms of the MX4J License in the documentation provided with this software.
+
+ Author: Carlos Quiroz (tibu@users.sourceforge.net)
+ Revision: $Revision: 1.1.1.1 $
+ -->
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+ <!-- Import xalan extensions -->
+ <xsl:import href="xalan-ext.xsl" />
+
+ <!-- Defin string variables -->
+ <xsl:param name="request.locale">en</xsl:param>
+
+ <xsl:variable name="strings" select="document(concat('strings_', $request.locale, '.xml'))" />
+
+ <!-- Common head template -->
+ <xsl:template name="head">
+ <xsl:if test="$head.title">
+ <title>
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">
+ <xsl:value-of select="$head.title" />
+ </xsl:with-param>
+ </xsl:call-template>
+ </title>
+ </xsl:if>
+
+ <xsl:if test="$html.stylesheet">
+ <link rel="stylesheet" href="{$html.stylesheet}"
+ type="{$html.stylesheet.type}" />
+ </xsl:if>
+
+ <meta http-equiv="Expires" content ="0"/>
+ <meta http-equiv="Pragma" content="no-cache"/>
+ <meta http-equiv="Cache-Control" content="no-cache"/>
+ <meta name="generator" content="MX4J HttpAdaptor, JMX, JMX implementation" />
+
+ </xsl:template>
+
+ <!-- Common title template -->
+ <xsl:template name="toprow">
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="darker" colspan="2"/>
+ </tr>
+
+ <tr>
+ <td class="topheading">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">common.title</xsl:with-param>
+ </xsl:call-template>
+ <br/>
+ <div class="subtitle">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">common.subtitle</xsl:with-param>
+ </xsl:call-template>
+ </div>
+ </td>
+
+ <td class="topheading" align="right">
+ <xsl:variable name="str.logo">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">common.logo</xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="str.logo.gif">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">common.logo.gif</xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="str.site">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">common.site</xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="str.logo.width">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">common.logo.width</xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="str.logo.height">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">common.logo.height</xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+ <a href="http://{$str.site}"><img src="{$str.logo.gif}" width="{$str.logo.width}" height="{$str.logo.height}" border="0" alt="{$str.logo}" />
+ </a>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="darker" colspan="2" />
+ </tr>
+ </table>
+
+ <br />
+ </xsl:template>
+
+ <!-- Common bottom template -->
+ <xsl:template name="bottom">
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="fronttab"> </td>
+ </tr>
+
+ <tr>
+ <td class="darker" />
+ </tr>
+
+ <tr>
+ <td>
+ <div align="center" class="footer">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">common.bottom.banner</xsl:with-param>
+ <xsl:with-param name="p0">
+ <a href="http://mx4j.sourceforge.net">MX4J</a>
+ </xsl:with-param>
+ </xsl:call-template>
+ </div>
+ </td>
+ </tr>
+ </table>
+ </xsl:template>
+
+ <!-- Common tabs template -->
+ <xsl:template name="tabs">
+ <xsl:param name="selection" select="." />
+
+ <xsl:variable name="server.class">
+ <xsl:choose>
+ <xsl:when test="$selection='server'">fronttab</xsl:when>
+ <xsl:otherwise>backtab</xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <xsl:variable name="timer.class">
+ <xsl:choose>
+ <xsl:when test="$selection='timer'">fronttab</xsl:when>
+ <xsl:otherwise>backtab</xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <xsl:variable name="mbean.class">
+ <xsl:choose>
+ <xsl:when test="$selection='mbean'">fronttab</xsl:when>
+ <xsl:otherwise>backtab</xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <xsl:variable name="monitor.class">
+ <xsl:choose>
+ <xsl:when test="$selection='monitor'">fronttab</xsl:when>
+ <xsl:otherwise>backtab</xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <xsl:variable name="relation.class">
+ <xsl:choose>
+ <xsl:when test="$selection='relation'">fronttab</xsl:when>
+ <xsl:otherwise>backtab</xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <xsl:variable name="mlet.class">
+ <xsl:choose>
+ <xsl:when test="$selection='mlet'">fronttab</xsl:when>
+ <xsl:otherwise>backtab</xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <xsl:variable name="about.class">
+ <xsl:choose>
+ <xsl:when test="$selection='about'">fronttab</xsl:when>
+ <xsl:otherwise>backtab</xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="{$server.class}">
+ <xsl:if test="not ($selection='server')">
+ <a href="/serverbydomain" class="tabs">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">common.tabs.serverview</xsl:with-param>
+ </xsl:call-template>
+ </a>
+ </xsl:if>
+
+ <xsl:if test="$selection='server'">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">common.tabs.serverview</xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+ </td>
+
+ <td width="2"/>
+
+ <td class="{$mbean.class}">
+ <a href="/empty?template=emptymbean" class="tabs">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">common.tabs.mbeanview</xsl:with-param>
+ </xsl:call-template>
+ </a>
+ </td>
+
+ <td width="2"/>
+
+ <td class="{$timer.class}">
+ <a href="/serverbydomain?instanceof=javax.management.timer.Timer&template=timer" class="tabs">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">common.tabs.timerview</xsl:with-param>
+ </xsl:call-template>
+ </a>
+ </td>
+
+ <td width="2"/>
+
+ <td class="{$monitor.class}">
+ <a href="/serverbydomain?instanceof=javax.management.monitor.Monitor&template=monitor" class="tabs">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">common.tabs.monitorview</xsl:with-param>
+ </xsl:call-template>
+ </a>
+ </td>
+
+ <td width="2"/>
+
+ <td class="{$relation.class}">
+ <a href="/relation?instanceof=javax.management.relation.Relation&template=relation" class="tabs">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">common.tabs.relationview</xsl:with-param>
+ </xsl:call-template>
+ </a>
+ </td>
+
+ <td width="2"/>
+
+ <td class="{$mlet.class}">
+ <a href="/serverbydomain?instanceof=javax.management.loading.MLetMBean&template=mlet" class="tabs">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">common.tabs.mletview</xsl:with-param>
+ </xsl:call-template>
+ </a>
+ </td>
+
+ <td width="2"/>
+
+ <td class="{$about.class}">
+ <a href="/mbean?objectname=JMImplementation%3Atype%3DMBeanServerDelegate&template=about" class="tabs">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">common.tabs.about</xsl:with-param>
+ </xsl:call-template>
+ </a>
+ </td>
+ </tr>
+ </table>
+ </xsl:template>
+
+ <xsl:template name="serverview">
+ <tr>
+ <td class="darkline" align="right">
+ <a href="/">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">common.serverview.return</xsl:with-param>
+ </xsl:call-template>
+ </a>
+ </td>
+ </tr>
+ </xsl:template>
+
+ <xsl:template name="mbeanview">
+ <xsl:param name="objectname" />
+ <xsl:param name="colspan">1</xsl:param>
+ <xsl:param name="text">common.mbeanview.return</xsl:param>
+
+ <tr>
+ <td class="darkline" align="right" colspan="{$colspan}">
+ <xsl:variable name="objectname-encode">
+ <xsl:call-template name="uri-encode">
+ <xsl:with-param name="uri" select="$objectname" />
+ </xsl:call-template>
+ </xsl:variable>
+
+ <a href="/mbean?objectname={$objectname-encode}">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id"><xsl:value-of select="$text" /></xsl:with-param>
+ </xsl:call-template>
+ </a>
+ </td>
+ </tr>
+ </xsl:template>
+
+ <xsl:template name="aggregation-navigation">
+ <xsl:param name="url"/>
+ <xsl:param name="total"/>
+ <xsl:param name="step"/>
+ <xsl:param name="start"/>
+ <xsl:param name="str.prefix">common</xsl:param>
+
+ <xsl:if test="$total>$step">
+ <xsl:variable name="isfirst">
+ <xsl:choose>
+ <xsl:when test='$start=0'>true</xsl:when>
+ <xsl:when test='$start>0'>false</xsl:when>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:variable name="islast">
+ <xsl:choose>
+ <xsl:when test='$total<=($step + $start)'>true</xsl:when>
+ <xsl:otherwise>false</xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <tr><td/></tr>
+ <tr><td>
+ <xsl:choose>
+ <xsl:when test="$isfirst='false'">
+ <a href="{$url}&start=0">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id"><xsl:value-of select="concat($str.prefix, '.navigation.first')"/></xsl:with-param>
+ </xsl:call-template>
+ </a>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="str">
+ <xsl:with-param name="id"><xsl:value-of select="concat($str.prefix, '.navigation.first')"/></xsl:with-param>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ -
+ <xsl:choose>
+ <xsl:when test="$isfirst='false'">
+ <xsl:variable name="previndex" select="($start - $step)"/>
+ <a href="{$url}&start={$previndex}">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id"><xsl:value-of select="concat($str.prefix, '.navigation.previous')"/></xsl:with-param>
+ </xsl:call-template>
+ </a>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="str">
+ <xsl:with-param name="id"><xsl:value-of select="concat($str.prefix, '.navigation.previous')"/></xsl:with-param>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ -
+ <xsl:choose>
+ <xsl:when test="$islast='false'">
+ <xsl:variable name="nextindex" select="($start + $step)"/>
+ <a href="{$url}&start={$nextindex}">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id"><xsl:value-of select="concat($str.prefix, '.navigation.next')"/></xsl:with-param>
+ </xsl:call-template>
+ </a>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="str">
+ <xsl:with-param name="id"><xsl:value-of select="concat($str.prefix, '.navigation.next')"/></xsl:with-param>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ -
+ <xsl:choose>
+ <xsl:when test="$islast='false'">
+ <xsl:variable name="lastindex" select="($total - ($total mod $step))"/>
+ <a href="{$url}&start={$lastindex}">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id"><xsl:value-of select="concat($str.prefix, '.navigation.last')"/></xsl:with-param>
+ </xsl:call-template>
+ </a>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="str">
+ <xsl:with-param name="id"><xsl:value-of select="concat($str.prefix, '.navigation.last')"/></xsl:with-param>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </td>
+ </tr>
+ </xsl:if>
+ </xsl:template>
+
+ <!-- Finds a string in the strings file by id. It can replace two params -->
+ <xsl:template name="str">
+ <xsl:param name="id"/>
+ <xsl:param name="p0"/>
+ <xsl:param name="p1"/>
+
+ <xsl:variable name="str" select="$strings//str[@id=$id]" />
+
+ <!-- This is a bit lame, should be improved -->
+ <xsl:variable name="temp">
+ <xsl:call-template name="replace-param">
+ <xsl:with-param name="text" select="$str" />
+ <xsl:with-param name="paramText">{0}</xsl:with-param>
+ <xsl:with-param name="paramValue">
+ <xsl:copy-of select="$p0" />
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:choose>
+ <xsl:when test="$p1">
+ <xsl:call-template name="replace-param">
+ <xsl:with-param name="text" select="$temp" />
+ <xsl:with-param name="paramText">{1}</xsl:with-param>
+ <xsl:with-param name="paramValue">
+ <xsl:copy-of select="$p1" />
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:copy-of select="$temp"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <!-- Replaces paramText by paramValue in text -->
+ <xsl:template name="replace-param">
+ <xsl:param name="text"/>
+ <xsl:param name="paramText"/>
+ <xsl:param name="paramValue"/>
+
+ <xsl:choose>
+ <xsl:when test="contains($text, $paramText)">
+ <xsl:copy-of select="substring-before($text, $paramText)" />
+ <xsl:copy-of select="$paramValue" />
+ <xsl:copy-of select="substring-after($text, $paramText)" />
+ </xsl:when>
+
+ <xsl:otherwise>
+ <xsl:value-of select="$text" />
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+</xsl:stylesheet>
+
+
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/constructors.xsl b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/constructors.xsl
new file mode 100644
index 0000000..60dfad6
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/constructors.xsl
@@ -0,0 +1,233 @@
+<?xml version="1.0"?>
+<!--
+ Copyright (C) MX4J.
+ All rights reserved.
+
+ This software is distributed under the terms of the MX4J License version 1.0.
+ See the terms of the MX4J License in the documentation provided with this software.
+
+ Author: Carlos Quiroz (tibu@users.sourceforge.net)
+ Revision: $Revision: 1.1.1.1 $
+ -->
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+ <xsl:output method="html" indent="yes" encoding="UTF-8"/>
+
+ <xsl:param name="html.stylesheet">stylesheet.css</xsl:param>
+ <xsl:param name="html.stylesheet.type">text/css</xsl:param>
+ <xsl:param name="head.title">constructors.title</xsl:param>
+ <xsl:include href="common.xsl"/>
+ <xsl:include href="mbean_attributes.xsl"/>
+
+ <xsl:param name="request.objectname"/>
+
+ <!-- Constructor's parameters tempalte -->
+ <xsl:template name="parameters" match="Parameter">
+ <xsl:param name="class"/>
+
+ <tr>
+ <td colspan="3">
+ <p class="darklinebottom">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">constructors.parameters.title</xsl:with-param>
+ </xsl:call-template>
+ </p>
+ </td>
+ </tr>
+ <tr class="darkline">
+ <td width="3%">
+ <div class="tableheader">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">constructors.parameters.id</xsl:with-param>
+ </xsl:call-template>
+ </div>
+ </td>
+ <td>
+ <div class="tableheader">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">constructors.parameters.type</xsl:with-param>
+ </xsl:call-template>
+ </div>
+ </td>
+ <td align="right">
+ <div class="tableheader">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">constructors.parameters.value</xsl:with-param>
+ </xsl:call-template>
+ </div>
+ </td>
+ </tr>
+ <xsl:for-each select="Parameter">
+ <xsl:sort data-type="text" order="ascending" select="@id"/>
+ <xsl:variable name="type.id" select="concat('type', position()-1)"/>
+ <xsl:variable name="name.id" select="concat('value', position()-1)"/>
+ <xsl:variable name="type" select="@type"/>
+ <tr class="{$class}">
+ <td align="left" class="constructorrow">
+ <div align="left"><xsl:value-of select="@id"/></div>
+ </td>
+ <td align="left" class="constructorrow">
+ <xsl:value-of select="@type"/>
+ </td>
+ <td align="right" width="15%" class="constructorrow">
+ <xsl:choose>
+ <xsl:when test="@type='java.lang.String'
+ or @type='java.lang.Double'
+ or @type='java.lang.Short'
+ or @type='java.lang.Integer'
+ or @type='java.lang.Long'
+ or @type='java.lang.Float'
+ or @type='java.lang.Byte'
+ or @type='java.lang.Character'
+ or @type='java.lang.Boolean'
+ or @type='java.lang.Number'
+ or @type='javax.management.ObjectName'
+ or @type='int'
+ or @type='long'
+ or @type='short'
+ or @type='boolean'
+ or @type='byte'
+ or @type='char'
+ or @type='double'
+ or @type='float'">
+ <xsl:attribute name="valid">
+ true
+ </xsl:attribute>
+ <xsl:call-template name="raw-input">
+ <xsl:with-param name="name" select="$name.id"/>
+ <xsl:with-param name="type" select="$type"/>
+ <xsl:with-param name="value"/>
+ <xsl:with-param name="strinit">false</xsl:with-param>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="@strinit='true'">
+ <xsl:attribute name="valid">true</xsl:attribute>
+ <xsl:call-template name="raw-input">
+ <xsl:with-param name="name" select="$name.id"/>
+ <xsl:with-param name="type" select="$type"/>
+ <xsl:with-param name="value"/>
+ <xsl:with-param name="strinit">true</xsl:with-param>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:attribute name="valid">
+ false
+ </xsl:attribute>
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">constructors.parameters.unknowntype</xsl:with-param>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ <input type="hidden" name="{$type.id}" value="{$type}"/>
+ </td>
+ </tr>
+ </xsl:for-each>
+ </xsl:template>
+
+ <!-- Template for a Constructor node -->
+ <xsl:template match="Constructor" name="constructors">
+ <xsl:for-each select="//Constructor">
+ <form action="create">
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
+
+ <xsl:variable name="classtype">
+ <xsl:if test="(position() mod 2)=1">clearline</xsl:if>
+ <xsl:if test="(position() mod 2)=0">darkline</xsl:if>
+ </xsl:variable>
+ <xsl:variable name="hasParameters">
+ <xsl:if test="count(Parameter)>0">true</xsl:if>
+ <xsl:if test="count(Parameter)=0">false</xsl:if>
+ </xsl:variable>
+ <xsl:variable name="classname"><xsl:value-of select="@name"/></xsl:variable>
+ <tr class="{$classtype}">
+ <td valign="top" class="constructorrow">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">constructors.constructors.intro</xsl:with-param>
+ <xsl:with-param name="p0"><xsl:value-of select="@name"/></xsl:with-param>
+ </xsl:call-template>
+ </td>
+ </tr>
+ <tr class="{$classtype}">
+ <td>
+ <table cellpadding="0" width="100%" cellspacing="0" border="0">
+ <xsl:if test="$hasParameters='true'">
+ <xsl:call-template name="parameters"/>
+ </xsl:if>
+ <xsl:if test="$hasParameters='false'">
+ <tr>
+ <td width="100%" colspan="3"></td>
+ </tr>
+ </xsl:if>
+ </table>
+ </td>
+ </tr>
+ <tr class="{$classtype}">
+ <td valign="bottom" align="right" class="constructorrow">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">constructors.constructors.objectnameinput</xsl:with-param>
+ </xsl:call-template>
+ <input type="input" name="objectname"/>
+ </td>
+ </tr>
+ <tr class="{$classtype}">
+ <td align="right" class="constructorrow">
+ <xsl:variable name="str.createnew">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">constructors.constructors.createnew</xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <input type="submit" value="{$str.createnew}"/>
+ <input type="hidden" name="class" value="{$classname}"/>
+ </td>
+ </tr>
+
+ </table>
+ </form>
+ </xsl:for-each>
+ </xsl:template>
+
+ <!-- Exception handling template -->
+ <xsl:template match="Exception" name="error">
+ <xsl:for-each select="Exception">
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="fronttab">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">constructors.error.exception</xsl:with-param>
+ <xsl:with-param name="p0"><xsl:value-of select="@errorMsg"/></xsl:with-param>
+ </xsl:call-template>
+ </td>
+ </tr>
+ </table>
+ </xsl:for-each>
+ </xsl:template>
+
+ <!-- Main template -->
+ <xsl:template match="/" name="main">
+ <html>
+ <xsl:call-template name="head"/>
+ <body>
+ <xsl:call-template name="toprow"/>
+ <xsl:call-template name="tabs">
+ <xsl:with-param name="selection">mbean</xsl:with-param>
+ </xsl:call-template>
+ <xsl:for-each select="Class|Exception">
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td width="100%" class="page_title">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">constructors.main.title</xsl:with-param>
+ <xsl:with-param name="p0"><xsl:value-of select="@classname"/></xsl:with-param>
+ </xsl:call-template>
+ </td>
+ </tr>
+ </table>
+ </xsl:for-each>
+ <xsl:call-template name="error"/>
+ <xsl:call-template name="constructors"/>
+ <xsl:call-template name="bottom"/>
+ </body>
+ </html>
+ </xsl:template>
+</xsl:stylesheet>
+
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/create.xsl b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/create.xsl
new file mode 100644
index 0000000..774880b
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/create.xsl
@@ -0,0 +1,74 @@
+<?xml version="1.0"?>
+<!--
+ Copyright (C) MX4J.
+ All rights reserved.
+
+ This software is distributed under the terms of the MX4J License version 1.0.
+ See the terms of the MX4J License in the documentation provided with this software.
+
+ Author: Carlos Quiroz (tibu@users.sourceforge.net)
+ Revision: $Revision: 1.1.1.1 $
+ -->
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+ <xsl:output method="html" indent="yes" encoding="UTF-8"/>
+
+ <!-- Overall parameters -->
+ <xsl:param name="html.stylesheet">stylesheet.css</xsl:param>
+ <xsl:param name="html.stylesheet.type">text/css</xsl:param>
+ <xsl:param name="head.title">create.title</xsl:param>
+
+ <!-- Request parameters -->
+ <xsl:param name="request.objectname"/>
+ <xsl:param name="request.class"/>
+
+ <xsl:include href="common.xsl"/>
+
+ <!-- Operation processing template -->
+ <xsl:template name="operation" >
+ <xsl:for-each select="Operation">
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td width="100%" class="page_title">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">create.operation.title</xsl:with-param>
+ <xsl:with-param name="p0"><xsl:value-of select="$request.class"/></xsl:with-param>
+ <xsl:with-param name="p1"><xsl:value-of select="$request.objectname"/></xsl:with-param>
+ </xsl:call-template>
+ </td>
+ </tr>
+ <tr class="darkline">
+ <td>
+ <xsl:if test="@result='success'">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">create.operation.success</xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+ <xsl:if test="@result='error'">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">create.operation.error</xsl:with-param>
+ <xsl:with-param name="p0"><xsl:value-of select="@errorMsg"/></xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+ </td>
+ </tr>
+ <xsl:call-template name="serverview"/>
+ </table>
+ </xsl:for-each>
+ </xsl:template>
+
+ <xsl:template match="MBeanOperation">
+ <html>
+ <xsl:call-template name="head"/>
+ <body>
+ <xsl:call-template name="toprow"/>
+ <xsl:call-template name="tabs">
+ <xsl:with-param name="selection">mbean</xsl:with-param>
+ </xsl:call-template>
+ <xsl:call-template name="operation"/>
+ <xsl:call-template name="bottom"/>
+ </body>
+ </html>
+</xsl:template>
+</xsl:stylesheet>
+
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/delete.xsl b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/delete.xsl
new file mode 100644
index 0000000..af968c4
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/delete.xsl
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+<!--
+ Copyright (C) MX4J.
+ All rights reserved.
+
+ This software is distributed under the terms of the MX4J License version 1.0.
+ See the terms of the MX4J License in the documentation provided with this software.
+
+ Author: Carlos Quiroz (tibu@users.sourceforge.net)
+ Revision: $Revision: 1.1.1.1 $
+ -->
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+ <xsl:output method="html" indent="yes" encoding="UTF-8"/>
+
+ <!-- Overall parameters -->
+ <xsl:param name="html.stylesheet">stylesheet.css</xsl:param>
+ <xsl:param name="html.stylesheet.type">text/css</xsl:param>
+ <xsl:param name="head.title">delete.title</xsl:param>
+
+ <!-- Request parameters -->
+ <xsl:param name="request.objectname"/>
+
+ <xsl:include href="common.xsl"/>
+
+ <xsl:template name="operation" >
+ <xsl:for-each select="Operation">
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td colspan="2" width="100%" class="page_title">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">delete.operation.title</xsl:with-param>
+ <xsl:with-param name="p0"><xsl:value-of select="$request.objectname"/></xsl:with-param>
+ </xsl:call-template>
+ </td>
+ </tr>
+ <tr class="darkline">
+ <td>
+ <xsl:if test="@result='success'">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">delete.operation.success</xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+ <xsl:if test="@result='error'">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">delete.operation.error</xsl:with-param>
+ <xsl:with-param name="p0"><xsl:value-of select="@errorMsg"/></xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+ </td>
+ </tr>
+ <xsl:call-template name="serverview"/>
+ </table>
+ </xsl:for-each>
+ </xsl:template>
+
+ <xsl:template match="MBeanOperation">
+ <html>
+ <xsl:call-template name="head"/>
+ <body>
+ <xsl:call-template name="toprow"/>
+ <xsl:call-template name="tabs">
+ <xsl:with-param name="selection">mbean</xsl:with-param>
+ </xsl:call-template>
+ <xsl:call-template name="operation"/>
+ <xsl:call-template name="bottom"/>
+ </body>
+ </html>
+</xsl:template>
+</xsl:stylesheet>
+
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/emptymbean.xsl b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/emptymbean.xsl
new file mode 100644
index 0000000..c755f2b
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/emptymbean.xsl
@@ -0,0 +1,63 @@
+<?xml version="1.0"?>
+<!--
+ Copyright (C) MX4J.
+ All rights reserved.
+
+ This software is distributed under the terms of the MX4J License version 1.0.
+ See the terms of the MX4J License in the documentation provided with this software.
+
+ Author: Carlos Quiroz (tibu@users.sourceforge.net)
+ Revision: $Revision: 1.1.1.1 $
+ -->
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+ <xsl:output method="html" indent="yes" encoding="ISO-8859-1"/>
+ <xsl:include href="common.xsl"/>
+ <xsl:include href="xalan-ext.xsl"/>
+
+ <xsl:param name="html.stylesheet">stylesheet.css</xsl:param>
+ <xsl:param name="html.stylesheet.type">text/css</xsl:param>
+ <xsl:param name="head.title">emptymbean.title</xsl:param>
+
+ <!-- Main template -->
+ <xsl:template match="/">
+ <html>
+ <xsl:call-template name="head"/>
+ <body>
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
+ <tr width="100%">
+ <td>
+ <xsl:call-template name="toprow"/>
+ <xsl:call-template name="tabs">
+ <xsl:with-param name="selection">mbean</xsl:with-param>
+ </xsl:call-template>
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="page_title">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">emptymbean.title</xsl:with-param>
+ </xsl:call-template>
+ </td>
+ </tr>
+ <tr>
+ <form action="/constructors">
+ <td class="page_title">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">emptymbean.querycontructors</xsl:with-param>
+ </xsl:call-template>
+ <xsl:variable name="str.query">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">emptymbean.query</xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+ <input type="input" name="classname"/><input type="submit" value="{$str.query}"/>
+ </td></form></tr>
+ </table>
+ <xsl:call-template name="bottom"/>
+ </td>
+ </tr>
+ </table>
+ </body>
+ </html>
+ </xsl:template>
+</xsl:stylesheet>
+
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/error.xsl b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/error.xsl
new file mode 100644
index 0000000..3bbc4e8
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/error.xsl
@@ -0,0 +1,57 @@
+<?xml version="1.0"?>
+<!--
+ Copyright (C) MX4J.
+ All rights reserved.
+
+ This software is distributed under the terms of the MX4J License version 1.0.
+ See the terms of the MX4J License in the documentation provided with this software.
+
+ Author: Carlos Quiroz (tibu@users.sourceforge.net)
+ Revision: $Revision: 1.1.1.1 $
+ -->
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+ <xsl:output method="html" indent="yes" encoding="UTF-8"/>
+
+ <xsl:param name="html.stylesheet">stylesheet.css</xsl:param>
+ <xsl:param name="html.stylesheet.type">text/css</xsl:param>
+ <xsl:param name="head.title">error.title</xsl:param>
+ <xsl:include href="common.xsl"/>
+
+ <xsl:template match="/" name="httpexception">
+ <html>
+ <xsl:call-template name="head"/>
+ <body>
+ <xsl:call-template name="toprow"/>
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td width="100%" class="page_title">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">error.title</xsl:with-param>
+ </xsl:call-template>
+ </td>
+ </tr>
+ <xsl:for-each select="HttpException">
+ <tr>
+ <td>
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">error.httpexception.code</xsl:with-param>
+ <xsl:with-param name="p0"><xsl:value-of select="@code"/></xsl:with-param>
+ </xsl:call-template>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">error.httpexception.message</xsl:with-param>
+ <xsl:with-param name="p0"><xsl:value-of select="@description"/></xsl:with-param>
+ </xsl:call-template>
+ </td>
+ </tr>
+ </xsl:for-each>
+ </table>
+ <xsl:call-template name="bottom"/>
+ </body>
+ </html>
+ </xsl:template>
+</xsl:stylesheet>
+
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/favicon.ico b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/favicon.ico
new file mode 100644
index 0000000..fd64bfa
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/favicon.ico
Binary files differ
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/identity.xsl b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/identity.xsl
new file mode 100644
index 0000000..4977d05
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/identity.xsl
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<!--
+ Copyright (C) MX4J.
+ All rights reserved.
+
+ This software is distributed under the terms of the MX4J License version 1.0.
+ See the terms of the MX4J License in the documentation provided with this software.
+
+ Author: Carlos Quiroz (tibu@users.sourceforge.net)
+ Revision: $Revision: 1.1.1.1 $
+
+ Note: Extracted from xalan distribution
+ -->
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+<!-- From the XSLT spec: "the identity transformation can be written using xsl:copy as follows:" -->
+ <xsl:template match="@*|node()">
+ <xsl:copy>
+ <xsl:apply-templates select="@*|node()"/>
+ </xsl:copy>
+ </xsl:template>
+</xsl:stylesheet>
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/invoke.xsl b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/invoke.xsl
new file mode 100644
index 0000000..c107fb6
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/invoke.xsl
@@ -0,0 +1,95 @@
+<?xml version="1.0"?>
+<!--
+ Copyright (C) MX4J.
+ All rights reserved.
+
+ This software is distributed under the terms of the MX4J License version 1.0.
+ See the terms of the MX4J License in the documentation provided with this software.
+
+ Author: Carlos Quiroz (tibu@users.sourceforge.net)
+ Revision: $Revision: 1.1.1.1 $
+ -->
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+ <xsl:output method="html" indent="yes" encoding="UTF-8"/>
+
+ <!-- Overall parameters -->
+ <xsl:param name="html.stylesheet">stylesheet.css</xsl:param>
+ <xsl:param name="html.stylesheet.type">text/css</xsl:param>
+ <xsl:param name="head.title">invoke.title</xsl:param>
+
+ <!-- Request parameters -->
+ <xsl:param name="request.objectname"/>
+ <xsl:param name="request.method"/>
+
+ <xsl:include href="common.xsl"/>
+ <xsl:include href="mbean_attributes.xsl"/>
+
+ <!-- Operation invoke -->
+ <xsl:template name="operation" >
+ <xsl:for-each select="Operation">
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td width="100%" class="page_title">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">invoke.operation.title</xsl:with-param>
+ <xsl:with-param name="p0"><xsl:value-of select="$request.method"/></xsl:with-param>
+ <xsl:with-param name="p1"><xsl:value-of select="$request.objectname"/></xsl:with-param>
+ </xsl:call-template>
+ </td>
+ </tr>
+ <tr>
+ <td class="clearline">
+ <xsl:if test="@result='success'">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">invoke.operation.success</xsl:with-param>
+ </xsl:call-template>
+ <br/>
+ <xsl:if test="not (@return='')">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">invoke.operation.success.result</xsl:with-param>
+ <xsl:with-param name="p0">
+ <xsl:call-template name="renderobject">
+ <xsl:with-param name="objectclass" select="@returnclass"/>
+ <xsl:with-param name="objectvalue" select="@return"/>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+ <xsl:if test="@return=''">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">invoke.operation.success.noresult</xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+ </xsl:if>
+ <xsl:if test="@result='error'">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">invoke.operation.success.error</xsl:with-param>
+ <xsl:with-param name="p0"><xsl:value-of select="@errorMsg"/></xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+ </td>
+ </tr>
+ <xsl:call-template name="mbeanview">
+ <xsl:with-param name="objectname" select="$request.objectname"/>
+ </xsl:call-template>
+ </table>
+ </xsl:for-each>
+ </xsl:template>
+
+ <!-- Main template -->
+ <xsl:template match="MBeanOperation" name="main">
+ <html>
+ <xsl:call-template name="head"/>
+ <body>
+ <xsl:call-template name="toprow"/>
+ <xsl:call-template name="tabs">
+ <xsl:with-param name="selection">mbean</xsl:with-param>
+ </xsl:call-template>
+ <xsl:call-template name="operation"/>
+ <xsl:call-template name="bottom"/>
+ </body>
+ </html>
+ </xsl:template>
+</xsl:stylesheet>
+
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/logo.gif b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/logo.gif
new file mode 100644
index 0000000..31522aa
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/logo.gif
Binary files differ
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/mbean.xsl b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/mbean.xsl
new file mode 100644
index 0000000..bbde9fc
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/mbean.xsl
@@ -0,0 +1,391 @@
+<?xml version="1.0"?>
+<!--
+ Copyright (C) MX4J.
+ All rights reserved.
+
+ This software is distributed under the terms of the MX4J License version 1.0.
+ See the terms of the MX4J License in the documentation provided with this software.
+
+ Author: Carlos Quiroz (tibu@users.sourceforge.net)
+ Contribution: Lachezar Dobrev (l.dobrev@lsnsoft.com)
+ Revision: $Revision: 1.1.1.1 $
+ -->
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+ <xsl:output method="html" indent="yes" encoding="UTF-8"/>
+
+ <xsl:param name="html.stylesheet">stylesheet.css</xsl:param>
+ <xsl:param name="html.stylesheet.type">text/css</xsl:param>
+ <xsl:param name="head.title">mbean.title</xsl:param>
+ <xsl:include href="common.xsl"/>
+ <xsl:include href="mbean_attributes.xsl"/>
+
+ <xsl:param name="request.objectname"/>
+
+ <xsl:template name="parameters" match="Parameter">
+ <xsl:param name="class"/>
+ <xsl:for-each select="Parameter">
+ <xsl:sort data-type="text" order="ascending" select="@id"/>
+ <xsl:variable name="type.id" select="concat('type', position()-1)"/>
+ <xsl:variable name="name.id" select="concat('value', position()-1)"/>
+ <xsl:variable name="type" select="@type"/>
+ <tr class="{$class}">
+ <td width="4%" align="left" class="mbean_row">
+ <div align="left"><xsl:value-of select="@id"/></div>
+ </td>
+ <td width="18%" align="left" class="mbean_row">
+ <xsl:value-of select="@name"/>
+ </td>
+ <td width="18%" align="left" class="mbean_row">
+ <xsl:value-of select="@description"/>
+ </td>
+ <td width="45%" align="left" class="mbean_row">
+ <xsl:value-of select="@type"/>
+ </td>
+ <td align="right" width="15%" class="mbean_row">
+ <xsl:choose>
+ <xsl:when test="@type='java.lang.String'
+ or @type='java.lang.String'
+ or @type='java.lang.Double'
+ or @type='java.lang.Short'
+ or @type='java.lang.Integer'
+ or @type='java.lang.Long'
+ or @type='java.lang.Float'
+ or @type='java.lang.Byte'
+ or @type='java.lang.Boolean'
+ or @type='java.lang.Number'
+ or @type='java.lang.Character'
+ or @type='javax.management.ObjectName'
+ or @type='int'
+ or @type='short'
+ or @type='boolean'
+ or @type='byte'
+ or @type='double'
+ or @type='long'
+ or @type='char'
+ or @type='float'">
+ <xsl:attribute name="valid">true</xsl:attribute>
+ <xsl:call-template name="raw-input">
+ <xsl:with-param name="name" select="$name.id"/>
+ <xsl:with-param name="type" select="$type"/>
+ <xsl:with-param name="value"/>
+ <xsl:with-param name="strinit">false</xsl:with-param>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="@strinit='true'">
+ <xsl:attribute name="valid">true</xsl:attribute>
+ <xsl:call-template name="raw-input">
+ <xsl:with-param name="name" select="$name.id"/>
+ <xsl:with-param name="type" select="$type"/>
+ <xsl:with-param name="value"/>
+ <xsl:with-param name="strinit">true</xsl:with-param>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:attribute name="valid">false</xsl:attribute>
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">mbean.parameters.unknown</xsl:with-param>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ <input type="hidden" name="{$type.id}" value="{$type}"/>
+ </td>
+ </tr>
+ </xsl:for-each>
+ </xsl:template>
+
+ <xsl:template name="operations">
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td colspan="7" width="100%" class="mbeans">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">mbean.operations.title</xsl:with-param>
+ </xsl:call-template>
+ </td>
+ </tr>
+ </table>
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
+ <tr class="darkline">
+ <td width="20%">
+ <div class="tableheader">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">mbean.operations.name</xsl:with-param>
+ </xsl:call-template>
+ </div>
+ </td>
+ <td width="20%">
+ <div class="tableheader">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">mbean.operations.returntype</xsl:with-param>
+ </xsl:call-template>
+ </div>
+ </td>
+ <td width="*">
+ <div class="tableheader">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">mbean.operations.description</xsl:with-param>
+ </xsl:call-template>
+ </div>
+ </td>
+ <td/>
+ </tr>
+ <xsl:variable name="invoke.str">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">mbean.operations.invoke</xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:for-each select="Operation">
+ <xsl:variable name="name"><xsl:value-of select="@name"/></xsl:variable>
+ <xsl:variable name="classtype">
+ <xsl:if test="(position() mod 2)=1">clearline</xsl:if>
+ <xsl:if test="(position() mod 2)=0">darkline</xsl:if>
+ </xsl:variable>
+ <xsl:variable name="hasParameters">
+ <xsl:if test="count(./Parameter)>0">true</xsl:if>
+ <xsl:if test="count(./Parameter)=0">false</xsl:if>
+ </xsl:variable>
+
+
+ <tr class="{$classtype}">
+ <form action="invoke">
+ <input name="operation" type="hidden" value="{$name}"/>
+ <input type="hidden" name="objectname" value="{$request.objectname}"/>
+ <td width="20%" align="left" class="mbean_row">
+ <xsl:value-of select="@name"/>
+ </td>
+ <td align="left" class="mbean_row">
+ <xsl:value-of select="@return"/>
+ </td>
+ <td align="left" class="mbean_row">
+ <xsl:value-of select="@description"/>
+ </td>
+ <xsl:if test="$hasParameters='false'">
+ <td align="center" class="mbean_row">
+ <input type="submit" value="{$invoke.str}"/>
+ </td>
+ </xsl:if>
+ <xsl:if test="$hasParameters='true'">
+ <td/>
+ <tr class="{$classtype}">
+ <td valign="top" align="left" width="20%" class="mbean_row">
+ <strong>
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">mbean.operations.parameter</xsl:with-param>
+ </xsl:call-template>
+ </strong>
+ </td>
+ <td colspan="2">
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
+ <tr class="{$classtype}">
+ <td width="4%" class="mbean_row">
+ <strong>
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">mbean.operations.parameterid</xsl:with-param>
+ </xsl:call-template>
+ </strong>
+ </td>
+ <td width="18%" class="mbean_row">
+ <strong>
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">mbean.operations.parametername</xsl:with-param>
+ </xsl:call-template>
+ </strong>
+ </td>
+ <td width="50%" class="mbean_row">
+ <strong>
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">mbean.operations.parameterdescription</xsl:with-param>
+ </xsl:call-template>
+ </strong>
+ </td>
+ <td class="mbean_row">
+ <strong>
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">mbean.operations.parameterclass</xsl:with-param>
+ </xsl:call-template>
+ </strong>
+ </td>
+ </tr>
+ <xsl:call-template name="parameters">
+ <xsl:with-param name="class" select="$classtype"/>
+ </xsl:call-template>
+ </table>
+ <td align="center" valign="bottom">
+ <input style="pad-right: 1em;" type="submit" value="{$invoke.str}"/>
+ </td>
+ </td>
+ </tr>
+ </xsl:if>
+ </form>
+ </tr>
+ </xsl:for-each>
+ </table>
+ </xsl:template>
+
+ <xsl:template name="constructors">
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
+ <xsl:for-each select="Constructor">
+ <xsl:if test="(position())=1">
+ <tr class="darkline">
+ <td>
+ <div class="tableheader">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">mbean.constructors.class</xsl:with-param>
+ </xsl:call-template>
+ </div>
+ </td>
+ <td>
+ <div class="tableheader">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">mbean.constructors.description</xsl:with-param>
+ </xsl:call-template>
+ </div>
+ </td>
+
+ </tr>
+ </xsl:if>
+ <form action="create">
+ <xsl:variable name="classtype">
+ <xsl:if test="(position() mod 2)=1">clearline</xsl:if>
+ <xsl:if test="(position() mod 2)=0">darkline</xsl:if>
+ </xsl:variable>
+ <xsl:variable name="classname"><xsl:value-of select="../@classname"/></xsl:variable>
+ <tr class="{$classtype}">
+ <td class="mbean_row">
+ <xsl:value-of select="$classname"/>
+ </td>
+ <td class="mbean_row">
+ <xsl:value-of select="@description"/>
+ </td>
+ </tr>
+ <tr class="{$classtype}">
+ <td valign="top" align="left" width="20%" class="mbean_row">
+ <strong>
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">mbean.constructors.parameter</xsl:with-param>
+ </xsl:call-template>
+ </strong>
+ </td>
+ <td>
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td width="4%" class="mbean_row">
+ <strong>
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">mbean.constructors.parameterid</xsl:with-param>
+ </xsl:call-template>
+ </strong>
+ </td>
+ <td width="18%" class="mbean_row">
+ <strong>
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">mbean.constructors.parametername</xsl:with-param>
+ </xsl:call-template>
+ </strong>
+ </td>
+ <td width="50%" class="mbean_row">
+ <strong>
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">mbean.constructors.parameterdescription</xsl:with-param>
+ </xsl:call-template>
+ </strong>
+ </td>
+ <td class="mbean_row">
+ <strong>
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">mbean.constructors.parameterclass</xsl:with-param>
+ </xsl:call-template>
+ </strong>
+ </td>
+ </tr>
+ <xsl:call-template name="parameters">
+ <!--<xsl:with-param name="class" select="$classtype"/>-->
+ </xsl:call-template>
+ </table>
+ </td>
+ </tr>
+ <tr class="{$classtype}">
+ <td class="mbean_row" align="right" colspan="2">
+ <strong>
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">mbean.constructors.objectname</xsl:with-param>
+ </xsl:call-template>
+ </strong>
+ <input name="objectname" value=""/>
+ </td>
+ </tr>
+ <tr class="{$classtype}">
+ <td class="mbean_row" colspan="2">
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
+ <tr class="$class">
+ <td align="right" colspan="4"/>
+ <td align="right" class="mbean_row">
+ <xsl:variable name="create.str">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">mbean.constructors.create</xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+ <input type="submit" value="{$create.str}"/>
+ <input type="hidden" name="class" value="{$classname}"/>
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ </form>
+ </xsl:for-each>
+ </table>
+ </xsl:template>
+
+ <!-- Main processing template -->
+ <xsl:template match="MBean">
+ <html>
+ <xsl:call-template name="head"/>
+ <body>
+ <xsl:call-template name="toprow"/>
+ <xsl:call-template name="tabs">
+ <xsl:with-param name="selection">mbean</xsl:with-param>
+ </xsl:call-template>
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="page_title">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">mbean.mbean.title</xsl:with-param>
+ <xsl:with-param name="p0"><xsl:value-of select="@objectname"/></xsl:with-param>
+ </xsl:call-template>
+
+ <xsl:if test="not (@description='')">
+ <br/>
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">mbean.mbean.description</xsl:with-param>
+ <xsl:with-param name="p0"><xsl:value-of select="@description"/></xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+ </td>
+ </tr>
+ <tr>
+ <td width="100%" class="mbeans">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">mbean.mbean.attributes</xsl:with-param>
+ </xsl:call-template>
+ </td>
+ </tr>
+ </table>
+ <xsl:call-template name="attribute"/>
+ <xsl:call-template name="operations"/>
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td colspan="7" width="100%" class="mbeans">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">mbean.mbean.constructors</xsl:with-param>
+ </xsl:call-template>
+ </td>
+ </tr>
+ </table>
+ <xsl:call-template name="constructors"/>
+ <xsl:call-template name="bottom"/>
+ </body>
+ </html>
+</xsl:template>
+</xsl:stylesheet>
+
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/mbean_attributes.xsl b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/mbean_attributes.xsl
new file mode 100644
index 0000000..6a87530
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/mbean_attributes.xsl
@@ -0,0 +1,377 @@
+<?xml version="1.0"?>
+<!--
+ Copyright (C) MX4J.
+ All rights reserved.
+
+ This software is distributed under the terms of the MX4J License version 1.0.
+ See the terms of the MX4J License in the documentation provided with this software.
+
+ Author: Carlos Quiroz (tibu@users.sourceforge.net)
+ Revision: $Revision: 1.1.1.1 $
+ -->
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+ <xsl:output method="html" indent="yes" encoding="UTF-8"/>
+
+ <!-- array link generator -->
+ <xsl:template name="array">
+
+ <xsl:choose>
+ <xsl:when test="@isnull='false'">
+ <xsl:variable name="url">getattribute?objectname=<xsl:value-of select="../@objectname"/>&attribute=<xsl:value-of select="@name"/>&format=array&template=viewarray</xsl:variable>
+ <a href="{$url}">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">mbean_attributes.array.view</xsl:with-param>
+ </xsl:call-template>
+ </a>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">mbean_attributes.array.null</xsl:with-param>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <!-- Collection link generator -->
+ <xsl:template name="collection">
+
+ <xsl:choose>
+ <xsl:when test="@isnull='false'">
+ <xsl:variable name="url">getattribute?objectname=<xsl:value-of select="../@objectname"/>&attribute=<xsl:value-of select="@name"/>&format=collection&template=viewcollection</xsl:variable>
+ <a href="{$url}">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">mbean_attributes.collection.view</xsl:with-param>
+ </xsl:call-template>
+ </a>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">mbean_attributes.collection.null</xsl:with-param>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <!-- Map link generator -->
+ <xsl:template name="map">
+
+ <xsl:choose>
+ <xsl:when test="@isnull='false'">
+ <xsl:variable name="url">getattribute?objectname=<xsl:value-of select="../@objectname"/>&attribute=<xsl:value-of select="@name"/>&format=map&template=viewmap</xsl:variable>
+ <a href="{$url}">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">mbean_attributes.map.view</xsl:with-param>
+ </xsl:call-template>
+ </a>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">mbean_attributes.map.null</xsl:with-param>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <!-- Composite data -->
+ <xsl:template name="compositedata">
+
+ <xsl:choose>
+ <xsl:when test="@isnull='false'">
+ <xsl:variable name="url">getattribute?objectname=<xsl:value-of select="../@objectname"/>&attribute=<xsl:value-of select="@name"/>&format=compositedata&template=identity</xsl:variable>
+ <a href="{$url}">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">mbean_attributes.compositedata.view</xsl:with-param>
+ </xsl:call-template>
+ </a>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">mbean_attributes.compositedata.null</xsl:with-param>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <!-- Composite data -->
+ <xsl:template name="tabulardata">
+
+ <xsl:choose>
+ <xsl:when test="@isnull='false'">
+ <xsl:variable name="url">getattribute?objectname=<xsl:value-of select="../@objectname"/>&attribute=<xsl:value-of select="@name"/>&format=tabulardata&template=viewtabulardata</xsl:variable>
+ <a href="{$url}">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">mbean_attributes.tabulardata.view</xsl:with-param>
+ </xsl:call-template>
+ </a>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">mbean_attributes.tabulardata.null</xsl:with-param>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template name="raw-input">
+ <xsl:param name="type"/>
+ <xsl:param name="value"/>
+ <xsl:param name="name"/>
+ <xsl:param name="strinit"/>
+
+ <xsl:variable name="result">none</xsl:variable>
+ <xsl:choose>
+ <xsl:when test="$type='java.lang.Boolean' or $type='boolean'">
+ <xsl:choose>
+ <xsl:when test="$value='true'">
+ <input name="{$name}" type="radio" checked="checked" value="true">true </input>
+ <input name="{$name}" type="radio" value="false">false </input>
+ </xsl:when>
+ <xsl:when test="$value='false'">
+ <input name="{$name}" type="radio" value="true">true </input>
+ <input name="{$name}" type="radio" checked="checked" value="false">false </input>
+ </xsl:when>
+ <xsl:otherwise>
+ <input name="{$name}" type="radio" value="true">true </input>
+ <input name="{$name}" type="radio" value="false">false </input>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ <xsl:otherwise>
+ <input type="text" name="{$name}" value="{$value}"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template match="Attribute[@type]" name="form">
+ <xsl:param name="value"/>
+ <xsl:choose>
+ <xsl:when test="@strinit='true'">
+ <xsl:variable name="name" select="@name"/>
+ <xsl:call-template name="raw-input">
+ <xsl:with-param name="type" select="@type"/>
+ <xsl:with-param name="value" select="$value"/>
+ <xsl:with-param name="name">value_<xsl:value-of select="@name"/>
+ </xsl:with-param>
+ <xsl:with-param name="strinit">true</xsl:with-param>
+ </xsl:call-template>
+ <xsl:call-template name="submit">
+ <xsl:with-param name="name" select="@name"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">mbean_attributes.form.unknowntype</xsl:with-param>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <!-- Makes the submit button for setting one attribute -->
+ <xsl:template match="Attribute[@type]" name="submit">
+ <xsl:param name="name"/>
+ <xsl:if test="@strinit='true'">
+ <xsl:variable name="str.set">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">mbean_attributes.submit.set</xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+ <input type="Submit" name="set_{$name}" value="{$str.set}"/>
+ </xsl:if>
+ </xsl:template>
+
+ <!-- makes a link for objectnames from current value element -->
+ <xsl:template name="objectnamevalue">
+ <xsl:call-template name="renderobject">
+ <xsl:with-param name="objectclass">javax.management.ObjectName</xsl:with-param>
+ <xsl:with-param name="objectvalue" select="@value"/>
+ </xsl:call-template>
+ </xsl:template>
+
+ <!-- Renders an object
+ Currently transforms javax.management.ObjectName to links
+ Renders others as strings -->
+ <xsl:template name="renderobject">
+ <xsl:param name="objectclass"/>
+ <xsl:param name="objectvalue"/>
+ <xsl:choose>
+ <xsl:when test="$objectclass='javax.management.ObjectName'">
+ <xsl:variable name="name_encoded">
+ <xsl:call-template name="uri-encode">
+ <xsl:with-param name="uri">
+ <xsl:value-of select="$objectvalue"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+ <a href="/mbean?objectname={$name_encoded}">
+ <xsl:value-of select="$objectvalue"/>
+ </a>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$objectvalue"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template match="Attribute" name="WO">
+ <td align="right" class="mbean_row">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">mbean_attributes.WO.readonly</xsl:with-param>
+ </xsl:call-template>
+ </td>
+ <td align="right" class="mbean_row">
+ <xsl:call-template name="form"/>
+ </td>
+ </xsl:template>
+
+ <!-- Template for readwrite attributes -->
+ <xsl:template match="Attribute" name="RW">
+ <td align="right" class="mbean_row">
+ <xsl:choose>
+ <xsl:when test="@aggregation='collection'">
+ <xsl:call-template name="collection"/>
+ </xsl:when>
+ <xsl:when test="@aggregation='map'">
+ <xsl:call-template name="map"/>
+ </xsl:when>
+ <xsl:when test="starts-with(@type, '[L')">
+ <xsl:call-template name="array"/>
+ </xsl:when>
+ <xsl:when test="@type='javax.management.ObjectName'">
+ <xsl:call-template name="objectnamevalue"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="@value"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </td>
+ <td align="right" class="mbean_row">
+ <xsl:call-template name="form">
+ <xsl:with-param name="value" select="@value"/>
+ </xsl:call-template>
+ </td>
+ </xsl:template>
+
+ <!-- Template for readonly attributes -->
+ <xsl:template match="Attribute" name="RO">
+ <td align="right" class="mbean_row">
+ <xsl:choose>
+ <xsl:when test="@aggregation='collection'">
+ <xsl:call-template name="collection"/>
+ </xsl:when>
+ <xsl:when test="@aggregation='map'">
+ <xsl:call-template name="map"/>
+ </xsl:when>
+ <xsl:when test="starts-with(@type, '[L')">
+ <xsl:call-template name="array"/>
+ </xsl:when>
+ <xsl:when test="@type='javax.management.ObjectName'">
+ <xsl:call-template name="objectnamevalue"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="@value"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </td>
+ <td align="right" class="mbean_row">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">mbean_attributes.RO.readonly</xsl:with-param>
+ </xsl:call-template>
+ </td>
+ </xsl:template>
+
+ <!-- MBean's attributes template -->
+ <xsl:template name="attribute">
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
+ <tr class="darkline">
+ <td width="20%" align="left" class="darkline">
+ <div class="tableheader">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">mbean_attributes.attribute.name</xsl:with-param>
+ </xsl:call-template>
+ </div>
+ </td>
+ <td width="20%" align="left" class="darkline">
+ <div class="tableheader">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">mbean_attributes.attribute.description</xsl:with-param>
+ </xsl:call-template>
+ </div>
+ </td>
+ <td width="20%" align="left" class="darkline">
+ <div class="tableheader">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">mbean_attributes.attribute.type</xsl:with-param>
+ </xsl:call-template>
+ </div>
+ </td>
+ <td width="20%" align="right" class="darkline">
+ <div class="tableheader">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">mbean_attributes.attribute.value</xsl:with-param>
+ </xsl:call-template>
+ </div>
+ </td>
+ <td width="*" align="right" class="darkline">
+ <div class="tableheader">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">mbean_attributes.attribute.newvalue</xsl:with-param>
+ </xsl:call-template>
+ </div>
+ </td>
+ </tr>
+ <form action="setattributes" method="get">
+ <xsl:for-each select="Attribute">
+ <xsl:sort data-type="text" order="ascending" select="@name"/>
+ <xsl:variable name="classtype">
+ <xsl:if test="(position() mod 2)=1">clearline</xsl:if>
+ <xsl:if test="(position() mod 2)=0">darkline</xsl:if>
+ </xsl:variable>
+ <tr class="{$classtype}">
+ <td class="mbean_row">
+ <xsl:value-of select="@name"/>
+ </td>
+ <td class="mbean_row">
+ <xsl:value-of select="@description"/>
+ </td>
+ <td class="mbean_row">
+ <xsl:choose>
+ <xsl:when test="starts-with(@type, '[L')">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">mbean_attributes.attribute.arrayof</xsl:with-param>
+ <xsl:with-param name="p0">
+ <xsl:value-of select="substring-before(substring-after(@type, '[L'), ';')"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="@type"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </td>
+ <xsl:choose>
+ <xsl:when test="@availability='RO'">
+ <xsl:call-template name="RO"/>
+ </xsl:when>
+ <xsl:when test="@availability='RW'">
+ <xsl:call-template name="RW"/>
+ </xsl:when>
+ <xsl:when test="@availability='WO'">
+ <xsl:call-template name="WO"/>
+ </xsl:when>
+ </xsl:choose>
+ </tr>
+ </xsl:for-each>
+ <td colspan="5" align="right" class="attributes_setall">
+ <input type="hidden" name="objectname" value="{$request.objectname}"/>
+ <xsl:variable name="str.setall">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">mbean_attributes.attribute.setall</xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+ <input type="Submit" name="setall" value="{$str.setall}"/>
+ </td>
+ </form>
+ </table>
+ </xsl:template>
+</xsl:stylesheet>
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/mlet.xsl b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/mlet.xsl
new file mode 100644
index 0000000..5fd78ad
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/mlet.xsl
@@ -0,0 +1,81 @@
+<?xml version="1.0"?>
+<!--
+ Copyright (C) MX4J.
+ All rights reserved.
+
+ This software is distributed under the terms of the MX4J License version 1.0.
+ See the terms of the MX4J License in the documentation provided with this software.
+
+ Author: Carlos Quiroz (tibu@users.sourceforge.net)
+ Revision: $Revision: 1.1.1.1 $
+ -->
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+ <xsl:output method="html" indent="yes" encoding="UTF-8"/>
+
+ <xsl:param name="html.stylesheet">stylesheet.css</xsl:param>
+ <xsl:param name="html.stylesheet.type">text/css</xsl:param>
+ <xsl:param name="head.title">mlet.title</xsl:param>
+ <xsl:include href="common.xsl"/>
+
+ <xsl:template name="domain">
+ <xsl:for-each select="Domain[Mbean]">
+ <tr>
+ <td class="domainline">
+ <div class="domainheading"><xsl:value-of select="@name"/></div>
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
+ <xsl:call-template name="mbean"/>
+ </table>
+ </td>
+ </tr>
+ </xsl:for-each>
+ </xsl:template>
+
+ <xsl:template match="MBean" name="mbean">
+ <xsl:for-each select="MBean">
+ <tr>
+ <xsl:variable name="classtype">
+ <xsl:if test="(position() mod 2)=1">darkline</xsl:if>
+ <xsl:if test="(position() mod 2)=0">clearline</xsl:if>
+ </xsl:variable>
+ <xsl:variable name="objectname" select="@objectname"/>
+ <td class="{$classtype}">
+ <a href="mbean?objectname={$objectname}"><xsl:value-of select="$objectname"/></a>
+ </td>
+ <td align="right" class="{$classtype}">
+ <a href="delete?objectname={$objectname}">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">mlet.mbean.unregister</xsl:with-param>
+ </xsl:call-template>
+ </a>
+ </td>
+ </tr>
+ </xsl:for-each>
+ </xsl:template>
+
+ <!-- Main processing template -->
+ <xsl:template match="Server" name="main">
+ <html>
+ <xsl:call-template name="head"/>
+ <body>
+ <xsl:call-template name="toprow"/>
+ <xsl:call-template name="tabs">
+ <xsl:with-param name="selection">mlet</xsl:with-param>
+ </xsl:call-template>
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td colspan="7" width="100%" class="page_title">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">mlet.main.title</xsl:with-param>
+ </xsl:call-template>
+ </td>
+ </tr>
+ </table>
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
+ <xsl:call-template name="domain"/>
+ </table>
+ <xsl:call-template name="bottom"/>
+ </body>
+ </html>
+</xsl:template>
+</xsl:stylesheet>
+
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/monitor.xsl b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/monitor.xsl
new file mode 100644
index 0000000..952a57f
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/monitor.xsl
@@ -0,0 +1,147 @@
+<?xml version="1.0"?>
+<!--
+ Copyright (C) MX4J.
+ All rights reserved.
+
+ This software is distributed under the terms of the MX4J License version 1.0.
+ See the terms of the MX4J License in the documentation provided with this software.
+
+ Author: Carlos Quiroz (tibu@users.sourceforge.net)
+ Revision: $Revision: 1.1.1.1 $
+ -->
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+ <xsl:output method="html" indent="yes" encoding="UTF-8"/>
+
+ <xsl:param name="html.stylesheet">stylesheet.css</xsl:param>
+ <xsl:param name="html.stylesheet.type">text/css</xsl:param>
+ <xsl:param name="head.title">monitor.title</xsl:param>
+ <xsl:include href="common.xsl"/>
+
+ <!-- Domain template -->
+ <xsl:template name="domain">
+ <xsl:for-each select="Domain[MBean]">
+ <tr>
+ <td class="domainline">
+ <div class="domainheading"><xsl:value-of select="@name"/></div>
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
+ <xsl:call-template name="mbean"/>
+ </table>
+ </td>
+ </tr>
+ </xsl:for-each>
+ </xsl:template>
+
+ <!-- MBean template -->
+ <xsl:template match="MBean" name="mbean">
+ <xsl:for-each select="MBean">
+ <tr>
+ <xsl:variable name="classtype">
+ <xsl:if test="(position() mod 2)=1">darkline</xsl:if>
+ <xsl:if test="(position() mod 2)=0">clearline</xsl:if>
+ </xsl:variable>
+ <xsl:variable name="objectname">
+ <xsl:call-template name="uri-encode">
+ <xsl:with-param name="uri" select="@objectname"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <td class="{$classtype}">
+ <a href="mbean?objectname={$objectname}"><xsl:value-of select="@objectname"/></a>
+ </td>
+ <td align="right" class="{$classtype}">
+ <a href="delete?objectname={$objectname}">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">monitor.mbean.unregister</xsl:with-param>
+ </xsl:call-template>
+ </a>
+ </td>
+ </tr>
+ </xsl:for-each>
+ </xsl:template>
+
+ <!-- Main template -->
+ <xsl:template match="Server" name="main">
+ <html>
+ <xsl:call-template name="head"/>
+ <body>
+ <xsl:call-template name="toprow"/>
+ <xsl:call-template name="tabs">
+ <xsl:with-param name="selection">monitor</xsl:with-param>
+ </xsl:call-template>
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td colspan="7" width="100%" class="page_title">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">monitor.main.title</xsl:with-param>
+ </xsl:call-template>
+ </td>
+ </tr>
+ <tr class="fronttab">
+ <form action="create">
+ <xsl:variable name="str.createstring.button">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">monitor.main.createstring.button</xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+ <td width="100%" align="right">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">monitor.main.createstring.label</xsl:with-param>
+ </xsl:call-template>
+ <input type="input" name="objectname"/>
+ <input type="hidden" name="template" value="monitor_create"/>
+ <input type="hidden" name="class" value="javax.management.monitor.StringMonitor"/>
+ </td>
+ <td align="right">
+ <input type="submit" style="width: 15em;" value="{$str.createstring.button}"/>
+ </td>
+ </form>
+ </tr>
+ <tr class="fronttab">
+ <form action="create">
+ <xsl:variable name="str.creategauge.button">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">monitor.main.creategauge.button</xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+ <td align="right">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">monitor.main.creategauge.label</xsl:with-param>
+ </xsl:call-template>
+ <input type="input" name="objectname"/>
+ <input type="hidden" name="template" value="monitor_create"/>
+ <input type="hidden" name="class" value="javax.management.monitor.GaugeMonitor"/>
+ </td>
+ <td align="right">
+ <input type="submit" style="width: 15em;" value="{$str.creategauge.button}"/>
+ </td>
+ </form>
+ </tr>
+ <tr class="fronttab">
+ <form action="create">
+ <xsl:variable name="str.createcounter.button">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">monitor.main.createcounter.button</xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+ <td width="100%" align="right">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">monitor.main.createcounter.label</xsl:with-param>
+ </xsl:call-template>
+ <input type="input" name="objectname"/>
+ </td>
+ <td align="right">
+ <input type="hidden" name="template" value="monitor_create"/>
+ <input type="hidden" name="class" value="javax.management.monitor.CounterMonitor"/>
+ <input type="submit" style="width: 15em;" value="{$str.createcounter.button}"/>
+ </td>
+ </form>
+ </tr>
+ </table>
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
+ <xsl:call-template name="domain"/>
+ </table>
+ <xsl:call-template name="bottom"/>
+ </body>
+ </html>
+ </xsl:template>
+</xsl:stylesheet>
+
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/monitor_create.xsl b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/monitor_create.xsl
new file mode 100644
index 0000000..1c39bab
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/monitor_create.xsl
@@ -0,0 +1,99 @@
+<?xml version="1.0"?>
+<!--
+ Copyright (C) MX4J.
+ All rights reserved.
+
+ This software is distributed under the terms of the MX4J License version 1.0.
+ See the terms of the MX4J License in the documentation provided with this software.
+
+ Author: Carlos Quiroz (tibu@users.sourceforge.net)
+ Revision: $Revision: 1.1.1.1 $
+ -->
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+ <xsl:output method="html" indent="yes" encoding="UTF-8"/>
+
+ <!-- Overall parameters -->
+ <xsl:param name="html.stylesheet">stylesheet.css</xsl:param>
+ <xsl:param name="html.stylesheet.type">text/css</xsl:param>
+ <xsl:param name="head.title">monitor_create.title</xsl:param>
+
+ <!-- Request parameters -->
+ <xsl:param name="request.objectname"/>
+ <xsl:param name="request.class"/>
+
+ <xsl:include href="common.xsl"/>
+
+ <xsl:template name="operation" >
+ <xsl:for-each select="Operation">
+ <xsl:variable name="monitor_type">
+ <xsl:if test="$request.class='javax.management.monitor.StringMonitor'">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">monitor_create.operation.stringmonitor</xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+ <xsl:if test="$request.class='javax.management.monitor.GaugeMonitor'">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">monitor_create.operation.gaguemonitor</xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+ <xsl:if test="$request.class='javax.management.monitor.CounterMonitor'">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">monitor_create.operation.countermonitor</xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+ </xsl:variable>
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td width="100%" class="page_title"><xsl:value-of select="$monitor_type"/>
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">monitor_create.operation.title</xsl:with-param>
+ <xsl:with-param name="p0"><xsl:value-of select="$request.objectname"/></xsl:with-param>
+ </xsl:call-template>
+ </td>
+ </tr>
+ <tr>
+ <td class="clearline">
+ <xsl:if test="@result='success'">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">monitor_create.operation.success</xsl:with-param>
+ <xsl:with-param name="p0"><xsl:value-of select="$monitor_type"/></xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+ <xsl:if test="@result='error'">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">monitor_create.operation.error</xsl:with-param>
+ <xsl:with-param name="p0"><xsl:value-of select="$monitor_type"/></xsl:with-param>
+ <xsl:with-param name="p1"><xsl:value-of select="@errorMsg"/></xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+ </td>
+ </tr>
+ <xsl:if test="@result='success'">
+ <xsl:call-template name="mbeanview">
+ <xsl:with-param name="objectname"><xsl:value-of select="$request.objectname"/></xsl:with-param>
+ <xsl:with-param name="text">monitor_create.operation.mbeanview</xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+ <xsl:if test="@result='error'">
+ <xsl:call-template name="serverview"/>
+ </xsl:if>
+ </table>
+ </xsl:for-each>
+ </xsl:template>
+
+ <xsl:template match="MBeanOperation">
+ <html>
+ <xsl:call-template name="head"/>
+ <body>
+ <xsl:call-template name="toprow"/>
+ <xsl:call-template name="tabs">
+ <xsl:with-param name="selection">timer</xsl:with-param>
+ </xsl:call-template>
+ <xsl:call-template name="operation"/>
+ <xsl:call-template name="bottom"/>
+ </body>
+ </html>
+</xsl:template>
+</xsl:stylesheet>
+
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/relation.xsl b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/relation.xsl
new file mode 100644
index 0000000..f89317c
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/relation.xsl
@@ -0,0 +1,179 @@
+<?xml version="1.0"?>
+<!--
+ Copyright (C) MX4J.
+ All rights reserved.
+
+ This software is distributed under the terms of the MX4J License version 1.0.
+ See the terms of the MX4J License in the documentation provided with this software.
+
+ Author: Bronwen Cassidy (shadow12@users.sourceforge.net)
+ Revision: $Revision: 1.1.1.1 $
+ -->
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+ <xsl:output method="html" indent="yes" encoding="UTF-8"/>
+
+ <xsl:param name="html.stylesheet">stylesheet.css</xsl:param>
+ <xsl:param name="html.stylesheet.type">text/css</xsl:param>
+ <xsl:param name="head.title">relation.title</xsl:param>
+ <xsl:include href="common.xsl"/>
+
+ <xsl:template match="relation-type-name" name="relationtypename">
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td colspan="7" width="50%" class="mbeans">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">relation.typename.title</xsl:with-param>
+ </xsl:call-template>
+ </td>
+ <td colspan="7" width="50%" class="mbeans"><xsl:value-of select="@name"/></td>
+ </tr>
+ <tr class="darkline">
+ <td>
+ <div class="tableheader">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">relation.metadata.title</xsl:with-param>
+ </xsl:call-template>
+ </div>
+ </td>
+ </tr>
+ <tr><xsl:apply-templates select="./relation-meta-data"/></tr>
+ <tr class="darkline">
+ <td>
+ <div class="tableheader">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">relation.relationids.title</xsl:with-param>
+ </xsl:call-template>
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td class="domainline">
+ <xsl:apply-templates select="./relation-id"/>
+ </td>
+ </tr>
+ </table>
+ </xsl:template>
+
+ <xsl:template match="relation-meta-data" name="meta-data">
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
+ <xsl:variable name="position">
+ <xsl:if test="(position() mod 2)=1">darkline</xsl:if>
+ <xsl:if test="(position() mod 2)=0">clearline</xsl:if>
+ </xsl:variable>
+ <tr width="100%" border="1">
+ <td class="{$position}"><b>
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">relation.rolename.title</xsl:with-param>
+ </xsl:call-template></b>
+ </td><td><xsl:apply-templates select="./role-name"/></td>
+ <td class="{$position}"><b>
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">relation.classname.title</xsl:with-param>
+ </xsl:call-template></b>
+ </td><td><xsl:apply-templates select="./mbean-classname"/></td>
+ </tr>
+ <tr border="1">
+ <td class="{$position}"><b>
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">relation.description.title</xsl:with-param>
+ </xsl:call-template></b>
+ </td><td><xsl:apply-templates select="./description"/></td>
+ <td class="{$position}"><b>
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">relation.mindegree.title</xsl:with-param>
+ </xsl:call-template></b>
+ </td><td><xsl:apply-templates select="./min-degree"/></td>
+ </tr>
+ <tr border="1">
+ <td class="{$position}"><b>
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">relation.maxdegree.title</xsl:with-param>
+ </xsl:call-template></b>
+ </td><td><xsl:apply-templates select="./max-degree"/></td>
+ <td class="{$position}"><b>
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">relation.readable.title</xsl:with-param>
+ </xsl:call-template></b>
+ </td><td><xsl:apply-templates select="./is-readable"/></td>
+ <td class="{$position}"><b>
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">relation.writable.title</xsl:with-param>
+ </xsl:call-template></b>
+ </td><td><xsl:apply-templates select="./is-writable"/></td>
+ </tr>
+ </table>
+ </xsl:template>
+
+ <xsl:template match="role-name" name="roleName">
+ <xsl:value-of select="text()"/>
+ </xsl:template>
+
+ <xsl:template match="mbean-classname" name="classname">
+ <xsl:value-of select="text()"/>
+ </xsl:template>
+
+ <xsl:template match="description" name="description">
+ <xsl:value-of select="text()"/>
+ </xsl:template>
+
+ <xsl:template match="min-degree" name="minimum">
+ <xsl:value-of select="text()"/>
+ </xsl:template>
+
+ <xsl:template match="max-degree" name="maximum">
+ <xsl:value-of select="text()"/>
+ </xsl:template>
+
+ <xsl:template match="is-readable" name="reading">
+ <xsl:value-of select="text()"/>
+ </xsl:template>
+
+ <xsl:template match="is-writable" name="writing">
+ <xsl:value-of select="text()"/>
+ </xsl:template>
+
+ <xsl:template match="default" name="default">
+ <xsl:value-of select="text()"/>
+ </xsl:template>
+
+ <xsl:template match="relation-id" name="relationId">
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
+ <xsl:variable name="position">
+ <xsl:if test="(position() mod 2)=1">darkline</xsl:if>
+ <xsl:if test="(position() mod 2)=0">clearline</xsl:if>
+ </xsl:variable>
+ <tr>
+ <td class="{$position}" align="justify">
+ <xsl:value-of select="text()"/>
+ </td>
+ </tr>
+ </table>
+ </xsl:template>
+
+ <xsl:template match="RelationServer">
+ <html>
+ <xsl:call-template name="head"/>
+ <body>
+ <xsl:call-template name="toprow"/>
+ <xsl:call-template name="tabs">
+ <xsl:with-param name="selection">relation</xsl:with-param>
+ </xsl:call-template>
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td colspan="7" width="100%" align="center" class="fronttab">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">relation.inprogress</xsl:with-param>
+ </xsl:call-template>
+ </td>
+ </tr>
+ </table>
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
+ <xsl:apply-templates select="./default"/>
+ <xsl:apply-templates select="./relation-type-name"/>
+ </table>
+ <xsl:call-template name="bottom"/>
+ </body>
+ </html>
+</xsl:template>
+</xsl:stylesheet>
+
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/server.xsl b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/server.xsl
new file mode 100644
index 0000000..f22f941
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/server.xsl
@@ -0,0 +1,89 @@
+<?xml version="1.0"?>
+<!--
+ Copyright (C) MX4J.
+ All rights reserved.
+
+ This software is distributed under the terms of the MX4J License version 1.0.
+ See the terms of the MX4J License in the documentation provided with this software.
+
+ Author: Carlos Quiroz (tibu@users.sourceforge.net)
+ Revision: $Revision: 1.1.1.1 $
+-->
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+ <xsl:output method="html" indent="yes" encoding="UTF-8"/>
+
+ <xsl:param name="html.stylesheet">stylesheet.css</xsl:param>
+ <xsl:param name="html.stylesheet.type">text/css</xsl:param>
+ <xsl:param name="head.title">server.title</xsl:param>
+ <xsl:include href="common.xsl"/>
+ <xsl:include href="xalan-ext.xsl"/>
+
+ <xsl:template name="mbean">
+ <xsl:for-each select="MBean">
+ <xsl:sort data-type="text" order="ascending" select="@objectname"/>
+ <xsl:variable name="classtype">
+ <xsl:if test="(position() mod 2)=1">darkline</xsl:if>
+ <xsl:if test="(position() mod 2)=0">clearline</xsl:if>
+ </xsl:variable>
+ <xsl:variable name="objectname">
+ <xsl:call-template name="uri-encode">
+ <xsl:with-param name="uri" select="@objectname"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <tr class="{$classtype}" width="100%">
+ <td class="domainline"/>
+ <td width="35%" align="left">
+ <a href="mbean?objectname={$objectname}"><xsl:value-of select="@objectname"/></a>
+ </td>
+ <td width="20%" align="left">
+ <xsl:value-of select="@classname"/>
+ </td>
+ <td width="35%" align="left">
+ <xsl:value-of select="@description"/>
+ </td>
+ <td width="10%" align="right" class="{$classtype}" >
+ <a href="delete?objectname={$objectname}">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">server.unregister</xsl:with-param>
+ </xsl:call-template>
+ </a>
+ </td>
+ </tr>
+ </xsl:for-each>
+ </xsl:template>
+
+ <xsl:template match="Server">
+ <html>
+ <xsl:call-template name="head"/>
+ <body>
+ <xsl:call-template name="toprow"/>
+ <xsl:call-template name="tabs">
+ <xsl:with-param name="selection">server</xsl:with-param>
+ </xsl:call-template>
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
+ <tr class="fronttab">
+ <td >
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">server.mbeans.title</xsl:with-param>
+ </xsl:call-template>
+ </td>
+ <form action="server">
+ <td align="right">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">server.filter.title</xsl:with-param>
+ </xsl:call-template>
+ <input type="text" name="querynames" value="*:*"/>
+ <input type="submit" value="query"/>
+ </td>
+ </form>
+ </tr>
+ </table>
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
+ <xsl:call-template name="mbean"/>
+ </table>
+ <xsl:call-template name="bottom"/>
+ </body>
+ </html>
+</xsl:template>
+</xsl:stylesheet>
+
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/serverbydomain.xsl b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/serverbydomain.xsl
new file mode 100644
index 0000000..14c0deb
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/serverbydomain.xsl
@@ -0,0 +1,134 @@
+<?xml version="1.0"?>
+<!--
+ Copyright (C) MX4J.
+ All rights reserved.
+
+ This software is distributed under the terms of the MX4J License version 1.0.
+ See the terms of the MX4J License in the documentation provided with this software.
+
+ Author: Carlos Quiroz (tibu@users.sourceforge.net)
+ Revision: $Revision: 1.1.1.1 $
+ -->
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+ <xsl:output method="html" indent="yes" encoding="ISO-8859-1"/>
+ <xsl:include href="common.xsl"/>
+ <xsl:include href="xalan-ext.xsl"/>
+
+ <xsl:param name="html.stylesheet">stylesheet.css</xsl:param>
+ <xsl:param name="html.stylesheet.type">text/css</xsl:param>
+ <xsl:param name="head.title">serverbydomain.title</xsl:param>
+
+ <!-- Invoked when a query error is produced -->
+ <xsl:template match="Domain" name="error">
+ <xsl:for-each select="Exception">
+ <tr>
+ <td class="serverbydomain_domainline" colspan="5">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">serverbydomain.error.query</xsl:with-param>
+ <xsl:with-param name="p0">
+ <xsl:value-of select="@errorMsg"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </td>
+ </tr>
+ </xsl:for-each>
+ </xsl:template>
+
+ <!-- Invoked to display each domain -->
+ <xsl:template match="Domain" name="domain">
+ <xsl:for-each select="Domain">
+ <xsl:sort data-type="text" order="ascending" select="@name"/>
+ <tr>
+ <td class="serverbydomain_domainline" colspan="5">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">serverbydomain.domain.label</xsl:with-param>
+ <xsl:with-param name="p0">
+ <xsl:value-of select="@name"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </td>
+ <xsl:call-template name="mbean"/>
+ </tr>
+ </xsl:for-each>
+ </xsl:template>
+
+ <!-- invoked for each mbean -->
+ <xsl:template match="MBean" name="mbean">
+ <xsl:for-each select="MBean">
+ <xsl:sort data-type="text" order="ascending" select="@objectname"/>
+ <xsl:variable name="classtype">
+ <xsl:if test="(position() mod 2)=1">darkline</xsl:if>
+ <xsl:if test="(position() mod 2)=0">clearline</xsl:if>
+ </xsl:variable>
+ <xsl:variable name="objectname">
+ <xsl:call-template name="uri-encode">
+ <xsl:with-param name="uri" select="@objectname"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <tr class="{$classtype}" width="100%">
+ <td width="35%" align="left" class="serverbydomain_row">
+ <a href="mbean?objectname={$objectname}"><xsl:value-of select="@objectname"/></a>
+ </td>
+ <td width="20%" align="left" class="serverbydomain_row">
+ <p><xsl:value-of select="@classname"/></p>
+ </td>
+ <td width="35%" align="left" class="serverbydomain_row">
+ <p><xsl:value-of select="@description"/></p>
+ </td>
+ <td width="10%" align="right" class="serverbydomain_row">
+ <p>
+ <a href="delete?objectname={$objectname}">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">serverbydomain.mbean.unregister</xsl:with-param>
+ </xsl:call-template>
+ </a></p>
+ </td>
+ </tr>
+ </xsl:for-each>
+ </xsl:template>
+
+ <!-- Main template -->
+ <xsl:template match="Server">
+ <html>
+ <xsl:call-template name="head"/>
+ <body>
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
+ <tr width="100%">
+ <td>
+ <xsl:call-template name="toprow"/>
+ <xsl:call-template name="tabs">
+ <xsl:with-param name="selection">server</xsl:with-param>
+ </xsl:call-template>
+ <xsl:variable name="query">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">serverbydomain.server.query</xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
+
+ <tr>
+ <td class="page_title">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">serverbydomain.server.title</xsl:with-param>
+ </xsl:call-template>
+ </td>
+ <form action="serverbydomain">
+ <td align="right" class="page_title">
+ <xsl:call-template name="str"><xsl:with-param name="id">serverbydomain.server.filter</xsl:with-param></xsl:call-template><input type="text" name="querynames" value="*:*"/><input type="submit" value="{$query}"/>
+ </td>
+ </form>
+ </tr>
+ </table>
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
+ <xsl:call-template name="domain"/>
+ <xsl:call-template name="error"/>
+ </table>
+ <xsl:call-template name="bottom"/>
+ </td>
+ </tr>
+ </table>
+ </body>
+ </html>
+ </xsl:template>
+</xsl:stylesheet>
+
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/setattribute.xsl b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/setattribute.xsl
new file mode 100644
index 0000000..714d883
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/setattribute.xsl
@@ -0,0 +1,81 @@
+<?xml version="1.0"?>
+<!--
+ Copyright (C) MX4J.
+ All rights reserved.
+
+ This software is distributed under the terms of the MX4J License version 1.0.
+ See the terms of the MX4J License in the documentation provided with this software.
+
+ Author: Carlos Quiroz (tibu@users.sourceforge.net)
+ Revision: $Revision: 1.1.1.1 $
+ -->
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+ <xsl:output method="html" indent="yes" encoding="UTF-8"/>
+
+ <xsl:param name="html.stylesheet">stylesheet.css</xsl:param>
+ <xsl:param name="html.stylesheet.type">text/css</xsl:param>
+ <xsl:param name="head.title">setattribute.title</xsl:param>
+ <xsl:include href="common.xsl"/>
+
+ <!-- Request parameters -->
+ <xsl:param name="request.objectname"/>
+ <xsl:param name="request.attribute"/>
+ <xsl:param name="request.value"/>
+
+ <xsl:template name="operation">
+ <xsl:for-each select="Operation">
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
+ <xsl:variable name="classtype">
+ <xsl:if test="(position() mod 2)=1">darkline</xsl:if>
+ <xsl:if test="(position() mod 2)=0">clearline</xsl:if>
+ </xsl:variable>
+ <tr>
+ <td width="100%" class="fronttab">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">setattribute.operation.title</xsl:with-param>
+ <xsl:with-param name="p0"><xsl:value-of select="$request.attribute"/></xsl:with-param>
+ <xsl:with-param name="p1"><xsl:value-of select="$request.objectname"/></xsl:with-param>
+ </xsl:call-template>
+ </td>
+ </tr>
+ <tr>
+ <td class="{$classtype}">
+ <xsl:if test="@result='success'">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">setattribute.operation.success</xsl:with-param>
+ <xsl:with-param name="p0"><xsl:value-of select="$request.attribute"/></xsl:with-param>
+ <xsl:with-param name="p1"><xsl:value-of select="$request.value"/></xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+ <xsl:if test="@result='error'">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">setattribute.operation.error</xsl:with-param>
+ <xsl:with-param name="p0"><xsl:value-of select="@errorMessage"/></xsl:with-param>
+ </xsl:call-template>
+
+ </xsl:if>
+ </td>
+ </tr>
+ <xsl:call-template name="mbeanview">
+ <xsl:with-param name="objectname" select="$request.objectname"/>
+ </xsl:call-template>
+ </table>
+ </xsl:for-each>
+ </xsl:template>
+
+ <xsl:template match="MBeanOperation">
+ <html>
+ <xsl:call-template name="head"/>
+ <body>
+ <xsl:call-template name="toprow"/>
+ <xsl:call-template name="tabs">
+ <xsl:with-param name="selection">mbean</xsl:with-param>
+ </xsl:call-template>
+ <xsl:call-template name="operation"/>
+ <xsl:call-template name="bottom"/>
+ </body>
+ </html>
+</xsl:template>
+</xsl:stylesheet>
+
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/setattributes.xsl b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/setattributes.xsl
new file mode 100644
index 0000000..ac606e4
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/setattributes.xsl
@@ -0,0 +1,89 @@
+<?xml version="1.0"?>
+<!--
+ Copyright (C) MX4J.
+ All rights reserved.
+
+ This software is distributed under the terms of the MX4J License version 1.0.
+ See the terms of the MX4J License in the documentation provided with this software.
+
+ Author: Carlos Quiroz (tibu@users.sourceforge.net)
+ Revision: $Revision: 1.1.1.1 $
+ -->
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+ <xsl:output method="html" indent="yes" encoding="UTF-8"/>
+
+ <xsl:param name="html.stylesheet">stylesheet.css</xsl:param>
+ <xsl:param name="html.stylesheet.type">text/css</xsl:param>
+ <xsl:param name="head.title">setattributes.title</xsl:param>
+ <xsl:include href="common.xsl"/>
+
+ <!-- Request parameters -->
+ <xsl:param name="request.objectname"/>
+ <xsl:param name="request.attribute"/>
+ <xsl:param name="request.value"/>
+
+ <xsl:template name="operation">
+ <xsl:for-each select="Operation">
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
+
+ <xsl:variable name="classtype">
+ <xsl:if test="(position() mod 2)=1">darkline</xsl:if>
+ <xsl:if test="(position() mod 2)=0">clearline</xsl:if>
+ </xsl:variable>
+ <tr>
+ <td width="100%" class="page_title">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">setattributes.operation.title</xsl:with-param>
+ <xsl:with-param name="p0"><xsl:value-of select="$request.objectname"/></xsl:with-param>
+ </xsl:call-template>
+
+ </td>
+ </tr>
+ <xsl:for-each select="//Attribute">
+ <xsl:if test="@result='success'">
+ <tr class="{$classtype}">
+ <td>
+ <!-- This would be better with a 2 param replacement -->
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">setattributes.operation.success</xsl:with-param>
+ <xsl:with-param name="p0"><xsl:value-of select="@attribute"/></xsl:with-param>
+ <xsl:with-param name="p1"><xsl:value-of select="@value"/></xsl:with-param>
+ </xsl:call-template>
+ </td>
+ </tr>
+ </xsl:if>
+ <xsl:if test="@result='error'">
+ <tr class="{$classtype}">
+ <td>
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">setattributes.operation.error</xsl:with-param>
+ <xsl:with-param name="p0"><xsl:value-of select="@attribute"/></xsl:with-param>
+ <xsl:with-param name="p1"><xsl:value-of select="@errorMsg"/></xsl:with-param>
+ </xsl:call-template>
+ </td>
+ </tr>
+ </xsl:if>
+ </xsl:for-each>
+ <xsl:call-template name="mbeanview">
+ <xsl:with-param name="objectname" select="$request.objectname"/>
+ </xsl:call-template>
+ </table>
+ </xsl:for-each>
+ </xsl:template>
+
+ <xsl:template match="MBeanOperation">
+ <html>
+ <xsl:call-template name="head"/>
+ <body>
+ <xsl:call-template name="toprow"/>
+ <xsl:call-template name="tabs">
+ <xsl:with-param name="selection">mbean</xsl:with-param>
+ </xsl:call-template>
+ <xsl:call-template name="operation"/>
+ <xsl:call-template name="bottom"/>
+ </body>
+ </html>
+</xsl:template>
+</xsl:stylesheet>
+
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/strings_en.xml b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/strings_en.xml
new file mode 100644
index 0000000..b680e28
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/strings_en.xml
@@ -0,0 +1,223 @@
+<?xml version="1.0"?>
+<strings>
+ <str id="none"></str>
+ <str id="common.title">MX4J/Http Adaptor</str>
+ <str id="common.subtitle">JMX Management Console</str>
+ <str id="common.tabs.serverview">Server view</str>
+ <str id="common.tabs.mbeanview">MBean view</str>
+ <str id="common.tabs.timerview">Timers</str>
+ <str id="common.tabs.monitorview">Monitors</str>
+ <str id="common.tabs.relationview">Relations</str>
+ <str id="common.tabs.mletview">MLet</str>
+ <str id="common.tabs.about">About</str>
+ <str id="common.serverview.return">Return to server view</str>
+ <str id="common.bottom.banner">Built using {0} HttpAdaptor</str>
+ <str id="common.mbeanview.return">Return to MBean view</str>
+ <str id="common.logo">MX4J logo</str>
+ <str id="common.logo.gif">logo.gif</str>
+ <str id="common.logo.width">100</str>
+ <str id="common.logo.height">50</str>
+ <str id="common.site">mx4j.sourceforge.net</str>
+
+ <str id="serverbydomain.title">MX4J - Agent View</str>
+ <str id="serverbydomain.error.query">Exception during query: {0}</str>
+ <str id="serverbydomain.domain.label">Domain: {0}</str>
+ <str id="serverbydomain.server.title">MBean By Domain:</str>
+ <str id="serverbydomain.server.filter">Filter:</str>
+ <str id="serverbydomain.server.query">Query</str>
+ <str id="serverbydomain.mbean.unregister">Unregister</str>
+
+ <str id="emptymbean.title">MBean - View</str>
+ <str id="emptymbean.querycontructors">Query constructors for class:</str>
+ <str id="emptymbean.query">query</str>
+
+ <str id="mbean.title">MX4J - MBean View</str>
+ <str id="mbean.parameters.unknown">Unknown type</str>
+ <str id="mbean.operations.title">Operations</str>
+ <str id="mbean.operations.name">Name</str>
+ <str id="mbean.operations.returntype">Return type</str>
+ <str id="mbean.operations.description">Description</str>
+ <str id="mbean.operations.parameter">Parameters</str>
+ <str id="mbean.operations.parameterid">id</str>
+ <str id="mbean.operations.parametername">Name</str>
+ <str id="mbean.operations.parameterdescription">Description</str>
+ <str id="mbean.operations.parameterclass">Class</str>
+ <str id="mbean.operations.invoke">Invoke</str>
+ <str id="mbean.constructors.class">Class</str>
+ <str id="mbean.constructors.objectname">ObjectName: </str>
+ <str id="mbean.constructors.description">Description</str>
+ <str id="mbean.constructors.parameter">Parameters</str>
+ <str id="mbean.constructors.parameterid">id</str>
+ <str id="mbean.constructors.parametername">Name</str>
+ <str id="mbean.constructors.parameterdescription">Description</str>
+ <str id="mbean.constructors.parameterclass">Class</str>
+ <str id="mbean.constructors.create">Create new</str>
+ <str id="mbean.mbean.title">MBean {0}</str>
+ <str id="mbean.mbean.description">Description {0}</str>
+ <str id="mbean.mbean.attributes">Attributes</str>
+ <str id="mbean.mbean.constructors">Constructors</str>
+
+ <str id="mbean_attributes.attribute.name">Name</str>
+ <str id="mbean_attributes.attribute.description">Description</str>
+ <str id="mbean_attributes.attribute.type">Type</str>
+ <str id="mbean_attributes.attribute.value">Value</str>
+ <str id="mbean_attributes.attribute.newvalue">New Value</str>
+ <str id="mbean_attributes.attribute.arrayof">Array of {0}</str>
+ <str id="mbean_attributes.attribute.setall">Set all</str>
+ <str id="mbean_attributes.RO.readonly">Read-only attribute</str>
+ <str id="mbean_attributes.WO.readonly">Write-only attribute</str>
+ <str id="mbean_attributes.submit.set">set</str>
+ <str id="mbean_attributes.form.unknowntype">Unknown type</str>
+ <str id="mbean_attributes.array.view">View array</str>
+ <str id="mbean_attributes.map.view">View map</str>
+ <str id="mbean_attributes.collection.view">View collection</str>
+ <str id="mbean_attributes.array.null">Array is null</str>
+ <str id="mbean_attributes.map.null">Map is null</str>
+ <str id="mbean_attributes.collection.null">Collection is null</str>
+
+ <str id="setattributes.title">MX4J - MBean View</str>
+ <str id="setattributes.operation.title">MBean operation: set attributes on MBean {0}</str>
+ <str id="setattributes.operation.success">Attribute {0} set to {1} </str>
+ <str id="setattributes.operation.error">Exception during set attribute {0}, message: {1} </str>
+
+ <str id="error.title">MX4J - Exception</str>
+ <str id="error.httpexception.title">Error during request</str>
+ <str id="error.httpexception.code">Code: {0}</str>
+ <str id="error.httpexception.message">Message: {0}</str>
+
+ <str id="constructors.constructors.objectnameinput">ObjectName:</str>
+ <str id="constructors.constructors.createnew">Create new</str>
+ <str id="constructors.constructors.intro">Constructor for class {0}</str>
+ <str id="constructors.title">MX4J - MBean Constructor's View</str>
+ <str id="constructors.main.title">Constructors for class {0}</str>
+ <str id="constructors.error.exception">Exception: {0}</str>
+ <str id="constructors.parameters.title">Parameters</str>
+ <str id="constructors.parameters.id">id</str>
+ <str id="constructors.parameters.type">type</str>
+ <str id="constructors.parameters.value">value</str>
+ <str id="constructors.parameters.unknowntype">Unkown type</str>
+
+ <str id="create.title">MX4J - MBean View</str>
+ <str id="create.operation.success">MBean successfully created</str>
+ <str id="create.operation.error">Error during MBean creation, message: {0}</str>
+ <str id="create.operation.title">MBean operation: create MBean of class {0} and object name {1}</str>
+
+ <str id="delete.title">MX4J - MBean View</str>
+ <str id="delete.operation.title">MBean delete, objectname {0}</str>
+ <str id="delete.operation.success">MBean successfully deleted</str>
+ <str id="delete.operation.error">Error during MBean deletion, message: {0}</str>
+
+ <str id="timer.title">MX4J - Timer Service</str>
+ <str id="timer.main.title">Timers by Domain:</str>
+ <str id="timer.main.createlabel">ObjectName:</str>
+ <str id="timer.main.createbutton">New timer</str>
+ <str id="timer.mbean.unregister">Unregister</str>
+ <str id="timer.domain.title">Timers for domain: {0}</str>
+ <str id="timer.domain.objectname">ObjectName</str>
+
+ <str id="timer_create.title">MX4J - Timer Creation</str>
+ <str id="timer_create.operation.title">Timer creation with object name {0}</str>
+ <str id="timer_create.operation.success">Timer created</str>
+ <str id="timer_create.operation.error">Exception during timer creation, message: {0}</str>
+ <str id="timer_create.operation.mbeanview">Configure timer</str>
+
+ <str id="viewarray.title">MX4J - Array View</str>
+ <str id="viewarray.main.title">MBean {0}</str>
+ <str id="viewarray.main.arraytitle">Array attribute {0} of type {1}</str>
+ <str id="viewarray.main.index">Index</str>
+ <str id="viewarray.main.value">Value</str>
+ <str id="viewarray.main.navigation.first">first</str>
+ <str id="viewarray.main.navigation.previous">previous</str>
+ <str id="viewarray.main.navigation.next">next</str>
+ <str id="viewarray.main.navigation.last">last</str>
+
+ <str id="viewcollection.title">MX4J - Collection View</str>
+ <str id="viewcollection.main.title">MBean {0}</str>
+ <str id="viewcollection.main.viewcollectiontitle">Collection of class {0} on attribute {1}</str>
+ <str id="viewcollection.main.index">Index</str>
+ <str id="viewcollection.main.valueclass">Value class</str>
+ <str id="viewcollection.main.value">Value</str>
+ <str id="viewcollection.main.navigation.first">first</str>
+ <str id="viewcollection.main.navigation.previous">previous</str>
+ <str id="viewcollection.main.navigation.next">next</str>
+ <str id="viewcollection.main.navigation.last">last</str>
+
+ <str id="viewmap.title">MX4J - Map View</str>
+ <str id="viewmap.main.title">MBean {0}</str>
+ <str id="viewmap.main.viewmaptitle">Map of class {0} on attribute {1}</str>
+ <str id="viewmap.main.key">Key</str>
+ <str id="viewmap.main.keyclass">Key class</str>
+ <str id="viewmap.main.valueclass">Value class</str>
+ <str id="viewmap.main.value">Value</str>
+ <str id="viewmap.main.navigation.first">first</str>
+ <str id="viewmap.main.navigation.previous">previous</str>
+ <str id="viewmap.main.navigation.next">next</str>
+ <str id="viewmap.main.navigation.last">last</str>
+
+ <str id="monitor.title">MX4J - Monitor Service</str>
+ <str id="monitor.mbean.unregister">Unregister</str>
+ <str id="monitor.main.title">Monitors By Domain</str>
+ <str id="monitor.main.createstring.label">ObjectName:</str>
+ <str id="monitor.main.createstring.button">New StringMonitor</str>
+ <str id="monitor.main.creategauge.label">ObjectName:</str>
+ <str id="monitor.main.creategauge.button">New GaugeMonitor</str>
+ <str id="monitor.main.createcounter.label">ObjectName:</str>
+ <str id="monitor.main.createcounter.button">New CounterMonitor</str>
+
+ <str id="monitor_create.title">MX4J - Monitor creation</str>
+ <str id="monitor_create.operation.title"> creation with object name {0}</str>
+ <str id="monitor_create.operation.success">Monitor type {0} successfully created</str>
+ <str id="monitor_create.operation.error">Exception during {0} creation, mesage: {1}</str>
+ <str id="monitor_create.operation.mbeanview">Configure Monitor</str>
+ <str id="monitor_create.operation.stringmonitor">StringMonitor</str>
+ <str id="monitor_create.operation.gaugemonitor">GaugeMonitor</str>
+ <str id="monitor_create.operation.countermonitor">CounterMonitor</str>
+
+ <str id="mlet.title">MX4J - MLet Service</str>
+ <str id="mlet.mbean.unregister">MX4J - MLet Service</str>
+ <str id="mlet.main.title">Mlet: (Not yet implemented)</str>
+
+ <str id="invoke.title">MX4J - MBean View</str>
+ <str id="invoke.operation.title">MBean operation: invoke method {0} on MBean {1}</str>
+ <str id="invoke.operation.success">Invocation successful</str>
+ <str id="invoke.operation.success.result">Result value: <pre>{0}</pre></str>
+ <str id="invoke.operation.success.noresult">No result</str>
+ <str id="invoke.operation.success.error">Error during MBean operation invocation<br/>Message: {0}</str>
+
+ <str id="about.title">MX4J - About</str>
+ <str id="about.main.title">{0} - HttpAdaptor</str>
+ <str id="about.main.url">http://mx4j.sourceforge.net</str>
+ <str id="about.main.url2">http://www.javasoft.com/jmx</str>
+ <str id="about.main.line1">Built based on the {0} specification</str>
+ <str id="about.main.implementation">JMX Implementation:</str>
+ <str id="about.main.implementationversion">Implementation Version:</str>
+ <str id="about.main.serverid">MBeanServer ID:</str>
+
+ <!-- relation service strings -->
+ <str id="relation.title">MX4J - Relation Service</str>
+ <str id="relation.typename.title">RelationTypeName:</str>
+ <str id="relation.metadata.title">Relation Type metaData:</str>
+ <str id="relation.relationids.title">RelationIds:</str>
+ <str id="relation.rolename.title">Role Name:</str>
+ <str id="relation.classname.title">MBeanClass:</str>
+ <str id="relation.description.title">Description:</str>
+ <str id="relation.mindegree.title">Min Degree:</str>
+ <str id="relation.maxdegree.title">Max Degree:</str>
+ <str id="relation.readable.title">Readable:</str>
+ <str id="relation.writable.title">Writable:</str>
+ <str id="relation.paramname">relation</str>
+ <str id="relation.inprogress">Relation Service: (In Progress)</str>
+
+ <!--MBean Server strings -->
+ <str id="server.title">MX4J - Agent View</str>
+ <str id="server.unregister">Unregister</str>
+ <str id="server.mbeans.title">MBeans:</str>
+ <str id="server.filter.title">Filter:</str>
+
+ <!-- Set attribute stylesheet, to be deprecated -->
+ <str id="setattribute.title">MX4J - MBean View</str>
+ <str id="setattribute.operation.title">MBean operation: set attribute {0} on MBean {1}</str>
+ <str id="setattribute.operation.success">Attribute {0} set to {1}</str>
+ <str id="setattribute.operation.error">Error during set attribute, message: {0}</str>
+
+</strings>
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/stylesheet.css b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/stylesheet.css
new file mode 100644
index 0000000..ec0380a
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/stylesheet.css
@@ -0,0 +1,436 @@
+/*
+
+ * Copyright (C) MX4J.
+
+ * All rights reserved.
+
+ *
+
+ * This software is distributed under the terms of the MX4J License version 1.0.
+
+ * See the terms of the MX4J License in the documentation provided with this software.
+
+ * Author: Carlos Quiroz
+
+ * Revision: $Revision: 1.1.1.1 $
+
+ */
+
+
+
+body {
+
+ background: white;
+
+ color: black;
+
+ font-family: tahoma,verdana,helvetica,arial,sans-serif;
+
+ margin-top: 5px;
+
+ margin-left: 5px;
+
+ margin-right: 5px;
+
+ margin-bottom: 5px;
+
+}
+
+
+
+/* Footer class */
+
+div.footer {
+
+ font-weight: bold;
+
+ text-align: center;
+
+}
+
+
+
+/* Tabs styles */
+
+td.fronttab {
+
+ background: rgb(220,220,220);
+
+ color: black;
+
+ padding-left: 10px;
+
+ padding-right: 10px;
+
+ padding-bottom: 3px;
+
+ font-size: small;
+
+}
+
+
+
+td.backtab {
+
+ background: rgb(240,240,240);
+
+ color: black;
+
+ height: 25px;
+
+ padding-left: 10px;
+
+ padding-right: 10px;
+
+ font-size: small;
+
+}
+
+
+
+a.tabs {
+
+ color: black;
+
+ text-decoration: none;
+
+ font-size: small;
+
+}
+
+/* End of tabs styles */
+
+
+
+/* Header styles */
+
+td.darker {
+
+ background: rgb(57,128,144);
+
+ height: 18px;
+
+}
+
+
+
+td.topheading {
+
+ background: rgb(183,187,184);
+
+ color: black;
+
+ font-weight: bold;
+
+ padding-left: 10px;
+
+}
+
+/* End of Header styles */
+
+
+
+td.domainline {
+
+ background: rgb(220,220,220);
+
+ color: black;
+
+ padding-left: 10px;
+
+}
+
+
+
+td.page_title {
+
+ background: rgb(220,220,220);
+
+ color: black;
+
+ padding-left: 10px;
+
+ padding-right: 10px;
+
+ padding-top: 2px;
+
+ padding-bottom: 2px;
+
+ font-weight: bold;
+
+}
+
+
+
+div.subtitle {
+
+ font-size: smaller;
+
+}
+
+
+
+/* Server by domain styles */
+
+td.serverbydomain_domainline {
+
+ background: rgb(200,200,200);
+
+ color: black;
+
+ padding-left: 10px;
+
+ font-weight: bold;
+
+}
+
+
+
+tr.clearline {
+
+ background: rgb(255,255,255);
+
+ color: black;
+
+ padding-left: 10px;
+
+ padding-right: 10px;
+
+ padding-top: 2px;
+
+ padding-bottom: 2px;
+
+}
+
+
+
+tr.darkline {
+
+ background: rgb(240,240,240);
+
+ color: black;
+
+ padding-left: 10px;
+
+ padding-right: 10px;
+
+}
+
+
+
+td.serverbydomain_row {
+
+ font-size: x-small;
+
+ padding-left: 10px;
+
+}
+
+
+
+/* MBean section title */
+
+td.mbeans {
+
+ background: rgb(183,187,184);
+
+}
+
+
+
+p.darklinebottom {
+
+ background: rgb(240,240,240);
+
+ color: black;
+
+ height: 20px;
+
+ padding-left: 10px;
+
+ font-weight: bold;
+
+}
+
+
+
+div.tableheader {
+
+ font-weight: bold;
+
+ padding-top: 2px;
+
+ padding-bottom: 2px;
+
+ font-size: small
+
+}
+
+
+
+td.mbean_row {
+
+ font-size: x-small;
+
+ padding-left: 1px;
+
+}
+
+
+
+td.attributes_setall {
+
+ padding-right: 20px;
+
+ padding-top: 5px;
+
+ padding-bottom: 5px;
+
+}
+
+
+
+/* MBean section title */
+
+td.mbeans {
+
+ background: rgb(183,187,184);
+
+ color: black;
+
+ height: 20px;
+
+ padding-left: 10px;
+
+ padding-right: 10px;
+
+ font-weight: bold;
+
+}
+
+
+
+div.tableheader {
+
+ font-weight: bold;
+
+ padding-top: 2px;
+
+ padding-bottom: 2px;
+
+ font-size: small
+
+}
+
+
+
+td.mbean_row {
+
+ font-size: x-small;
+
+ padding-left: 1px;
+
+}
+
+
+
+td.aggregationrow {
+
+ font-size: small;
+
+ padding-left: 1px;
+
+}
+
+
+
+td.constructorrow {
+
+ font-size: small;
+
+ padding-left: 1px;
+
+}
+
+
+
+td.attributes_setall {
+
+ padding-right: 20px;
+
+ padding-top: 5px;
+
+ padding-bottom: 5px;
+
+}
+
+
+
+tr.about {
+
+ background: rgb(220,220,220);
+
+}
+
+
+
+h1.about {
+
+ padding-left: 20px;
+
+ padding-right: 20px;
+
+ padding-top: 20px;
+
+ padding-bottom: 20px;
+
+ font-size: xx-large;
+
+ background: rgb(220,220,220);
+
+ color: black;
+
+}
+
+
+
+h2.about {
+
+ padding-left: 20px;
+
+ padding-right: 20px;
+
+ padding-top: 15px;
+
+ padding-bottom: 15px;
+
+ font-size: x-large;
+
+ background: rgb(220,220,220);
+
+ color: black;
+
+}
+
+
+
+h3.about {
+
+ padding-left: 20px;
+
+ padding-right: 20px;
+
+ padding-top: 15px;
+
+ padding-bottom: 15px;
+
+ font-size: large;
+
+ background: rgb(220,220,220);
+
+ color: black;
+
+}
+
+
+
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/timer.xsl b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/timer.xsl
new file mode 100644
index 0000000..25532ec
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/timer.xsl
@@ -0,0 +1,121 @@
+<?xml version="1.0"?>
+<!--
+ Copyright (C) MX4J.
+ All rights reserved.
+
+ This software is distributed under the terms of the MX4J License version 1.0.
+ See the terms of the MX4J License in the documentation provided with this software.
+
+ Author: Carlos Quiroz (tibu@users.sourceforge.net)
+ Revision: $Revision: 1.1.1.1 $
+ -->
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:xalan="http://xml.apache.org/xslt">
+ <xsl:output method="html" indent="yes" encoding="UTF-8" xalan:indent-amount="4"/>
+
+ <xsl:param name="html.stylesheet">stylesheet.css</xsl:param>
+ <xsl:param name="html.stylesheet.type">text/css</xsl:param>
+ <xsl:param name="head.title">timer.title</xsl:param>
+ <xsl:include href="common.xsl"/>
+
+ <xsl:template name="domain">
+ <xsl:for-each select="Domain[MBean]">
+ <tr>
+ <td class="serverbydomain_domainline">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">timer.domain.title</xsl:with-param>
+ <xsl:with-param name="p0">
+ <xsl:value-of select="@name"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <div class="tableheader">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">timer.domain.objectname</xsl:with-param>
+ </xsl:call-template>
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
+ <xsl:call-template name="mbean"/>
+ </table>
+ </td>
+ </tr>
+ </xsl:for-each>
+ </xsl:template>
+
+ <xsl:template match="MBean" name="mbean">
+ <xsl:for-each select="MBean">
+ <xsl:variable name="classtype">
+ <xsl:if test="(position() mod 2)=1">darkline</xsl:if>
+ <xsl:if test="(position() mod 2)=0">clearline</xsl:if>
+ </xsl:variable>
+ <tr class="{$classtype}">
+ <xsl:variable name="objectname">
+ <xsl:call-template name="uri-encode">
+ <xsl:with-param name="uri" select="@objectname"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <td class="mbean_row">
+ <a href="mbean?objectname={$objectname}"><xsl:value-of select="@objectname"/></a>
+ </td>
+ <td align="right" class="mbean_row">
+ <a href="delete?objectname={$objectname}">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">timer.mbean.unregister</xsl:with-param>
+ </xsl:call-template>
+ </a>
+ </td>
+ </tr>
+ </xsl:for-each>
+ </xsl:template>
+
+ <!-- Main template -->
+ <xsl:template match="Server" name="main">
+ <html>
+ <xsl:call-template name="head"/>
+ <body>
+ <xsl:call-template name="toprow"/>
+ <xsl:call-template name="tabs">
+ <xsl:with-param name="selection">timer</xsl:with-param>
+ </xsl:call-template>
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td width="100%" class="page_title">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">timer.main.title</xsl:with-param>
+ </xsl:call-template>
+ </td>
+ </tr>
+ <tr class="fronttab">
+ <form action="create">
+ <td align="right">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">timer.main.createlabel</xsl:with-param>
+ </xsl:call-template>
+ <xsl:variable name="str.createbutton">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">timer.main.createbutton</xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+ <input type="input" name="objectname"/>
+ <input type="hidden" name="template" value="timer_create"/>
+ <input type="hidden" name="class" value="javax.management.timer.Timer"/>
+ <input type="submit" value="{$str.createbutton}"/>
+ </td>
+ </form>
+ </tr>
+ </table>
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
+ <xsl:call-template name="domain"/>
+ </table>
+ <xsl:call-template name="bottom"/>
+ </body>
+ </html>
+</xsl:template>
+</xsl:stylesheet>
+
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/timer_create.xsl b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/timer_create.xsl
new file mode 100644
index 0000000..b0fe328
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/timer_create.xsl
@@ -0,0 +1,82 @@
+<?xml version="1.0"?>
+<!--
+ Copyright (C) MX4J.
+ All rights reserved.
+
+ This software is distributed under the terms of the MX4J License version 1.0.
+ See the terms of the MX4J License in the documentation provided with this software.
+
+ Author: Carlos Quiroz (tibu@users.sourceforge.net)
+ Revision: $Revision: 1.1.1.1 $
+ -->
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+ <xsl:output method="html" indent="yes" encoding="UTF-8"/>
+
+ <!-- Overall parameters -->
+ <xsl:param name="html.stylesheet">stylesheet.css</xsl:param>
+ <xsl:param name="html.stylesheet.type">text/css</xsl:param>
+ <xsl:param name="head.title">timer_create.title</xsl:param>
+
+ <!-- Request parameters -->
+ <xsl:param name="request.objectname"/>
+ <xsl:param name="request.class"/>
+
+ <xsl:include href="common.xsl"/>
+
+ <!-- Operation template -->
+ <xsl:template name="operation" >
+ <xsl:for-each select="Operation">
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td width="100%" class="page_title">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">timer_create.operation.title</xsl:with-param>
+ <xsl:with-param name="p0"><xsl:value-of select="$request.objectname"/></xsl:with-param>
+ </xsl:call-template>
+ </td>
+ </tr>
+ <tr>
+ <td class="clearline">
+ <xsl:if test="@result='success'">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">timer_create.operation.success</xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+ <xsl:if test="@result='error'">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">timer_create.operation.error</xsl:with-param>
+ <xsl:with-param name="p0"><xsl:value-of select="@errorMsg"/></xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+ </td>
+ </tr>
+ <xsl:if test="@result='success'">
+ <xsl:call-template name="mbeanview">
+ <xsl:with-param name="objectname"><xsl:value-of select="$request.objectname"/></xsl:with-param>
+ <xsl:with-param name="text">timer_create.operation.mbeanview</xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+ <xsl:if test="@result='error'">
+ <xsl:call-template name="serverview"/>
+ </xsl:if>
+ </table>
+ </xsl:for-each>
+ </xsl:template>
+
+ <!-- Main template -->
+ <xsl:template match="MBeanOperation">
+ <html>
+ <xsl:call-template name="head"/>
+ <body>
+ <xsl:call-template name="toprow"/>
+ <xsl:call-template name="tabs">
+ <xsl:with-param name="selection">timer</xsl:with-param>
+ </xsl:call-template>
+ <xsl:call-template name="operation"/>
+ <xsl:call-template name="bottom"/>
+ </body>
+ </html>
+</xsl:template>
+</xsl:stylesheet>
+
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/viewarray.xsl b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/viewarray.xsl
new file mode 100644
index 0000000..cb22bbf
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/viewarray.xsl
@@ -0,0 +1,110 @@
+<?xml version="1.0"?>
+<!--
+ Copyright (C) MX4J.
+ All rights reserved.
+
+ This software is distributed under the terms of the MX4J License version 1.0.
+ See the terms of the MX4J License in the documentation provided with this software.
+
+ Author: Carlos Quiroz (tibu@users.sourceforge.net)
+ Revision: $Revision: 1.1.1.1 $
+ -->
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+ <xsl:output method="html" indent="yes" encoding="UTF-8"/>
+
+ <xsl:param name="html.stylesheet">stylesheet.css</xsl:param>
+ <xsl:param name="html.stylesheet.type">text/css</xsl:param>
+ <xsl:param name="head.title">viewarray.title</xsl:param>
+ <xsl:param name="request.step">30</xsl:param>
+ <xsl:param name="request.start">0</xsl:param>
+ <xsl:param name="request.objectname"/>
+ <xsl:param name="request.attribute"/>
+ <xsl:param name="request.format"/>
+ <xsl:param name="request.template"/>
+
+ <xsl:include href="common.xsl"/>
+ <xsl:include href="mbean_attributes.xsl"/>
+
+ <!-- Main template -->
+ <xsl:template match="/" name="main">
+ <html>
+ <xsl:call-template name="head"/>
+ <body>
+ <xsl:call-template name="toprow"/>
+ <xsl:call-template name="tabs">
+ <xsl:with-param name="selection">mbean</xsl:with-param>
+ </xsl:call-template>
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td colspan="2" class="page_title">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">viewarray.main.title</xsl:with-param>
+ <xsl:with-param name="p0"><xsl:value-of select="MBean/@objectname"/></xsl:with-param>
+ </xsl:call-template>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2" class="fronttab">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">viewarray.main.arraytitle</xsl:with-param>
+ <xsl:with-param name="p0"><xsl:value-of select="MBean/Attribute/@attribute"/></xsl:with-param>
+ <xsl:with-param name="p1"><xsl:value-of select="substring-before(substring-after(MBean/Attribute/@classname, '[L'), ';')"/></xsl:with-param>
+ </xsl:call-template>
+ </td>
+ </tr>
+ <tr>
+ <td class="fronttab">
+ <div class="tableheader">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">viewarray.main.index</xsl:with-param>
+ </xsl:call-template>
+ </div>
+ </td>
+ <td class="fronttab">
+ <div class="tableheader">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">viewarray.main.value</xsl:with-param>
+ </xsl:call-template>
+ </div>
+ </td>
+ </tr>
+ <xsl:for-each select="MBean/Attribute/Array/Element">
+ <xsl:sort order="ascending" select="@index"/>
+ <xsl:variable name="classtype">
+ <xsl:if test="(position() mod 2)=1">clearline</xsl:if>
+ <xsl:if test="(position() mod 2)=0">darkline</xsl:if>
+ </xsl:variable>
+ <tr class="{$classtype}">
+ <td class="aggregationrow"><xsl:value-of select="@index"/></td>
+ <td class="aggregationrow">
+ <xsl:call-template name="renderobject">
+ <xsl:with-param name="objectclass" select="../@componentclass"/>
+ <xsl:with-param name="objectvalue" select="@element"/>
+ </xsl:call-template>
+ </td>
+ </tr>
+ </xsl:for-each>
+
+ <xsl:variable name="url">getattribute?objectname=<xsl:call-template name="uri-encode"><xsl:with-param name="uri"><xsl:value-of select="$request.objectname"/></xsl:with-param></xsl:call-template>&attribute=<xsl:value-of select="$request.attribute"/>&format=array&template=viewarray&locale=<xsl:value-of select="$request.locale"/></xsl:variable>
+ <xsl:call-template name="aggregation-navigation">
+ <xsl:with-param name="url" select="$url"/>
+ <xsl:with-param name="total" select="count(MBean/Attribute/Array/Element)"/>
+ <xsl:with-param name="start" select="$request.start"/>
+ <xsl:with-param name="step" select="$request.step"/>
+ <xsl:with-param name="str.prefix">viewarray.main</xsl:with-param>
+ </xsl:call-template>
+
+ <xsl:call-template name="mbeanview">
+ <xsl:with-param name="objectname" select="MBean/@objectname"/>
+ <xsl:with-param name="colspan" select="4"/>
+ </xsl:call-template>
+
+ </table>
+
+ <xsl:call-template name="bottom"/>
+ </body>
+ </html>
+ </xsl:template>
+</xsl:stylesheet>
+
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/viewcollection.xsl b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/viewcollection.xsl
new file mode 100644
index 0000000..613feb0
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/viewcollection.xsl
@@ -0,0 +1,119 @@
+<?xml version="1.0"?>
+<!--
+ Copyright (C) MX4J.
+ All rights reserved.
+
+ This software is distributed under the terms of the MX4J License version 1.0.
+ See the terms of the MX4J License in the documentation provided with this software.
+
+ Author: Carlos Quiroz (tibu@users.sourceforge.net)
+ Revision: $Revision: 1.1.1.1 $
+ -->
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+ <xsl:output method="html" indent="yes" encoding="UTF-8"/>
+
+ <xsl:param name="html.stylesheet">stylesheet.css</xsl:param>
+ <xsl:param name="html.stylesheet.type">text/css</xsl:param>
+ <xsl:param name="head.title">viewcollection.title</xsl:param>
+ <xsl:param name="request.step">30</xsl:param>
+ <xsl:param name="request.start">0</xsl:param>
+ <xsl:param name="request.objectname"/>
+ <xsl:param name="request.attribute"/>
+ <xsl:param name="request.format"/>
+ <xsl:param name="request.template"/>
+ <xsl:include href="common.xsl"/>
+ <xsl:include href="mbean_attributes.xsl"/>
+
+ <!-- Main template -->
+ <xsl:template match="/" name="main">
+ <html>
+ <xsl:call-template name="head"/>
+ <body>
+ <xsl:call-template name="toprow"/>
+ <xsl:call-template name="tabs">
+ <xsl:with-param name="selection">mbean</xsl:with-param>
+ </xsl:call-template>
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td colspan="3" class="page_title">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">viewcollection.main.title</xsl:with-param>
+ <xsl:with-param name="p0"><xsl:value-of select="MBean/@objectname"/></xsl:with-param>
+ </xsl:call-template>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="3" class="fronttab">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">viewcollection.main.viewcollectiontitle</xsl:with-param>
+ <xsl:with-param name="p0"><xsl:value-of select="MBean/Attribute/@classname"/></xsl:with-param>
+ <xsl:with-param name="p1"><xsl:value-of select="MBean/Attribute/@name"/></xsl:with-param>
+ </xsl:call-template>
+ </td>
+ </tr>
+ <tr>
+ <td class="fronttab">
+ <div class="tableheader">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">viewcollection.main.index</xsl:with-param>
+ </xsl:call-template>
+ </div>
+ </td>
+ <td class="fronttab">
+ <div class="tableheader">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">viewcollection.main.value</xsl:with-param>
+ </xsl:call-template>
+ </div>
+ </td>
+ <td class="fronttab">
+ <div class="tableheader">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">viewcollection.main.valueclass</xsl:with-param>
+ </xsl:call-template>
+ </div>
+ </td>
+ </tr>
+
+ <xsl:for-each select="MBean/Attribute/Collection/Element">
+ <xsl:sort order="ascending" select="@index"/>
+ <xsl:if test="position()<($request.step+$request.start) and position()>$request.start">
+ <xsl:variable name="classtype">
+ <xsl:if test="(position() mod 2)=1">clearline</xsl:if>
+ <xsl:if test="(position() mod 2)=0">darkline</xsl:if>
+ </xsl:variable>
+ <tr class="{$classtype}">
+ <td class="aggregationrow"><xsl:value-of select="@index"/></td>
+ <td class="aggregationrow">
+ <xsl:call-template name="renderobject">
+ <xsl:with-param name="objectclass" select="@elementclass"/>
+ <xsl:with-param name="objectvalue" select="@element"/>
+ </xsl:call-template>
+ </td>
+ <td class="aggregationrow"><xsl:value-of select="@elementclass"/></td>
+ </tr>
+ </xsl:if>
+ </xsl:for-each>
+
+ <xsl:variable name="url">getattribute?objectname=<xsl:call-template name="uri-encode"><xsl:with-param name="uri"><xsl:value-of select="$request.objectname"/></xsl:with-param></xsl:call-template>&attribute=<xsl:value-of select="$request.attribute"/>&format=collection&template=viewcollection&locale=<xsl:value-of select="$request.locale"/></xsl:variable>
+ <xsl:call-template name="aggregation-navigation">
+ <xsl:with-param name="url" select="$url"/>
+ <xsl:with-param name="total" select="count(MBean/Attribute/Collection/Element)"/>
+ <xsl:with-param name="start" select="$request.start"/>
+ <xsl:with-param name="step" select="$request.step"/>
+ <xsl:with-param name="str.prefix">viewcollection.main</xsl:with-param>
+ </xsl:call-template>
+
+ <xsl:call-template name="mbeanview">
+ <xsl:with-param name="objectname" select="MBean/@objectname"/>
+ <xsl:with-param name="colspan" select="3"/>
+ </xsl:call-template>
+ </table>
+
+ <xsl:call-template name="bottom"/>
+ </body>
+ </html>
+ </xsl:template>
+</xsl:stylesheet>
+
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/viewmap.xsl b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/viewmap.xsl
new file mode 100644
index 0000000..14b525e
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/viewmap.xsl
@@ -0,0 +1,131 @@
+<?xml version="1.0"?>
+<!--
+ Copyright (C) MX4J.
+ All rights reserved.
+
+ This software is distributed under the terms of the MX4J License version 1.0.
+ See the terms of the MX4J License in the documentation provided with this software.
+
+ Author: Carlos Quiroz (tibu@users.sourceforge.net)
+ Revision: $Revision: 1.1.1.1 $
+ -->
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+ <xsl:output method="html" indent="yes" encoding="UTF-8"/>
+
+ <xsl:param name="html.stylesheet">stylesheet.css</xsl:param>
+ <xsl:param name="html.stylesheet.type">text/css</xsl:param>
+ <xsl:param name="head.title">viewmap.title</xsl:param>
+ <xsl:param name="request.step">30</xsl:param>
+ <xsl:param name="request.start">0</xsl:param>
+ <xsl:param name="request.objectname"/>
+ <xsl:param name="request.attribute"/>
+ <xsl:param name="request.format"/>
+ <xsl:param name="request.template"/>
+ <xsl:include href="common.xsl"/>
+ <xsl:include href="mbean_attributes.xsl"/>
+
+ <!-- Main template -->
+ <xsl:template match="/" name="main">
+ <html>
+ <xsl:call-template name="head"/>
+ <body>
+ <xsl:call-template name="toprow"/>
+ <xsl:call-template name="tabs">
+ <xsl:with-param name="selection">mbean</xsl:with-param>
+ </xsl:call-template>
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td colspan="4" class="page_title">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">viewmap.main.title</xsl:with-param>
+ <xsl:with-param name="p0"><xsl:value-of select="MBean/@objectname"/></xsl:with-param>
+ </xsl:call-template>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="4" class="fronttab">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">viewmap.main.viewmaptitle</xsl:with-param>
+ <xsl:with-param name="p0"><xsl:value-of select="MBean/Attribute/@classname"/></xsl:with-param>
+ <xsl:with-param name="p1"><xsl:value-of select="MBean/Attribute/@name"/></xsl:with-param>
+ </xsl:call-template>
+ </td>
+ </tr>
+ <tr>
+ <td class="fronttab">
+ <div class="tableheader">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">viewmap.main.key</xsl:with-param>
+ </xsl:call-template>
+ </div>
+ </td>
+ <td class="fronttab">
+ <div class="tableheader">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">viewmap.main.keyclass</xsl:with-param>
+ </xsl:call-template>
+ </div>
+ </td>
+ <td class="fronttab">
+ <div class="tableheader">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">viewmap.main.value</xsl:with-param>
+ </xsl:call-template>
+ </div>
+ </td>
+ <td class="fronttab">
+ <div class="tableheader">
+ <xsl:call-template name="str">
+ <xsl:with-param name="id">viewmap.main.valueclass</xsl:with-param>
+ </xsl:call-template>
+ </div>
+ </td>
+ </tr>
+ <xsl:for-each select="MBean/Attribute/Map/Element">
+ <xsl:sort order="ascending" select="@index"/>
+ <xsl:if test="position()<($request.step+$request.start) and position()>$request.start">
+ <xsl:variable name="classtype">
+ <xsl:if test="(position() mod 2)=1">clearline</xsl:if>
+ <xsl:if test="(position() mod 2)=0">darkline</xsl:if>
+ </xsl:variable>
+ <tr class="{$classtype}">
+ <td class="aggregationrow">
+ <xsl:call-template name="renderobject">
+ <xsl:with-param name="objectclass" select="@keyclass"/>
+ <xsl:with-param name="objectvalue" select="@key"/>
+ </xsl:call-template>
+ </td>
+ <td class="aggregationrow"><xsl:value-of select="@keyclass"/></td>
+ <td class="aggregationrow">
+ <xsl:call-template name="renderobject">
+ <xsl:with-param name="objectclass" select="@elementclass"/>
+ <xsl:with-param name="objectvalue" select="@element"/>
+ </xsl:call-template>
+ </td>
+ <td class="aggregationrow"><xsl:value-of select="@elementclass"/></td>
+ </tr>
+ </xsl:if>
+ </xsl:for-each>
+
+ <xsl:variable name="url">getattribute?objectname=<xsl:call-template name="uri-encode"><xsl:with-param name="uri"><xsl:value-of select="$request.objectname"/></xsl:with-param></xsl:call-template>&attribute=<xsl:value-of select="$request.attribute"/>&format=map&template=viewmap&locale=<xsl:value-of select="$request.locale"/></xsl:variable>
+ <xsl:call-template name="aggregation-navigation">
+ <xsl:with-param name="url" select="$url"/>
+ <xsl:with-param name="total" select="count(MBean/Attribute/Map/Element)"/>
+ <xsl:with-param name="start" select="$request.start"/>
+ <xsl:with-param name="step" select="$request.step"/>
+ <xsl:with-param name="str.prefix">viewmap.main</xsl:with-param>
+ </xsl:call-template>
+
+ <xsl:call-template name="mbeanview">
+ <xsl:with-param name="objectname" select="MBean/@objectname"/>
+ <xsl:with-param name="colspan" select="4"/>
+ </xsl:call-template>
+ </table>
+
+ <xsl:call-template name="bottom"/>
+ </body>
+ </html>
+ </xsl:template>
+</xsl:stylesheet>
+
diff --git a/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/xalan-ext.xsl b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/xalan-ext.xsl
new file mode 100644
index 0000000..f1e54ba
--- /dev/null
+++ b/org.apache.felix.mosgi.jmx.httpconnector/src/main/java/org/apache/felix/mosgi/jmx/httpconnector/mx4j/tools/adaptor/http/xsl/xalan-ext.xsl
@@ -0,0 +1,35 @@
+<?xml version="1.0"?>
+<!--
+ Copyright (C) MX4J.
+ All rights reserved.
+
+ This software is distributed under the terms of the MX4J License version 1.0.
+ See the terms of the MX4J License in the documentation provided with this software.
+
+ Author: Carlos Quiroz (tibu@users.sourceforge.net)
+ Brett Knights
+ Revision: $Revision: 1.1.1.1 $
+ -->
+<xsl:stylesheet
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ version="1.0"
+ xmlns:encoder="/java.net.URLEncoder"
+ xmlns:java="http://xml.apache.org/xslt/java"
+ exclude-result-prefixes="java">
+
+ <xsl:template name="uri-encode">
+ <xsl:param name="uri"/>
+ <xsl:choose>
+ <xsl:when test="function-available('java:java.net.URLEncoder.encode')">
+ <xsl:value-of select="java:java.net.URLEncoder.encode($uri)"/>
+ </xsl:when>
+ <xsl:when test="function-available('encoder:encode')">
+ <xsl:value-of select="encoder:encode($uri)"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:message>No encode function available</xsl:message>
+ <xsl:value-of select="$uri"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+</xsl:stylesheet>