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 9e827e1eff FELIX-6626 : Support jakarta servlet registration
9e827e1eff is described below
commit 9e827e1eff91af1d757edd6933527ec671593ae1
Author: Carsten Ziegeler <[email protected]>
AuthorDate: Mon Aug 21 10:24:58 2023 +0200
FELIX-6626 : Support jakarta servlet registration
---
webconsole/pom.xml | 7 +
.../felix/webconsole/AbstractWebConsolePlugin.java | 36 ++-
.../felix/webconsole/DefaultBrandingPlugin.java | 6 +-
.../felix/webconsole/DefaultVariableResolver.java | 29 +-
.../felix/webconsole/SimpleWebConsolePlugin.java | 2 +-
.../apache/felix/webconsole/VariableResolver.java | 4 +-
.../felix/webconsole/WebConsoleConstants.java | 6 +-
.../webconsole/WebConsoleSecurityProvider2.java | 2 +-
.../apache/felix/webconsole/WebConsoleUtil.java | 93 ++++---
.../felix/webconsole/i18n/LocalizationHelper.java | 10 +-
.../internal/configuration/ConfigManager.java | 31 ++-
.../webconsole/internal/core/BundlesServlet.java | 45 ++-
.../core/PermissionsConfigurationPrinter.java | 6 +-
.../core/ServicesConfigurationPrinter.java | 64 +----
.../webconsole/internal/core/ServicesServlet.java | 14 +-
.../internal/core/ServicesUsedInfoProvider.java | 9 +-
.../internal/filter/FilteringResponseWrapper.java | 6 +-
.../internal/filter/ResourceFilteringWriter.java | 9 +-
.../internal/i18n/CombinedEnumeration.java | 24 +-
.../internal/i18n/CombinedResourceBundle.java | 2 +-
.../i18n/ConsolePropertyResourceBundle.java | 26 +-
.../internal/i18n/ResourceBundleCache.java | 87 +++---
.../webconsole/internal/misc/LicenseServlet.java | 5 +-
.../internal/misc/SystemPropertiesPrinter.java | 3 +-
.../internal/servlet/JakartaServletAdapter.java | 303 +++++++++++++++++++++
.../internal/servlet/JakartaServletTracker.java | 6 +
.../webconsole/internal/servlet/PluginHolder.java | 20 +-
.../webconsole/internal/system/VMStatPlugin.java | 6 +-
.../felix/webconsole/servlet/AbstractServlet.java | 201 ++++++++++++++
.../servlet/RequestVariableResolver.java | 62 +++++
.../felix/webconsole/servlet/ServletConstants.java | 75 +++++
.../webconsole/{spi => servlet}/package-info.java | 4 +-
.../apache/felix/webconsole/spi/package-info.java | 2 +-
.../webconsole/AbstractWebConsolePluginTest.java | 4 +
.../internal/servlet/OsgiManagerTest.java | 4 +-
35 files changed, 888 insertions(+), 325 deletions(-)
diff --git a/webconsole/pom.xml b/webconsole/pom.xml
index a373d50a11..3a3258d334 100644
--- a/webconsole/pom.xml
+++ b/webconsole/pom.xml
@@ -384,6 +384,13 @@
<scope>provided</scope>
</dependency>
+ <dependency>
+ <groupId>org.owasp.encoder</groupId>
+ <artifactId>encoder</artifactId>
+ <version>1.2.3</version>
+ <scope>provided</scope>
+ </dependency>
+
<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.service.log</artifactId>
diff --git
a/webconsole/src/main/java/org/apache/felix/webconsole/AbstractWebConsolePlugin.java
b/webconsole/src/main/java/org/apache/felix/webconsole/AbstractWebConsolePlugin.java
index 25932644a5..374d6f305f 100644
---
a/webconsole/src/main/java/org/apache/felix/webconsole/AbstractWebConsolePlugin.java
+++
b/webconsole/src/main/java/org/apache/felix/webconsole/AbstractWebConsolePlugin.java
@@ -45,6 +45,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.felix.webconsole.internal.servlet.OsgiManager;
+import org.apache.felix.webconsole.servlet.RequestVariableResolver;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.service.log.LogService;
@@ -638,11 +639,9 @@ public abstract class AbstractWebConsolePlugin extends
HttpServlet {
* @throws IOException on I/O error
* @see #endResponse(PrintWriter)
*/
- @SuppressWarnings({ "unchecked" })
- protected PrintWriter startResponse( HttpServletRequest request,
HttpServletResponse response ) throws IOException
- {
- response.setCharacterEncoding( "utf-8" ); //$NON-NLS-1$
- response.setContentType( "text/html" ); //$NON-NLS-1$
+ protected PrintWriter startResponse( HttpServletRequest request,
HttpServletResponse response ) throws IOException {
+ response.setCharacterEncoding( "utf-8" );
+ response.setContentType( "text/html" );
final PrintWriter pw = response.getWriter();
@@ -650,24 +649,21 @@ public abstract class AbstractWebConsolePlugin extends
HttpServlet {
// support localization of the plugin title
String title = getTitle();
- if ( title.startsWith( "%" ) ) //$NON-NLS-1$
+ if ( title.startsWith( "%" ) )
{
- title = "${" + title.substring( 1 ) + "}"; //$NON-NLS-1$
//$NON-NLS-2$
+ title = "${" + title.substring( 1 ) + "}";
}
- VariableResolver resolver =
WebConsoleUtil.getVariableResolver(request);
- if (resolver instanceof DefaultVariableResolver) {
- DefaultVariableResolver r = (DefaultVariableResolver) resolver;
- r.put("head.title", title); //$NON-NLS-1$
- r.put("head.label", getLabel()); //$NON-NLS-1$
- r.put("head.cssLinks", getCssLinks(appRoot)); //$NON-NLS-1$
- r.put("brand.name", brandingPlugin.getBrandName()); //$NON-NLS-1$
- r.put("brand.product.url", brandingPlugin.getProductURL());
//$NON-NLS-1$
- r.put("brand.product.name", brandingPlugin.getProductName());
//$NON-NLS-1$
- r.put("brand.product.img", toUrl(
brandingPlugin.getProductImage(), appRoot )); //$NON-NLS-1$
- r.put("brand.favicon", toUrl( brandingPlugin.getFavIcon(), appRoot
)); //$NON-NLS-1$
- r.put("brand.css", toUrl( brandingPlugin.getMainStyleSheet(),
appRoot )); //$NON-NLS-1$
- }
+ final RequestVariableResolver r =
WebConsoleUtil.getRequestVariableResolver(request);
+ r.put("head.title", title);
+ r.put("head.label", getLabel());
+ r.put("head.cssLinks", getCssLinks(appRoot));
+ r.put("brand.name", brandingPlugin.getBrandName());
+ r.put("brand.product.url", brandingPlugin.getProductURL());
+ r.put("brand.product.name", brandingPlugin.getProductName());
+ r.put("brand.product.img", toUrl( brandingPlugin.getProductImage(),
appRoot ));
+ r.put("brand.favicon", toUrl( brandingPlugin.getFavIcon(), appRoot ));
+ r.put("brand.css", toUrl( brandingPlugin.getMainStyleSheet(), appRoot
));
pw.println( getHeader() );
return pw;
diff --git
a/webconsole/src/main/java/org/apache/felix/webconsole/DefaultBrandingPlugin.java
b/webconsole/src/main/java/org/apache/felix/webconsole/DefaultBrandingPlugin.java
index 0da020b530..c4e1ed66bf 100644
---
a/webconsole/src/main/java/org/apache/felix/webconsole/DefaultBrandingPlugin.java
+++
b/webconsole/src/main/java/org/apache/felix/webconsole/DefaultBrandingPlugin.java
@@ -63,7 +63,7 @@ import java.util.Properties;
* <tr>
* <td>Vendor URL</td>
* <td>webconsole.vendor.url</td>
- * <td>http://www.apache.org</td>
+ * <td>https://www.apache.org</td>
* </tr>
* <tr>
* <td>Vendor Image</td>
@@ -133,10 +133,10 @@ public class DefaultBrandingPlugin implements
BrandingPlugin
// set the fields from the properties now
brandName = props.getProperty( "webconsole.brand.name", "Apache Felix
Web Console" ); //$NON-NLS-1$
productName = props.getProperty( "webconsole.product.name", "Apache
Felix" ); //$NON-NLS-1$
- productURL = props.getProperty( "webconsole.product.url",
"http://felix.apache.org" ); //$NON-NLS-1$
+ productURL = props.getProperty( "webconsole.product.url",
"https://felix.apache.org" ); //$NON-NLS-1$
productImage = props.getProperty( "webconsole.product.image",
"/res/imgs/logo.png" ); //$NON-NLS-1$
vendorName = props.getProperty( "webconsole.vendor.name", "The Apache
Software Foundation" ); //$NON-NLS-1$
- vendorURL = props.getProperty( "webconsole.vendor.url",
"http://www.apache.org" ); //$NON-NLS-1$
+ vendorURL = props.getProperty( "webconsole.vendor.url",
"https://www.apache.org" ); //$NON-NLS-1$
vendorImage = props.getProperty( "webconsole.vendor.image",
"/res/imgs/logo.png" ); //$NON-NLS-1$
favIcon = props.getProperty( "webconsole.favicon",
"/res/imgs/favicon.ico" ); //$NON-NLS-1$
mainStyleSheet = props.getProperty( "webconsole.stylesheet",
"/res/ui/webconsole.css" ); //$NON-NLS-1$
diff --git
a/webconsole/src/main/java/org/apache/felix/webconsole/DefaultVariableResolver.java
b/webconsole/src/main/java/org/apache/felix/webconsole/DefaultVariableResolver.java
index 9fa37de286..1c422fc948 100644
---
a/webconsole/src/main/java/org/apache/felix/webconsole/DefaultVariableResolver.java
+++
b/webconsole/src/main/java/org/apache/felix/webconsole/DefaultVariableResolver.java
@@ -18,10 +18,10 @@
*/
package org.apache.felix.webconsole;
-
import java.util.HashMap;
import java.util.Map;
+import org.apache.felix.webconsole.servlet.RequestVariableResolver;
/**
* The <code>DefaultVariableResolver</code> is a <code>HashMap</code> based
@@ -30,9 +30,11 @@ import java.util.Map;
* used by the
* {@link WebConsoleUtil#getVariableResolver(javax.servlet.ServletRequest)}
* as the variable resolver if none has yet been assigned to the request.
+ * @deprecated Use {@link RequestVariableResolver} instead.
*/
@SuppressWarnings({ "rawtypes" })
-public class DefaultVariableResolver extends HashMap implements
VariableResolver {
+@Deprecated
+public class DefaultVariableResolver extends RequestVariableResolver
implements VariableResolver {
private static final long serialVersionUID = 4148807223433047780L;
@@ -51,7 +53,7 @@ public class DefaultVariableResolver extends HashMap
implements VariableResolver
* @see HashMap#HashMap(int, float)
*/
public DefaultVariableResolver( final int initialCapacity, final float
loadFactor ) {
- super( initialCapacity, loadFactor );
+ this();
}
/**
@@ -61,7 +63,7 @@ public class DefaultVariableResolver extends HashMap
implements VariableResolver
* @see HashMap#HashMap(int)
*/
public DefaultVariableResolver( final int initialCapacity ) {
- super( initialCapacity );
+ this();
}
/**
@@ -72,23 +74,6 @@ public class DefaultVariableResolver extends HashMap
implements VariableResolver
*/
@SuppressWarnings({"unchecked"})
public DefaultVariableResolver( final Map source ) {
- super( source );
- }
-
- /**
- * Returns the string representation of the value stored under the variable
- * name in this map. If no value is stored under the variable name,
- * <code>null</code> is returned.
- *
- * @param variable The name of the variable whose value is to be returned.
- * @return The variable value or <code>null</code> if there is no entry
- * with the given name in this map.
- */
- public String resolve( final String variable ) {
- Object value = get( variable );
- if ( value != null ) {
- return value.toString();
- }
- return null;
+ this.putAll(source);
}
}
diff --git
a/webconsole/src/main/java/org/apache/felix/webconsole/SimpleWebConsolePlugin.java
b/webconsole/src/main/java/org/apache/felix/webconsole/SimpleWebConsolePlugin.java
index f91e666625..178bb662e8 100644
---
a/webconsole/src/main/java/org/apache/felix/webconsole/SimpleWebConsolePlugin.java
+++
b/webconsole/src/main/java/org/apache/felix/webconsole/SimpleWebConsolePlugin.java
@@ -133,7 +133,7 @@ public abstract class SimpleWebConsolePlugin extends
AbstractWebConsolePlugin
LocalizationHelper localization = new LocalizationHelper( bundle );
ResourceBundle rb =
localization.getResourceBundle(Locale.getDefault());
if (rb != null) {
- if ( this.title != null && this.title.startsWith( "%" ) ) {
//$NON-NLS-1$
+ if ( this.title != null && this.title.startsWith( "%" ) ) {
String key = this.title.substring(1);
if (rb.containsKey(key)) {
this.servletName = rb.getString(key);
diff --git
a/webconsole/src/main/java/org/apache/felix/webconsole/VariableResolver.java
b/webconsole/src/main/java/org/apache/felix/webconsole/VariableResolver.java
index 7065437a91..99ead1c58e 100644
--- a/webconsole/src/main/java/org/apache/felix/webconsole/VariableResolver.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/VariableResolver.java
@@ -18,8 +18,8 @@
*/
package org.apache.felix.webconsole;
+import org.apache.felix.webconsole.servlet.RequestVariableResolver;
import org.osgi.annotation.versioning.ConsumerType;
-import org.osgi.annotation.versioning.ProviderType;
/**
* The <code>VariableResolver</code> interface defines the API for an object
@@ -41,8 +41,10 @@ import org.osgi.annotation.versioning.ProviderType;
*
* @see WebConsoleUtil#getVariableResolver(javax.servlet.ServletRequest)
* @see WebConsoleUtil#setVariableResolver(javax.servlet.ServletRequest,
VariableResolver)
+ * @deprecated Use {@link RequestVariableResolver} instead.
*/
@ConsumerType
+@Deprecated
public interface VariableResolver {
/**
diff --git
a/webconsole/src/main/java/org/apache/felix/webconsole/WebConsoleConstants.java
b/webconsole/src/main/java/org/apache/felix/webconsole/WebConsoleConstants.java
index 4831d9ff91..4992106561 100644
---
a/webconsole/src/main/java/org/apache/felix/webconsole/WebConsoleConstants.java
+++
b/webconsole/src/main/java/org/apache/felix/webconsole/WebConsoleConstants.java
@@ -18,6 +18,8 @@
*/
package org.apache.felix.webconsole;
+import org.apache.felix.webconsole.servlet.RequestVariableResolver;
+
/**
* WebConsoleConstants provides some common constants that are used by plugin
* developers.
@@ -173,9 +175,11 @@ public interface WebConsoleConstants
* @see VariableResolver
* @see WebConsoleUtil#getVariableResolver(javax.servlet.ServletRequest)
* @see WebConsoleUtil#setVariableResolver(javax.servlet.ServletRequest,
VariableResolver)
+ * @deprecated Use {@link RequestVariableResolver#REQUEST_ATTRIBUTE}
instead
* @since 3.0
*/
- static final String ATTR_CONSOLE_VARIABLE_RESOLVER =
"felix.webconsole.variable.resolver"; //$NON-NLS-1$
+ @Deprecated
+ static final String ATTR_CONSOLE_VARIABLE_RESOLVER =
RequestVariableResolver.REQUEST_ATTRIBUTE;
/**
* The name of the request attribute holding the language {@link
java.util.Map}
diff --git
a/webconsole/src/main/java/org/apache/felix/webconsole/WebConsoleSecurityProvider2.java
b/webconsole/src/main/java/org/apache/felix/webconsole/WebConsoleSecurityProvider2.java
index 3a78b8aa9d..62b2d533ca 100644
---
a/webconsole/src/main/java/org/apache/felix/webconsole/WebConsoleSecurityProvider2.java
+++
b/webconsole/src/main/java/org/apache/felix/webconsole/WebConsoleSecurityProvider2.java
@@ -53,7 +53,7 @@ public interface WebConsoleSecurityProvider2 extends
WebConsoleSecurityProvider
* Authenticates the given request or asks the client for credentials.
* <p>
* Implementations of this method are expected to respect and implement
- * the semantics of the <code>HttpContext.handleSecurity</code> method
+ * the semantics of the <code>ServletContextHelper.handleSecurity</code>
method
* as specified in the OSGi HTTP Service specification.
* <p>
* If this method returns <code>true</code> it is assumed the request
diff --git
a/webconsole/src/main/java/org/apache/felix/webconsole/WebConsoleUtil.java
b/webconsole/src/main/java/org/apache/felix/webconsole/WebConsoleUtil.java
index e48421e589..408859482b 100644
--- a/webconsole/src/main/java/org/apache/felix/webconsole/WebConsoleUtil.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/WebConsoleUtil.java
@@ -38,6 +38,7 @@ import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.fileupload.servlet.ServletRequestContext;
+import org.apache.felix.webconsole.servlet.RequestVariableResolver;
/**
@@ -72,23 +73,42 @@ public final class WebConsoleUtil
* @param request The request whose attribute is returned (or set)
*
* @return The {@link VariableResolver} for the given request.
+ * @deprecated Use the {@link getRequestVariableResolver} instead.
*/
- @SuppressWarnings("unchecked")
- public static VariableResolver getVariableResolver( final ServletRequest
request )
- {
+ @Deprecated
+ public static VariableResolver getVariableResolver( final ServletRequest
request ) {
final Object resolverObj = request.getAttribute(
WebConsoleConstants.ATTR_CONSOLE_VARIABLE_RESOLVER );
- if ( resolverObj instanceof VariableResolver )
- {
+ if ( resolverObj instanceof VariableResolver ) {
return ( VariableResolver ) resolverObj;
}
final DefaultVariableResolver resolver = new DefaultVariableResolver();
- resolver.put( "appRoot", request.getAttribute(
WebConsoleConstants.ATTR_APP_ROOT ) );
- resolver.put( "pluginRoot", request.getAttribute(
WebConsoleConstants.ATTR_PLUGIN_ROOT ) );
+ resolver.put( "appRoot", (String) request.getAttribute(
WebConsoleConstants.ATTR_APP_ROOT ) );
+ resolver.put( "pluginRoot", (String) request.getAttribute(
WebConsoleConstants.ATTR_PLUGIN_ROOT ) );
setVariableResolver( request, resolver );
return resolver;
}
+ /**
+ * Returns the {@link RequestVariableResolver} for the given request.
+ * <p>
+ * The resolver is added to the request attributes via the web console main
+ * servlet before it invokes any plugins.
+ * The preset properties are
+ * <code>appRoot</code> set to the value of the
+ * {@link WebConsoleConstants#ATTR_APP_ROOT} request attribute and
+ * <code>pluginRoot</code> set to the value of the
+ * {@link WebConsoleConstants#ATTR_PLUGIN_ROOT} request attribute.
+ * <p>
+ *
+ * @param request The request whose attribute is returned
+ *
+ * @return The {@link RequestVariableResolver} for the given request.
+ * @since 3.5.0
+ */
+ public static RequestVariableResolver getRequestVariableResolver( final
ServletRequest request) {
+ return (RequestVariableResolver) request.getAttribute(
RequestVariableResolver.REQUEST_ATTRIBUTE );
+ }
/**
* Sets the {@link VariableResolver} as the
@@ -98,9 +118,10 @@ public final class WebConsoleUtil
*
* @param request The request whose attribute is set
* @param resolver The {@link VariableResolver} to place into the request
+ * @deprecated Use the {@link RequestVaraibleResolver} instead.
*/
- public static void setVariableResolver( final ServletRequest request,
final VariableResolver resolver )
- {
+ @Deprecated
+ public static void setVariableResolver( final ServletRequest request,
final VariableResolver resolver ) {
request.setAttribute(
WebConsoleConstants.ATTR_CONSOLE_VARIABLE_RESOLVER, resolver );
}
@@ -243,13 +264,13 @@ public final class WebConsoleUtil
*
* @param text the text to escape
* @return the escaped text
+ * @deprecated It is better to use specialized encoders instead
*/
- public static final String escapeHtml(String text)
- {
+ @Deprecated
+ public static final String escapeHtml(String text) {
StringBuilder sb = new StringBuilder(text.length() * 4 / 3);
char ch, oldch = '_';
- for (int i = 0; i < text.length(); i++)
- {
+ for (int i = 0; i < text.length(); i++) {
switch (ch = text.charAt(i))
{
case '<':
@@ -349,46 +370,36 @@ public final class WebConsoleUtil
* @param value the value to convert
* @return the string representation of the value
*/
- public static final String toString(Object value)
- {
- if (value == null)
- {
- return "n/a"; //$NON-NLS-1$
- }
- else if (value.getClass().isArray())
- {
+ public static final String toString(Object value) {
+ if (value == null) {
+ return "n/a";
+ } else if (value.getClass().isArray()) {
final StringBuilder sb = new StringBuilder();
- final int len = Array.getLength(value);
+ int len = Array.getLength(value);
sb.append('[');
- for (int i = 0; i < len; i++)
- {
+
+ for(int i = 0; i < len; ++i) {
final Object element = Array.get(value, i);
- if (element instanceof Byte)
- {
- // convert byte[] to hex string
- sb.append("0x"); //$NON-NLS-1$
- final String x = Integer.toHexString(((Byte)
element).intValue() & 0xff);
- if (1 == x.length())
- {
+ if (element instanceof Byte) {
+ sb.append("0x");
+ final String x =
Integer.toHexString(((Byte)element).intValue() & 255);
+ if (1 == x.length()) {
sb.append('0');
}
+
sb.append(x);
- }
- else
- {
+ } else {
sb.append(toString(element));
}
- if (i < len - 1)
- {
- sb.append(", "); //$NON-NLS-1$
+ if (i < len - 1) {
+ sb.append(", ");
}
}
+
return sb.append(']').toString();
- }
- else
- {
+ } else {
return value.toString();
}
- }
+ }
}
diff --git
a/webconsole/src/main/java/org/apache/felix/webconsole/i18n/LocalizationHelper.java
b/webconsole/src/main/java/org/apache/felix/webconsole/i18n/LocalizationHelper.java
index a29b6c1c04..b830e38caa 100644
---
a/webconsole/src/main/java/org/apache/felix/webconsole/i18n/LocalizationHelper.java
+++
b/webconsole/src/main/java/org/apache/felix/webconsole/i18n/LocalizationHelper.java
@@ -40,10 +40,10 @@ public class LocalizationHelper {
* the bundle that provides the localization resources. See the
* standard OSGi-type localization support.
*/
- public LocalizationHelper(Bundle bundle) {
- if (null == bundle)
- throw new NullPointerException();
- this.cache = new ResourceBundleCache(bundle);
+ public LocalizationHelper(final Bundle bundle) {
+ if (null == bundle)
+ throw new NullPointerException();
+ this.cache = new ResourceBundleCache(bundle);
}
/**
@@ -54,6 +54,6 @@ public class LocalizationHelper {
* @return the resource bundle (could be empty, but never
<code>null</code>)
*/
public ResourceBundle getResourceBundle(final Locale locale) {
- return cache.getResourceBundle(locale);
+ return cache.getResourceBundle(locale);
}
}
diff --git
a/webconsole/src/main/java/org/apache/felix/webconsole/internal/configuration/ConfigManager.java
b/webconsole/src/main/java/org/apache/felix/webconsole/internal/configuration/ConfigManager.java
index d9ec9da064..416edf8627 100644
---
a/webconsole/src/main/java/org/apache/felix/webconsole/internal/configuration/ConfigManager.java
+++
b/webconsole/src/main/java/org/apache/felix/webconsole/internal/configuration/ConfigManager.java
@@ -35,6 +35,7 @@ import org.apache.felix.webconsole.WebConsoleUtil;
import org.apache.felix.webconsole.internal.OsgiManagerPlugin;
import org.apache.felix.webconsole.internal.Util;
import org.apache.felix.webconsole.internal.misc.ServletSupport;
+import org.apache.felix.webconsole.servlet.RequestVariableResolver;
import org.apache.felix.webconsole.spi.ConfigurationHandler;
import org.apache.felix.webconsole.spi.ValidationException;
import org.osgi.framework.BundleContext;
@@ -423,9 +424,9 @@ public class ConfigManager extends SimpleWebConsolePlugin
implements OsgiManager
cas.getJsonSupport().listFactoryConfigurations( jw, pidFilter,
locale );
}
if ( !hasConfigs && !hasMetatype && cas != null ) {
- jw.key("noconfigs").value(true); //$NON-NLS-1$
+ jw.key("noconfigs").value(true);
} else {
- jw.key("noconfigs").value(false); //$NON-NLS-1$
+ jw.key("noconfigs").value(false);
}
jw.endObject();
@@ -438,19 +439,19 @@ public class ConfigManager extends SimpleWebConsolePlugin
implements OsgiManager
// prepare variables
final String referer = request.getParameter( REFERER );
- final boolean factoryCreate = "true".equals(
request.getParameter(FACTORY_CREATE) ); //$NON-NLS-1$
- @SuppressWarnings("unchecked")
- final Map<String, Object> vars = ( ( Map<String, Object> )
WebConsoleUtil.getVariableResolver( request ) );
- vars.put( "__data__", json.toString() ); //$NON-NLS-1$
- vars.put( "selectedPid", pid != null ? pid : "" ); //$NON-NLS-1$
//$NON-NLS-2$
- vars.put( "configurationReferer", referer != null ? referer : "" );
//$NON-NLS-1$ //$NON-NLS-2$
- vars.put( "factoryCreate", Boolean.valueOf(factoryCreate) );
//$NON-NLS-1$
- vars.put( "param.apply", ACTION_APPLY ); //$NON-NLS-1$
- vars.put( "param.create", ACTION_CREATE ); //$NON-NLS-1$
- vars.put( "param.unbind", ACTION_UNBIND ); //$NON-NLS-1$
- vars.put( "param.delete", ACTION_DELETE ); //$NON-NLS-1$
- vars.put( "param.propertylist", PROPERTY_LIST ); //$NON-NLS-1$
- vars.put( "param.pidFilter", PID_FILTER ); //$NON-NLS-1$
+ final boolean factoryCreate = "true".equals(
request.getParameter(FACTORY_CREATE) );
+
+ final RequestVariableResolver vars =
WebConsoleUtil.getRequestVariableResolver(request);
+ vars.put( "__data__", json.toString() );
+ vars.put( "selectedPid", pid != null ? pid : "" );
+ vars.put( "configurationReferer", referer != null ? referer : "" );
+ vars.put( "factoryCreate", Boolean.valueOf(factoryCreate) );
+ vars.put( "param.apply", ACTION_APPLY );
+ vars.put( "param.create", ACTION_CREATE );
+ vars.put( "param.unbind", ACTION_UNBIND );
+ vars.put( "param.delete", ACTION_DELETE );
+ vars.put( "param.propertylist", PROPERTY_LIST );
+ vars.put( "param.pidFilter", PID_FILTER );
response.getWriter().print(TEMPLATE);
}
diff --git
a/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/BundlesServlet.java
b/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/BundlesServlet.java
index f0bebf8bd2..e564c24e28 100644
---
a/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/BundlesServlet.java
+++
b/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/BundlesServlet.java
@@ -57,7 +57,6 @@ import org.apache.felix.utils.json.JSONWriter;
import org.apache.felix.utils.manifest.Clause;
import org.apache.felix.utils.manifest.Parser;
import org.apache.felix.webconsole.ConfigurationPrinter;
-import org.apache.felix.webconsole.DefaultVariableResolver;
import org.apache.felix.webconsole.SimpleWebConsolePlugin;
import org.apache.felix.webconsole.WebConsoleConstants;
import org.apache.felix.webconsole.WebConsoleUtil;
@@ -65,6 +64,7 @@ import org.apache.felix.webconsole.bundleinfo.BundleInfo;
import org.apache.felix.webconsole.bundleinfo.BundleInfoProvider;
import org.apache.felix.webconsole.internal.OsgiManagerPlugin;
import org.apache.felix.webconsole.internal.Util;
+import org.apache.felix.webconsole.servlet.RequestVariableResolver;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
@@ -75,12 +75,14 @@ import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.osgi.framework.Version;
import org.osgi.framework.VersionRange;
+import org.osgi.framework.startlevel.BundleStartLevel;
+import org.osgi.framework.startlevel.FrameworkStartLevel;
+import org.osgi.framework.wiring.BundleRevision;
import org.osgi.framework.wiring.FrameworkWiring;
import org.osgi.service.cm.ConfigurationAdmin;
import org.osgi.service.log.LogService;
import org.osgi.service.packageadmin.ExportedPackage;
import org.osgi.service.packageadmin.PackageAdmin;
-import org.osgi.service.startlevel.StartLevel;
import org.osgi.util.tracker.ServiceTracker;
import org.osgi.util.tracker.ServiceTrackerCustomizer;
@@ -518,16 +520,17 @@ public class BundlesServlet extends
SimpleWebConsolePlugin implements OsgiManage
* @see
org.apache.felix.webconsole.AbstractWebConsolePlugin#renderContent(javax.servlet.http.HttpServletRequest,
javax.servlet.http.HttpServletResponse)
*/
@Override
- @SuppressWarnings("unchecked")
protected void renderContent( HttpServletRequest request,
HttpServletResponse response ) throws IOException
{
// get request info from request attribute
final RequestInfo reqInfo = getRequestInfo(request);
- final int startLevel = getStartLevel().getInitialBundleStartLevel();
+ final Bundle systemBundle =
this.getBundleContext().getBundle(Constants.SYSTEM_BUNDLE_LOCATION);
+ final FrameworkStartLevel fsl =
systemBundle.adapt(FrameworkStartLevel.class);
+ final int startLevel = fsl.getInitialBundleStartLevel();
// prepare variables
- DefaultVariableResolver vars = ( ( DefaultVariableResolver )
WebConsoleUtil.getVariableResolver( request ) );
+ final RequestVariableResolver vars =
WebConsoleUtil.getRequestVariableResolver(request);
vars.put( "startLevel", String.valueOf(startLevel));
vars.put( "drawDetails", reqInfo.bundleRequested ? Boolean.TRUE :
Boolean.FALSE );
vars.put( "currentBundle", (reqInfo.bundleRequested && reqInfo.bundle
!= null ? String.valueOf(reqInfo.bundle.getBundleId()) : "null"));
@@ -755,15 +758,13 @@ public class BundlesServlet extends
SimpleWebConsolePlugin implements OsgiManage
}
- private final boolean isFragmentBundle( Bundle bundle )
- {
+ private final boolean isFragmentBundle(final Bundle bundle ) {
// Workaround for FELIX-3670
- if ( bundle.getState() == Bundle.UNINSTALLED )
- {
+ if ( bundle.getState() == Bundle.UNINSTALLED ) {
return bundle.getHeaders().get( Constants.FRAGMENT_HOST ) != null;
}
-
- return getPackageAdmin().getBundleType( bundle ) ==
PackageAdmin.BUNDLE_TYPE_FRAGMENT;
+ final BundleRevision rev = bundle.adapt(BundleRevision.class);
+ return rev != null && (rev.getTypes() & BundleRevision.TYPE_FRAGMENT)
== BundleRevision.TYPE_FRAGMENT;
}
private void keyVal(final List<Map<String, Object>> props, final String
key, final Object val)
@@ -865,14 +866,11 @@ public class BundlesServlet extends
SimpleWebConsolePlugin implements OsgiManage
}
- private final Integer getStartLevel( Bundle bundle )
- {
- if ( bundle.getState() != Bundle.UNINSTALLED )
- {
- StartLevel sl = getStartLevel();
- if ( sl != null )
- {
- return sl.getBundleStartLevel( bundle );
+ private final Integer getStartLevel( Bundle bundle ) {
+ if ( bundle.getState() != Bundle.UNINSTALLED ){
+ final BundleStartLevel bsl = bundle.adapt( BundleStartLevel.class
);
+ if (bsl != null ) {
+ return bsl.getStartLevel();
}
}
@@ -881,8 +879,7 @@ public class BundlesServlet extends SimpleWebConsolePlugin
implements OsgiManage
}
- private void listImportExport( List<Map<String, Object>> props, Bundle
bundle, final String pluginRoot )
- {
+ private void listImportExport( List<Map<String, Object>> props, Bundle
bundle, final String pluginRoot ) {
PackageAdmin packageAdmin = getPackageAdmin();
if ( packageAdmin == null )
{
@@ -1467,12 +1464,6 @@ public class BundlesServlet extends
SimpleWebConsolePlugin implements OsgiManage
return ( PackageAdmin ) getService( PackageAdmin.class.getName() );
}
- private final StartLevel getStartLevel()
- {
- return ( StartLevel ) getService( StartLevel.class.getName() );
- }
-
-
//---------- Bundle Installation handler (former InstallAction)
private void installBundles( final HttpServletRequest request )
diff --git
a/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/PermissionsConfigurationPrinter.java
b/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/PermissionsConfigurationPrinter.java
index 1701350edb..f1083874e0 100644
---
a/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/PermissionsConfigurationPrinter.java
+++
b/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/PermissionsConfigurationPrinter.java
@@ -59,8 +59,8 @@ public final class PermissionsConfigurationPrinter extends
AbstractConfiguration
public final void printConfiguration(PrintWriter pw)
{
final BundleContext bc = getBundleContext();
- final ServiceReference paRef = bc.getServiceReference(
PERMISSION_ADMIN_NAME );
- final ServiceReference cpaRef = bc.getServiceReference(
CONDITIONAL_PERMISSION_ADMIN_NAME );
+ final ServiceReference<?> paRef = bc.getServiceReference(
PERMISSION_ADMIN_NAME );
+ final ServiceReference<?> cpaRef = bc.getServiceReference(
CONDITIONAL_PERMISSION_ADMIN_NAME );
final Object paSvc = paRef != null ? bc.getService(paRef) : null;
final Object cpaSvc = cpaRef != null ? bc.getService(cpaRef) : null;
@@ -112,7 +112,7 @@ public final class PermissionsConfigurationPrinter extends
AbstractConfiguration
boolean hasPermissions = false;
//final java.util.List list =
cpa.newConditionalPermissionUpdate().getConditionalPermissionInfos();
//for (int i = 0; list != null && i < list.size(); i++)
- for (Enumeration e = cpa.getConditionalPermissionInfos();
e.hasMoreElements();)
+ for (Enumeration<ConditionalPermissionInfo> e =
cpa.getConditionalPermissionInfos(); e.hasMoreElements();)
{
hasPermissions = true;
//final ConditionalPermissionInfo info =
(ConditionalPermissionInfo) list.get(i);
diff --git
a/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/ServicesConfigurationPrinter.java
b/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/ServicesConfigurationPrinter.java
index 56d11870d4..11af2fcc19 100644
---
a/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/ServicesConfigurationPrinter.java
+++
b/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/ServicesConfigurationPrinter.java
@@ -47,7 +47,7 @@ public class ServicesConfigurationPrinter extends
AbstractConfigurationPrinter
" Using Bundle {0} - {1} ({2}), version {3}");
// don't create empty reference array all the time, create it only once -
it is immutable
- private static final ServiceReference[] NO_REFS = new ServiceReference[0];
+ private static final ServiceReference<?>[] NO_REFS = new
ServiceReference[0];
/**
* @see org.apache.felix.webconsole.ConfigurationPrinter#getTitle()
@@ -65,7 +65,7 @@ public class ServicesConfigurationPrinter extends
AbstractConfigurationPrinter
public final void printConfiguration(PrintWriter pw)
{
final Object[] data = new Object[4]; // used as message formatter
parameters
- final ServiceReference refs[] = getServices();
+ final ServiceReference<?> refs[] = getServices();
pw.print("Status: ");
pw.println(ServicesServlet.getStatusLine(refs));
@@ -118,7 +118,7 @@ public class ServicesConfigurationPrinter extends
AbstractConfigurationPrinter
return data;
}
- private static final Object[] params(ServiceReference ref, Object[] data)
+ private static final Object[] params(ServiceReference<?> ref, Object[]
data)
{
data[0] = ServicesServlet.propertyAsString(ref, Constants.SERVICE_ID);
data[1] = ServicesServlet.propertyAsString(ref, Constants.OBJECTCLASS);
@@ -127,64 +127,20 @@ public class ServicesConfigurationPrinter extends
AbstractConfigurationPrinter
return data;
}
- private final ServiceReference[] getServices()
- {
- ServiceReference[] refs = null;
- try
- {
+ private final ServiceReference<?>[] getServices() {
+ ServiceReference<?>[] refs = null;
+ try {
refs =
BundleContextUtil.getWorkingBundleContext(getBundleContext()).getAllServiceReferences(null,
null);
- }
- catch (InvalidSyntaxException e)
- {
+ } catch (InvalidSyntaxException e) {
// ignore
}
// no services or invalid filter syntax (unlikely)
- if (refs != null)
- {
- Arrays.sort(refs, new ServiceReferenceComparator());
- }
- else
- {
+ if (refs != null) {
+ Arrays.sort(refs);
+ } else {
refs = NO_REFS;
}
return refs;
}
-
-}
-
-class ServiceReferenceComparator implements Comparator
-{
- private static final Long ZERO = new Long(0);
-
- public int compare(ServiceReference p1, ServiceReference p2)
- {
- Long id1 = null;
- if (p1 != null)
- {
- id1 = (Long) p1.getProperty(Constants.SERVICE_ID);
- }
- if (id1 == null)
- {
- id1 = ZERO;
- }
-
- Long id2 = null;
- if (p2 != null)
- {
- id2 = (Long) p2.getProperty(Constants.SERVICE_ID);
- }
- if (id2 == null)
- {
- id2 = ZERO;
- }
-
- return id1.compareTo(id2);
- }
-
- @Override
- public int compare(Object o1, Object o2)
- {
- return compare((ServiceReference) o1, (ServiceReference) o2);
- }
}
diff --git
a/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/ServicesServlet.java
b/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/ServicesServlet.java
index 52a0983835..4aeea6b73f 100644
---
a/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/ServicesServlet.java
+++
b/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/ServicesServlet.java
@@ -30,18 +30,19 @@ 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.WebConsoleConstants;
import org.apache.felix.webconsole.WebConsoleUtil;
import org.apache.felix.webconsole.internal.OsgiManagerPlugin;
import org.apache.felix.webconsole.internal.Util;
+import org.apache.felix.webconsole.servlet.RequestVariableResolver;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
+import org.owasp.encoder.Encode;
/**
@@ -50,12 +51,12 @@ import org.osgi.framework.ServiceRegistration;
public class ServicesServlet extends SimpleWebConsolePlugin implements
OsgiManagerPlugin
{
// don't create empty reference array all the time, create it only once -
it is immutable
- private static final ServiceReference[] NO_REFS = new ServiceReference[0];
+ private static final ServiceReference<?>[] NO_REFS = new
ServiceReference[0];
private final class RequestInfo
{
public final String extension;
- public final ServiceReference service;
+ public final ServiceReference<?> service;
public final boolean serviceRequested;
@@ -404,8 +405,7 @@ public class ServicesServlet extends SimpleWebConsolePlugin
implements OsgiManag
/**
* @see
org.apache.felix.webconsole.AbstractWebConsolePlugin#renderContent(javax.servlet.http.HttpServletRequest,
javax.servlet.http.HttpServletResponse)
*/
- protected void renderContent( HttpServletRequest request,
HttpServletResponse response ) throws IOException
- {
+ protected void renderContent( HttpServletRequest request,
HttpServletResponse response ) throws IOException {
// get request info from request attribute
final RequestInfo reqInfo = getRequestInfo( request );
@@ -415,11 +415,11 @@ public class ServicesServlet extends
SimpleWebConsolePlugin implements OsgiManag
writeJSON(w, reqInfo.service, request.getLocale(), filter);
// prepare variables
- DefaultVariableResolver vars = ( ( DefaultVariableResolver )
WebConsoleUtil.getVariableResolver( request ) );
+ final RequestVariableResolver vars =
WebConsoleUtil.getRequestVariableResolver(request);
vars.put( "bundlePath", appRoot + "/" + BundlesServlet.NAME + "/" );
vars.put( "drawDetails", String.valueOf(reqInfo.serviceRequested));
vars.put( "__data__", w.toString() );
- vars.put( "filter", filter == null ? "" :
WebConsoleUtil.escapeHtml(filter));
+ vars.put( "filter", filter == null ? "" :
Encode.forHtmlContent(filter) );
response.getWriter().print( TEMPLATE );
}
diff --git
a/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/ServicesUsedInfoProvider.java
b/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/ServicesUsedInfoProvider.java
index 8ab35886d9..2139a6117c 100644
---
a/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/ServicesUsedInfoProvider.java
+++
b/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/ServicesUsedInfoProvider.java
@@ -61,7 +61,7 @@ final class ServicesUsedInfoProvider implements
BundleInfoProvider
public BundleInfo[] getBundleInfo( Bundle bundle, String webConsoleRoot,
Locale locale )
{
- final ServiceReference[] refs = bundle.getServicesInUse();
+ final ServiceReference<?>[] refs = bundle.getServicesInUse();
if ( null == refs || refs.length == 0 )
return NO_INFO;
@@ -74,7 +74,7 @@ final class ServicesUsedInfoProvider implements
BundleInfoProvider
}
- private BundleInfo toInfo( ServiceReference ref, String webConsoleRoot,
Locale locale )
+ private BundleInfo toInfo( ServiceReference<?> ref, String webConsoleRoot,
Locale locale )
{
final String[] classes = ( String[] ) ref.getProperty(
Constants.OBJECTCLASS );
final Object id = ref.getProperty( Constants.SERVICE_ID );
@@ -91,9 +91,8 @@ final class ServicesUsedInfoProvider implements
BundleInfoProvider
}
- ServiceRegistration register( BundleContext context )
- {
- return context.registerService( BundleInfoProvider.class.getName(),
this, null );
+ ServiceRegistration<BundleInfoProvider> register( BundleContext context ) {
+ return context.registerService( BundleInfoProvider.class, this, null );
}
}
diff --git
a/webconsole/src/main/java/org/apache/felix/webconsole/internal/filter/FilteringResponseWrapper.java
b/webconsole/src/main/java/org/apache/felix/webconsole/internal/filter/FilteringResponseWrapper.java
index 02880a6bf7..6b6d41b279 100644
---
a/webconsole/src/main/java/org/apache/felix/webconsole/internal/filter/FilteringResponseWrapper.java
+++
b/webconsole/src/main/java/org/apache/felix/webconsole/internal/filter/FilteringResponseWrapper.java
@@ -27,8 +27,8 @@ import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
-import org.apache.felix.webconsole.VariableResolver;
import org.apache.felix.webconsole.WebConsoleUtil;
+import org.apache.felix.webconsole.servlet.RequestVariableResolver;
/**
@@ -86,8 +86,8 @@ public class FilteringResponseWrapper extends
HttpServletResponseWrapper
final PrintWriter base = super.getWriter();
if ( doWrap() )
{
- final VariableResolver resolver =
WebConsoleUtil.getVariableResolver( request );
- final ResourceFilteringWriter filter = new
ResourceFilteringWriter( base, locale, resolver );
+ final RequestVariableResolver vars =
WebConsoleUtil.getRequestVariableResolver(request);
+ final ResourceFilteringWriter filter = new
ResourceFilteringWriter( base, locale, vars );
writer = new PrintWriter( filter );
}
else
diff --git
a/webconsole/src/main/java/org/apache/felix/webconsole/internal/filter/ResourceFilteringWriter.java
b/webconsole/src/main/java/org/apache/felix/webconsole/internal/filter/ResourceFilteringWriter.java
index f9e2aa6560..23c34d116a 100644
---
a/webconsole/src/main/java/org/apache/felix/webconsole/internal/filter/ResourceFilteringWriter.java
+++
b/webconsole/src/main/java/org/apache/felix/webconsole/internal/filter/ResourceFilteringWriter.java
@@ -25,8 +25,7 @@ import java.io.Writer;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
-import org.apache.felix.webconsole.DefaultVariableResolver;
-import org.apache.felix.webconsole.VariableResolver;
+import org.apache.felix.webconsole.servlet.RequestVariableResolver;
/**
@@ -75,7 +74,7 @@ class ResourceFilteringWriter extends FilterWriter
*/
private final ResourceBundle locale;
- private final VariableResolver variables;
+ private final RequestVariableResolver variables;
/**
* The buffer to gather the text to be translated
@@ -88,11 +87,11 @@ class ResourceFilteringWriter extends FilterWriter
private int state = STATE_NULL;
- ResourceFilteringWriter( final Writer out, final ResourceBundle locale,
final VariableResolver variables )
+ ResourceFilteringWriter( final Writer out, final ResourceBundle locale,
final RequestVariableResolver variables )
{
super( out );
this.locale = locale;
- this.variables = ( variables != null ) ? variables : new
DefaultVariableResolver();
+ this.variables = variables;
}
diff --git
a/webconsole/src/main/java/org/apache/felix/webconsole/internal/i18n/CombinedEnumeration.java
b/webconsole/src/main/java/org/apache/felix/webconsole/internal/i18n/CombinedEnumeration.java
index 5d0441b1c9..b9947a6231 100644
---
a/webconsole/src/main/java/org/apache/felix/webconsole/internal/i18n/CombinedEnumeration.java
+++
b/webconsole/src/main/java/org/apache/felix/webconsole/internal/i18n/CombinedEnumeration.java
@@ -32,28 +32,28 @@ import java.util.Set;
* So if both enumerations would produce the same result, say "123", only the
* first would be returned.
*/
-class CombinedEnumeration implements Enumeration
+class CombinedEnumeration implements Enumeration<String>
{
// the first enumeration to iterate
- private final Enumeration first;
+ private final Enumeration<String> first;
// the second enumeration to iterate once the first is exhausted
- private final Enumeration second;
+ private final Enumeration<String> second;
// the set of values already returned to prevent duplicate entries
- private final Set seenKeys;
+ private final Set<String> seenKeys;
// preview to the next return value for nextElement(), null at the end
- private Object nextKey;
+ private String nextKey;
- CombinedEnumeration( final Enumeration first, final Enumeration second )
+ CombinedEnumeration( final Enumeration<String> first, final
Enumeration<String> second )
{
this.first = first;
this.second = second;
- this.seenKeys = new HashSet();
+ this.seenKeys = new HashSet<>();
this.nextKey = seek();
}
@@ -64,14 +64,14 @@ class CombinedEnumeration implements Enumeration
}
- public Object nextElement()
+ public String nextElement()
{
if ( !hasMoreElements() )
{
throw new NoSuchElementException();
}
- Object result = nextKey;
+ String result = nextKey;
nextKey = seek();
return result;
}
@@ -82,11 +82,11 @@ class CombinedEnumeration implements Enumeration
* (unique) element is available, null is returned. The element returned
* is also added to the set of seen elements to prevent duplicate provision
*/
- private Object seek()
+ private String seek()
{
while ( first.hasMoreElements() )
{
- final Object next = first.nextElement();
+ final String next = first.nextElement();
if ( !seenKeys.contains( next ) )
{
seenKeys.add( next );
@@ -95,7 +95,7 @@ class CombinedEnumeration implements Enumeration
}
while ( second.hasMoreElements() )
{
- final Object next = second.nextElement();
+ final String next = second.nextElement();
if ( !seenKeys.contains( next ) )
{
seenKeys.add( next );
diff --git
a/webconsole/src/main/java/org/apache/felix/webconsole/internal/i18n/CombinedResourceBundle.java
b/webconsole/src/main/java/org/apache/felix/webconsole/internal/i18n/CombinedResourceBundle.java
index eafc68eecf..19130c6fc5 100644
---
a/webconsole/src/main/java/org/apache/felix/webconsole/internal/i18n/CombinedResourceBundle.java
+++
b/webconsole/src/main/java/org/apache/felix/webconsole/internal/i18n/CombinedResourceBundle.java
@@ -48,7 +48,7 @@ class CombinedResourceBundle extends ResourceBundle
}
- public Enumeration getKeys()
+ public Enumeration<String> getKeys()
{
return new CombinedEnumeration( resourceBundle.getKeys(),
defaultResourceBundle.getKeys() );
}
diff --git
a/webconsole/src/main/java/org/apache/felix/webconsole/internal/i18n/ConsolePropertyResourceBundle.java
b/webconsole/src/main/java/org/apache/felix/webconsole/internal/i18n/ConsolePropertyResourceBundle.java
index c1d389b3e6..82d028bfd3 100644
---
a/webconsole/src/main/java/org/apache/felix/webconsole/internal/i18n/ConsolePropertyResourceBundle.java
+++
b/webconsole/src/main/java/org/apache/felix/webconsole/internal/i18n/ConsolePropertyResourceBundle.java
@@ -27,14 +27,11 @@ import java.util.Properties;
import java.util.ResourceBundle;
-class ConsolePropertyResourceBundle extends ResourceBundle
-{
+class ConsolePropertyResourceBundle extends ResourceBundle {
private final Properties props;
-
- ConsolePropertyResourceBundle( final ResourceBundle parent, final URL
source )
- {
+ ConsolePropertyResourceBundle( final ResourceBundle parent, final URL
source ) {
setParent( parent );
props = new Properties();
@@ -47,21 +44,18 @@ class ConsolePropertyResourceBundle extends ResourceBundle
}
}
-
- public Enumeration getKeys()
- {
- Enumeration keysEnum = null;
- if (parent == null) {
- keysEnum = props.keys();
- } else {
- keysEnum = new CombinedEnumeration( props.keys(), parent.getKeys()
);
+ @Override
+ public Enumeration<String> getKeys() {
+ @SuppressWarnings({"unchecked", "rawtypes"})
+ Enumeration<String> keysEnum = (Enumeration) props.keys();
+ if (parent != null) {
+ keysEnum = new CombinedEnumeration( keysEnum, parent.getKeys() );
}
return keysEnum;
}
-
- protected Object handleGetObject( String key )
- {
+ @Override
+ protected Object handleGetObject( String key ) {
return props.get( key );
}
}
diff --git
a/webconsole/src/main/java/org/apache/felix/webconsole/internal/i18n/ResourceBundleCache.java
b/webconsole/src/main/java/org/apache/felix/webconsole/internal/i18n/ResourceBundleCache.java
index 9962d209c5..19bb78d1c4 100644
---
a/webconsole/src/main/java/org/apache/felix/webconsole/internal/i18n/ResourceBundleCache.java
+++
b/webconsole/src/main/java/org/apache/felix/webconsole/internal/i18n/ResourceBundleCache.java
@@ -33,8 +33,7 @@ import org.osgi.framework.Constants;
/**
* The <code>ResourceBundleCache</code> caches resource bundles per OSGi
bundle.
*/
-public class ResourceBundleCache
-{
+public class ResourceBundleCache {
/**
* The default locale corresponding to the default language in the
@@ -46,9 +45,9 @@ public class ResourceBundleCache
private final Bundle bundle;
- private final Map resourceBundles;
+ private final Map<Locale, ResourceBundle> resourceBundles;
- private Map resourceBundleEntries;
+ private volatile Map<String, URL> resourceBundleEntries;
/**
@@ -56,10 +55,9 @@ public class ResourceBundleCache
*
* @param bundle the bundle which resources should be loaded.
*/
- public ResourceBundleCache( final Bundle bundle )
- {
+ public ResourceBundleCache( final Bundle bundle ) {
this.bundle = bundle;
- this.resourceBundles = new HashMap();
+ this.resourceBundles = new HashMap<>();
}
@@ -69,10 +67,8 @@ public class ResourceBundleCache
* @param locale the requested locale
* @return the resource bundle for the requested locale
*/
- public ResourceBundle getResourceBundle( final Locale locale )
- {
- if ( locale == null )
- {
+ public ResourceBundle getResourceBundle( final Locale locale ) {
+ if ( locale == null ) {
return getResourceBundleInternal( DEFAULT_LOCALE );
}
@@ -80,26 +76,21 @@ public class ResourceBundleCache
}
- ResourceBundle getResourceBundleInternal( final Locale locale )
- {
- if ( locale == null )
- {
+ ResourceBundle getResourceBundleInternal( final Locale locale ) {
+ if ( locale == null ) {
return null;
}
- synchronized ( resourceBundles )
- {
- ResourceBundle bundle = ( ResourceBundle ) resourceBundles.get(
locale );
- if ( bundle != null )
- {
+ synchronized ( resourceBundles ) {
+ ResourceBundle bundle = resourceBundles.get( locale );
+ if ( bundle != null ) {
return bundle;
}
}
ResourceBundle parent = getResourceBundleInternal( getParentLocale(
locale ) );
ResourceBundle bundle = loadResourceBundle( parent, locale );
- synchronized ( resourceBundles )
- {
+ synchronized ( resourceBundles ) {
resourceBundles.put( locale, bundle );
}
@@ -107,43 +98,36 @@ public class ResourceBundleCache
}
- private ResourceBundle loadResourceBundle( final ResourceBundle parent,
final Locale locale )
- {
- final String path = "_" + locale.toString(); //$NON-NLS-1$
- final URL source = ( URL ) getResourceBundleEntries().get( path );
+ private ResourceBundle loadResourceBundle( final ResourceBundle parent,
final Locale locale ) {
+ final String path = "_" + locale.toString();
+ final URL source = getResourceBundleEntries().get( path );
return new ConsolePropertyResourceBundle( parent, source );
}
- private synchronized Map getResourceBundleEntries()
- {
- if ( this.resourceBundleEntries == null )
- {
+ private synchronized Map<String, URL> getResourceBundleEntries() {
+ if ( this.resourceBundleEntries == null ) {
String file = ( String ) bundle.getHeaders().get(
Constants.BUNDLE_LOCALIZATION );
- if ( file == null )
- {
+ if ( file == null ) {
file = Constants.BUNDLE_LOCALIZATION_DEFAULT_BASENAME;
}
// remove leading slash
- if ( file.startsWith( "/" ) ) //$NON-NLS-1$
- {
+ if ( file.startsWith( "/" ) ) {
file = file.substring( 1 );
}
// split path and base name
int slash = file.lastIndexOf( '/' );
String fileName = file.substring( slash + 1 );
- String path = ( slash <= 0 ) ? "/" : file.substring( 0, slash );
//$NON-NLS-1$
+ String path = ( slash <= 0 ) ? "/" : file.substring( 0, slash );
- HashMap resourceBundleEntries = new HashMap();
+ HashMap<String, URL> resourceBundleEntries = new HashMap<>();
- Enumeration locales = bundle.findEntries( path, fileName +
"*.properties", false ); //$NON-NLS-1$
- if ( locales != null )
- {
- while ( locales.hasMoreElements() )
- {
- URL entry = ( URL ) locales.nextElement();
+ Enumeration<URL> locales = bundle.findEntries( path, fileName +
"*.properties", false );
+ if ( locales != null ) {
+ while ( locales.hasMoreElements() ) {
+ URL entry = locales.nextElement();
// calculate the key
String entryPath = entry.getPath();
@@ -154,7 +138,7 @@ public class ResourceBundleCache
// the default language is "name.properties" thus the entry
// path is empty and must default to "_"+DEFAULT_LOCALE
if (entryPath.length() == 0) {
- entryPath = "_" + DEFAULT_LOCALE; //$NON-NLS-1$
+ entryPath = "_" + DEFAULT_LOCALE;
}
// only add this entry, if the "language" is not provided
@@ -172,23 +156,16 @@ public class ResourceBundleCache
}
- private static final Locale getParentLocale( Locale locale )
- {
- if ( locale.getVariant().length() != 0 )
- {
+ private static final Locale getParentLocale( Locale locale ) {
+ if ( locale.getVariant().length() != 0 ) {
return new Locale( locale.getLanguage(), locale.getCountry() );
- }
- else if ( locale.getCountry().length() != 0 )
- {
- return new Locale( locale.getLanguage(), "" ); //$NON-NLS-1$
- }
- else if ( !locale.getLanguage().equals( DEFAULT_LOCALE.getLanguage() )
)
- {
+ } else if ( locale.getCountry().length() != 0 ) {
+ return new Locale( locale.getLanguage(), "" );
+ } else if ( !locale.getLanguage().equals( DEFAULT_LOCALE.getLanguage()
) ) {
return DEFAULT_LOCALE;
}
// no more parents
return null;
}
-
}
diff --git
a/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/LicenseServlet.java
b/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/LicenseServlet.java
index 6503cdc93d..dc12107f87 100644
---
a/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/LicenseServlet.java
+++
b/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/LicenseServlet.java
@@ -42,11 +42,11 @@ import javax.servlet.http.HttpServletResponse;
import org.apache.felix.utils.json.JSONWriter;
import org.apache.felix.utils.manifest.Clause;
import org.apache.felix.utils.manifest.Parser;
-import org.apache.felix.webconsole.DefaultVariableResolver;
import org.apache.felix.webconsole.SimpleWebConsolePlugin;
import org.apache.felix.webconsole.WebConsoleUtil;
import org.apache.felix.webconsole.internal.OsgiManagerPlugin;
import org.apache.felix.webconsole.internal.Util;
+import org.apache.felix.webconsole.servlet.RequestVariableResolver;
import org.osgi.framework.Bundle;
@@ -109,14 +109,13 @@ public final class LicenseServlet extends
SimpleWebConsolePlugin implements Osgi
/**
* @see
org.apache.felix.webconsole.AbstractWebConsolePlugin#renderContent(javax.servlet.http.HttpServletRequest,
javax.servlet.http.HttpServletResponse)
*/
- @SuppressWarnings("unchecked")
protected void renderContent( HttpServletRequest request,
HttpServletResponse res ) throws IOException
{
Bundle[] bundles = getBundleContext().getBundles();
Util.sort( bundles, request.getLocale() );
// prepare variables
- DefaultVariableResolver vars = ( ( DefaultVariableResolver )
WebConsoleUtil.getVariableResolver( request ) );
+ final RequestVariableResolver vars =
WebConsoleUtil.getRequestVariableResolver(request);
vars.put( "__data__", getBundleData( bundles, request.getLocale() ));
res.getWriter().print(TEMPLATE);
diff --git
a/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/SystemPropertiesPrinter.java
b/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/SystemPropertiesPrinter.java
index dbd71c6963..43183f7aba 100644
---
a/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/SystemPropertiesPrinter.java
+++
b/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/SystemPropertiesPrinter.java
@@ -28,8 +28,7 @@ import java.util.TreeSet;
import org.apache.felix.webconsole.internal.AbstractConfigurationPrinter;
-public class SystemPropertiesPrinter extends AbstractConfigurationPrinter
-{
+public class SystemPropertiesPrinter extends AbstractConfigurationPrinter {
private static final String TITLE = "System Properties";
diff --git
a/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/JakartaServletAdapter.java
b/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/JakartaServletAdapter.java
new file mode 100644
index 0000000000..458d5d0498
--- /dev/null
+++
b/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/JakartaServletAdapter.java
@@ -0,0 +1,303 @@
+/*
+ * 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.internal.servlet;
+
+
+import java.io.IOException;
+import java.util.*;
+
+import javax.servlet.Servlet;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.felix.http.jakartawrappers.HttpServletRequestWrapper;
+import org.apache.felix.http.jakartawrappers.HttpServletResponseWrapper;
+import org.apache.felix.http.jakartawrappers.ServletConfigWrapper;
+import org.apache.felix.http.javaxwrappers.ServletExceptionUtil;
+import org.apache.felix.webconsole.AbstractWebConsolePlugin;
+import org.apache.felix.webconsole.servlet.AbstractServlet;
+import org.apache.felix.webconsole.servlet.ServletConstants;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * The <code>JakartaServletAdapter</code> is an adapter to the
+ * {@link AbstractWebConsolePlugin} for regular servlets registered with the
+ * {@link org.apache.felix.webconsole.WebConsoleConstants#PLUGIN_TITLE}
+ * service attribute using jakarta.servlet.Servlet
+ */
+public class JakartaServletAdapter extends AbstractWebConsolePlugin {
+
+ /** serial UID */
+ private static final long serialVersionUID = 1L;
+
+ // the plugin label (aka address)
+ private final String label;
+
+ // the plugin title
+ private final String title;
+
+ // the actual plugin to forward rendering requests to
+ private final AbstractServlet plugin;
+
+ // the CSS references (null if none)
+ private final String[] cssReferences;
+
+ /**
+ * Creates a new wrapper for a Web Console Plugin
+ *
+ * @param label the label
+ * @param plugin the plugin itself
+ * @param serviceReference reference to the plugin
+ */
+ public JakartaServletAdapter( final AbstractServlet plugin,
ServiceReference<Servlet> serviceReference ) {
+ this.label = (String) serviceReference.getProperty(
ServletConstants.PLUGIN_LABEL );
+ this.title = (String) serviceReference.getProperty(
ServletConstants.PLUGIN_TITLE );
+ this.plugin = plugin;
+ this.cssReferences = toStringArray( serviceReference.getProperty(
ServletConstants.PLUGIN_CSS_REFERENCES ) );
+
+ // activate this abstract plugin (mainly to set the bundle context)
+ activate( serviceReference.getBundle().getBundleContext() );
+ }
+
+
+ //---------- AbstractWebConsolePlugin API
+
+ @Override
+ public String getLabel() {
+ return label;
+ }
+
+ @Override
+ public String getTitle() {
+ return this.title;
+ }
+
+ @Override
+ protected String[] getCssReferences() {
+ return cssReferences;
+ }
+
+ @Override
+ protected void renderContent( final HttpServletRequest req, final
HttpServletResponse res )
+ throws ServletException, IOException {
+ try {
+ plugin.renderContent(
(jakarta.servlet.http.HttpServletRequest)HttpServletRequestWrapper.getWrapper(req),
+
(jakarta.servlet.http.HttpServletResponse)HttpServletResponseWrapper.getWrapper(res)
);
+ } catch (final jakarta.servlet.ServletException s) {
+ throw ServletExceptionUtil.getServletException(s);
+ }
+ }
+
+ /**
+ * Returns the registered plugin class to be able to call the
+ * <code>getResource()</code> method on that object for this plugin to
+ * provide additional resources.
+ *
+ * @see
org.apache.felix.webconsole.AbstractWebConsolePlugin#getResourceProvider()
+ */
+ protected Object getResourceProvider() {
+ return plugin;
+ }
+
+
+ //---------- Servlet API overwrite
+
+ /**
+ * Initializes this servlet as well as the plugin servlet.
+ *
+ * @see javax.servlet.GenericServlet#init(javax.servlet.ServletConfig)
+ */
+ public void init( ServletConfig config ) throws ServletException {
+ // no need to activate the plugin, this has already been done
+ // when the instance was setup
+ try {
+ // base classe initialization
+ super.init( config );
+
+ // plugin initialization
+ try {
+ plugin.init( new ServletConfigWrapper(config) );
+ } catch ( final jakarta.servlet.ServletException s) {
+ throw ServletExceptionUtil.getServletException(s);
+ }
+ } catch ( ServletException se ) {
+ // if init fails, the plugin will not be destroyed and thus
+ // the plugin not deactivated. Do it here
+ deactivate();
+
+ // rethrow the exception
+ throw se;
+ }
+ }
+
+ /**
+ * Detects whether this request is intended to have the headers and
+ * footers of this plugin be rendered or not. The decision is taken based
+ * on whether and what extension the request URI has: If the request URI
+ * has no extension or the the extension is <code>.html</code>, the request
+ * is assumed to be rendered with header and footer. Otherwise the
+ * headers and footers are omitted and the
+ * {@link #renderContent(HttpServletRequest, HttpServletResponse)}
+ * method is called without any decorations and without setting any
+ * response headers.
+ *
+ * @see
org.apache.felix.webconsole.AbstractWebConsolePlugin#isHtmlRequest(javax.servlet.http.HttpServletRequest)
+ */
+ protected boolean isHtmlRequest( final HttpServletRequest request ) {
+ final String requestUri = request.getRequestURI();
+ if ( requestUri.endsWith( ".html" ) ) {
+ return true;
+ }
+ // check if there is an extension
+ final int lastSlash = requestUri.lastIndexOf('/');
+ final int lastDot = requestUri.indexOf('.', lastSlash + 1);
+ return lastDot < 0;
+ }
+
+ private static final class CheckHttpServletResponse extends
HttpServletResponseWrapper {
+
+ private boolean done = false;
+ public CheckHttpServletResponse(HttpServletResponse response) {
+ super(response);
+ }
+
+ public boolean isDone() {
+ return this.done;
+ }
+
+ @Override
+ public void reset() {
+ this.done = false;
+ super.reset();
+ }
+
+ @Override
+ public void sendError(final int sc) throws IOException {
+ this.done = true;
+ super.sendError(sc);
+ }
+
+ @Override
+ public void sendError(final int sc, final String msg) throws
IOException {
+ this.done = true;
+ super.sendError(sc, msg);
+ }
+
+ @Override
+ public void sendRedirect(final String location) throws IOException {
+ this.done = true;
+ super.sendRedirect(location);
+ }
+
+ @Override
+ public void setStatus(final int sc) {
+ this.done = true;
+ super.setStatus(sc);
+ }
+
+ @Override
+ public void setStatus(final int sc, final String sm) {
+ this.done = true;
+ super.setStatus(sc, sm);
+ }
+ }
+
+ /**
+ * Directly refer to the plugin's service method unless the request method
+ * is <code>GET</code> in which case we defer the call into the service
method
+ * until the abstract web console plugin calls the
+ * {@link #renderContent(HttpServletRequest, HttpServletResponse)}
+ * method.
+ *
+ * @see
javax.servlet.http.HttpServlet#service(javax.servlet.ServletRequest,
javax.servlet.ServletResponse)
+ */
+ public void service( HttpServletRequest req, HttpServletResponse resp )
+ throws ServletException, IOException {
+ final CheckHttpServletResponse checkResponse = new
CheckHttpServletResponse(resp);
+ // call plugin first
+ try {
+ plugin.service(
(jakarta.servlet.http.HttpServletRequest)HttpServletRequestWrapper.getWrapper(req),
+
(jakarta.servlet.http.HttpServletResponse)HttpServletResponseWrapper.getWrapper(resp)
);
+ } catch (final jakarta.servlet.ServletException s) {
+ throw ServletExceptionUtil.getServletException(s);
+ }
+ // if a GET request and plugin did not create a response yet, call
super to get full HTML response
+ if ( !checkResponse.isDone() && req.getMethod().equals( "GET" ) ) {
+ // handle the GET request here and call into plugin on
renderContent
+ super.service( req, resp );
+ }
+ }
+
+ /**
+ * Destroys this servlet as well as the plugin servlet.
+ *
+ * @see javax.servlet.GenericServlet#destroy()
+ */
+ public void destroy() {
+ try {
+ plugin.destroy();
+ super.destroy();
+ } finally {
+ deactivate();
+ }
+ }
+
+
+ //---------- internal
+
+ @SuppressWarnings("rawtypes")
+ private String[] toStringArray( final Object value ) {
+ if ( value instanceof String )
+ {
+ return new String[]
+ { ( String ) value };
+ }
+ else if ( value != null )
+ {
+ final Collection cssListColl;
+ if ( value.getClass().isArray() )
+ {
+ cssListColl = Arrays.asList( ( Object[] ) value );
+ }
+ else if ( value instanceof Collection )
+ {
+ cssListColl = ( Collection ) value;
+ }
+ else
+ {
+ cssListColl = null;
+ }
+
+ if ( cssListColl != null && !cssListColl.isEmpty() )
+ {
+ String[] entries = new String[cssListColl.size()];
+ int i = 0;
+ for ( Iterator cli = cssListColl.iterator(); cli.hasNext();
i++ )
+ {
+ entries[i] = String.valueOf( cli.next() );
+ }
+ return entries;
+ }
+ }
+
+ return null;
+ }
+}
diff --git
a/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/JakartaServletTracker.java
b/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/JakartaServletTracker.java
index 277e5548f8..b0e1a140a1 100644
---
a/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/JakartaServletTracker.java
+++
b/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/JakartaServletTracker.java
@@ -25,6 +25,7 @@ import org.apache.felix.http.javaxwrappers.ServletWrapper;
import org.apache.felix.webconsole.WebConsoleConstants;
import org.apache.felix.webconsole.internal.Util;
import org.apache.felix.webconsole.internal.servlet.Plugin.ServletPlugin;
+import org.apache.felix.webconsole.servlet.AbstractServlet;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.Filter;
@@ -84,14 +85,19 @@ public class JakartaServletTracker implements Closeable,
ServiceTrackerCustomize
public static class JakartaServletPlugin extends ServletPlugin {
+ @SuppressWarnings({"unchecked", "rawtypes"})
public JakartaServletPlugin(PluginHolder holder,
ServiceReference<jakarta.servlet.Servlet> serviceReference,
String label) {
super(holder, (ServiceReference)serviceReference, label);
}
+ @SuppressWarnings({"unchecked", "rawtypes"})
protected javax.servlet.Servlet getService() {
final Servlet servlet = (Servlet)
getHolder().getBundleContext().getService(
(ServiceReference)this.getServiceReference() );
if (servlet != null) {
+ if ( servlet instanceof AbstractServlet ) {
+ return new JakartaServletAdapter((AbstractServlet)servlet,
this.getServiceReference());
+ }
return new ServletWrapper(servlet);
}
return null;
diff --git
a/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/PluginHolder.java
b/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/PluginHolder.java
index c5e06396c6..b6d241d85a 100644
---
a/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/PluginHolder.java
+++
b/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/PluginHolder.java
@@ -242,29 +242,21 @@ class PluginHolder implements
ServiceTrackerCustomizer<Servlet, Plugin> {
// support only one level for now
Map categoryMap = null;
String category = plugin.getCategory();
- if ( category == null || category.trim().length() == 0 )
- {
+ if ( category == null || category.trim().length() == 0 ) {
// FELIX-3798 configured default category
category = defaultCategory;
}
- // TODO: FELIX-3769; translate the Category
-
categoryMap = findCategoryMap( map, category );
final String label = plugin.getLabel();
String title = plugin.getTitle();
- if ( title.startsWith( "%" ) )
- {
- try
- {
- final ResourceBundle resourceBundle =
resourceBundleManager.getResourceBundle( plugin.getBundle(),
- locale );
+ if ( title.startsWith( "%" ) ) {
+ try {
+ final ResourceBundle resourceBundle =
resourceBundleManager.getResourceBundle( plugin.getBundle(), locale );
title = resourceBundle.getString( title.substring( 1 ) );
- }
- catch ( Throwable e )
- {
- /* ignore missing resource - use default title */
+ } catch ( Throwable e ) {
+ // ignore missing resource - use default title
}
}
diff --git
a/webconsole/src/main/java/org/apache/felix/webconsole/internal/system/VMStatPlugin.java
b/webconsole/src/main/java/org/apache/felix/webconsole/internal/system/VMStatPlugin.java
index 1b7c2fba0b..226a2195c9 100644
---
a/webconsole/src/main/java/org/apache/felix/webconsole/internal/system/VMStatPlugin.java
+++
b/webconsole/src/main/java/org/apache/felix/webconsole/internal/system/VMStatPlugin.java
@@ -31,12 +31,12 @@ 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.WebConsoleConstants;
import org.apache.felix.webconsole.WebConsoleUtil;
import org.apache.felix.webconsole.internal.OsgiManagerPlugin;
import org.apache.felix.webconsole.internal.servlet.OsgiManager;
+import org.apache.felix.webconsole.servlet.RequestVariableResolver;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleException;
import org.osgi.service.startlevel.StartLevel;
@@ -190,7 +190,7 @@ public class VMStatPlugin extends SimpleWebConsolePlugin
implements OsgiManagerP
jw.endObject();
jw.flush();
- DefaultVariableResolver vars = ( ( DefaultVariableResolver )
WebConsoleUtil.getVariableResolver( request ) );
+ final RequestVariableResolver vars =
WebConsoleUtil.getRequestVariableResolver(request);
vars.put( "data", json.toString() );
body = TPL_VM_RESTART;
@@ -250,7 +250,7 @@ public class VMStatPlugin extends SimpleWebConsolePlugin
implements OsgiManagerP
jw.flush();
- DefaultVariableResolver vars = ( ( DefaultVariableResolver )
WebConsoleUtil.getVariableResolver( request ) );
+ final RequestVariableResolver vars =
WebConsoleUtil.getRequestVariableResolver(request);
vars.put( "startData", json.toString() );
response.getWriter().print( body );
diff --git
a/webconsole/src/main/java/org/apache/felix/webconsole/servlet/AbstractServlet.java
b/webconsole/src/main/java/org/apache/felix/webconsole/servlet/AbstractServlet.java
new file mode 100644
index 0000000000..031ad59cdc
--- /dev/null
+++
b/webconsole/src/main/java/org/apache/felix/webconsole/servlet/AbstractServlet.java
@@ -0,0 +1,201 @@
+/*
+ * 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.servlet;
+
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.StringWriter;
+import java.net.URL;
+import java.net.URLConnection;
+import java.nio.charset.StandardCharsets;
+
+import jakarta.servlet.ServletException;
+import jakarta.servlet.http.HttpServlet;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+
+
+/**
+ * This class can be used as a base class for a web console plugin.
+ * The plugin (servlet) needs to be registered as a servlet service
+ * with at least the label property.
+ *
+ * @see ServletConstants#PLUGIN_LABEL
+ * @see ServletConstants#PLUGIN_TITLE
+ * @see ServletConstants#PLUGIN_CATEGORY
+ */
+public abstract class AbstractServlet extends HttpServlet {
+
+ /**
+ * Called to identify resources.
+ * By default, if the path starts with "/res/" this is treated as a
resource
+ * and the URL to the resource is tried to be loaded via the class loader.
+ * @param path the path
+ * @return the URL of the resource or <code>null</code> if not found.
+ */
+ protected URL getResource( final String path ) {
+ final int index = path.indexOf( '/', 1 );
+ if (index != -1) {
+ if (path.substring(index).startsWith("/res/") ) {
+ return getClass().getResource( path.substring(index) );
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Handle get requests. This method can be used to return resources, like
JSON responses etc.
+ * If the plugin is serving a resource, this method call {@link
HttpServletResponse#setStatus(int)}.
+ * This method is also allowed to send a redirect or an error.
+ * If none of the three applies, the webconsole will call {@link
#renderContent(HttpServletRequest, HttpServletResponse)}
+ */
+ @Override
+ protected void doGet( final HttpServletRequest request, final
HttpServletResponse response )
+ throws ServletException, IOException {
+ this.spoolResource( request, response );
+ }
+
+ /**
+ * This method is used to render the main contents of the plugin
+ * @param request The request
+ * @param response The response
+ * @throws ServletException If an error occurs
+ * @throws IOException If writing the response fails
+ */
+ public void renderContent( final HttpServletRequest request, final
HttpServletResponse response)
+ throws ServletException, IOException {
+ throw new ServletException("Render method not implemented");
+ }
+
+ /**
+ * If the request addresses a resource , this method serves it
+ * and returns <code>true</code>. Otherwise <code>false</code> is returned.
+ * <p>
+ * If <code>true</code> is returned, the request is considered complete and
+ * request processing terminates. Otherwise request processing continues
+ * with normal plugin rendering.
+ *
+ * @param request The request object
+ * @param response The response object
+ * @return <code>true</code> if the request causes a resource to be sent
back.
+ *
+ * @throws IOException If an error occurs accessing or spooling the
resource.
+ */
+ protected final void spoolResource(final HttpServletRequest request, final
HttpServletResponse response)
+ throws IOException {
+ // check for a resource, fail if none
+ final URL url = this.getResource(request.getPathInfo());
+ if ( url == null ) {
+ return;
+ }
+
+ // open the connection and the stream (we use the stream to be able
+ // to at least hint to close the connection because there is no
+ // method to explicitly close the conneciton, unfortunately)
+ final URLConnection connection = url.openConnection();
+ try ( final InputStream ins = connection.getInputStream()) {
+ // FELIX-2017 Equinox may return an URL for a non-existing
+ // resource but then (instead of throwing) return null on
+ // getInputStream. We should account for this situation and
+ // just assume a non-existing resource in this case.
+ if (ins == null) {
+ return;
+ }
+
+ // check whether we may return 304/UNMODIFIED
+ long lastModified = connection.getLastModified();
+ if ( lastModified > 0 ) {
+ long ifModifiedSince = request.getDateHeader(
"If-Modified-Since" );
+ if ( ifModifiedSince >= ( lastModified / 1000 * 1000 ) ) {
+ // Round down to the nearest second for a proper compare
+ // A ifModifiedSince of -1 will always be less
+ response.setStatus( HttpServletResponse.SC_NOT_MODIFIED );
+
+ return;
+ }
+
+ // have to send, so set the last modified header now
+ response.setDateHeader( "Last-Modified", lastModified );
//$NON-NLS-1$
+ }
+
+ // describe the contents
+ response.setContentType( getServletContext().getMimeType(
request.getPathInfo() ) );
+ if (connection.getContentLength() != -1) {
+ response.setContentLength( connection.getContentLength() );
+ }
+ response.setStatus( HttpServletResponse.SC_OK);
+
+ // spool the actual contents
+ final OutputStream out = response.getOutputStream();
+ final byte[] buf = new byte[2048];
+ int rd;
+ while ( ( rd = ins.read( buf ) ) >= 0 ) {
+ out.write( buf, 0, rd );
+ }
+ }
+ }
+
+ /**
+ * Reads the <code>templateFile</code> as a resource through the class
+ * loader of this class converting the binary data into a string using
+ * UTF-8 encoding.
+ *
+ * @param templateFile The absolute path to the template file to read.
+ * @return The contents of the template file as a string
+ *
+ * @throws NullPointerException if <code>templateFile</code> is
+ * <code>null</code>
+ * @throws FileNotFoundException If template file cannot be found
+ * @throws IOException On any other error reading the template file
+ */
+ protected final String readTemplateFile( final String templateFile )
throws IOException {
+ return readTemplateFile( getClass(), templateFile );
+ }
+
+ private final String readTemplateFile( final Class<?> clazz, final String
templateFile) throws IOException {
+ try(final InputStream templateStream = clazz.getResourceAsStream(
templateFile )) {
+ if ( templateStream != null ) {
+ try ( final StringWriter w = new StringWriter()) {
+ final byte[] buf = new byte[2048];
+ int l;
+ while ( ( l = templateStream.read(buf)) > 0 ) {
+ w.write(new String(buf, 0, l, StandardCharsets.UTF_8));
+ }
+ String str = w.toString();
+ switch ( str.charAt(0) ) { // skip BOM
+ case 0xFEFF: // UTF-16/UTF-32, big-endian
+ case 0xFFFE: // UTF-16, little-endian
+ case 0xEFBB: // UTF-8
+ return str.substring(1);
+ }
+ return str;
+ }
+ }
+ }
+
+ throw new FileNotFoundException("Template " + templateFile + " not
found");
+ }
+
+ protected RequestVariableResolver getVariableResolver(final
HttpServletRequest request) {
+ return (RequestVariableResolver)
request.getAttribute(RequestVariableResolver.REQUEST_ATTRIBUTE);
+ }
+}
diff --git
a/webconsole/src/main/java/org/apache/felix/webconsole/servlet/RequestVariableResolver.java
b/webconsole/src/main/java/org/apache/felix/webconsole/servlet/RequestVariableResolver.java
new file mode 100644
index 0000000000..4efdc3aacd
--- /dev/null
+++
b/webconsole/src/main/java/org/apache/felix/webconsole/servlet/RequestVariableResolver.java
@@ -0,0 +1,62 @@
+/*
+ * 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.servlet;
+
+import java.util.HashMap;
+
+/**
+ * The <code>RequestVariableResolver</code> is a <code>HashMap</code> that
+ * is used by the webconsole to process variables in the template.
+ * The resolver is stored as a request attribute with the name
+ * {@link #REQUEST_ATTRIBUTE}.
+ */
+public class RequestVariableResolver extends HashMap<String, Object> {
+
+ /**
+ * The name of the request attribute holding the {@link
RequestVariableResolver}
+ * for the request (value is "felix.webconsole.variable.resolver").
+ *
+ * @since 3.0
+ */
+ public static final String REQUEST_ATTRIBUTE =
"felix.webconsole.variable.resolver";
+
+ /**
+ * Creates a new variable resolver with default capacity.
+ */
+ public RequestVariableResolver() {
+ super();
+ }
+
+ /**
+ * Returns the string representation of the value stored under the variable
+ * name in this map. If no value is stored under the variable name,
+ * <code>null</code> is returned.
+ *
+ * @param variable The name of the variable whose value is to be returned.
+ * @return The variable value or <code>null</code> if there is no entry
+ * with the given name in this map.
+ */
+ public String resolve( final String variable ) {
+ final Object value = this.get(variable);
+ if ( value != null ) {
+ return value.toString();
+ }
+ return null;
+ }
+}
diff --git
a/webconsole/src/main/java/org/apache/felix/webconsole/servlet/ServletConstants.java
b/webconsole/src/main/java/org/apache/felix/webconsole/servlet/ServletConstants.java
new file mode 100644
index 0000000000..7b5f2f1431
--- /dev/null
+++
b/webconsole/src/main/java/org/apache/felix/webconsole/servlet/ServletConstants.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.servlet;
+
+/**
+ * Constants for servlets registered with the web console.
+ */
+public abstract class ServletConstants {
+
+ /**
+ * The URI address label under which the servlet is called by
+ * the web console (value is "felix.webconsole.label").
+ * <p>
+ * This service registration property must be set to a single non-empty
+ * String value. Otherwise the Servlet services will
+ * be ignored by the web console and not be used as a plugin.
+ */
+ public static final String PLUGIN_LABEL = "felix.webconsole.label";
+
+ /**
+ * The title under which the servlet is called by
+ * the web console (value is "felix.webconsole.title").
+ * <p>
+ * This property is required for the service to be used as a plugin.
+ * Otherwise the service is just ignored by the web console.
+ * <p>
+ */
+ public static final String PLUGIN_TITLE = "felix.webconsole.title";
+
+ /**
+ * The category under which the servlet is listed in the top
+ * navigation by the web console (value is "felix.webconsole.category").
+ * <p>
+ * If not specified, the servlet is put into the default category.
+ */
+ public static final String PLUGIN_CATEGORY = "felix.webconsole.category";
+
+ /**
+ * The name of the service registration properties providing references
+ * to addition CSS files that should be loaded when rendering the header
+ * for a registered plugin.
+ * <p>
+ * This property is expected to be a single string value, array of string
+ * values or a Collection (or Vector) of string values.
+ */
+ public static final String PLUGIN_CSS_REFERENCES = "felix.webconsole.css";
+
+ /**
+ * The name of the request attribute providing the absolute path of the
+ * Web Console root (value is "felix.webconsole.appRoot"). This consists of
+ * the servlet context path (from
<code>HttpServletRequest.getContextPath()</code>)
+ * and the Web Console servlet path (from
+ * <code>HttpServletRequest.getServletPath()</code>,
+ * <code>/system/console</code> by default).
+ * <p>
+ * The type of this request attribute is <code>String</code>.
+ */
+ public static final String ATTR_APP_ROOT = "felix.webconsole.appRoot";
+}
diff --git
a/webconsole/src/main/java/org/apache/felix/webconsole/spi/package-info.java
b/webconsole/src/main/java/org/apache/felix/webconsole/servlet/package-info.java
similarity index 89%
copy from
webconsole/src/main/java/org/apache/felix/webconsole/spi/package-info.java
copy to
webconsole/src/main/java/org/apache/felix/webconsole/servlet/package-info.java
index da3a407a37..6792c7703b 100644
--- a/webconsole/src/main/java/org/apache/felix/webconsole/spi/package-info.java
+++
b/webconsole/src/main/java/org/apache/felix/webconsole/servlet/package-info.java
@@ -16,6 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
[email protected]("1.1.0")
-package org.apache.felix.webconsole.spi;
[email protected]("1.0.0")
+package org.apache.felix.webconsole.servlet;
diff --git
a/webconsole/src/main/java/org/apache/felix/webconsole/spi/package-info.java
b/webconsole/src/main/java/org/apache/felix/webconsole/spi/package-info.java
index da3a407a37..966e63eb77 100644
--- a/webconsole/src/main/java/org/apache/felix/webconsole/spi/package-info.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/spi/package-info.java
@@ -16,6 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
[email protected]("1.1.0")
[email protected]("1.2.0")
package org.apache.felix.webconsole.spi;
diff --git
a/webconsole/src/test/java/org/apache/felix/webconsole/AbstractWebConsolePluginTest.java
b/webconsole/src/test/java/org/apache/felix/webconsole/AbstractWebConsolePluginTest.java
index 02270e51e5..d4f811a020 100644
---
a/webconsole/src/test/java/org/apache/felix/webconsole/AbstractWebConsolePluginTest.java
+++
b/webconsole/src/test/java/org/apache/felix/webconsole/AbstractWebConsolePluginTest.java
@@ -122,6 +122,7 @@ public class AbstractWebConsolePluginTest extends TestCase
private static class PrivateTestPlugin extends TestPlugin
{
+ @SuppressWarnings("unused")
private URL getResource( String name )
{
return null;
@@ -130,6 +131,7 @@ public class AbstractWebConsolePluginTest extends TestCase
private static class ProtectedTestPlugin extends TestPlugin
{
+ @SuppressWarnings("unused")
protected URL getResource( String name )
{
return null;
@@ -138,6 +140,7 @@ public class AbstractWebConsolePluginTest extends TestCase
private static class PackageTestPlugin extends TestPlugin
{
+ @SuppressWarnings("unused")
URL getResource( String name )
{
return null;
@@ -146,6 +149,7 @@ public class AbstractWebConsolePluginTest extends TestCase
private static class PublicTestPlugin extends TestPlugin
{
+ @SuppressWarnings("unused")
public URL getResource( String name )
{
return null;
diff --git
a/webconsole/src/test/java/org/apache/felix/webconsole/internal/servlet/OsgiManagerTest.java
b/webconsole/src/test/java/org/apache/felix/webconsole/internal/servlet/OsgiManagerTest.java
index 70b8574d18..99ca52fdad 100644
---
a/webconsole/src/test/java/org/apache/felix/webconsole/internal/servlet/OsgiManagerTest.java
+++
b/webconsole/src/test/java/org/apache/felix/webconsole/internal/servlet/OsgiManagerTest.java
@@ -70,7 +70,7 @@ public class OsgiManagerTest {
OsgiManager.splitCommaSeparatedString(" abc , x.y.z,123"));
}
- @SuppressWarnings({ "unchecked", "rawtypes", "serial" })
+ @SuppressWarnings({ "unchecked", "rawtypes"})
@Test
public void testUpdateDependenciesCustomizerAdd() throws Exception {
BundleContext bc = mockBundleContext();
@@ -98,7 +98,7 @@ public class OsgiManagerTest {
assertEquals(1, updateCalled.size());
}
- @SuppressWarnings({ "unchecked", "rawtypes", "serial" })
+ @SuppressWarnings({ "unchecked", "rawtypes" })
@Test
public void testUpdateDependenciesCustomzerRemove() throws Exception {
BundleContext bc = mockBundleContext();