/* * Copyright 2000-2001,2004 The Apache Software Foundation. * * Licensed 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.jetspeed.cache.disk; //standard java stuff import java.io.File; import java.net.MalformedURLException; import java.net.URL; import java.util.Enumeration; import java.util.Vector; //turbine import org.apache.turbine.services.servlet.TurbineServlet; // Jetspeed classes import org.apache.jetspeed.services.logging.JetspeedLogFactoryService; import org.apache.jetspeed.services.logging.JetspeedLogger; import org.apache.jetspeed.services.resources.JetspeedResources; import org.apache.jetspeed.util.URIEncoder; /** <p> Misc utils for managing the disk cache. </p> <p> This tries to separate URLs into three categories: <ul> <li> Virtual: URLs which are contructored such as: /test/test.xml </li> <li> Local: URLs which are contructored such as: http://localhost/test/test.xml </li> <li> Remote: URLs which are contructored such as: http://REMOTE.SERVER/test/test.xml </li> </ul> </p> @see DiskCache @author <A HREF="mailto:burton@apache.org">Kevin A. Burton</A> @version $Id: DiskCacheUtils.java,v 1.20 2004/02/23 02:45:29 jford Exp $ */ public class DiskCacheUtils { /** Used to determine if a given URL should be cached. This prevents people from trying to cache documents that aren't supported. http and ftp should fit almost any situation. */ public final static String[] VALID_PROTOCOLS = { "http", "ftp" }; /** Stores the protocols which sould be recognized as local */ private static Vector localprotocols = JetspeedResources.getVector("diskcache.localprotocols"); /** * Static initialization of the logger for this class */ private static final JetspeedLogger logger = JetspeedLogFactoryService.getLogger(DiskCacheUtils.class.getName()); private static String hostName = "localhost"; static { try { hostName = java.net.InetAddress.getLocalHost().getHostName(); } catch (Throwable t) {} if (localprotocols.size()==0) { // default values, if key is not defined localprotocols.add("file"); } } /** Give an full url: http://www.cnn.com/test just return the virutal portion: /test */ public static String getVirtual( String url ) { //strip off the begining of the URL if necessary: int begin = 0; if ( url.indexOf(":/") != -1 ) { begin = url.indexOf( ":/" ) + 2; } if ( begin > 0 ) { url = url.substring( begin, url.length() ); } url = url.substring( url.indexOf("/"), url.length() ); return url; } /** Given a virtual URL, resolve it to a local URL: Ex: /test.xml -> http://localhost:80/test.xml */ public static String getLocalURL( String virtual ) { //if this virtual URL is actually a local, return it directly. if ( virtual != null && isLocal( virtual ) && virtual.indexOf("/") != 0 ) { return virtual; } if ( isVirtual( virtual ) == false ) { throw new IllegalArgumentException( "The URL specifies is not a virtual URL: " + virtual ); } String url = TurbineServlet.getResource( virtual ).toString(); return url; } /** Return true if this URL is virtual. EX: /tmp/test.xml */ public static boolean isVirtual( String url ) { if ( url.indexOf( "/" ) == 0 ) { return true; } return false; } /** Return true if this URL is on the local server. */ public static boolean isLocal( String url ) { /* If the URL is virtual, return true: EX: /test/test.xml */ if ( url != null && url.length() > 1 ) { if ( ( url.indexOf( ":/" ) == -1 ) ) { //this must be a local URL because it is virtual "/test/test.xml" return true; } /* ok... perform two more tests. if the URL is on the local server.. or on localhost then return true EX: http://localhost http://server.domain */ if ( ( url.indexOf( "http://localhost" ) == 0 ) || ( url.indexOf( "http://127.0.0.1" ) == 0 ) || ( url.indexOf( "http://" + hostName ) == 0 ) || // RL: using EngineContext doesn't work because the serverName // and serverPort is a request-based information. // We should either fix EngineContext to use a config property // or remove it altogether and find something that always works ! /* ( url.indexOf( EngineContext.getInstance().getServerScheme() + "://" + EngineContext.getInstance().getServerName() ) == 0 ) */ ( false ) ) { return true; } /* SH Testing local protocols also */ if (localprotocols!=null) { Enumeration en = localprotocols.elements(); while(en.hasMoreElements()) { String protocol = (String)en.nextElement()+":"; if ( url.indexOf(protocol) != -1 ) { return true; } } } } return false; } /** Return true if this URL is NOT on the local server. */ public static boolean isRemote( String url ) { return ! isLocal( url ); } /** Return true if this url is in the cache. @see DiskCache#isCached( String ) */ public static boolean isCached( DiskCache instance, String url ) { /* if ( isLocal( url ) ) { //SGP: I think we should not cache local urls return false; }*/ // return DiskCacheUtils.getFile( instance, url ).exists(); return instance.isCached(url); } /** @see DiskCacheUtils#isCached( DiskCache, String ) */ public static boolean isCached( String url ) { return isCached( JetspeedDiskCache.getInstance(), url ); } /** Return true if the given URL should be cached or not. */ public static boolean isCacheable( String url ) { for (int i = 0; i < VALID_PROTOCOLS.length;++i) { String uri = VALID_PROTOCOLS[i] + ":/"; if (url.length() >= uri.length() && url.substring(0, uri.length() ).equals( uri ) ) { return isRemote( url ); //SGP was true } } return false; } /** Given a URL, determine what the filename would be within the cache. Note that this doesn't return a URL just a path to where it would be stored locally. */ public static File getFile( DiskCache instance, String url ) { String file = URIEncoder.encode( url ); file = instance.getRoot() + "/" + file; return new File( file ); } /** Given a url and an disk cache instance, determine what the correct URL for this cache entry for the remote URL would be. */ public static String getFileURL( DiskCache instance, String url ) { URL fileURL = null; try { fileURL = DiskCacheUtils.getFile( instance, url ).toURL(); } catch (MalformedURLException e) { // what can we do in this case ? logger.error("Exception getting URL", e); return null; } return fileURL.toString(); } }