Package org.apache.portals.applications.webcontent.proxy.impl

Source Code of org.apache.portals.applications.webcontent.proxy.impl.DefaultHttpReverseProxyPathMapperProviderImpl

/*
* 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.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.collections.map.LRUMap;
import org.apache.commons.lang.StringUtils;
import org.apache.portals.applications.webcontent.proxy.HttpReverseProxyPathMapper;
import org.apache.portals.applications.webcontent.proxy.HttpReverseProxyPathMapperProvider;
import org.apache.portals.applications.webcontent.rewriter.RewriterController;
import org.apache.portals.applications.webcontent.rewriter.rules.Ruleset;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Default <CODE>HttpReverseProxyPathMapperProvider</CODE> implementation
*
* @version $Id: DefaultHttpReverseProxyPathMapperProviderImpl.java 833059 2009-11-05 15:38:39Z woonsan $
*/
public class DefaultHttpReverseProxyPathMapperProviderImpl implements HttpReverseProxyPathMapperProvider
{
   
    private static String [] GLOB_EXPR_SEARCHES = { "*", ".", "/", "?", "+" };
   
    private static String [] GLOB_EXPR_REPLACES = { "([^\\/]+)", "\\.", "\\/", "\\?", "\\+" };
   
    private static String [] GROUP_REF_SEARCHES = { "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9" };
   
    private static String [] GROUP_REF_REPLACES = { "([^\\/]+)", "([^\\/]+)", "([^\\/]+)", "([^\\/]+)", "([^\\/]+)",
                                                    "([^\\/]+)", "([^\\/]+)", "([^\\/]+)", "([^\\/]+)" };
   
    private static Logger log = LoggerFactory.getLogger(DefaultHttpReverseProxyPathMapperProviderImpl.class);
   
    /**
     * Maximum matching path part count
     */
    private int maxMatchingPathPartCount = 2;
   
    /**
     * Static proxy path mappers
     */
    private Map<String, HttpReverseProxyPathMapper> staticProxyPathMappersMap;
   
    /**
     * Dynamic proxy path mappers
     */
    private Map dynamicProxyPathMappersMap;
   
    /**
     * Maximum size of dynamic proxy path map
     */
    private int dynamicProxyPathMapperCacheCount;
   
    /**
     * Proxy path Glob mappers
     */
    private List<HttpReverseProxyPathMapper> proxyPathGlobMappers;
   
    /**
     * rewriter controller mappers
     */
    private Map<HttpReverseProxyPathMapper, RewriterController> rewriterControllerMap;
   
    /**
     * rewriter rulesets
     */
    private Map<HttpReverseProxyPathMapper, Ruleset> rewriterRulesetMap;
   
    private Map<HttpReverseProxyPathMapper, Pattern> localBasePathGlobPatternMap;
   
    private Map<HttpReverseProxyPathMapper, Pattern> remoteBaseURLGlobPatternMap;
   
    public DefaultHttpReverseProxyPathMapperProviderImpl(List<HttpReverseProxyPathMapper> proxyPathMappers,
                                                         Map<HttpReverseProxyPathMapper, RewriterController> rewriterControllerMap,
                                                         Map<HttpReverseProxyPathMapper, Ruleset> rewriterRulesetMap)
    {
        this(proxyPathMappers, 1000, rewriterControllerMap, rewriterRulesetMap);
    }
   
    public DefaultHttpReverseProxyPathMapperProviderImpl(List<HttpReverseProxyPathMapper> proxyPathMappers,
                                                         int dynamicProxyPathMapperCacheCount,
                                                         Map<HttpReverseProxyPathMapper, RewriterController> rewriterControllerMap,
                                                         Map<HttpReverseProxyPathMapper, Ruleset> rewriterRulesetMap)
    {
        this.dynamicProxyPathMapperCacheCount = dynamicProxyPathMapperCacheCount;
        this.rewriterControllerMap = rewriterControllerMap;
        this.rewriterRulesetMap = rewriterRulesetMap;
       
        this.staticProxyPathMappersMap = new HashMap<String, HttpReverseProxyPathMapper>();
        this.dynamicProxyPathMappersMap = Collections.synchronizedMap(new LRUMap(this.dynamicProxyPathMapperCacheCount));
        this.proxyPathGlobMappers = new ArrayList<HttpReverseProxyPathMapper>();
       
        this.localBasePathGlobPatternMap = Collections.synchronizedMap(new HashMap<HttpReverseProxyPathMapper, Pattern>());
        this.remoteBaseURLGlobPatternMap = Collections.synchronizedMap(new HashMap<HttpReverseProxyPathMapper, Pattern>());
       
        for (HttpReverseProxyPathMapper proxyPathMapper : proxyPathMappers)
        {
            String localBasePath = proxyPathMapper.getLocalBasePath();
            String remoteBaseURL = proxyPathMapper.getRemoteBaseURL();
           
            if (!StringUtils.contains(proxyPathMapper.getLocalBasePath(), '*'))
            {
                staticProxyPathMappersMap.put(StringUtils.removeEnd(localBasePath, "/"), proxyPathMapper);
                staticProxyPathMappersMap.put(StringUtils.removeEnd(remoteBaseURL, "/"), proxyPathMapper);
            }
            else
            {
                this.proxyPathGlobMappers.add(proxyPathMapper);
               
                try
                {
                    String expr = StringUtils.replaceEach(proxyPathMapper.getLocalBasePath(), GLOB_EXPR_SEARCHES, GLOB_EXPR_REPLACES);
                    localBasePathGlobPatternMap.put(proxyPathMapper, Pattern.compile(expr));
                    expr = StringUtils.replaceEach(proxyPathMapper.getRemoteBaseURL(), GLOB_EXPR_SEARCHES, GLOB_EXPR_REPLACES);
                    expr = StringUtils.replaceEach(expr, GROUP_REF_SEARCHES, GROUP_REF_REPLACES);
                    remoteBaseURLGlobPatternMap.put(proxyPathMapper, Pattern.compile(expr));
                }
                catch (Exception e)
                {
                    if (log.isDebugEnabled())
                    {
                        log.error("Failed to create regular expression pattern for " + proxyPathMapper.getLocalBasePath(), e);
                    }
                    else
                    {
                        log.error("Failed to create regular expression pattern for {}. {}", proxyPathMapper.getLocalBasePath(), e);
                    }
                }
            }
        }
    }
   
    public void setMaxMatchingPathPartCount(int maxMatchingPathPartCount)
    {
        this.maxMatchingPathPartCount = maxMatchingPathPartCount;
    }
   
    public int getMaxMatchingPathPartCount()
    {
        return maxMatchingPathPartCount;
    }
   
    public HttpReverseProxyPathMapper findMapper(String pathInfo)
    {
        String [] pathParts = StringUtils.split(pathInfo, "/", maxMatchingPathPartCount + 1);
        int pathPartCount = (pathParts != null ? pathParts.length : 0);
       
        if (pathPartCount == 0)
        {
            return null;
        }
       
        for (int i = Math.min(pathPartCount, maxMatchingPathPartCount); i > 0; i--)
        {
            String localBasePathKey = "/" + StringUtils.join(pathParts, "/", 0, i);
            HttpReverseProxyPathMapper proxyPathMapper = staticProxyPathMappersMap.get(localBasePathKey);
           
            if (proxyPathMapper == null)
            {
                proxyPathMapper = (HttpReverseProxyPathMapper) dynamicProxyPathMappersMap.get(localBasePathKey);
            }
           
            if (proxyPathMapper != null)
            {
                return proxyPathMapper;
            }
        }
       
        if (!proxyPathGlobMappers.isEmpty())
        {
            for (HttpReverseProxyPathMapper proxyPathMapper : proxyPathGlobMappers)
            {
                Pattern pattern = localBasePathGlobPatternMap.get(proxyPathMapper);
               
                if (pattern == null)
                {
                    continue;
                }
               
                Matcher matcher = pattern.matcher(pathInfo);
               
                if (matcher.lookingAt())
                {
                    int groupCount = matcher.groupCount();
                    String [] replaces = new String[groupCount];
                    String [] searches = new String[groupCount];
                   
                    for (int i = 0; i < groupCount; i++)
                    {
                        replaces[i] = matcher.group(i + 1);
                        searches[i] = "$" + (i + 1);
                    }
                   
                    //HttpReverseProxyPathMapper cloned = (HttpReverseProxyPathMapper) proxyPathMapper.clone();
                    String localBasePath = matcher.group(0);
                    String remoteBaseURL = StringUtils.replaceEach(proxyPathMapper.getRemoteBaseURL(), searches, replaces);
                    HttpReverseProxyPathMapper derivedMapper =
                        new DefaultHttpReverseProxyPathMapperImpl(proxyPathMapper.getName() + ":" + localBasePath,
                                                                  localBasePath,
                                                                  remoteBaseURL,
                                                                  proxyPathMapper.getDefaultRequestHeaders(),
                                                                  proxyPathMapper.getDefaultRequestCookies(),
                                                                  proxyPathMapper.getRewriteCookiePathIncludes(),
                                                                  proxyPathMapper.getRewriteCookiePathExcludes());
                   
                    RewriterController rewriterController = rewriterControllerMap.get(proxyPathMapper);
                    Ruleset rewriterRules = rewriterRulesetMap.get(proxyPathMapper);
                   
                    if (rewriterController != null)
                    {
                        rewriterControllerMap.put(derivedMapper, rewriterController);
                    }
                   
                    if (rewriterRules != null)
                    {
                        rewriterRulesetMap.put(derivedMapper, rewriterRules);
                    }
                   
                    synchronized (dynamicProxyPathMappersMap)
                    {
                        dynamicProxyPathMappersMap.put(StringUtils.removeEnd(localBasePath, "/"), derivedMapper);
                        dynamicProxyPathMappersMap.put(StringUtils.removeEnd(remoteBaseURL, "/"), derivedMapper);
                    }
                   
                    return derivedMapper;
                }
            }
        }
       
        return null;
    }
   
    public HttpReverseProxyPathMapper findMapperByRemoteURL(String remoteURL)
    {
        String [] pathParts = StringUtils.split(remoteURL, "/", maxMatchingPathPartCount + 2);
        int pathPartCount = (pathParts != null ? pathParts.length : 0);
       
        if (pathPartCount < 2)
        {
            return null;
        }

        String scheme = pathParts[0];

        for (int i = Math.min(pathPartCount, maxMatchingPathPartCount + 1); i > 1; i--)
        {
            String remoteBaseURLKey = scheme + "//" + StringUtils.join(pathParts, "/", 1, i);
            HttpReverseProxyPathMapper proxyPathMapper = (HttpReverseProxyPathMapper) staticProxyPathMappersMap.get(remoteBaseURLKey);
           
            if (proxyPathMapper == null)
            {
                proxyPathMapper = (HttpReverseProxyPathMapper) dynamicProxyPathMappersMap.get(remoteBaseURLKey);
            }
           
            if (proxyPathMapper != null)
            {
                return proxyPathMapper;
            }
        }
       
        if (!proxyPathGlobMappers.isEmpty())
        {
            for (HttpReverseProxyPathMapper proxyPathMapper : proxyPathGlobMappers)
            {
                Pattern pattern = remoteBaseURLGlobPatternMap.get(proxyPathMapper);
               
                if (pattern == null)
                {
                    continue;
                }
               
                Matcher matcher = pattern.matcher(remoteURL);
               
                if (matcher.lookingAt())
                {
                    int groupCount = matcher.groupCount();
                    String [] replaces = new String[groupCount];
                    String [] searches = new String[groupCount];
                   
                    for (int i = 0; i < groupCount; i++)
                    {
                        replaces[i] = matcher.group(i + 1);
                        searches[i] = "$" + (i + 1);
                    }
                   
                    String remoteBaseURL = matcher.group(0);
                    String localBasePath = proxyPathMapper.getLocalBasePath();
                   
                    for (int i = 1; StringUtils.contains(localBasePath, '*'); i++)
                    {
                        localBasePath = StringUtils.replaceOnce(localBasePath, "*", "$" + i);
                    }
                   
                    localBasePath = StringUtils.replaceEach(localBasePath, searches, replaces);
                    HttpReverseProxyPathMapper derivedMapper =
                        new DefaultHttpReverseProxyPathMapperImpl(proxyPathMapper.getName() + ":" + localBasePath,
                                                                  localBasePath,
                                                                  remoteBaseURL,
                                                                  proxyPathMapper.getDefaultRequestHeaders(),
                                                                  proxyPathMapper.getDefaultRequestCookies(),
                                                                  proxyPathMapper.getRewriteCookiePathIncludes(),
                                                                  proxyPathMapper.getRewriteCookiePathExcludes());
                   
                    RewriterController rewriterController = rewriterControllerMap.get(proxyPathMapper);
                    Ruleset rewriterRules = rewriterRulesetMap.get(proxyPathMapper);
                   
                    if (rewriterController != null)
                    {
                        rewriterControllerMap.put(derivedMapper, rewriterController);
                    }
                   
                    if (rewriterRules != null)
                    {
                        rewriterRulesetMap.put(derivedMapper, rewriterRules);
                    }
                   
                    synchronized (dynamicProxyPathMappersMap)
                    {
                        dynamicProxyPathMappersMap.put(StringUtils.removeEnd(localBasePath, "/"), derivedMapper);
                        dynamicProxyPathMappersMap.put(StringUtils.removeEnd(remoteBaseURL, "/"), derivedMapper);
                    }
                   
                    return derivedMapper;
                }
            }
        }
       
        return null;
    }

    public RewriterController getRewriterController(HttpReverseProxyPathMapper proxyPathMapper)
    {
        return rewriterControllerMap.get(proxyPathMapper);
    }
   
    public Ruleset getRewriterRuleset(HttpReverseProxyPathMapper proxyPathMapper)
    {
        return rewriterRulesetMap.get(proxyPathMapper);
    }
   
}
TOP

Related Classes of org.apache.portals.applications.webcontent.proxy.impl.DefaultHttpReverseProxyPathMapperProviderImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.