This is an automated email from the ASF dual-hosted git repository.
cziegeler pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/felix-dev.git
The following commit(s) were added to refs/heads/master by this push:
new 042aaf6d6f FELIX-6631 : Migrate webconsole plugins to jakarta.servlet
api
042aaf6d6f is described below
commit 042aaf6d6f36c0fcc020e91fc25559efc27aeb76
Author: Carsten Ziegeler <[email protected]>
AuthorDate: Mon Aug 21 13:17:50 2023 +0200
FELIX-6631 : Migrate webconsole plugins to jakarta.servlet api
---
webconsole-plugins/ds/pom.xml | 17 +-
.../webconsole/plugins/ds/internal/Activator.java | 117 ++---
.../ds/internal/ComponentConfigurationPrinter.java | 29 +-
.../plugins/ds/internal/ConfigurationSupport.java | 22 +-
.../plugins/ds/internal/InfoProvider.java | 4 +-
.../plugins/ds/internal/ServiceRegistrations.java | 75 ++++
.../plugins/ds/internal/WebConsolePlugin.java | 474 ++++++++-------------
7 files changed, 306 insertions(+), 432 deletions(-)
diff --git a/webconsole-plugins/ds/pom.xml b/webconsole-plugins/ds/pom.xml
index 1f30b7d105..7ac5f61e75 100644
--- a/webconsole-plugins/ds/pom.xml
+++ b/webconsole-plugins/ds/pom.xml
@@ -56,7 +56,7 @@
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>3.5.0</version>
+ <version>5.1.9</version>
<extensions>true</extensions>
<configuration>
<instructions>
@@ -66,9 +66,6 @@
<Bundle-Activator>
org.apache.felix.webconsole.plugins.ds.internal.Activator
</Bundle-Activator>
- <Include-Resource>
- {maven-resources},OSGI-INF=target/classes/OSGI-INF
- </Include-Resource>
<Import-Package>
org.osgi.service.cm;version="[1.6,2)";resolution:=optional,
org.osgi.service.metatype;version="[1.2,2)";resolution:=optional,
@@ -79,7 +76,7 @@
org.osgi.service.metatype;version="[1.2,2)"
</DynamicImport-Package>
<Embed-Dependency>
-
org.apache.felix.utils;inline=org/apache/felix/utils/json/JSONWriter**
+
org.apache.felix.utils;inline=org/apache/felix/utils/json/JSONWriter**
</Embed-Dependency>
</instructions>
</configuration>
@@ -89,9 +86,9 @@
<dependencies>
<dependency>
- <groupId>javax.servlet</groupId>
- <artifactId>servlet-api</artifactId>
- <version>2.4</version>
+ <groupId>jakarta.servlet</groupId>
+ <artifactId>jakarta.servlet-api</artifactId>
+ <version>5.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
@@ -127,7 +124,7 @@
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.webconsole</artifactId>
- <version>4.2.0</version>
+ <version>4.8.13-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
@@ -139,7 +136,7 @@
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.utils</artifactId>
- <version>1.9.0</version>
+ <version>1.11.8</version>
<scope>provided</scope>
</dependency>
</dependencies>
diff --git
a/webconsole-plugins/ds/src/main/java/org/apache/felix/webconsole/plugins/ds/internal/Activator.java
b/webconsole-plugins/ds/src/main/java/org/apache/felix/webconsole/plugins/ds/internal/Activator.java
index 5f3e9c86de..cb276f2437 100644
---
a/webconsole-plugins/ds/src/main/java/org/apache/felix/webconsole/plugins/ds/internal/Activator.java
+++
b/webconsole-plugins/ds/src/main/java/org/apache/felix/webconsole/plugins/ds/internal/Activator.java
@@ -16,17 +16,9 @@
*/
package org.apache.felix.webconsole.plugins.ds.internal;
-import java.util.Dictionary;
-import java.util.Hashtable;
-
-import org.apache.felix.inventory.Format;
-import org.apache.felix.inventory.InventoryPrinter;
-import org.apache.felix.webconsole.SimpleWebConsolePlugin;
-import org.apache.felix.webconsole.bundleinfo.BundleInfoProvider;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
-import org.osgi.framework.ServiceRegistration;
import org.osgi.service.component.runtime.ServiceComponentRuntime;
import org.osgi.util.tracker.ServiceTracker;
import org.osgi.util.tracker.ServiceTrackerCustomizer;
@@ -34,107 +26,46 @@ import org.osgi.util.tracker.ServiceTrackerCustomizer;
/**
* Activator is the main starting class.
*/
-public class Activator implements BundleActivator,
ServiceTrackerCustomizer<ServiceComponentRuntime, ServiceComponentRuntime>
-{
-
- private ServiceTracker<ServiceComponentRuntime, ServiceComponentRuntime>
tracker;
- private BundleContext context;
-
- private SimpleWebConsolePlugin plugin;
+public class Activator
+ implements BundleActivator,
ServiceTrackerCustomizer<ServiceComponentRuntime, ServiceRegistrations> {
- private ServiceRegistration<InventoryPrinter> printerRegistration;
+ private volatile ServiceTracker<ServiceComponentRuntime,
ServiceRegistrations> tracker;
- private ServiceRegistration<BundleInfoProvider> infoRegistration;
+ private volatile BundleContext bundleContext;
- /**
- * @see
org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
- */
- @SuppressWarnings({ "unchecked", "rawtypes" })
- public final void start(BundleContext context) throws Exception
- {
- this.context = context;
- this.tracker = new ServiceTracker(context,
ServiceComponentRuntime.class, this);
+ @Override
+ public final void start(final BundleContext context) throws Exception {
+ this.bundleContext = context;
+ this.tracker = new ServiceTracker<>(context,
ServiceComponentRuntime.class, this);
this.tracker.open();
}
- /**
- * @see
org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
- */
- public final void stop(BundleContext context) throws Exception
- {
- if (tracker != null)
- {
+ @Override
+ public final void stop(final BundleContext context) throws Exception {
+ if (tracker != null) {
tracker.close();
tracker = null;
}
+ this.bundleContext = null;
}
// - begin tracker
- /**
- * @see
org.osgi.util.tracker.ServiceTrackerCustomizer#modifiedService(org.osgi.framework.ServiceReference,
- * java.lang.Object)
- */
- public final void modifiedService(final
ServiceReference<ServiceComponentRuntime> reference, final
ServiceComponentRuntime service)
- {/* unused */
+ @Override
+ public final void modifiedService(final
ServiceReference<ServiceComponentRuntime> reference, final ServiceRegistrations
service) {
+ // nothing to do
}
- /**
- * @see
org.osgi.util.tracker.ServiceTrackerCustomizer#addingService(org.osgi.framework.ServiceReference)
- */
- public final ServiceComponentRuntime addingService(final
ServiceReference<ServiceComponentRuntime> reference)
- {
- SimpleWebConsolePlugin plugin = this.plugin;
- if (plugin == null)
- {
- final ServiceComponentRuntime service =
context.getService(reference);
- this.plugin = plugin = new
WebConsolePlugin(service).register(context);
-
- final Dictionary<String, Object> props = new Hashtable<String,
Object>();
- final String name = "Declarative Services Components";
- props.put(InventoryPrinter.NAME, "scr"); //$NON-NLS-1$
- props.put(InventoryPrinter.TITLE, name);
- props.put(InventoryPrinter.FORMAT, new String[] {
- Format.TEXT.toString(),
- Format.JSON.toString()
- });
- printerRegistration =
context.registerService(InventoryPrinter.class,
- new ComponentConfigurationPrinter(service, (WebConsolePlugin)
plugin),
- props);
-
- infoRegistration = new InfoProvider(context.getBundle(),
service).register(context);
+ @Override
+ public final ServiceRegistrations addingService(final
ServiceReference<ServiceComponentRuntime> reference) {
+ final ServiceComponentRuntime service =
this.bundleContext.getService(reference);
+ if (service != null) {
+ return new ServiceRegistrations(this.bundleContext, service);
}
-
- return context.getService(reference);
+ return null;
}
- /**
- * @see
org.osgi.util.tracker.ServiceTrackerCustomizer#removedService(org.osgi.framework.ServiceReference,
- * java.lang.Object)
- */
- public final void removedService(final
ServiceReference<ServiceComponentRuntime> reference, final
ServiceComponentRuntime service)
- {
- SimpleWebConsolePlugin plugin = this.plugin;
-
- if (tracker.getTrackingCount() == 0 && plugin != null)
- {
- // remove service
- plugin.unregister();
- this.plugin = null;
- // unregister configuration printer too
- ServiceRegistration<?> reg = printerRegistration;
- if (reg != null)
- {
- reg.unregister();
- printerRegistration = null;
- }
- // unregister info provider too
- reg = infoRegistration;
- if (reg != null)
- {
- reg.unregister();
- infoRegistration = null;
- }
- }
-
+ @Override
+ public final void removedService(final
ServiceReference<ServiceComponentRuntime> reference, final ServiceRegistrations
service) {
+ service.destroy();
}
}
diff --git
a/webconsole-plugins/ds/src/main/java/org/apache/felix/webconsole/plugins/ds/internal/ComponentConfigurationPrinter.java
b/webconsole-plugins/ds/src/main/java/org/apache/felix/webconsole/plugins/ds/internal/ComponentConfigurationPrinter.java
index 97906cc450..630319d8c3 100644
---
a/webconsole-plugins/ds/src/main/java/org/apache/felix/webconsole/plugins/ds/internal/ComponentConfigurationPrinter.java
+++
b/webconsole-plugins/ds/src/main/java/org/apache/felix/webconsole/plugins/ds/internal/ComponentConfigurationPrinter.java
@@ -24,16 +24,15 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.TreeMap;
import java.util.TreeSet;
import org.apache.felix.inventory.Format;
import org.apache.felix.inventory.InventoryPrinter;
import org.apache.felix.utils.json.JSONWriter;
-import org.apache.felix.webconsole.WebConsoleUtil;
import org.osgi.framework.Constants;
import org.osgi.framework.dto.ServiceReferenceDTO;
import org.osgi.service.component.ComponentConstants;
@@ -176,7 +175,7 @@ class ComponentConfigurationPrinter implements
InventoryPrinter
TreeMap<Long, ComponentConfigurationDTO> componentMap = new
TreeMap<>();
for(final ComponentConfigurationDTO cfg : configurations)
{
- componentMap.put(new Long(cfg.id), cfg);
+ componentMap.put(cfg.id, cfg);
}
// render components
@@ -343,14 +342,12 @@ class ComponentConfigurationPrinter implements
InventoryPrinter
pw.println(" Properties=");
TreeSet<String> keys = new TreeSet<>(props.keySet());
- for (Iterator<String> ki = keys.iterator(); ki.hasNext();)
- {
- String key = ki.next();
+ for(final String key : keys) {
Object value = props.get(key);
- value = WebConsoleUtil.toString(value);
- if (value.getClass().isArray())
- {
- value = Arrays.asList((Object[]) value);
+ if (value != null && value.getClass().isArray()) {
+ value = Arrays.toString((Object[]) value);
+ } else {
+ value = Objects.toString(value, "n/a");
}
pw.println(" " + key + "=" + value);
}
@@ -358,14 +355,12 @@ class ComponentConfigurationPrinter implements
InventoryPrinter
if ( cfg == null && description.factoryProperties != null ) {
pw.println(" FactoryProperties=");
TreeSet<String> keys = new
TreeSet<>(description.factoryProperties.keySet());
- for (Iterator<String> ki = keys.iterator(); ki.hasNext();)
- {
- String key = ki.next();
+ for(final String key : keys) {
Object value = props.get(key);
- value = WebConsoleUtil.toString(value);
- if (value.getClass().isArray())
- {
- value = Arrays.asList((Object[]) value);
+ if (value != null && value.getClass().isArray()) {
+ value = Arrays.toString((Object[]) value);
+ } else {
+ value = Objects.toString(value, "n/a");
}
pw.println(" " + key + "=" + value);
}
diff --git
a/webconsole-plugins/ds/src/main/java/org/apache/felix/webconsole/plugins/ds/internal/ConfigurationSupport.java
b/webconsole-plugins/ds/src/main/java/org/apache/felix/webconsole/plugins/ds/internal/ConfigurationSupport.java
index 667bb5c883..717c5f3621 100644
---
a/webconsole-plugins/ds/src/main/java/org/apache/felix/webconsole/plugins/ds/internal/ConfigurationSupport.java
+++
b/webconsole-plugins/ds/src/main/java/org/apache/felix/webconsole/plugins/ds/internal/ConfigurationSupport.java
@@ -31,8 +31,7 @@ public class ConfigurationSupport {
private final ServiceTracker<Object, Object> metatypeTracker;
- public ConfigurationSupport(final BundleContext bundleContext)
- {
+ public ConfigurationSupport(final BundleContext bundleContext) {
this.configAdminTracker = new ServiceTracker<Object,
Object>(bundleContext, "org.osgi.service.cm.ConfigurationAdmin", null);
this.metatypeTracker = new ServiceTracker<Object,
Object>(bundleContext, "org.osgi.service.metatype.MetaTypeService", null);
@@ -40,8 +39,7 @@ public class ConfigurationSupport {
this.metatypeTracker.open();
}
- public void close()
- {
+ public void close() {
this.configAdminTracker.close();
this.metatypeTracker.close();
}
@@ -54,23 +52,18 @@ public class ConfigurationSupport {
* @param pid A non null pid
* @return <code>true</code> if the component is configurable.
*/
- public boolean isConfigurable(final Bundle providingBundle, final String
pid)
- {
+ public boolean isConfigurable(final Bundle providingBundle, final String
pid) {
// we first check if the config admin has something for this pid
final Object ca = this.configAdminTracker.getService();
- if (ca != null)
- {
- if ( new ConfigurationAdminSupport().check(ca, pid) )
- {
+ if (ca != null) {
+ if ( new ConfigurationAdminSupport().check(ca, pid) ) {
return true;
}
}
// second check is using the meta type service
- if (providingBundle != null)
- {
+ if (providingBundle != null) {
final Object mts = this.metatypeTracker.getService();
- if (mts != null)
- {
+ if (mts != null) {
return new MetatypeSupport().check(mts, providingBundle, pid);
}
}
@@ -90,5 +83,4 @@ public class ConfigurationSupport {
}
return new
MetatypeSupport().getPasswordAttributeDefinitionIds(metaTypeService, bundle,
configurationPids);
}
-
}
\ No newline at end of file
diff --git
a/webconsole-plugins/ds/src/main/java/org/apache/felix/webconsole/plugins/ds/internal/InfoProvider.java
b/webconsole-plugins/ds/src/main/java/org/apache/felix/webconsole/plugins/ds/internal/InfoProvider.java
index ce26da0de6..be353d06fa 100644
---
a/webconsole-plugins/ds/src/main/java/org/apache/felix/webconsole/plugins/ds/internal/InfoProvider.java
+++
b/webconsole-plugins/ds/src/main/java/org/apache/felix/webconsole/plugins/ds/internal/InfoProvider.java
@@ -143,9 +143,7 @@ class InfoProvider implements BundleInfoProvider
BundleInfoType.LINK, descr);
}
- ServiceRegistration<BundleInfoProvider> register(BundleContext context)
- {
+ ServiceRegistration<BundleInfoProvider> register(final BundleContext
context) {
return context.registerService(BundleInfoProvider.class, this, null);
}
-
}
diff --git
a/webconsole-plugins/ds/src/main/java/org/apache/felix/webconsole/plugins/ds/internal/ServiceRegistrations.java
b/webconsole-plugins/ds/src/main/java/org/apache/felix/webconsole/plugins/ds/internal/ServiceRegistrations.java
new file mode 100644
index 0000000000..81690ed89f
--- /dev/null
+++
b/webconsole-plugins/ds/src/main/java/org/apache/felix/webconsole/plugins/ds/internal/ServiceRegistrations.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.felix.webconsole.plugins.ds.internal;
+
+import java.io.Closeable;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.List;
+
+import org.apache.felix.inventory.Format;
+import org.apache.felix.inventory.InventoryPrinter;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.component.runtime.ServiceComponentRuntime;
+
+public class ServiceRegistrations {
+
+ private final List<ServiceRegistration<?>> registrations = new
ArrayList<>();
+
+ private final List<Closeable> closeables = new ArrayList<>();
+
+ public ServiceRegistrations(final BundleContext bundleContext, final
ServiceComponentRuntime runtime) {
+ final WebConsolePlugin plugin = new WebConsolePlugin(bundleContext,
runtime);
+ this.closeables.add(plugin);
+ this.registrations.add(plugin.register(bundleContext));
+
+ final Dictionary<String, Object> props = new Hashtable<String,
Object>();
+ final String name = "Declarative Services Components";
+ props.put(InventoryPrinter.NAME, "scr"); //$NON-NLS-1$
+ props.put(InventoryPrinter.TITLE, name);
+ props.put(InventoryPrinter.FORMAT, new String[] {
+ Format.TEXT.toString(),
+ Format.JSON.toString()
+ });
+
this.registrations.add(bundleContext.registerService(InventoryPrinter.class,
+ new ComponentConfigurationPrinter(runtime, (WebConsolePlugin)
plugin),
+ props));
+
+ this.registrations.add(new InfoProvider(bundleContext.getBundle(),
runtime).register(bundleContext));
+ }
+
+ public void destroy() {
+ for(final ServiceRegistration<?> reg : this.registrations) {
+ try {
+ reg.unregister();
+ } catch (final IllegalStateException e) {
+ // ignore - bundle is already stopped
+ }
+ }
+ this.registrations.clear();
+ for(final Closeable c : this.closeables) {
+ try {
+ c.close();
+ } catch (final Exception e) {
+ // ignore
+ }
+ }
+ this.closeables.clear();
+ }
+}
diff --git
a/webconsole-plugins/ds/src/main/java/org/apache/felix/webconsole/plugins/ds/internal/WebConsolePlugin.java
b/webconsole-plugins/ds/src/main/java/org/apache/felix/webconsole/plugins/ds/internal/WebConsolePlugin.java
index a7c4715f61..f0ae969ed4 100644
---
a/webconsole-plugins/ds/src/main/java/org/apache/felix/webconsole/plugins/ds/internal/WebConsolePlugin.java
+++
b/webconsole-plugins/ds/src/main/java/org/apache/felix/webconsole/plugins/ds/internal/WebConsolePlugin.java
@@ -16,6 +16,7 @@
*/
package org.apache.felix.webconsole.plugins.ds.internal;
+import java.io.Closeable;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
@@ -23,22 +24,22 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
+import java.util.Dictionary;
+import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.TreeSet;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
import org.apache.felix.utils.json.JSONWriter;
-import org.apache.felix.webconsole.DefaultVariableResolver;
-import org.apache.felix.webconsole.SimpleWebConsolePlugin;
-import org.apache.felix.webconsole.WebConsoleUtil;
+import org.apache.felix.webconsole.servlet.AbstractServlet;
+import org.apache.felix.webconsole.servlet.RequestVariableResolver;
+import org.apache.felix.webconsole.servlet.ServletConstants;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceRegistration;
import org.osgi.service.component.ComponentConstants;
import org.osgi.service.component.runtime.ServiceComponentRuntime;
import org.osgi.service.component.runtime.dto.ComponentConfigurationDTO;
@@ -47,150 +48,121 @@ import
org.osgi.service.component.runtime.dto.ReferenceDTO;
import org.osgi.service.component.runtime.dto.SatisfiedReferenceDTO;
import org.osgi.util.promise.Promise;
+import jakarta.servlet.Servlet;
+import jakarta.servlet.ServletException;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+
/**
* ComponentsServlet provides a plugin for managing Service Components Runtime.
*/
-class WebConsolePlugin extends SimpleWebConsolePlugin
-{
+public class WebConsolePlugin extends AbstractServlet implements Closeable {
private static final long serialVersionUID = 1L;
- private static final String LABEL = "components"; //$NON-NLS-1$
- private static final String TITLE = "%components.pluginTitle";
//$NON-NLS-1$
- private static final String CATEGORY = "OSGi"; //$NON-NLS-1$
- private static final String CSS[] = { "/res/ui/bundles.css" }; // yes,
it's correct! //$NON-NLS-1$
- private static final String RES = "/" + LABEL + "/res/"; //$NON-NLS-1$
//$NON-NLS-2$
+ private static final String LABEL = "components";
+ private static final String TITLE = "%components.pluginTitle";
+ private static final String CATEGORY = "OSGi";
+ private static final String CSS[] = { "/res/ui/bundles.css" };
+ private static final String RES = "/" + LABEL + "/res/";
// actions
- private static final String OPERATION = "action"; //$NON-NLS-1$
- private static final String OPERATION_ENABLE = "enable"; //$NON-NLS-1$
- private static final String OPERATION_DISABLE = "disable"; //$NON-NLS-1$
- //private static final String OPERATION_CONFIGURE = "configure";
+ private static final String OPERATION = "action";
+ private static final String OPERATION_ENABLE = "enable";
+ private static final String OPERATION_DISABLE = "disable";
// templates
- private final String TEMPLATE;
+ private final String template;
- private volatile ConfigurationSupport support;
+ private final ConfigurationSupport support;
private final ServiceComponentRuntime runtime;
- /** Default constructor */
- WebConsolePlugin(final ServiceComponentRuntime service)
- {
- super(LABEL, TITLE, CSS);
+ private final BundleContext bundleContext;
+ /** Default constructor */
+ public WebConsolePlugin(final BundleContext bundleContext, final
ServiceComponentRuntime service) {
this.runtime = service;
- // load templates
- TEMPLATE = readTemplateFile("/res/plugin.html"); //$NON-NLS-1$
- }
-
-
- @Override
- public void deactivate() {
- if ( this.support != null )
- {
- this.support.close();
- this.support = null;
+ this.bundleContext = bundleContext;
+ try {
+ this.template = readTemplateFile("/res/plugin.html");
+ } catch ( final IOException ioe) {
+ throw new RuntimeException("Unable to read template file", ioe);
}
- super.deactivate();
- }
-
-
- @Override
- public void activate(final BundleContext bundleContext)
- {
- super.activate(bundleContext);
this.support = new ConfigurationSupport(bundleContext);
}
+ public ServiceRegistration<Servlet> register(final BundleContext context) {
+ final Dictionary<String, Object> props = new Hashtable<>();
+ props.put(ServletConstants.PLUGIN_LABEL, LABEL);
+ props.put(ServletConstants.PLUGIN_TITLE, TITLE);
+ props.put(ServletConstants.PLUGIN_CATEGORY, CATEGORY);
+ props.put(ServletConstants.PLUGIN_CSS_REFERENCES, CSS);
+ return context.registerService(Servlet.class, this, props);
+ }
@Override
- public String getCategory()
- {
- return CATEGORY;
+ public void close() {
+ this.support.close();
}
-
- private void wait(final Promise<Void> p )
- {
- while ( !p.isDone() )
- {
- try
- {
+
+ private void wait(final Promise<Void> p ) {
+ while ( !p.isDone() ) {
+ try {
Thread.sleep(5);
- }
- catch (final InterruptedException e)
- {
+ } catch (final InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
- /**
- * @see
javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest,
javax.servlet.http.HttpServletResponse)
- */
@Override
- protected void doPost(HttpServletRequest request, HttpServletResponse
response)
- throws IOException
- {
+ protected void doPost(final HttpServletRequest request, final
HttpServletResponse response)
+ throws IOException {
final String op = request.getParameter(OPERATION);
RequestInfo reqInfo = new RequestInfo(request, true);
- if (reqInfo.componentRequested)
- {
+ if (reqInfo.componentRequested) {
boolean found = false;
- if ( reqInfo.component != null )
- {
- if (OPERATION_ENABLE.equals(op))
- {
+ if ( reqInfo.component != null ) {
+ if (OPERATION_ENABLE.equals(op)) {
wait(this.runtime.enableComponent(reqInfo.component.description));
reqInfo = new RequestInfo(request, false);
found = true;
- }
- else if ( OPERATION_DISABLE.equals(op) )
- {
+ } else if ( OPERATION_DISABLE.equals(op) ) {
wait(this.runtime.disableComponent(reqInfo.component.description));
found = true;
}
}
- if ( !found )
- {
+ if ( !found ) {
response.sendError(404);
return;
}
- }
- else
- {
+ } else {
response.sendError(500);
return;
}
final PrintWriter pw = response.getWriter();
- response.setContentType("application/json"); //$NON-NLS-1$
- response.setCharacterEncoding("UTF-8"); //$NON-NLS-1$
+ response.setContentType("application/json");
+ response.setCharacterEncoding("UTF-8");
renderResult(pw, reqInfo, null);
}
- /**
- * @see
org.apache.felix.webconsole.AbstractWebConsolePlugin#doGet(javax.servlet.http.HttpServletRequest,
javax.servlet.http.HttpServletResponse)
- */
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse
response)
- throws ServletException, IOException
- {
- String path = request.getPathInfo();
+ throws ServletException, IOException {
+ final String path = request.getPathInfo();
// don't process if this is request to load a resource
- if (!path.startsWith(RES))
- {
+ if (!path.startsWith(RES)) {
final RequestInfo reqInfo = new RequestInfo(request, true);
- if (reqInfo.component == null && reqInfo.componentRequested)
- {
+ if (reqInfo.component == null && reqInfo.componentRequested) {
response.sendError(404);
return;
}
- if (reqInfo.extension.equals("json")) //$NON-NLS-1$
- {
- response.setContentType("application/json"); //$NON-NLS-1$
- response.setCharacterEncoding("UTF-8"); //$NON-NLS-1$
-
+ if (reqInfo.extension.equals("json")) {
+ response.setContentType("application/json");
+ response.setCharacterEncoding("UTF-8");
+ response.setStatus(HttpServletResponse.SC_OK);
this.renderResult(response.getWriter(), reqInfo,
reqInfo.component);
// nothing more to do
@@ -200,62 +172,46 @@ class WebConsolePlugin extends SimpleWebConsolePlugin
super.doGet(request, response);
}
- /**
- * @see
org.apache.felix.webconsole.AbstractWebConsolePlugin#renderContent(javax.servlet.http.HttpServletRequest,
javax.servlet.http.HttpServletResponse)
- */
- @SuppressWarnings("unchecked")
@Override
- protected void renderContent(HttpServletRequest request,
HttpServletResponse response)
- throws IOException
- {
+ public void renderContent(final HttpServletRequest request, final
HttpServletResponse response)
+ throws IOException {
// get request info from request attribute
final RequestInfo reqInfo = getRequestInfo(request);
- StringWriter w = new StringWriter();
+ final StringWriter w = new StringWriter();
PrintWriter w2 = new PrintWriter(w);
renderResult(w2, reqInfo, reqInfo.component);
// prepare variables
- DefaultVariableResolver vars = ((DefaultVariableResolver)
WebConsoleUtil.getVariableResolver(request));
- vars.put("__drawDetails__", reqInfo.componentRequested ? Boolean.TRUE
: Boolean.FALSE); //$NON-NLS-1$
- vars.put("__data__", w.toString()); //$NON-NLS-1$
-
- response.getWriter().print(TEMPLATE);
+ RequestVariableResolver resolver = this.getVariableResolver(request);
+ resolver.put("__drawDetails__", reqInfo.componentRequested ?
Boolean.TRUE : Boolean.FALSE);
+ resolver.put("__data__", w.toString());
+ response.getWriter().print(this.template);
}
- private void renderResult(final PrintWriter pw, RequestInfo info, final
ComponentConfigurationDTO component)
- throws IOException
- {
+ private void renderResult(final PrintWriter pw, final RequestInfo info,
final ComponentConfigurationDTO component)
+ throws IOException {
final JSONWriter jw = new JSONWriter(pw);
jw.object();
- jw.key("status"); //$NON-NLS-1$
+ jw.key("status");
jw.value(info.configurations.size());
- if ( !info.configurations.isEmpty() )
- {
+ if ( !info.configurations.isEmpty() ) {
// render components
- jw.key("data"); //$NON-NLS-1$
+ jw.key("data");
jw.array();
- if (component != null)
- {
- if ( component.state == -1 )
- {
+ if (component != null) {
+ if ( component.state == -1 ) {
component(jw, component.description, null, true);
- }
- else
- {
+ } else {
component(jw, component.description, component, true);
}
- }
- else
- {
- for( final ComponentDescriptionDTO cd : info.disabled )
- {
+ } else {
+ for( final ComponentDescriptionDTO cd : info.disabled ) {
component(jw, cd, null, false);
}
- for (final ComponentConfigurationDTO cfg : info.configurations)
- {
+ for (final ComponentConfigurationDTO cfg :
info.configurations) {
component(jw, cfg.description, cfg, false);
}
}
@@ -263,10 +219,10 @@ class WebConsolePlugin extends SimpleWebConsolePlugin
}
jw.endObject();
+ jw.flush();
}
- void writePid(final JSONWriter jw, final ComponentDescriptionDTO desc)
throws IOException
- {
+ void writePid(final JSONWriter jw, final ComponentDescriptionDTO desc)
throws IOException {
final String configurationPid = desc.configurationPid[0];
final String pid;
if (desc.configurationPid.length == 1) {
@@ -274,60 +230,51 @@ class WebConsolePlugin extends SimpleWebConsolePlugin
} else {
pid = Arrays.toString(desc.configurationPid);
}
- jw.key("pid"); //$NON-NLS-1$
+ jw.key("pid");
jw.value(pid);
final ConfigurationSupport localSupport = this.support;
if (localSupport != null && localSupport.isConfigurable(
-
this.getBundleContext().getBundle(0).getBundleContext().getBundle(desc.bundle.id),
- configurationPid))
- {
- jw.key("configurable"); //$NON-NLS-1$
+
this.bundleContext.getBundle(0).getBundleContext().getBundle(desc.bundle.id),
+ configurationPid)) {
+ jw.key("configurable");
jw.value(configurationPid);
}
}
void component(JSONWriter jw,
final ComponentDescriptionDTO desc,
- final ComponentConfigurationDTO config, boolean details) throws
IOException
- {
+ final ComponentConfigurationDTO config, boolean details) throws
IOException {
String id = config == null ? "" : String.valueOf(config.id);
String name = desc.name;
jw.object();
// component information
- jw.key("id"); //$NON-NLS-1$
+ jw.key("id");
jw.value(id);
- jw.key("bundleId"); //$NON-NLS-1$
+ jw.key("bundleId");
jw.value(desc.bundle.id);
- jw.key("name"); //$NON-NLS-1$
+ jw.key("name");
jw.value(name);
- jw.key("state"); //$NON-NLS-1$
- if ( config != null )
- {
+ jw.key("state");
+ if ( config != null ) {
jw.value(ComponentConfigurationPrinter.toStateString(config.state));
- jw.key("stateRaw"); //$NON-NLS-1$
+ jw.key("stateRaw");
jw.value(config.state);
- }
- else
- {
- if ( desc.defaultEnabled &&
"require".equals(desc.configurationPolicy))
- {
+ } else {
+ if ( desc.defaultEnabled &&
"require".equals(desc.configurationPolicy)) {
jw.value("no config");
+ } else {
+ jw.value("disabled");
}
- else
- {
- jw.value("disabled"); //$NON-NLS-1$
- }
- jw.key("stateRaw"); //$NON-NLS-1$
+ jw.key("stateRaw");
jw.value(-1);
}
writePid(jw, desc);
// component details
- if (details)
- {
+ if (details) {
gatherComponentDetails(jw, desc, config);
}
@@ -336,18 +283,16 @@ class WebConsolePlugin extends SimpleWebConsolePlugin
private void gatherComponentDetails(JSONWriter jw,
ComponentDescriptionDTO desc,
- ComponentConfigurationDTO component) throws IOException
- {
- final Bundle bundle =
this.getBundleContext().getBundle(0).getBundleContext().getBundle(desc.bundle.id);
+ ComponentConfigurationDTO component) throws IOException {
+ final Bundle bundle =
this.bundleContext.getBundle(0).getBundleContext().getBundle(desc.bundle.id);
- jw.key("props"); //$NON-NLS-1$
+ jw.key("props");
jw.array();
keyVal(jw, "Bundle", bundle.getSymbolicName() + " ("
+ bundle.getBundleId() + ")");
keyVal(jw, "Implementation Class", desc.implementationClass);
- if (desc.factory != null)
- {
+ if (desc.factory != null) {
keyVal(jw, "Component Factory Name", desc.factory);
}
keyVal(jw, "Default State", desc.defaultEnabled ? "enabled" :
"disabled");
@@ -373,11 +318,9 @@ class WebConsolePlugin extends SimpleWebConsolePlugin
jw.endArray();
}
- private void listServices(JSONWriter jw, ComponentDescriptionDTO desc)
throws IOException
- {
+ private void listServices(JSONWriter jw, ComponentDescriptionDTO desc)
throws IOException {
String[] services = desc.serviceInterfaces;
- if (services == null)
- {
+ if (services == null) {
return;
}
@@ -389,49 +332,39 @@ class WebConsolePlugin extends SimpleWebConsolePlugin
jw.value("Services");
jw.key("value");
jw.array();
- for (int i = 0; i < services.length; i++)
- {
+ for (int i = 0; i < services.length; i++) {
jw.value(services[i]);
}
jw.endArray();
jw.endObject();
}
- private SatisfiedReferenceDTO findReference(final
ComponentConfigurationDTO component, final String name)
- {
- for(final SatisfiedReferenceDTO dto : component.satisfiedReferences)
- {
- if ( dto.name.equals(name))
- {
+ private SatisfiedReferenceDTO findReference(final
ComponentConfigurationDTO component, final String name) {
+ for(final SatisfiedReferenceDTO dto : component.satisfiedReferences) {
+ if ( dto.name.equals(name)) {
return dto;
}
}
return null;
}
- private void listReferences(JSONWriter jw, ComponentDescriptionDTO desc,
ComponentConfigurationDTO config) throws IOException
- {
- for(final ReferenceDTO dto : desc.references)
- {
+ private void listReferences(JSONWriter jw, ComponentDescriptionDTO desc,
ComponentConfigurationDTO config) throws IOException {
+ for(final ReferenceDTO dto : desc.references) {
jw.object();
jw.key("key");
jw.value("Reference " + dto.name);
jw.key("value");
jw.array();
final SatisfiedReferenceDTO satisfiedRef;
- if ( config != null )
- {
+ if ( config != null ) {
satisfiedRef = findReference(config, dto.name);
jw.value(satisfiedRef != null ? "Satisfied" : "Unsatisfied");
- }
- else
- {
+ } else {
satisfiedRef = null;
}
jw.value("Service Name: " + dto.interfaceName);
- if (dto.target != null)
- {
+ if (dto.target != null) {
jw.value("Target Filter: " + dto.target);
}
jw.value("Cardinality: " + dto.cardinality);
@@ -439,8 +372,7 @@ class WebConsolePlugin extends SimpleWebConsolePlugin
jw.value("Policy Option: " + dto.policyOption);
// list bound services
- if ( satisfiedRef != null )
- {
+ if ( satisfiedRef != null ) {
for (int j = 0; j < satisfiedRef.boundServices.length; j++)
{
final StringBuffer b = new StringBuffer();
@@ -448,25 +380,20 @@ class WebConsolePlugin extends SimpleWebConsolePlugin
b.append(satisfiedRef.boundServices[j].id);
String name = (String)
satisfiedRef.boundServices[j].properties.get(ComponentConstants.COMPONENT_NAME);
- if (name == null)
- {
+ if (name == null) {
name = (String)
satisfiedRef.boundServices[j].properties.get(Constants.SERVICE_PID);
- if (name == null)
- {
+ if (name == null) {
name = (String)
satisfiedRef.boundServices[j].properties.get(Constants.SERVICE_DESCRIPTION);
}
}
- if (name != null)
- {
+ if (name != null) {
b.append(" (");
b.append(name);
b.append(")");
}
jw.value(b.toString());
}
- }
- else if ( config != null )
- {
+ } else if ( config != null ) {
jw.value("No Services bound");
}
@@ -475,20 +402,19 @@ class WebConsolePlugin extends SimpleWebConsolePlugin
}
}
- private void listProperties(JSONWriter jw, ComponentDescriptionDTO desc,
ComponentConfigurationDTO component) throws IOException
- {
+ private void listProperties(JSONWriter jw, ComponentDescriptionDTO desc,
ComponentConfigurationDTO component)
+ throws IOException {
Map<String, Object> props = component != null ? component.properties :
desc.properties;
// Is this the right way to get bundle and configuration PID?
- Bundle bundle =
this.getBundleContext().getBundle(0).getBundleContext().getBundle(desc.bundle.id);
+ Bundle bundle =
this.bundleContext.getBundle(0).getBundleContext().getBundle(desc.bundle.id);
String[] configurationPids = desc.configurationPid;
final ConfigurationSupport localSupport = this.support;
Collection<String> passwordPropertyIds = localSupport != null ?
localSupport.getPasswordAttributeDefinitionIds(bundle,
configurationPids) : Collections.emptyList();
- if (props != null)
- {
+ if (props != null) {
jw.object();
jw.key("key");
jw.value("Properties");
@@ -505,7 +431,11 @@ class WebConsolePlugin extends SimpleWebConsolePlugin
b.append("********");
} else {
Object prop = props.get(key);
- prop = WebConsoleUtil.toString(prop);
+ if (prop != null && prop.getClass().isArray()) {
+ prop = Arrays.toString((Object[]) prop);
+ } else {
+ prop = Objects.toString(prop, "n/a");
+ }
b.append(prop);
}
@@ -521,8 +451,7 @@ class WebConsolePlugin extends SimpleWebConsolePlugin
jw.key("value");
jw.array();
TreeSet<String> keys = new
TreeSet<String>(desc.factoryProperties.keySet());
- for (Iterator<String> ki = keys.iterator(); ki.hasNext();)
- {
+ for (Iterator<String> ki = keys.iterator(); ki.hasNext();) {
final String key = ki.next();
final StringBuilder b = new StringBuilder();
b.append(key).append(" = ");
@@ -531,7 +460,11 @@ class WebConsolePlugin extends SimpleWebConsolePlugin
b.append("********");
} else {
Object prop = props.get(key);
- prop = WebConsoleUtil.toString(prop);
+ if (prop != null && prop.getClass().isArray()) {
+ prop = Arrays.toString((Object[]) prop);
+ } else {
+ prop = Objects.toString(prop, "n/a");
+ }
b.append(prop);
}
@@ -542,14 +475,12 @@ class WebConsolePlugin extends SimpleWebConsolePlugin
}
}
- private void keyVal(JSONWriter jw, String key, Object value) throws
IOException
- {
- if (key != null && value != null)
- {
+ private void keyVal(JSONWriter jw, String key, Object value) throws
IOException {
+ if (key != null && value != null) {
jw.object();
- jw.key("key"); //$NON-NLS-1$
+ jw.key("key");
jw.value(key);
- jw.key("value"); //$NON-NLS-1$
+ jw.key("value");
jw.value(value);
jw.endObject();
}
@@ -557,8 +488,7 @@ class WebConsolePlugin extends SimpleWebConsolePlugin
- private final class RequestInfo
- {
+ private final class RequestInfo {
public final String extension;
public final ComponentConfigurationDTO component;
public final boolean componentRequested;
@@ -566,59 +496,44 @@ class WebConsolePlugin extends SimpleWebConsolePlugin
public final List<ComponentConfigurationDTO> configurations = new
ArrayList<ComponentConfigurationDTO>();
public final List<ComponentDescriptionDTO> disabled = new
ArrayList<ComponentDescriptionDTO>();
- protected RequestInfo(final HttpServletRequest request, final boolean
checkPathInfo)
- {
+ protected RequestInfo(final HttpServletRequest request, final boolean
checkPathInfo) {
String info = request.getPathInfo();
// remove label and starting slash
- info = info.substring(getLabel().length() + 1);
+ info = info.substring(LABEL.length() + 1);
// get extension
- if (info.endsWith(".json")) //$NON-NLS-1$
+ if (info.endsWith(".json"))
{
- extension = "json"; //$NON-NLS-1$
+ extension = "json";
info = info.substring(0, info.length() - 5);
- }
- else
- {
- extension = "html"; //$NON-NLS-1$
+ } else {
+ extension = "html";
}
this.descriptions.addAll(runtime.getComponentDescriptionDTOs());
- if (checkPathInfo && info.length() > 1 && info.startsWith("/"))
//$NON-NLS-1$
- {
+ if (checkPathInfo && info.length() > 1 && info.startsWith("/")) {
this.componentRequested = true;
info = info.substring(1);
ComponentConfigurationDTO component = getComponentId(info);
- if (component == null)
- {
+ if (component == null) {
component = getComponentByName(info);
}
this.component = component;
- if ( this.component != null )
- {
+ if ( this.component != null ) {
this.configurations.add(this.component);
}
- }
- else
- {
+ } else {
this.componentRequested = false;
this.component = null;
- for(final ComponentDescriptionDTO d : this.descriptions)
- {
- if ( !runtime.isComponentEnabled(d) )
- {
+ for(final ComponentDescriptionDTO d : this.descriptions) {
+ if ( !runtime.isComponentEnabled(d) ) {
disabled.add(d);
- }
- else
- {
+ } else {
final Collection<ComponentConfigurationDTO> configs =
runtime.getComponentConfigurationDTOs(d);
- if ( configs.isEmpty() )
- {
+ if ( configs.isEmpty() ) {
disabled.add(d);
- }
- else
- {
+ } else {
configurations.addAll(configs);
}
}
@@ -629,97 +544,69 @@ class WebConsolePlugin extends SimpleWebConsolePlugin
request.setAttribute(WebConsolePlugin.this.getClass().getName(),
this);
}
- protected ComponentConfigurationDTO getComponentId(final String
componentIdPar)
- {
- try
- {
+ protected ComponentConfigurationDTO getComponentId(final String
componentIdPar) {
+ try {
final long componentId = Long.parseLong(componentIdPar);
- for(final ComponentDescriptionDTO desc : this.descriptions)
- {
- for(final ComponentConfigurationDTO cfg :
runtime.getComponentConfigurationDTOs(desc))
- {
- if ( cfg.id == componentId )
- {
+ for(final ComponentDescriptionDTO desc : this.descriptions) {
+ for(final ComponentConfigurationDTO cfg :
runtime.getComponentConfigurationDTOs(desc)) {
+ if ( cfg.id == componentId ) {
return cfg;
}
}
}
- }
- catch (NumberFormatException nfe)
- {
+ } catch (NumberFormatException nfe) {
// don't care
}
return null;
}
- protected ComponentConfigurationDTO getComponentByName(final String
names)
- {
- if (names.length() > 0)
- {
+ protected ComponentConfigurationDTO getComponentByName(final String
names) {
+ if (names.length() > 0) {
final int slash = names.lastIndexOf('/');
final String componentName;
final String pid;
long bundleId = -1;
- if (slash > 0)
- {
+ if (slash > 0) {
pid = names.substring(slash + 1);
final String firstPart = names.substring(0, slash);
final int bundleIndex = firstPart.indexOf('/');
- if ( bundleIndex == -1 )
- {
+ if ( bundleIndex == -1 ) {
componentName = firstPart;
- }
- else
- {
+ } else {
componentName = firstPart.substring(bundleIndex + 1);
- try
- {
+ try {
bundleId = Long.valueOf(firstPart.substring(0,
bundleIndex));
- }
- catch ( final NumberFormatException nfe)
- {
+ } catch ( final NumberFormatException nfe) {
// wrong format
return null;
}
}
- }
- else
- {
+ } else {
componentName = names;
pid = null;
}
Collection<ComponentConfigurationDTO> components = null;
- for(final ComponentDescriptionDTO d : this.descriptions)
- {
- if ( d.name.equals(componentName) && (bundleId == -1 ||
d.bundle.id == bundleId))
- {
+ for(final ComponentDescriptionDTO d : this.descriptions) {
+ if ( d.name.equals(componentName) && (bundleId == -1 ||
d.bundle.id == bundleId)) {
components = runtime.getComponentConfigurationDTOs(d);
- if ( components.isEmpty() )
- {
+ if ( components.isEmpty() ) {
final ComponentConfigurationDTO cfg = new
ComponentConfigurationDTO();
cfg.description = d;
cfg.state = -1;
return cfg;
- }
- else
- {
- if (pid != null)
- {
+ } else {
+ if (pid != null) {
final Iterator<ComponentConfigurationDTO> i =
components.iterator();
- while ( i.hasNext() )
- {
+ while ( i.hasNext() ) {
ComponentConfigurationDTO c = i.next();
- if (
pid.equals(c.description.configurationPid[0]))
- {
+ if (
pid.equals(c.description.configurationPid[0])) {
return c;
}
}
- }
- else if (components.size() > 0)
- {
+ } else if (components.size() > 0) {
return components.iterator().next();
}
@@ -732,8 +619,7 @@ class WebConsolePlugin extends SimpleWebConsolePlugin
}
}
- static RequestInfo getRequestInfo(final HttpServletRequest request)
- {
+ static RequestInfo getRequestInfo(final HttpServletRequest request) {
return (RequestInfo)
request.getAttribute(WebConsolePlugin.class.getName());
}
}