/*
* 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.portals.applications.webcontent.proxy.impl;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.commons.configuration.reloading.FileChangedReloadingStrategy;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.apache.http.HttpHost;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpHead;
import org.apache.http.client.methods.HttpOptions;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpTrace;
import org.apache.http.client.params.ClientParamBean;
import org.apache.http.conn.params.ConnManagerParamBean;
import org.apache.http.conn.params.ConnPerRouteBean;
import org.apache.http.conn.routing.HttpRoute;
import org.apache.http.conn.routing.RouteInfo;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;
import org.apache.portals.applications.webcontent.proxy.HttpReverseProxyException;
import org.apache.portals.applications.webcontent.proxy.HttpReverseProxyNotFoundException;
import org.apache.portals.applications.webcontent.proxy.HttpReverseProxyPathMapper;
import org.apache.portals.applications.webcontent.proxy.HttpReverseProxyService;
import org.apache.portals.applications.webcontent.proxy.ReverseProxyRequestContextProvider;
import org.apache.portals.applications.webcontent.proxy.URICleaner;
import org.apache.portals.applications.webcontent.rewriter.MappingRewriterController;
import org.apache.portals.applications.webcontent.rewriter.RewriterController;
import org.apache.portals.applications.webcontent.rewriter.rules.Ruleset;
import org.apache.portals.applications.webcontent.util.WebResourceUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Default reverse proxy servlet implementation as an example.
*
* @version $Id: DefaultHttpReverseProxyServlet.java 1232749 2012-01-18 05:22:02Z woonsan $
*/
public class DefaultHttpReverseProxyServlet extends HttpServlet
{
private static final long serialVersionUID = 1L;
private static final Set<String> AVAILABLE_HTTP_METHOD_SET =
new HashSet<String>(Arrays.asList(HttpGet.METHOD_NAME,
HttpHead.METHOD_NAME,
HttpPost.METHOD_NAME,
HttpPut.METHOD_NAME,
HttpDelete.METHOD_NAME,
HttpOptions.METHOD_NAME,
HttpTrace.METHOD_NAME));
private static Logger log = LoggerFactory.getLogger(DefaultHttpReverseProxyServlet.class);
protected HttpReverseProxyService proxyService;
private PropertiesConfiguration configuration;
private long configurationRefreshDelay;
private FileChangedReloadingStrategy configReloadingStrategy;
@Override
public void init(ServletConfig config) throws ServletException
{
super.init(config);
configurationRefreshDelay = NumberUtils.toLong(getServletConfig().getInitParameter("reverseproxy.configuration.refresh.delay"), 0L);
if (configurationRefreshDelay > 0L)
{
configReloadingStrategy = new FileChangedReloadingStrategy()
{
@Override
public void reloadingPerformed()
{
super.reloadingPerformed();
try
{
if (proxyService != null)
{
recreateHttpReverseProxyService();
}
}
catch (Exception e)
{
if (log.isDebugEnabled())
{
log.error("Failed to recreate reverse proxy service.", e);
}
else
{
log.error("Failed to recreate reverse proxy service. {}", e.toString());
}
}
}
};
configReloadingStrategy.setRefreshDelay(Math.max(configurationRefreshDelay, 2000));
}
loadConfiguration();
recreateHttpReverseProxyService();
}
private void recreateHttpReverseProxyService() throws ServletException
{
if (log.isDebugEnabled())
{
log.debug("DefaultHttpReverseProxyServlet is to initialize reverse proxy service component...");
}
List<HttpReverseProxyPathMapper> proxyPathMappers = new ArrayList<HttpReverseProxyPathMapper>();
Map<HttpReverseProxyPathMapper, RewriterController> rewriterControllerMap = new HashMap<HttpReverseProxyPathMapper, RewriterController>();
Map<HttpReverseProxyPathMapper, Ruleset> rewriterRulesetMap = new HashMap<HttpReverseProxyPathMapper, Ruleset>();
Configuration passConf = configuration.subset("proxy.reverse.pass");
String [] pathNames = passConf.getStringArray("");
for (String pathName : pathNames)
{
Configuration pathPassConf = passConf.subset(pathName);
String localBasePath = pathPassConf.getString("local");
String remoteBaseURL = pathPassConf.getString("remote");
if (StringUtils.isBlank(localBasePath) || StringUtils.isBlank(remoteBaseURL))
{
log.error("Wrong configuration for pass mapping of " + pathName + ". local={}, remove={}.", localBasePath, remoteBaseURL);
continue;
}
Set<String> allowedRoles = null;
boolean secured = pathPassConf.containsKey("roles.allow");
if (secured)
{
allowedRoles = new HashSet<String>(Arrays.asList(pathPassConf.getStringArray("roles.allow")));
}
try
{
Map<String, String> defaultRequestHeaders = null;
Configuration defaultRequestHeadersConf = pathPassConf.subset("request.header");
if (!defaultRequestHeadersConf.isEmpty())
{
defaultRequestHeaders = new HashMap<String, String>();
for (Iterator it = defaultRequestHeadersConf.getKeys(); it.hasNext(); )
{
String key = (String) it.next();
defaultRequestHeaders.put(key, defaultRequestHeadersConf.getString(key));
}
}
Map<String, String> defaultRequestCookies = null;
Configuration defaultRequestCookiesConf = pathPassConf.subset("request.cookie");
if (!defaultRequestCookiesConf.isEmpty())
{
defaultRequestCookies = new HashMap<String, String>();
for (Iterator it = defaultRequestCookiesConf.getKeys(); it.hasNext(); )
{
String key = (String) it.next();
defaultRequestCookies.put(key, defaultRequestCookiesConf.getString(key));
}
}
Set<String> rewriteCookiePathIncludes = null;
String [] items = pathPassConf.getStringArray("response.cookie.path.rewrite.include");
if (items.length > 0)
{
rewriteCookiePathIncludes = new HashSet<String>();
for (String item : items)
{
rewriteCookiePathIncludes.add(item);
}
}
Set<String> rewriteCookiePathExcludes = null;
items = pathPassConf.getStringArray("response.cookie.path.rewrite.exclude");
if (items.length > 0)
{
rewriteCookiePathExcludes = new HashSet<String>();
for (String item : items)
{
rewriteCookiePathExcludes.add(item);
}
}
HttpReverseProxyPathMapper proxyPathMapper =
new DefaultHttpReverseProxyPathMapperImpl(pathName, localBasePath, remoteBaseURL,
secured, allowedRoles,
defaultRequestHeaders, defaultRequestCookies,
rewriteCookiePathIncludes, rewriteCookiePathExcludes);
proxyPathMappers.add(proxyPathMapper);
Configuration rewritersConf = pathPassConf.subset("rewriter");
if (!rewritersConf.isEmpty())
{
RewriterController rewriterController = createRewriterController(rewritersConf);
if (rewriterController != null)
{
rewriterControllerMap.put(proxyPathMapper, rewriterController);
String rules = rewritersConf.getString("rules");
Ruleset ruleset = loadRewriterRuleset(rewriterController, rules);
if (ruleset != null)
{
rewriterRulesetMap.put(proxyPathMapper, ruleset);
}
}
}
}
catch (Exception e)
{
if (log.isDebugEnabled())
{
log.error("Failure in initializing path mappings.", e);
}
else
{
log.error("Failure in initializing path mappings. {}", e.toString());
}
}
}
ReverseProxyRequestContextProvider defaultReverseProxyRequestContextProvider = null;
String reverseProxyRequestContextProviderClassName = passConf.getString("reverseProxyRequestContextProviderClassName", null);
if (StringUtils.isBlank(reverseProxyRequestContextProviderClassName))
{
defaultReverseProxyRequestContextProvider = new DefaultReverseProxyRequestContextProvider();
}
else
{
try
{
defaultReverseProxyRequestContextProvider = (ReverseProxyRequestContextProvider) Thread.currentThread().getContextClassLoader().loadClass(reverseProxyRequestContextProviderClassName).newInstance();
}
catch (Exception e)
{
throw new ServletException("Failure in instantiating the default reverse proxy request context provider: " + reverseProxyRequestContextProviderClassName, e);
}
}
int dynamicProxyPathMapperCacheCount = 1000;
try
{
dynamicProxyPathMapperCacheCount = passConf.getInt("dynamicProxyPathMapperCacheCount", dynamicProxyPathMapperCacheCount);
}
catch (Exception ignore)
{
}
int maxMatchingPathPartCount = 2;
try
{
maxMatchingPathPartCount = passConf.getInt("maxMatchingPathPartCount", maxMatchingPathPartCount);
}
catch (Exception ignore)
{
}
DefaultHttpReverseProxyPathMapperProviderImpl proxyPathMapperProvider =
new DefaultHttpReverseProxyPathMapperProviderImpl(proxyPathMappers, dynamicProxyPathMapperCacheCount,
rewriterControllerMap, rewriterRulesetMap);
proxyPathMapperProvider.setMaxMatchingPathPartCount(maxMatchingPathPartCount);
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
schemeRegistry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));
URICleaner defaultURICleaner = null;
String defaultUriCleanerClassName = configuration.getString("proxy.http.client.default.uri.cleaner", DefaultURICleanerImpl.class.getName());
try
{
defaultURICleaner = (URICleaner) Thread.currentThread().getContextClassLoader().loadClass(defaultUriCleanerClassName).newInstance();
Configuration uriCleanerParamsConf = configuration.subset("proxy.http.client.default.uri.cleaner.param");
if (!uriCleanerParamsConf.isEmpty())
{
setBeanPropertiesByConfiguration(defaultURICleaner, uriCleanerParamsConf);
}
}
catch (Exception e)
{
throw new ServletException("Failure in instantiating the default uri cleaner: " + defaultUriCleanerClassName, e);
}
RewritableHttpReverseProxyServiceImpl tempProxyService = new RewritableHttpReverseProxyServiceImpl(proxyPathMapperProvider, defaultReverseProxyRequestContextProvider);
tempProxyService.setSchemeRegistry(schemeRegistry);
ProxyHttpRoutePlanner httpRoutePlanner = new ProxyHttpRoutePlanner(schemeRegistry);
tempProxyService.setHttpRoutePlanner(httpRoutePlanner);
tempProxyService.setDefaultURICleaner(defaultURICleaner);
Configuration defaultProxiesConf = configuration.subset("proxy.http.client.default.proxy");
if (!defaultProxiesConf.isEmpty())
{
String [] proxyNames = defaultProxiesConf.getStringArray("");
if (proxyNames.length > 0)
{
HttpHost [] defaultProxyHosts = new HttpHost[proxyNames.length];
for (int i = 0; i < proxyNames.length; i++)
{
defaultProxyHosts[i] = buildHttpHost(defaultProxiesConf.subset(proxyNames[i]));
}
httpRoutePlanner.setDefaultProxyHosts(defaultProxyHosts);
}
}
Configuration serverConf = configuration.subset("proxy.server");
if (!StringUtils.isBlank(serverConf.getString("hostname")))
{
tempProxyService.setHostHeaderValue(serverConf.getString("hostname"));
}
if (!StringUtils.isBlank(serverConf.getString("baseurl")))
{
tempProxyService.setLocalBaseURL(serverConf.getString("baseurl"));
}
Configuration clientParamsConf = configuration.subset("proxy.http.client.param");
if (!clientParamsConf.isEmpty())
{
HttpParams clientParams = new BasicHttpParams();
setBeanPropertiesByConfiguration(new ClientParamBean(clientParams), clientParamsConf);
tempProxyService.setClientParams(clientParams);
}
Configuration connManagerParamsConf = configuration.subset("proxy.http.connManager.param");
Configuration routesConf = configuration.subset("proxy.http.route");
if (!connManagerParamsConf.isEmpty() || !routesConf.isEmpty())
{
HttpParams connManagerParams = new BasicHttpParams();
ConnManagerParamBean connManagerParamBean = new ConnManagerParamBean(connManagerParams);
setBeanPropertiesByConfiguration(connManagerParamBean, connManagerParamsConf);
Map<HttpHost, HttpRoute> proxyRouteMap = new HashMap<HttpHost, HttpRoute>();
if (!routesConf.isEmpty())
{
ConnPerRouteBean connPerRouteBean = new ConnPerRouteBean();
setBeanPropertiesByConfiguration(connPerRouteBean, routesConf.subset("param"));
Map<HttpRoute, Integer> maxForRoutes = new HashMap<HttpRoute, Integer>();
String [] routeNames = routesConf.getStringArray("");
for (String routeName : routeNames)
{
Configuration routeConf = routesConf.subset(routeName);
try
{
HttpRoute httpRoute = buildHttpRoute(routeConf);
int maxConnections = routeConf.getInt("maxConnections", -1);
if (maxConnections >= 0)
{
maxForRoutes.put(httpRoute, maxConnections);
}
if (httpRoute.getProxyHost() != null)
{
proxyRouteMap.put(httpRoute.getTargetHost(), httpRoute);
}
}
catch (Exception e)
{
throw new ServletException(e);
}
}
connPerRouteBean.setMaxForRoutes(maxForRoutes);
connManagerParamBean.setConnectionsPerRoute(connPerRouteBean);
}
tempProxyService.setConnectionManagerParams(connManagerParams);
if (!proxyRouteMap.isEmpty())
{
httpRoutePlanner.setProxyRouteMap(proxyRouteMap);
}
}
tempProxyService.initialize();
HttpReverseProxyService oldProxyService = proxyService;
proxyService = tempProxyService;
if (log.isInfoEnabled())
{
log.info("DefaultHttpReverseProxyServlet has (re)initialized reverse proxy service component...");
}
if (oldProxyService != null)
{
oldProxyService.destroy();
}
}
@Override
public void destroy()
{
if (proxyService != null)
{
proxyService.destroy();
}
proxyService = null;
}
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
if (!AVAILABLE_HTTP_METHOD_SET.contains(request.getMethod()))
{
super.service(request, response);
}
else
{
try
{
proxyService.invoke(request, response);
}
catch (HttpReverseProxyNotFoundException e)
{
response.sendError(404, e.getLocalizedMessage());
}
catch (HttpReverseProxyException e)
{
throw new ServletException(e);
}
finally
{
try
{
// dummy read for refreshing...
configuration.getString("proxy.reverse.pass");
}
catch (Exception e)
{
}
}
}
}
private RewriterController createRewriterController(final Configuration rewriterConf)
{
String ruleMappingsFilePath = null;
Class basicRewriterClass = null;
Class ruleBasedRewriterClass = null;
Map<String, Class> adaptorMimeTypeClassMap = new HashMap<String, Class>();
Map<String, String []> basicRewriterProps = null;
Map<String, String []> rulesetRewriterProps = null;
Map<String, Map<String, String []>> parserAdaptorMimeTypeMap = null;
try
{
String ruleMappings = rewriterConf.getString("ruleMappings");
if (!StringUtils.isBlank(ruleMappings))
{
File ruleMappingsFile =
WebResourceUtils.getResourceAsFile(ruleMappings,
Thread.currentThread().getContextClassLoader(),
getServletContext());
if (ruleMappingsFile != null && ruleMappingsFile.isFile())
{
ruleMappingsFilePath = ruleMappingsFile.getCanonicalPath();
}
}
Configuration basicRewriterConf = rewriterConf.subset("basic");
String basicRewriter = basicRewriterConf.getString("");
if (!StringUtils.isBlank(basicRewriter))
{
basicRewriterClass = Thread.currentThread().getContextClassLoader().loadClass(basicRewriter);
Configuration propsConf = basicRewriterConf.subset("property");
if (!propsConf.isEmpty())
{
basicRewriterProps = new HashMap<String, String []>();
for (Iterator it = propsConf.getKeys(); it.hasNext(); )
{
String propName = (String) it.next();
basicRewriterProps.put(propName, propsConf.getStringArray(propName));
}
}
}
Configuration ruleBasedRewriterConf = rewriterConf.subset("rulebased");
String ruleBasedRewriter = ruleBasedRewriterConf.getString("");
if (!StringUtils.isBlank(ruleBasedRewriter))
{
ruleBasedRewriterClass = Thread.currentThread().getContextClassLoader().loadClass(ruleBasedRewriter);
Configuration propsConf = ruleBasedRewriterConf.subset("property");
if (!propsConf.isEmpty())
{
rulesetRewriterProps = new HashMap<String, String []>();
for (Iterator it = propsConf.getKeys(); it.hasNext(); )
{
String propName = (String) it.next();
rulesetRewriterProps.put(propName, propsConf.getStringArray(propName));
}
}
}
Configuration parserAdaptorsConf = rewriterConf.subset("parserAdaptor");
String [] parserAdaptorNames = parserAdaptorsConf.getStringArray("");
if (!ArrayUtils.isEmpty(parserAdaptorNames))
{
for (String parserAdaptorName : parserAdaptorNames)
{
Configuration parserAdaptorConf = parserAdaptorsConf.subset(parserAdaptorName);
String mimeType = parserAdaptorConf.getString("mimeType");
String parserAdaptor = parserAdaptorConf.getString("");
if (!StringUtils.isBlank(parserAdaptor))
{
Class parserAdaptorClass = Thread.currentThread().getContextClassLoader().loadClass(parserAdaptor);
Configuration propsConf = parserAdaptorConf.subset("property");
if (!propsConf.isEmpty())
{
Map<String, String []> parserAdaptorProps = new HashMap<String, String []>();
for (Iterator it = propsConf.getKeys(); it.hasNext(); )
{
String propName = (String) it.next();
parserAdaptorProps.put(propName, propsConf.getStringArray(propName));
}
if (parserAdaptorMimeTypeMap == null)
{
parserAdaptorMimeTypeMap = new HashMap<String, Map<String, String []>>();
}
parserAdaptorMimeTypeMap.put(mimeType, parserAdaptorProps);
}
adaptorMimeTypeClassMap.put(mimeType, parserAdaptorClass);
}
}
}
MappingRewriterController rewriterController =
new MappingRewriterController(ruleMappingsFilePath,
basicRewriterClass, ruleBasedRewriterClass,
adaptorMimeTypeClassMap);
rewriterController.setBasicRewriterProps(basicRewriterProps);
rewriterController.setRulesetRewriterProps(basicRewriterProps);
rewriterController.setParserAdaptorMimeTypePropsMap(parserAdaptorMimeTypeMap);
return rewriterController;
}
catch (Exception e)
{
if (log.isDebugEnabled())
{
log.error("Failed to initialize rewriters.", e);
}
else
{
log.error("Failed to initialize rewriters. {}", e.toString());
}
}
return null;
}
private HttpRoute buildHttpRoute(Configuration routeConf) throws Exception
{
HttpRoute httpRoute = null;
HttpHost targetHost = null;
InetAddress localAddress = null;
HttpHost [] proxyHosts = null;
boolean secure = false;
String tunnelled = null;
String layered = null;
RouteInfo.TunnelType tunnelType = RouteInfo.TunnelType.PLAIN;
RouteInfo.LayerType layerType = RouteInfo.LayerType.PLAIN;
targetHost = buildHttpHost(routeConf.subset("target"));
String local = routeConf.getString("local");
if (local != null)
{
try
{
localAddress = InetAddress.getByName(local);
}
catch (Exception e)
{
if (log.isDebugEnabled())
{
log.error("Failed to convert ip address: " + local, e);
}
else
{
log.error("Failed to convert ip address: {}. {}", local, e);
}
}
}
Configuration proxiesConf = routeConf.subset("proxy");
if (!proxiesConf.isEmpty())
{
String [] proxyNames = proxiesConf.getStringArray("");
proxyHosts = new HttpHost[proxyNames.length];
for (int i = 0; i < proxyNames.length; i++)
{
Configuration proxyConf = proxiesConf.subset(proxyNames[i]);
proxyHosts[i] = buildHttpHost(proxyConf);
}
}
try
{
secure = routeConf.getBoolean("secure", false);
}
catch (Exception e)
{
}
try
{
tunnelled = routeConf.getString("tunnelled");
if (tunnelled != null)
{
tunnelType = RouteInfo.TunnelType.valueOf(tunnelled);
}
}
catch (Exception e)
{
}
try
{
layered = routeConf.getString("layered");
if (layered != null)
{
layerType = RouteInfo.LayerType.valueOf(layered);
}
}
catch (Exception e)
{
}
if (proxyHosts != null && proxyHosts.length > 0)
{
httpRoute = new HttpRoute(targetHost, localAddress, proxyHosts, secure, tunnelType, layerType);
}
else
{
httpRoute = new HttpRoute(targetHost, localAddress, secure);
}
return httpRoute;
}
private HttpHost buildHttpHost(Configuration hostConf)
{
HttpHost httpHost = null;
String hostname = null;
int port = 0;
String scheme = null;
hostname = hostConf.getString("hostname");
try
{
port = hostConf.getInt("port", 0);
}
catch (Exception e)
{
}
scheme = hostConf.getString("scheme");
if (StringUtils.isBlank(hostname))
{
throw new IllegalArgumentException("hostname is blank: " + hostConf);
}
if (port <= 0)
{
httpHost = new HttpHost(hostname);
}
else if (scheme == null)
{
httpHost = new HttpHost(hostname, port);
}
else
{
httpHost = new HttpHost(hostname, port, scheme);
}
return httpHost;
}
private List<Class> buildClassList(String [] classNames)
{
List<Class> classList = new ArrayList<Class>();
if (!ArrayUtils.isEmpty(classNames))
{
for (String className : classNames)
{
try
{
classList.add(Thread.currentThread().getContextClassLoader().loadClass(className));
}
catch (Exception e)
{
if (log.isDebugEnabled())
{
log.error("Failed to load class: " + className, e);
}
else
{
log.error("Failed to load class: {}. {}", className, e);
}
}
}
}
return classList;
}
private void loadConfiguration() throws ServletException
{
String configResourcePath = StringUtils.trim(getServletConfig().getInitParameter("reverseproxy.configuration"));
if (configResourcePath == null)
{
configResourcePath = "/WEB-INF/conf/reverseproxy*.properties";
}
File [] configResourceFiles =
WebResourceUtils.getResourcesAsFiles(configResourcePath, Thread.currentThread().getContextClassLoader(), getServletContext());
InputStream configInput = null;
try
{
configuration = new PropertiesConfiguration();
if (configResourceFiles != null && configResourceFiles.length > 0)
{
for (File configResourceFile : configResourceFiles)
{
configuration.load(configResourceFile);
}
if (configReloadingStrategy != null)
{
configuration.setReloadingStrategy(configReloadingStrategy);
}
}
else
{
configInput = WebResourceUtils.getResourceAsStream(configResourcePath, Thread.currentThread().getContextClassLoader(), getServletContext());
configuration.load(configInput);
}
}
catch (Exception e)
{
throw new ServletException("Failed to load configuration: " + configResourcePath);
}
finally
{
if (configInput != null)
{
IOUtils.closeQuietly(configInput);
}
}
}
private void setBeanPropertiesByConfiguration(Object bean, Configuration conf)
{
for (Iterator it = conf.getKeys(); it.hasNext(); )
{
String propName = (String) it.next();
if (!StringUtils.isBlank(propName))
{
String [] propValues = conf.getStringArray(propName);
try
{
BeanUtils.setProperty(bean, propName, propValues);
}
catch (Exception e)
{
if (log.isDebugEnabled())
{
log.error("Failed to set parameter named " + propName, e);
}
else
{
log.error("Failed to set parameter named {}. {}", propName, e);
}
}
}
}
}
private Ruleset loadRewriterRuleset(RewriterController rewriterController, String rulesConfResourcePath) throws IOException
{
Ruleset ruleset = null;
InputStream is = null;
InputStream bis = null;
try
{
if (rewriterController != null && !StringUtils.isBlank(rulesConfResourcePath))
{
is = WebResourceUtils.getResourceAsStream(rulesConfResourcePath, Thread.currentThread().getContextClassLoader(), getServletContext());
bis = new BufferedInputStream(is);
ruleset = rewriterController.loadRuleset(bis);
}
}
finally
{
if (bis != null)
{
IOUtils.closeQuietly(bis);
}
if (is != null)
{
IOUtils.closeQuietly(is);
}
}
return ruleset;
}
}