001 /* 002 * Copyright 1999,2004 The Apache Software Foundation. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017 package org.apache.commons.feedparser.network; 018 019 import java.io.ByteArrayInputStream; 020 import java.io.ByteArrayOutputStream; 021 import java.io.IOException; 022 import java.io.InputStream; 023 import java.io.OutputStream; 024 import java.net.HttpURLConnection; 025 import java.util.HashMap; 026 import java.util.Iterator; 027 028 /** 029 * 030 * @author <a href="mailto:burton@openprivacy.org">Kevin A. Burton</a> 031 * @version $Id: BaseResourceRequest.java 373622 2006-01-30 22:53:00Z mvdb $ 032 */ 033 public abstract class BaseResourceRequest implements ResourceRequest { 034 035 public static boolean FOLLOW_REDIRECTS = true; 036 037 private String resource = null; 038 039 private DataEvent event = new DataEvent(); 040 041 private long _ifModifiedSince = -1; 042 043 private long _responseCode = HttpURLConnection.HTTP_OK; 044 045 private String _etag = null; 046 047 private byte[] data = new byte[0]; 048 049 private boolean localCache = false; 050 051 private boolean followRedirects = FOLLOW_REDIRECTS; 052 053 /** 054 * A single resource request can now have a given event listener. 055 */ 056 private NetworkEventListener eventListener = null; 057 058 private HashMap requestHeaders = new HashMap(); 059 060 /** 061 * 062 * Get the value of <code>resource</code>. 063 * 064 * 065 */ 066 public String getResource() { 067 068 return this.resource; 069 070 } 071 072 /** 073 * 074 * Set the value of <code>resource</code>. 075 * 076 * 077 */ 078 public void setResource( String resource ) { 079 080 this.resource = resource; 081 082 } 083 084 /** 085 * Fire a new ArchiveEvent 086 * 087 * 088 */ 089 public void fireDataEvent( long count ) { 090 091 event.count = count; 092 event.resource = resource; 093 094 fireDataEvent( event ); 095 096 } 097 098 public void fireInit() { 099 100 DataEvent event = new DataEvent(); 101 event.request = this; 102 103 Iterator i = ResourceRequestFactory.getNetworkEventListeners(); 104 105 while ( i.hasNext() ) { 106 ((NetworkEventListener)i.next()).init( event ); 107 } 108 109 if ( eventListener != null ) 110 eventListener.init( event ); 111 } 112 113 /** 114 * Fire a new ArchiveEvent 115 * 116 * 117 */ 118 public void fireDataEvent( DataEvent event ) { 119 120 event.request = this; 121 122 Iterator i = ResourceRequestFactory.getNetworkEventListeners(); 123 124 while ( i.hasNext() ) { 125 ((NetworkEventListener)i.next()).dataEvent( event ); 126 } 127 128 if ( eventListener != null ) 129 eventListener.dataEvent( event ); 130 } 131 132 public void fireOnClosed() { 133 134 Iterator i = ResourceRequestFactory.getNetworkEventListeners(); 135 136 while ( i.hasNext() ) { 137 ((NetworkEventListener)i.next()).onClosed(); 138 } 139 140 if ( eventListener != null ) 141 eventListener.onClosed(); 142 } 143 144 /** 145 * @see ResourceRequest 146 * 147 */ 148 public String getInputStreamAsString() throws IOException { 149 return new String( getInputStreamAsByteArray() ); 150 } 151 152 /** 153 * @see ResourceRequest 154 * 155 */ 156 public byte[] getInputStreamAsByteArray() throws IOException { 157 158 InputStream is = getInputStream(); 159 160 int contentLength = -1; 161 162 try { 163 164 contentLength = getContentLength() + 5000; 165 166 } catch ( IOException e ) { e.printStackTrace(); } 167 168 if ( contentLength == -1 ) { 169 170 //use a larger default than what's provided with the 171 //ByteArrayOutputStream 172 173 contentLength = 100000; 174 } 175 176 //include length of content from the original site with contentLength 177 ByteArrayOutputStream bos = new ByteArrayOutputStream( contentLength ); 178 179 //now process the Reader... 180 byte data[] = new byte[200]; 181 182 int readCount = 0; 183 184 while( ( readCount = is.read( data )) > 0 ) { 185 bos.write( data, 0, readCount ); 186 } 187 188 is.close(); 189 bos.close(); 190 191 return bos.toByteArray(); 192 193 } 194 195 /** 196 * @see ResourceRequest 197 * 198 */ 199 public InputStream getLocalInputStream() throws NetworkException { 200 201 try { 202 203 byte[] data; 204 205 if ( this.data.length > 0 ) { 206 207 //we have cached this... return the cached value. 208 data = this.data; 209 210 } else { 211 212 data = getInputStreamAsByteArray(); 213 214 if ( localCache ) 215 this.data = data; 216 217 } 218 219 return new ByteArrayInputStream( data ); 220 221 } catch ( NetworkException n ) { 222 throw n; 223 } catch ( Throwable t ) { 224 throw new NetworkException( t ); 225 } 226 227 } 228 229 public byte[] getLocalInputStreamAsByteArray() throws IOException { 230 //FIXME: this needs to use the cache. 231 return this.data; 232 } 233 234 public void setLocalCache( boolean v ) { 235 this.localCache = v; 236 } 237 238 /** 239 * Copy this resource request to the given OutputStream 240 * 241 * 242 */ 243 public void toOutputStream( OutputStream out ) throws IOException { 244 245 InputStream is = getInputStream(); 246 247 //now process the Reader... 248 byte data[] = new byte[200]; 249 250 int readCount = 0; 251 252 while( ( readCount = is.read( data )) > 0 ) { 253 254 out.write( data, 0, readCount ); 255 } 256 257 is.close(); 258 259 } 260 261 public long getIfModifiedSince() { 262 return _ifModifiedSince; 263 } 264 265 public void setIfModifiedSince( long ifModifiedSince ) { 266 this._ifModifiedSince = ifModifiedSince; 267 } 268 269 public String getEtag() { 270 return _etag; 271 } 272 273 public void setEtag( String etag ) { 274 this._etag = etag; 275 } 276 277 /** 278 * Get and set an HTTP style response code. Only used with HTTP URLs. 279 * 280 * 281 */ 282 public long getResponseCode() { 283 return this._responseCode; 284 } 285 286 public void setResponseCode( int responseCode ) { 287 this._responseCode = responseCode; 288 } 289 290 public int getContentLength() throws IOException { 291 return -1; 292 } 293 294 public void setEventListener( NetworkEventListener eventListener ) { 295 this.eventListener = eventListener; 296 } 297 298 public String getHeaderField( String name ) { 299 //default impl always returns null 300 return null; 301 } 302 303 public void setRequestHeaderField( String name, String value ) { 304 requestHeaders.put( name, value ); 305 } 306 307 public Iterator getRequestHeaderFields() { 308 return requestHeaders.keySet().iterator(); 309 } 310 311 public String getRequestHeaderField( String name ) { 312 return (String)requestHeaders.get( name ); 313 } 314 315 public void setRequestMethod( String method ) throws NetworkException { 316 throw new NetworkException( "not implemented" ); 317 } 318 319 public boolean getFollowRedirects() { 320 return followRedirects; 321 } 322 323 public void setFollowRedirects( boolean v ) { 324 this.followRedirects = v; 325 } 326 327 public String getResourceFromRedirect() { 328 return getResource(); 329 } 330 331 }