View Javadoc

1   /*
2    * Copyright 2000-2001,2004 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.apache.jetspeed.cache.disk;
18  
19  //standard java stuff
20  import java.io.File;
21  import java.net.MalformedURLException;
22  import java.net.URL;
23  import java.util.Enumeration;
24  import java.util.Vector;
25  
26  //turbine
27  import org.apache.turbine.services.servlet.TurbineServlet;
28  
29  // Jetspeed classes
30  import org.apache.jetspeed.services.logging.JetspeedLogFactoryService;
31  import org.apache.jetspeed.services.logging.JetspeedLogger;
32  import org.apache.jetspeed.services.resources.JetspeedResources;
33  import org.apache.jetspeed.util.URIEncoder;
34  
35  /***
36     <p>
37     Misc utils for managing the disk cache.
38     </p>
39  
40     <p>
41     This tries to separate URLs into three categories:
42         <ul>
43             <li>
44             Virtual: URLs which are contructored such as: /test/test.xml
45             </li>
46  
47             <li>
48             Local: URLs which are contructored such as: http://localhost/test/test.xml
49             </li>
50  
51             <li>
52             Remote: URLs which are contructored such as: http://REMOTE.SERVER/test/test.xml
53             </li>
54             
55         </ul>
56     </p>
57     
58     @see DiskCache
59     @author <A HREF="mailto:burton@apache.org">Kevin A. Burton</A>
60     @version $Id: DiskCacheUtils.java,v 1.20 2004/02/23 02:45:29 jford Exp $
61  */
62  public class DiskCacheUtils {
63  
64      /***
65      Used to determine if a given URL should be cached.  This prevents people 
66      from trying to cache documents that aren't supported.  http and ftp should
67      fit almost any situation.
68      */
69      public final static String[] VALID_PROTOCOLS = { "http", "ftp" };
70      
71      /***
72      Stores the protocols which sould be recognized as local
73      */
74      private static Vector localprotocols = JetspeedResources.getVector("diskcache.localprotocols");
75  
76      /***
77       * Static initialization of the logger for this class
78       */
79      private static final JetspeedLogger logger = JetspeedLogFactoryService.getLogger(DiskCacheUtils.class.getName()); 
80      
81      private static String hostName = "localhost";
82      static {
83          try {
84              hostName = java.net.InetAddress.getLocalHost().getHostName();
85          } catch (Throwable t) {}
86          if (localprotocols.size()==0) { // default values, if key is not defined
87              localprotocols.add("file");
88          }
89      }
90      
91      /***
92      Give an full url:  http://www.cnn.com/test
93      
94      just return the virutal portion:  /test
95      */
96      public static String getVirtual( String url ) {
97          
98          //strip off the begining of the URL if necessary:
99          
100         int begin = 0;
101         
102         if ( url.indexOf(":/") != -1 ) {
103             begin = url.indexOf( ":/" ) + 2;
104         }
105         
106         if ( begin > 0 ) {
107             url = url.substring( begin, url.length() );
108         }
109         
110         url = url.substring( url.indexOf("/"), url.length() );
111         
112         
113         return url;
114     }
115     
116     /***
117        Given a virtual URL, resolve it to a local URL:
118     
119        Ex: /test.xml  -> http://localhost:80/test.xml
120     */
121     public static String getLocalURL( String virtual ) {
122 
123      //if this virtual URL is actually a local, return it directly.
124         if ( virtual != null &&
125              isLocal( virtual ) &&
126              virtual.indexOf("/") != 0 ) {
127             return virtual;
128         }
129 
130         if ( isVirtual( virtual ) == false ) {
131             throw new IllegalArgumentException( "The URL specifies is not a virtual URL: " + virtual );
132         }
133                 
134         String url = TurbineServlet.getResource( virtual ).toString();
135         
136         return url;
137     }
138 
139     /***
140        Return true if this URL is virtual.
141 
142        EX: /tmp/test.xml
143      */
144     public static boolean isVirtual( String url ) {
145 
146         if ( url.indexOf( "/" ) == 0 ) {
147             return true;
148         } 
149 
150         return false;
151     }
152     
153     /***
154     Return true if this URL is on the local server.
155     */
156     public static boolean isLocal( String url ) {
157 
158 
159         /*
160           If the URL is virtual, return true:
161 
162           EX: /test/test.xml
163               
164          */
165         
166         if ( url != null && url.length() > 1 ) {
167 
168             if ( ( url.indexOf( ":/" ) == -1 ) ) {
169                 //this must be a local URL because it is virtual "/test/test.xml"
170                 return true;
171             }
172 
173 
174         /*
175           ok... perform two more tests.  if the URL is on the local server.. or on
176           localhost then return true
177           
178           EX: http://localhost
179               http://server.domain
180          */
181             if ( ( url.indexOf( "http://localhost" ) == 0 ) || 
182                  ( url.indexOf( "http://127.0.0.1" ) == 0 ) || 
183                  ( url.indexOf( "http://" + hostName ) == 0 ) ||
184 
185            // RL: using EngineContext doesn't work because the serverName
186            // and serverPort is a request-based information.
187            // We should either fix EngineContext to use a config property
188            // or remove it altogether and find something that always works !
189         
190              /* ( url.indexOf( EngineContext.getInstance().getServerScheme() +
191                             "://" + 
192                             EngineContext.getInstance().getServerName() ) == 0 ) */
193                     ( false )
194                  ) {
195                 return true;
196             }
197             
198             /* SH Testing local protocols also */
199             if (localprotocols!=null) {
200                 Enumeration en = localprotocols.elements();
201                 while(en.hasMoreElements()) {
202                     String protocol = (String)en.nextElement()+":";
203                     if ( url.indexOf(protocol) != -1 ) 
204                     {
205                         return true;
206                     }
207                 }
208             }
209 
210         }
211         return false;
212     }
213     
214     /***
215     Return true if this URL is NOT on the local server.
216     */
217     public static boolean isRemote( String url ) {
218         return ! isLocal( url );
219     }
220     
221     /***
222     Return true if this url is in the cache.
223     @see DiskCache#isCached( String )
224     */
225     public static boolean isCached( DiskCache instance, 
226                                     String url ) {
227      
228     /*         if ( isLocal( url ) ) {
229                //SGP: I think we should not cache local urls
230                return false;
231                }*/
232                 
233     //         return DiskCacheUtils.getFile( instance, url ).exists();
234          return instance.isCached(url);
235     }
236 
237     /***
238     @see DiskCacheUtils#isCached( DiskCache, String )
239     */
240     public static boolean isCached( String url ) {
241         return isCached( JetspeedDiskCache.getInstance(), url );
242     }
243     
244     /***
245     Return true if the given URL should be cached or not.
246     */
247     public static boolean isCacheable( String url ) {
248 
249         for (int i = 0; i < VALID_PROTOCOLS.length;++i) {
250 
251             String uri = VALID_PROTOCOLS[i] + ":/";
252 
253             if (url.length() >= uri.length() &&
254         url.substring(0, uri.length() ).equals( uri ) ) {
255                 return isRemote( url ); //SGP was true
256             }
257 
258         }
259         return false;
260     }
261     
262     /***
263        Given a URL, determine what the filename would be within the cache.  Note 
264        that this doesn't return a URL just a path to where it would be stored 
265        locally.
266     */
267     public static File getFile( DiskCache instance, 
268                                 String url ) {
269 
270       String file = URIEncoder.encode( url );
271 
272       file = instance.getRoot() + "/" + file;
273 
274       return new File( file );
275       
276     }
277 
278     /***
279        Given a url and an disk cache instance, determine what the correct URL for this
280        cache entry for the remote URL would be.
281      */
282     public static String getFileURL( DiskCache instance,
283                                      String url ) {
284 
285         URL fileURL = null;
286         
287         try {
288             fileURL = DiskCacheUtils.getFile( instance, url ).toURL();
289         } catch (MalformedURLException e) {
290             // what can we do in this case ?
291             logger.error("Exception getting URL", e);
292             return null;
293         }
294         
295         return fileURL.toString();
296         
297     }
298     
299 }
300