001 /*
002 Copyright (c) 1996-2012, Damon Hart-Davis
003 All rights reserved.
004
005 Redistribution and use in source and binary forms, with or without
006 modification, are permitted provided that the following conditions are
007 met:
008
009 * Redistributions of source code must retain the above copyright
010 notice, this list of conditions and the following disclaimer.
011
012 * Redistributions in binary form must reproduce the above copyright
013 notice, this list of conditions and the following disclaimer in the
014 documentation and/or other materials provided with the
015 distribution.
016
017 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
018 IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
019 TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
020 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
021 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
022 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
023 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
024 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
025 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
026 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
027 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
028 */
029 package org.hd.d.pg2k.webSvr.util;
030
031 import java.io.IOException;
032
033 import javax.servlet.Filter;
034 import javax.servlet.FilterChain;
035 import javax.servlet.FilterConfig;
036 import javax.servlet.ServletException;
037 import javax.servlet.ServletRequest;
038 import javax.servlet.ServletResponse;
039
040 /**Filter to dynamically load and wrap a pluggable filter.
041 * This enables filters to be loaded entirely at runtime.
042 * <p>
043 * The param pluginClassName is used to give the class name of a
044 * Filter class to load and pass filter calls on to.
045 * If this class cannot be found or loaded, or is not specified,
046 * this PluginFilter performs no transformations at all.
047 */
048 public final class PluginFilter implements Filter
049 {
050 /**The filter configuration object we are associated with.
051 * If this value is null, this filter instance is not currently configured.
052 */
053 private FilterConfig config;
054
055 /**Config parameter; name of flag to record overload, or null if none chosen. */
056 private String pluginClassName;
057
058 /**Our plug-in class; or null if none loaded. */
059 private Filter plugin;
060
061
062 /**Place this filter into service.
063 * @param filterConfig the filter configuration object
064 */
065 public void init(final FilterConfig filterConfig)
066 {
067 config = filterConfig;
068
069 pluginClassName = null;
070 if(plugin != null) { plugin.destroy(); plugin = null; }
071
072 if(filterConfig != null)
073 {
074 pluginClassName = filterConfig.getInitParameter("pluginClassName");
075 if(pluginClassName != null)
076 {
077 try {
078 plugin = (Filter) (Class.forName(pluginClassName).newInstance());
079 // Successful! Initialise the plugin.
080 plugin.init(filterConfig);
081 }
082 catch(final ClassNotFoundException e)
083 {
084 plugin = null;
085 filterConfig.getServletContext().log("could not find plugin for class " + pluginClassName);
086 }
087 catch(final Exception e)
088 {
089 plugin = null;
090 filterConfig.getServletContext().log("could not init plugin for class " + pluginClassName, e);
091 }
092 }
093 }
094 }
095
096 /**Take this filter out of service. */
097 public void destroy()
098 {
099 if(plugin != null)
100 {
101 plugin.destroy();
102 plugin = null;
103 }
104
105 // Help GC.
106 config = null;
107 }
108
109 /**Called to handle each request. */
110 public void doFilter(final ServletRequest request,
111 final ServletResponse response,
112 final FilterChain chain)
113 throws IOException, ServletException
114 {
115 if(plugin == null)
116 {
117 // Pass-though because no plugin.
118 chain.doFilter(request, response);
119 return;
120 }
121
122 // Hand the request to the plugin to process!
123 plugin.doFilter(request, response, chain);
124 }
125 }
126