Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
ResourceRequestFactory |
|
| 1.8333333333333333;1.833 |
1 | /* | |
2 | * Copyright 1999,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.commons.feedparser.network; | |
18 | ||
19 | import java.net.URL; | |
20 | import java.util.ArrayList; | |
21 | import java.util.HashMap; | |
22 | import java.util.Iterator; | |
23 | ||
24 | import org.apache.log4j.Logger; | |
25 | ||
26 | /** | |
27 | * Get a ResourceRequest for a given URL. The request is handled based on the | |
28 | * URL. | |
29 | * | |
30 | * @author <a href="mailto:burton@openprivacy.org">Kevin A. Burton</a> | |
31 | * @version $Id: ResourceRequestFactory.java 373622 2006-01-30 22:53:00Z mvdb $ | |
32 | */ | |
33 | 0 | public class ResourceRequestFactory { |
34 | ||
35 | 0 | private static Logger log = Logger.getLogger( ResourceRequestFactory.class.getName() ); |
36 | ||
37 | /** | |
38 | * Specified in java.security to indicate the caching policy for successful | |
39 | * name lookups from the name service.. The value is specified as as integer | |
40 | * to indicate the number of seconds to cache the successful lookup. | |
41 | * | |
42 | * | |
43 | * sun.net.inetaddr.ttl: | |
44 | * | |
45 | * This is a sun private system property which corresponds to | |
46 | * networkaddress.cache.ttl. It takes the same value and has the same meaning, | |
47 | * but can be set as a command-line option. However, the preferred way is to | |
48 | * use the security property mentioned above. | |
49 | * | |
50 | * A value of -1 indicates "cache forever". | |
51 | */ | |
52 | 0 | public static int NETWORKADDRESS_CACHE_TTL = 5 * 60; |
53 | ||
54 | /** | |
55 | * These properties specify the default connect and read timeout (resp.) for | |
56 | * the protocol handler used by java.net.URLConnection. | |
57 | * | |
58 | * sun.net.client.defaultConnectTimeout specifies the timeout (in | |
59 | * milliseconds) to establish the connection to the host. For example for | |
60 | * http connections it is the timeout when establishing the connection to | |
61 | * the http server. For ftp connection it is the timeout when establishing | |
62 | * the connection to ftp servers. | |
63 | * | |
64 | * sun.net.client.defaultReadTimeout specifies the timeout (in milliseconds) | |
65 | * when reading from input stream when a connection is established to a | |
66 | * resource. | |
67 | */ | |
68 | 0 | public static int DEFAULT_CONNECT_TIMEOUT = 1 * 60 * 1000; |
69 | ||
70 | 0 | public static int DEFAULT_READ_TIMEOUT = DEFAULT_CONNECT_TIMEOUT; |
71 | ||
72 | /** | |
73 | * Specify the maximum number of redirects to use. | |
74 | */ | |
75 | 0 | public static int DEFAULT_MAX_REDIRECTS = 5; |
76 | ||
77 | //FIXME: (should this be a linked list?) | |
78 | 0 | private static ArrayList listeners = new ArrayList( 30 ); |
79 | ||
80 | 0 | private static HashMap schemeMap = null; |
81 | ||
82 | 0 | private static boolean transparentHTCacheEnabled = false; |
83 | ||
84 | /** | |
85 | * When offline we either throw an exception or return content from the | |
86 | * cache directly. This can be used to run code that does not depend on the | |
87 | * network. | |
88 | */ | |
89 | 0 | private static boolean offline = false; |
90 | ||
91 | public static ResourceRequest getResourceRequest( String resource, | |
92 | long ifModifiedSince ) throws NetworkException { | |
93 | ||
94 | 0 | return getResourceRequest( resource, ifModifiedSince, null ); |
95 | ||
96 | } | |
97 | ||
98 | /** | |
99 | * Get a ResourceRequest for the protocol represented in the resource URL. | |
100 | * It is important that we use a ResourceRequest implementation that supports | |
101 | * fetching the URL. | |
102 | * | |
103 | * | |
104 | */ | |
105 | public static ResourceRequest getResourceRequest( String resource, | |
106 | long ifModifiedSince, | |
107 | String etag ) throws NetworkException { | |
108 | ||
109 | //log.debug( resource ); | |
110 | ||
111 | //make sure we are initialized correctly. | |
112 | 0 | ResourceRequestFactory.init(); |
113 | ||
114 | //make sure we have an index.. | |
115 | ||
116 | 0 | int schemeIndex = resource.indexOf( ":" ); |
117 | ||
118 | 0 | if ( schemeIndex == -1 ) |
119 | 0 | throw new NetworkException( "Unknown scheme: '" + resource + "'" ); |
120 | ||
121 | 0 | String scheme = resource.substring( 0, schemeIndex ); |
122 | ||
123 | 0 | if ( scheme == null || scheme.equals( "" ) ) |
124 | 0 | throw new MalformedResourceException( "Not supported: " + resource ); |
125 | ||
126 | 0 | Class clazz = (Class)schemeMap.get( scheme ); |
127 | ||
128 | 0 | if ( clazz == null ) { |
129 | 0 | throw new MalformedResourceException( "Scheme not supported: " + scheme ); |
130 | } | |
131 | ||
132 | try { | |
133 | ||
134 | 0 | ResourceRequest request = (ResourceRequest)clazz.newInstance(); |
135 | ||
136 | 0 | request.setResource( resource ); |
137 | ||
138 | //setup resource request options. | |
139 | 0 | request.setIfModifiedSince( ifModifiedSince ); |
140 | ||
141 | //set the etag... when its null nothing will happen | |
142 | 0 | request.setEtag( etag ); |
143 | ||
144 | 0 | request.init(); |
145 | ||
146 | 0 | return request; |
147 | ||
148 | 0 | } catch ( Throwable t ) { |
149 | 0 | throw new NetworkException( t ); |
150 | } | |
151 | ||
152 | } | |
153 | ||
154 | /** | |
155 | * | |
156 | * @see #getResourceRequest( String ) | |
157 | * | |
158 | */ | |
159 | public static ResourceRequest getResourceRequest( String resource ) throws NetworkException { | |
160 | 0 | return getResourceRequest( resource, -1 ); |
161 | } | |
162 | ||
163 | /** | |
164 | * | |
165 | * @see #getResourceRequest( String ) | |
166 | * | |
167 | */ | |
168 | public static ResourceRequest getResourceRequest( URL resource ) throws NetworkException { | |
169 | 0 | return getResourceRequest( resource.toString() ); |
170 | } | |
171 | ||
172 | /** | |
173 | * Add an event listener to this instance of the factory. This provides a | |
174 | * mechanism to give default listeners to each new ResourceRequest. | |
175 | * | |
176 | * | |
177 | */ | |
178 | public static void addEventListener( NetworkEventListener listener ) { | |
179 | ||
180 | 0 | listeners.add( listener ); |
181 | ||
182 | 0 | } |
183 | ||
184 | /** | |
185 | * Get all event listeners. | |
186 | * | |
187 | * | |
188 | */ | |
189 | public static Iterator getNetworkEventListeners() { | |
190 | ||
191 | 0 | return listeners.iterator(); |
192 | ||
193 | } | |
194 | ||
195 | /** | |
196 | * Make sure the factory is initialized. Called once per JVM instance. | |
197 | * | |
198 | * | |
199 | */ | |
200 | private synchronized static void init() { | |
201 | ||
202 | //set the authenticator to use | |
203 | ||
204 | //FIXME: remove this until we figure out how to do proxy authentication. | |
205 | //java.net.Authenticator.setDefault ( new Authenticator() ); | |
206 | ||
207 | // A full list of properties is available here: | |
208 | ||
209 | // http://java.sun.com/j2se/1.4.2/docs/guide/net/properties.html | |
210 | ||
211 | 0 | System.setProperty( "sun.net.inetaddr.ttl", |
212 | Integer.toString( NETWORKADDRESS_CACHE_TTL ) ); | |
213 | ||
214 | 0 | System.setProperty( "networkaddress.cache.ttl", |
215 | Integer.toString( NETWORKADDRESS_CACHE_TTL ) ); | |
216 | ||
217 | 0 | System.setProperty( "sun.net.client.defaultReadTimeout", |
218 | Integer.toString( DEFAULT_READ_TIMEOUT ) ); | |
219 | ||
220 | 0 | System.setProperty( "sun.net.client.defaultConnectTimeout", |
221 | Integer.toString( DEFAULT_CONNECT_TIMEOUT ) ); | |
222 | ||
223 | 0 | System.setProperty( "http.maxRedirects", |
224 | Integer.toString( DEFAULT_MAX_REDIRECTS ) ); | |
225 | ||
226 | 0 | if ( schemeMap == null ) { |
227 | ||
228 | 0 | schemeMap = new HashMap(); |
229 | ||
230 | 0 | schemeMap.put( "file", URLResourceRequest.class ); |
231 | 0 | schemeMap.put( "http", URLResourceRequest.class ); |
232 | 0 | schemeMap.put( "https", URLResourceRequest.class ); |
233 | 0 | schemeMap.put( BlockingResourceRequest.SCHEME, BlockingResourceRequest.class ); |
234 | ||
235 | } | |
236 | ||
237 | 0 | } |
238 | ||
239 | /** | |
240 | * Return true if we support fetching content with the given scheme. | |
241 | * Examples would be "http" and "file" | |
242 | * | |
243 | * | |
244 | */ | |
245 | public static boolean isSupportedScheme( String scheme ) { | |
246 | ||
247 | 0 | return schemeMap.get( scheme ) != null; |
248 | ||
249 | } | |
250 | ||
251 | /** | |
252 | * When the transparent HTCache is enabled we will keep content local | |
253 | * similar to the Mozilla cache and return the cached copy and use | |
254 | * if-Modified-Since when necessary. | |
255 | * | |
256 | * | |
257 | */ | |
258 | public static void setTransparentHTCacheEnabled( boolean enabled ) { | |
259 | 0 | transparentHTCacheEnabled = enabled; |
260 | 0 | } |
261 | ||
262 | /** | |
263 | * Return true if we can enable the htcache. | |
264 | * | |
265 | * | |
266 | */ | |
267 | public static boolean isTransparentHTCacheEnabled() { | |
268 | 0 | return transparentHTCacheEnabled; |
269 | } | |
270 | ||
271 | /** | |
272 | * Enable/disable offline operation. | |
273 | * | |
274 | * | |
275 | */ | |
276 | public static void setOffline( boolean offline ) { | |
277 | 0 | ResourceRequestFactory.offline = offline; |
278 | 0 | } |
279 | ||
280 | /** | |
281 | * | |
282 | * | |
283 | * | |
284 | */ | |
285 | public static boolean isOffline() { | |
286 | 0 | return offline; |
287 | } | |
288 | ||
289 | } |