1 17 package com.sun.syndication.fetcher.impl; 18 19 import java.io.BufferedInputStream ; 20 import java.io.IOException ; 21 import java.io.InputStream ; 22 import java.net.HttpURLConnection ; 23 import java.net.URL ; 24 import java.net.URLConnection ; 25 import java.util.zip.GZIPInputStream ; 26 27 import com.sun.syndication.feed.synd.SyndFeed; 28 import com.sun.syndication.fetcher.FetcherEvent; 29 import com.sun.syndication.fetcher.FetcherException; 30 import com.sun.syndication.io.FeedException; 31 import com.sun.syndication.io.SyndFeedInput; 32 import com.sun.syndication.io.XmlReader; 33 34 60 public class HttpURLFeedFetcher extends AbstractFeedFetcher { 61 static final int POLL_EVENT = 1; 62 static final int RETRIEVE_EVENT = 2; 63 static final int UNCHANGED_EVENT = 3; 64 65 private FeedFetcherCache feedInfoCache; 66 67 68 72 public HttpURLFeedFetcher() { 73 super(); 74 } 75 76 81 public HttpURLFeedFetcher(FeedFetcherCache feedCache) { 82 this(); 83 feedInfoCache = feedCache; 84 } 85 86 96 public SyndFeed retrieveFeed(URL feedUrl) throws IllegalArgumentException , IOException , FeedException, FetcherException { 97 if (feedUrl == null) { 98 throw new IllegalArgumentException ("null is not a valid URL"); 99 } 100 101 URLConnection connection = feedUrl.openConnection(); 102 if (!(connection instanceof HttpURLConnection )) { 103 throw new IllegalArgumentException (feedUrl.toExternalForm() + " is not a valid HTTP Url"); 104 } 105 HttpURLConnection httpConnection = (HttpURLConnection )connection; 106 108 if (feedInfoCache != null) { 109 SyndFeedInfo syndFeedInfo = feedInfoCache.getFeedInfo(feedUrl); 110 setRequestHeaders(connection, syndFeedInfo); 111 connection.connect(); 112 fireEvent(FetcherEvent.EVENT_TYPE_FEED_POLLED, connection); 113 114 if (syndFeedInfo == null) { 115 syndFeedInfo = new SyndFeedInfo(); 117 retrieveAndCacheFeed(feedUrl, syndFeedInfo, httpConnection); 118 } else { 119 int responseCode = httpConnection.getResponseCode(); 121 if (responseCode != HttpURLConnection.HTTP_NOT_MODIFIED) { 122 retrieveAndCacheFeed(feedUrl, syndFeedInfo, httpConnection); 127 } else { 128 fireEvent(FetcherEvent.EVENT_TYPE_FEED_UNCHANGED, connection); 130 } 131 } 132 133 return syndFeedInfo.getSyndFeed(); 134 } else { 135 fireEvent(FetcherEvent.EVENT_TYPE_FEED_POLLED, connection); 136 try { 137 InputStream inputStream = feedUrl.openStream(); 138 return getSyndFeedFromStream(inputStream, connection); 139 } catch (java.io.IOException e) { 140 handleErrorCodes(((HttpURLConnection )connection).getResponseCode()); 141 } 142 return null; 144 } 145 } 146 147 protected void retrieveAndCacheFeed(URL feedUrl, SyndFeedInfo syndFeedInfo, HttpURLConnection connection) throws IllegalArgumentException , FeedException, FetcherException, IOException { 148 handleErrorCodes(connection.getResponseCode()); 149 150 resetFeedInfo(feedUrl, syndFeedInfo, connection); 151 if (feedInfoCache != null) { 155 feedInfoCache.setFeedInfo(feedUrl, syndFeedInfo); 156 } 157 } 158 159 protected void resetFeedInfo(URL orignalUrl, SyndFeedInfo syndFeedInfo, HttpURLConnection connection) throws IllegalArgumentException , IOException , FeedException { 160 syndFeedInfo.setUrl(connection.getURL()); 162 163 syndFeedInfo.setId(orignalUrl.toString()); 166 167 syndFeedInfo.setLastModified(new Long (connection.getLastModified())); 169 170 syndFeedInfo.setETag(connection.getHeaderField("ETag")); 172 173 InputStream inputStream = null; 175 try { 176 inputStream = connection.getInputStream(); 177 SyndFeed syndFeed = getSyndFeedFromStream(inputStream, connection); 178 179 String imHeader = connection.getHeaderField("IM"); 180 if (isUsingDeltaEncoding() && (imHeader!= null && imHeader.indexOf("feed") >= 0) && (feedInfoCache != null) && connection.getResponseCode() == 226) { 181 SyndFeedInfo cachedInfo = feedInfoCache.getFeedInfo(orignalUrl); 184 if (cachedInfo != null) { 185 SyndFeed cachedFeed = cachedInfo.getSyndFeed(); 186 187 syndFeed = combineFeeds(cachedFeed, syndFeed); 189 } 190 } 191 192 syndFeedInfo.setSyndFeed(syndFeed); 193 } finally { 194 if (inputStream != null) { 195 inputStream.close(); 196 } 197 } 198 } 199 200 206 protected void setRequestHeaders(URLConnection connection, SyndFeedInfo syndFeedInfo) { 207 if (syndFeedInfo != null) { 208 if (syndFeedInfo.getLastModified() != null) { 211 Object lastModified = syndFeedInfo.getLastModified(); 212 if (lastModified instanceof Long ) { 213 connection.setIfModifiedSince(((Long )syndFeedInfo.getLastModified()).longValue()); 214 } 215 } 216 if (syndFeedInfo.getETag() != null) { 217 connection.setRequestProperty("If-None-Match", syndFeedInfo.getETag()); 218 } 219 220 } 221 connection.setRequestProperty("Accept-Encoding", "gzip"); 223 224 connection.addRequestProperty("User-Agent", getUserAgent()); 226 227 if (isUsingDeltaEncoding()) { 228 connection.addRequestProperty("A-IM", "feed"); 229 } 230 } 231 232 private SyndFeed getSyndFeedFromStream(InputStream inputStream, URLConnection connection) throws IOException , IllegalArgumentException , FeedException { 233 BufferedInputStream is; 234 if ("gzip".equalsIgnoreCase(connection.getContentEncoding())) { 235 is = new BufferedInputStream (new GZIPInputStream (inputStream)); 237 } else { 238 is = new BufferedInputStream (inputStream); 239 } 240 241 243 245 XmlReader reader = null; 246 if (connection.getHeaderField("Content-Type") != null) { 247 reader = new XmlReader(is, connection.getHeaderField("Content-Type"), true); 248 } else { 249 reader = new XmlReader(is, true); 250 } 251 252 SyndFeed feed = new SyndFeedInput().build(reader); 253 fireEvent(FetcherEvent.EVENT_TYPE_FEED_RETRIEVED, connection, feed); 254 return feed; 255 } 256 257 260 public FeedFetcherCache getFeedInfoCache() { 261 return feedInfoCache; 262 } 263 264 267 public void setFeedInfoCache(FeedFetcherCache cache) { 268 feedInfoCache = cache; 269 } 270 } 271 | Popular Tags |