Coverage Report

##### Coverage Report - org.webmacro.resource.UrlProvider

Classes in this File | Line Coverage | Branch Coverage | Complexity
UrlProvider |
11% | 6/54
0% | 0/18
| 5.2;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 |  |