Coverage Report - org.webmacro.resource.UrlProvider
 
Classes in this File Line Coverage Branch Coverage Complexity
UrlProvider
11%
6/54
0%
0/18
5.2
 
 1  
 /*
 2  
  * Copyright (C) 1998-2000 Semiotek Inc.  All Rights Reserved.
 3  
  *
 4  
  * Redistribution and use in source and binary forms, with or without
 5  
  * modification, are permitted under the terms of either of the following
 6  
  * Open Source licenses:
 7  
  *
 8  
  * The GNU General Public License, version 2, or any later version, as
 9  
  * published by the Free Software Foundation
 10  
  * (http://www.fsf.org/copyleft/gpl.html);
 11  
  *
 12  
  *  or
 13  
  *
 14  
  * The Semiotek Public License (http://webmacro.org/LICENSE.)
 15  
  *
 16  
  * This software is provided "as is", with NO WARRANTY, not even the
 17  
  * implied warranties of fitness to purpose, or merchantability. You
 18  
  * assume all risks and liabilities associated with its use.
 19  
  *
 20  
  * See www.webmacro.org for more information on the WebMacro project.
 21  
  */
 22  
 
 23  
 
 24  
 package org.webmacro.resource;
 25  
 
 26  
 import java.io.BufferedInputStream;
 27  
 import java.io.File;
 28  
 import java.io.FileInputStream;
 29  
 import java.io.IOException;
 30  
 import java.io.InputStream;
 31  
 import java.io.InputStreamReader;
 32  
 import java.io.Reader;
 33  
 import java.io.StringWriter;
 34  
 import java.net.MalformedURLException;
 35  
 import java.net.URL;
 36  
 import java.net.URLConnection;
 37  
 
 38  
 import org.webmacro.Broker;
 39  
 import org.webmacro.InitException;
 40  
 import org.webmacro.ResourceException;
 41  
 import org.webmacro.util.Settings;
 42  
 
 43  
 /**
 44  
  * This is the canonical provider for mapping URLs to Handlers. The
 45  
  * reactor will request that the "handler" provider return a Handler
 46  
  * object when supplied with a URL.
 47  
  * <p>
 48  
  * You could implement your own version of this class to return
 49  
  * handlers based on whatever criteria you wanted.
 50  
  */
 51  6
 final public class UrlProvider extends CachingProvider
 52  
 {
 53  
 
 54  
     static final public long AVG_TIMEOUT = 10000;
 55  
     static final public long MAX_TIMEOUT = 60000;
 56  
     static final public long MIN_TIMEOUT = 5000;
 57  
 
 58  
     Broker _broker;
 59  
 
 60  
     private String defaultEncoding;
 61  
 
 62  
     /**
 63  
      * We serve up "url" type resources.
 64  
      */
 65  
     final public String getType ()
 66  
     {
 67  24
         return "url";
 68  
     }
 69  
 
 70  
 
 71  
     public void init (Broker b, Settings config) throws InitException
 72  
     {
 73  6
         super.init(b, config);
 74  6
         _broker = b;
 75  6
         defaultEncoding = config.getSetting("TemplateEncoding");
 76  6
     }
 77  
 
 78  
     /**
 79  
      * Load a URL from the specified name and return it. The expire
 80  
      * time for the SoftReference will be set to the expire time
 81  
      * for the loaded URL.
 82  
      * <p>
 83  
      * Http expires information will be obeyed between the MIN_TIMEOUT
 84  
      * and MAX_TIMEOUT bounds. URLs which do not specify a timeout,
 85  
      * and files from the filesystem, will be cached for AVG_TIMEOUT
 86  
      * milliseconds.
 87  
      */
 88  
     final public Object load (String name, CacheElement ce)
 89  
             throws ResourceException
 90  
     {
 91  
 
 92  
         try
 93  
         {
 94  
             URL u;
 95  0
             if (name.indexOf(":") < 3)
 96  
             {
 97  0
                 u = new URL("file", null, -1, name);
 98  
             }
 99  
             else
 100  
             {
 101  0
                 u = new URL(name);
 102  
             }
 103  
 
 104  
             URLConnection uc;
 105  
             InputStream is;
 106  
             try
 107  
             {
 108  0
                 uc = u.openConnection();
 109  0
                 is = uc.getInputStream();
 110  
             }
 111  0
             catch (IOException e)
 112  
             {
 113  0
                 if (name.indexOf(":") < 3)
 114  
                 {
 115  0
                     uc = _broker.getResource(name).openConnection();
 116  0
                     is = uc.getInputStream();
 117  
                 }
 118  
                 else
 119  
                 {
 120  0
                     e.printStackTrace();
 121  0
                     throw e;
 122  
                 }
 123  0
             }
 124  
 
 125  0
             String encoding = uc.getContentEncoding();
 126  0
             if (encoding == null)
 127  
             {
 128  
                 // we have to guess encoding, so let's take
 129  
                 // our default TemplateEncoding
 130  0
                 encoding = defaultEncoding;
 131  
             }
 132  0
             Reader in = new InputStreamReader(
 133  
                     new BufferedInputStream(is), encoding);
 134  
 
 135  0
             int length = uc.getContentLength();
 136  0
             if (length == -1)
 137  
             {
 138  0
                 length = 1024;
 139  
             }
 140  
             /**
 141  
              long now = System.currentTimeMillis();
 142  
              long timeout = uc.getExpiration();
 143  
              if (timeout != 0) {
 144  
              timeout -= now;
 145  
              }
 146  
              else {
 147  
              timeout = AVG_TIMEOUT;
 148  
              }
 149  
              if (timeout > MAX_TIMEOUT)
 150  
              timeout = MAX_TIMEOUT;
 151  
              else if (timeout < MIN_TIMEOUT) timeout = MIN_TIMEOUT;
 152  
              **/
 153  
 
 154  0
             char buf[] = new char[1024];
 155  0
             StringWriter sw = new StringWriter(length);
 156  
             int num;
 157  0
             while ((num = in.read(buf)) != -1)
 158  
             {
 159  0
                 sw.write(buf, 0, num);
 160  
             }
 161  0
             in.close();
 162  0
             return sw.toString();
 163  
         }
 164  0
         catch (Exception e)
 165  
         {
 166  0
             throw new ResourceException(this + " unable to load " + name, e);
 167  
         }
 168  
     }
 169  
 
 170  
 
 171  
     /**
 172  
      * Utility routine to get the last modification date for a URL.
 173  
      * The standard implementation of .getLastModified() doesn't work
 174  
      * for file or jar URLs, so we try to be a bit more clever (running
 175  
      * the risk that we'll shoot ourselves in the foot, of course.)
 176  
      * Also used by BrokerTemplateProvider; maybe this should go somewhere
 177  
      * else?
 178  
      */
 179  
     public static long getUrlLastModified (URL u)
 180  
     {
 181  0
         String protocol = u.getProtocol();
 182  0
         if (protocol.equals("file"))
 183  
         {
 184  
             // We're going to use the File mechanism instead
 185  0
             File f = new File(u.getFile());
 186  0
             return f.lastModified();
 187  
         }
 188  0
         else if (protocol.equals("jar"))
 189  
         {
 190  
             // We'll extract the jar source and recurse
 191  0
             String source = u.getFile();
 192  0
             int lastIndex = source.lastIndexOf("!");
 193  0
             if (lastIndex > 0)
 194  0
                 source = source.substring(0, lastIndex);
 195  
             try
 196  
             {
 197  0
                 return getUrlLastModified(new URL(source));
 198  
             }
 199  0
             catch (MalformedURLException e)
 200  
             {
 201  0
                 return 0;
 202  
             }
 203  
         }
 204  
         else
 205  
         {
 206  
             // Ask the URL, maybe it knows
 207  
             try
 208  
             {
 209  0
                 URLConnection uc = u.openConnection();
 210  0
                 uc.connect();
 211  0
                 return uc.getLastModified();
 212  
             }
 213  0
             catch (IOException e)
 214  
             {
 215  0
                 return 0;
 216  
             }
 217  
         }
 218  
     }
 219  
 
 220  
     /**
 221  
      * Utility routine to get the input stream associated with a URL.
 222  
      * It special-cases "file" URLs because this way is faster.  If it
 223  
      * doesn't work on some platforms (I could imagine some Windows JVM
 224  
      * breaking) then we can back off to the standard implementation.
 225  
      * Also used by BrokerTemplateProvider; maybe this should go somewhere
 226  
      * else?
 227  
      */
 228  
     public static InputStream getUrlInputStream (URL u) throws IOException
 229  
     {
 230  0
         if (u.getProtocol().equals("file"))
 231  
         {
 232  0
             InputStream is = new FileInputStream(new File(u.getFile()));
 233  0
             return is;
 234  
         }
 235  
         else
 236  0
             return u.openStream();
 237  
     }
 238  
 
 239  
 }
 240  
 
 241