/* * Copyright 2000-2013 Enonic AS * http://www.enonic.com/license */ package com.enonic.cms.core.vhost; import javax.servlet.http.HttpServletRequest; import org.springframework.core.style.ToStringCreator; import org.springframework.web.util.UrlPathHelper; /** * This class implements the holder of virtual host information. */ public final class VirtualHost implements Comparable<VirtualHost> { /** * Static reusable url path helper. */ private final static UrlPathHelper URL_PATH_HELPER = new UrlPathHelper(); static { URL_PATH_HELPER.setUrlDecode( false ); } /** * Separator. */ private final static char SERVER_SEPARATOR = '/'; /** * Server name. */ private String serverName; /** * Source path. */ private String sourceContext; /** * Target path. */ private String targetPath; /** * Construct the virtual host. */ public VirtualHost( String pattern, String targetPath ) throws InvalidVirtualHostPatternException { this.serverName = getServerNameFromPattern( pattern ); if ( this.serverName == null || this.serverName.trim().length() == 0 ) { throw new InvalidVirtualHostPatternException( pattern, "Missing server name" ); } this.sourceContext = resolveSourceContextFromPattern( pattern ); this.targetPath = normalizePath( targetPath ); } /** * Return the pattern. */ public String getPattern() { if ( this.sourceContext.equals( "" ) ) { return this.serverName + SERVER_SEPARATOR + this.sourceContext; } else { return this.serverName; } } /** * Return the server name. */ public String getServerName() { return this.serverName; } /** * Return the source context. */ public String getSourceContext() { return this.sourceContext; } /** * Return the source path. */ public String getSourcePath() { return this.sourceContext.equals( "" ) ? "/" : "/" + this.sourceContext; } /** * Return the source path. */ public String getFullSourcePath( HttpServletRequest req ) { String contextPath = req.getContextPath(); if ( !this.sourceContext.equals( "" ) ) { return contextPath + "/" + this.sourceContext; } else { return contextPath; } } /** * Return the target path. */ public String getTargetPath() { return this.targetPath; } /** * Return the target path. */ public String getFullTargetPath( HttpServletRequest req ) { String path = getRealRequestPathInfo( req ); String sourcePath = getSourcePath(); if ( !sourcePath.equals( "/" ) && path.startsWith( sourcePath ) ) { path = path.substring( sourcePath.length() ); } return this.targetPath + path; } /** * Return true if it matches. */ public boolean matches( HttpServletRequest req ) { return matchesServerName( req ) && matchesSourcePath( req ); } /** * Return true if it matches the server name. */ private boolean matchesServerName( HttpServletRequest req ) { String serverName = req.getServerName(); return ( serverName != null ) && this.serverName.equalsIgnoreCase( serverName ); } /** * Return true if it matches the source path. */ private boolean matchesSourcePath( HttpServletRequest req ) { String path = getRealRequestPath( req ); String sourcePath = getFullSourcePath( req ); return sourcePath.equals( "/" ) || path.equals( sourcePath ) || path.startsWith( sourcePath + "/" ); } /** * Return the real path. */ private String getRealRequestPath( HttpServletRequest req ) { return req.getContextPath() + getRealRequestPathInfo( req ); } /** * Return the real path. */ private String getRealRequestPathInfo( HttpServletRequest req ) { String pathInfo = URL_PATH_HELPER.getPathWithinApplication( req ); return pathInfo != null ? pathInfo : ""; } /** * Compare to other virtual host. */ public int compareTo( VirtualHost other ) { int compared = compareServerName( other.serverName ); if ( compared == 0 ) { return compareSourceContext( other.sourceContext ); } else { return compared; } } /** * Compare to other virtual host. */ private int compareServerName( String hostName ) { return this.serverName.compareTo( hostName ); } /** * Compare to other virtual host. */ private int compareSourceContext( String sourceContext ) { int compared = sourceContext.length() - this.sourceContext.length(); if ( compared == 0 ) { return this.sourceContext.compareTo( sourceContext ); } else { return compared; } } /** * Return true if equals. */ public boolean equals( Object other ) { return ( other instanceof VirtualHost ) && ( compareTo( (VirtualHost) other ) == 0 ); } /** * Normalize the server name. */ private static String getServerNameFromPattern( String pattern ) { pattern = pattern.trim(); String serverName = pattern; int pos = pattern.indexOf( SERVER_SEPARATOR ); if ( pos > -1 ) { serverName = pattern.substring( 0, pos ); } return removeTrailingDots( serverName ); } private static String removeTrailingDots( String str ) { while ( str.endsWith( "." ) ) { str = str.substring( 0, str.length() - 1 ); } return str; } private static String resolveSourceContextFromPattern( String pattern ) { int pos = pattern.indexOf( SERVER_SEPARATOR ); if ( pos > -1 ) { return pattern.substring( pos + 1 ).trim(); } else { return ""; } } private static String normalizePath( String path ) { if ( path.equals( "" ) ) { return "/"; } else if ( path.equals( "/" ) ) { return path; } else { if ( path.endsWith( "/" ) ) { path = path.substring( 0, path.length() - 1 ); } if ( !path.startsWith( "/" ) ) { path = "/" + path; } return path; } } public String toString() { ToStringCreator creator = new ToStringCreator( this ); creator.append( "serverName", this.serverName ); creator.append( "sourceContext", this.sourceContext ); creator.append( "targetPath", this.targetPath ); return creator.toString(); } }