FELIX-1501 Refactor VariableResolver infrastructure: The resolver relates to a request not to a bundle and thus must be provided by request. Also a default resolver implementation based on HashMap is provided.
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@903634 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/DefaultVariableResolver.java b/webconsole/src/main/java/org/apache/felix/webconsole/DefaultVariableResolver.java
new file mode 100644
index 0000000..3985535
--- /dev/null
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/DefaultVariableResolver.java
@@ -0,0 +1,83 @@
+/*
+ * 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;
+
+
+import java.util.HashMap;
+import java.util.Map;
+
+
+/**
+ * The <code>DefaultVariableResolver</code> is a <code>HashMap</code> based
+ * default implementation of the {@link VariableResolver} interface. It may
+ * be used by plugins to implement the interface for the request and is also
+ * used by the
+ * {@link WebConsoleUtil#getVariableResolver(javax.servlet.ServletRequest)}
+ * as the variable resolver if none has yet been assigned to the request.
+ */
+public class DefaultVariableResolver extends HashMap implements VariableResolver
+{
+
+ private static final long serialVersionUID = 4148807223433047780L;
+
+
+ public DefaultVariableResolver()
+ {
+ super();
+ }
+
+
+ public DefaultVariableResolver( final int initialCapacity, final float loadFactor )
+ {
+ super( initialCapacity, loadFactor );
+ }
+
+
+ public DefaultVariableResolver( final int initialCapacity )
+ {
+ super( initialCapacity );
+ }
+
+
+ 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;
+ }
+
+}
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 cc50236..833a97b 100644
--- a/webconsole/src/main/java/org/apache/felix/webconsole/VariableResolver.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/VariableResolver.java
@@ -20,32 +20,31 @@
/**
- * The <code>VariableResolver</code> interface is a very simple interface which
- * may be implemented by Web Console plugins to provide replacement values for
+ * The <code>VariableResolver</code> interface defines the API for an object
+ * which may be provided by plugins to provide replacement values for
* variables in the generated content.
* <p>
- * The main use of such a variable resolve is when a plugin is using a static
+ * Plugins should call the
+ * {@link WebConsoleUtil#setVariableResolver(javax.servlet.ServletRequest, VariableResolver)}
+ * method to provide their implementation for variable resolution.
+ * <p>
+ * The main use of such a variable resolver is when a plugin is using a static
* template which provides slots to place dynamically generated content
* parts.
+ * <p>
+ * <b>Note</b>: The variable resolver must be set in the request <b>before</b>
+ * the response writer is retrieved calling the
+ * <code>ServletRequest.getWriter()</code> method. Otherwise the variable
+ * resolver will not be used for resolving variables.
+ *
+ * @see WebConsoleUtil#getVariableResolver(javax.servlet.ServletRequest)
+ * @see WebConsoleUtil#setVariableResolver(javax.servlet.ServletRequest, VariableResolver)
*/
public interface VariableResolver
{
/**
- * Default implementation of the {@link VariableResolver} interface whose
- * {@link #get(String)} method always returns <code>null</code>.
- */
- VariableResolver DEFAULT = new VariableResolver()
- {
- public String get( String variable )
- {
- return null;
- }
- };
-
-
- /**
- * Return a replacement value for the named variable or <code>null</code>
+ * Returns a replacement value for the named variable or <code>null</code>
* if no replacement is available.
*
* @param variable The name of the variable for which to return a
@@ -53,6 +52,6 @@
* @return The replacement value or <code>null</code> if no replacement is
* available.
*/
- String get( String variable );
+ String resolve( String variable );
}
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 20f05fe..d634727 100644
--- a/webconsole/src/main/java/org/apache/felix/webconsole/WebConsoleConstants.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/WebConsoleConstants.java
@@ -110,4 +110,14 @@
*/
public static final String ATTR_LABEL_MAP = "felix.webconsole.labelMap";
+ /**
+ * The name of the request attribute holding the {@link VariableResolver}
+ * for the request (value is "felix.webconsole.variable.resolver").
+ *
+ * @see VariableResolver
+ * @see WebConsoleUtil#getVariableResolver(javax.servlet.ServletRequest)
+ * @see WebConsoleUtil#setVariableResolver(javax.servlet.ServletRequest, VariableResolver)
+ * @since 3.0
+ */
+ static final String ATTR_CONSOLE_VARIABLE_RESOLVER = "felix.webconsole.variable.resolver";
}
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/WebConsoleUtil.java b/webconsole/src/main/java/org/apache/felix/webconsole/WebConsoleUtil.java
new file mode 100644
index 0000000..5eaf7e3
--- /dev/null
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/WebConsoleUtil.java
@@ -0,0 +1,78 @@
+/*
+ * 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;
+
+
+import javax.servlet.ServletRequest;
+
+
+/**
+ * The <code>WebConsoleUtil</code> provides various utility methods for use
+ * by Web Console plugins.
+ */
+public final class WebConsoleUtil
+{
+
+ /**
+ * Returns the {@link VariableResolver} for the given request.
+ * <p>
+ * If not resolver
+ * has yet be created for the requets, an instance of the
+ * {@link DefaultVariableResolver} is created, placed into the request and
+ * returned.
+ * <p>
+ * <b>Note</b>: An object not implementing the {@link VariableResolver}
+ * interface already stored as the
+ * {@link WebConsoleConstants#ATTR_CONSOLE_VARIABLE_RESOLVER} attribute
+ * will silently be replaced by the {@link DefaultVariableResolver}
+ * instance.
+ *
+ * @param request The request whose attribute is returned (or set)
+ *
+ * @return The {@link VariableResolver} for the given request.
+ */
+ public static VariableResolver getVariableResolver( final ServletRequest request )
+ {
+ final Object resolverObj = request.getAttribute( WebConsoleConstants.ATTR_CONSOLE_VARIABLE_RESOLVER );
+ if ( resolverObj instanceof VariableResolver )
+ {
+ return ( VariableResolver ) resolverObj;
+ }
+
+ final VariableResolver resolver = new DefaultVariableResolver();
+ setVariableResolver( request, resolver );
+ return resolver;
+ }
+
+
+ /**
+ * Sets the {@link VariableResolver} as the
+ * {@link WebConsoleConstants#ATTR_CONSOLE_VARIABLE_RESOLVER}
+ * attribute in the given request. An attribute of that name already
+ * existing is silently replaced.
+ *
+ * @param request The request whose attribute is set
+ * @param resolver The {@link VariableResolver} to place into the request
+ */
+ public static void setVariableResolver( final ServletRequest request, final VariableResolver resolver )
+ {
+ request.setAttribute( WebConsoleConstants.ATTR_CONSOLE_VARIABLE_RESOLVER, resolver );
+ }
+
+}
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/internal/WebConsolePluginAdapter.java b/webconsole/src/main/java/org/apache/felix/webconsole/internal/WebConsolePluginAdapter.java
index 4d0b10c..e3c295d 100644
--- a/webconsole/src/main/java/org/apache/felix/webconsole/internal/WebConsolePluginAdapter.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/internal/WebConsolePluginAdapter.java
@@ -20,7 +20,6 @@
import java.io.IOException;
-import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
@@ -41,7 +40,7 @@
* {@link org.apache.felix.webconsole.WebConsoleConstants#PLUGIN_TITLE}
* service attribute.
*/
-public class WebConsolePluginAdapter extends AbstractWebConsolePlugin implements VariableResolver
+public class WebConsolePluginAdapter extends AbstractWebConsolePlugin
{
/** serial UID */
@@ -214,13 +213,6 @@
}
- //---------- VariableResolver
-
- public String get( String variable )
- {
- return getVariableResolver().get(variable);
- }
-
//---------- internal
private String[] toStringArray( final Object value )
@@ -260,69 +252,4 @@
return null;
}
-
-
- private VariableResolver getVariableResolver()
- {
- if ( varResolver == null )
- {
- if ( plugin instanceof VariableResolver )
- {
- varResolver = ( VariableResolver ) plugin;
- }
- else
- {
- varResolver = VariableResolverProxy.create( plugin );
- }
- }
-
- return varResolver;
- }
-
- private static class VariableResolverProxy implements VariableResolver
- {
- static VariableResolver create( Object object )
- {
- try
- {
- final Class stringClass = String.class;
- final Method getMethod = object.getClass().getMethod( "get", new Class[]
- { stringClass } );
- if ( getMethod.getReturnType() == stringClass )
- {
- return new VariableResolverProxy( object, getMethod );
- }
- }
- catch ( Throwable t )
- {
- }
-
- return VariableResolver.DEFAULT;
- }
-
- private final Object object;
-
- private final Method getMethod;
-
-
- private VariableResolverProxy( final Object object, final Method getMethod )
- {
- this.object = object;
- this.getMethod = getMethod;
- }
-
-
- public String get( String variable )
- {
- try
- {
- return ( String ) getMethod.invoke( object, new Object[]
- { variable } );
- }
- catch ( Throwable t )
- {
- return 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 3b2885e..5320f0c 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
@@ -23,10 +23,12 @@
import java.io.PrintWriter;
import java.util.ResourceBundle;
+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;
/**
@@ -44,7 +46,9 @@
// the resource bundle providing translations for the output
private final ResourceBundle locale;
- private final VariableResolver variables;
+ // the servlet request providing the variable resolver at the time
+ // the getWriter() method is called
+ private final ServletRequest request;
// the writer sending output in this response
private PrintWriter writer;
@@ -54,11 +58,12 @@
* Creates a wrapper instance using the given resource bundle for
* translations.
*/
- public FilteringResponseWrapper( HttpServletResponse response, ResourceBundle locale, VariableResolver variables )
+ public FilteringResponseWrapper( final HttpServletResponse response, final ResourceBundle locale,
+ final ServletRequest request )
{
super( response );
this.locale = locale;
- this.variables = variables;
+ this.request = request;
}
@@ -75,7 +80,8 @@
final PrintWriter base = super.getWriter();
if ( doWrap() )
{
- final ResourceFilteringWriter filter = new ResourceFilteringWriter( base, locale, variables );
+ final VariableResolver resolver = WebConsoleUtil.getVariableResolver( request );
+ final ResourceFilteringWriter filter = new ResourceFilteringWriter( base, locale, resolver );
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 71ab158..00c72f5 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,6 +25,7 @@
import java.util.MissingResourceException;
import java.util.ResourceBundle;
+import org.apache.felix.webconsole.DefaultVariableResolver;
import org.apache.felix.webconsole.VariableResolver;
@@ -87,11 +88,11 @@
private int state = STATE_NULL;
- ResourceFilteringWriter( Writer out, ResourceBundle locale, final VariableResolver variables )
+ ResourceFilteringWriter( final Writer out, final ResourceBundle locale, final VariableResolver variables )
{
super( out );
this.locale = locale;
- this.variables = ( variables != null ) ? variables : VariableResolver.DEFAULT;
+ this.variables = ( variables != null ) ? variables : new DefaultVariableResolver();
}
@@ -215,7 +216,7 @@
final String key = lineBuffer.toString();
lineBuffer.delete( 0, lineBuffer.length() );
- String value = variables.get( key );
+ String value = variables.resolve( key );
if ( value == null )
{
try
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManager.java b/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManager.java
index 30a6006..e9ffa20 100644
--- a/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManager.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManager.java
@@ -41,7 +41,6 @@
import org.apache.felix.webconsole.AbstractWebConsolePlugin;
import org.apache.felix.webconsole.Action;
import org.apache.felix.webconsole.BrandingPlugin;
-import org.apache.felix.webconsole.VariableResolver;
import org.apache.felix.webconsole.WebConsoleConstants;
import org.apache.felix.webconsole.internal.Logger;
import org.apache.felix.webconsole.internal.OsgiManagerPlugin;
@@ -498,8 +497,7 @@
{
final Locale locale = request.getLocale();
final ResourceBundle resourceBundle = resourceBundleManager.getResourceBundle( plugin.getBundle(), locale );
- final VariableResolver variables = ( plugin instanceof VariableResolver ) ? ( VariableResolver ) plugin : null;
- return new FilteringResponseWrapper( response, resourceBundle, variables );
+ return new FilteringResponseWrapper( response, resourceBundle, request );
}
private static class HttpServiceTracker extends ServiceTracker