1 27 package de.nava.informa.utils; 28 29 import de.nava.informa.core.ChannelBuilderIF; 30 import de.nava.informa.core.ChannelIF; 31 import de.nava.informa.core.FeedIF; 32 import de.nava.informa.core.ParseException; 33 import de.nava.informa.impl.basic.Feed; 34 import de.nava.informa.parsers.FeedParser; 35 36 import java.io.IOException ; 37 38 import java.net.URL ; 39 import java.net.HttpURLConnection ; 40 import java.net.URLConnection ; 41 42 import java.util.Date ; 43 44 import org.apache.commons.logging.Log; 45 import org.apache.commons.logging.LogFactory; 46 47 60 public class FeedManagerEntry { 61 62 private static final long MILLISECONDS_IN_HOUR = 3600000L; 63 64 private static final long MILLISECONDS_IN_DAY = 86400000L; 65 66 private static final long MILLISECONDS_IN_MONTH = 2419200000L; 67 68 69 private static final long MILLISECONDS_IN_YEAR = 31536000000L; 70 71 72 private static Log logger = LogFactory.getLog(FeedManagerEntry.class); 73 74 private String defaultUpdatePeriod; 75 76 private int defaultUpdateFrequency; 77 78 82 private long timeToExpire; 83 84 85 private FeedIF feed; 86 87 88 private long lastUpdate; 89 90 91 private String feedUri; 92 93 private ChannelBuilderIF channelBuilder; 94 95 96 private long wantedTtl = -1; 97 98 99 private ConditionalGetValues httpHeaders = new ConditionalGetValues(); 100 101 110 public FeedManagerEntry(String feedUri, ChannelBuilderIF builder, 111 String defaultUpdatePeriod, int defaultUpdateFrequency) 112 throws FeedManagerException { 113 this.feedUri = feedUri; 114 this.channelBuilder = builder; 115 this.defaultUpdatePeriod = defaultUpdatePeriod; 116 this.defaultUpdateFrequency = defaultUpdateFrequency; 117 this.feed = retrieveFeed(feedUri); 118 this.lastUpdate = System.currentTimeMillis(); 119 } 120 121 130 private FeedIF retrieveFeed(String uri) throws FeedManagerException { 131 try { 132 URL urlToRetrieve = new URL (uri); 133 134 URLConnection conn = null; 135 try { 136 conn = urlToRetrieve.openConnection(); 137 138 if (conn instanceof HttpURLConnection ) { 139 140 HttpURLConnection httpConn = (HttpURLConnection ) conn; 141 142 httpConn.setInstanceFollowRedirects(true); 144 HttpHeaderUtils.setUserAgent(httpConn, "Informa Java API"); 147 148 logger.debug("retr feed at url " + uri + ": ETag" 149 + HttpHeaderUtils.getETagValue(httpConn) + " if-modified :" 150 + HttpHeaderUtils.getLastModified(httpConn)); 151 152 this.httpHeaders.setETag(HttpHeaderUtils.getETagValue(httpConn)); 154 this.httpHeaders.setIfModifiedSince(HttpHeaderUtils 155 .getLastModified(httpConn)); 156 } 157 } catch (java.lang.ClassCastException e) { 158 conn = null; 159 logger.warn("problem cast to HttpURLConnection " + uri, e); 160 throw new FeedManagerException(e); 161 } catch (NullPointerException e) { 162 logger.error("problem NPE " + uri + " conn=" + conn, e); 163 conn = null; 164 throw new FeedManagerException(e); 165 } 166 167 ChannelIF channel = null; 168 172 channel = FeedParser.parse(getChannelBuilder(), conn.getInputStream()); 173 175 this.timeToExpire = getTimeToExpire(channel); 176 this.feed = new Feed(channel); 177 178 Date currDate = new Date (); 179 this.feed.setLastUpdated(currDate); 180 this.feed.setDateFound(currDate); 181 this.feed.setLocation(urlToRetrieve); 182 logger.info("feed retrieved " + uri); 183 184 } catch (IOException e) { 185 logger.error("IOException " + feedUri + " e=" + e); 186 e.printStackTrace(); 187 throw new FeedManagerException(e); 188 } catch (ParseException e) { 189 e.printStackTrace(); 190 throw new FeedManagerException(e); 191 } 192 193 return this.feed; 194 } 195 196 202 private synchronized void updateChannel() throws FeedManagerException { 203 try { 204 String feedUrl = this.feed.getLocation().toString(); 205 206 URL aURL = null; 207 try { 208 aURL = new URL (feedUrl); 209 } catch (java.net.MalformedURLException e) { 210 logger.error("Could not create URL for " + feedUrl); 211 } 212 213 URLConnection conn = null; 214 try { 215 conn = aURL.openConnection(); 216 217 if (conn instanceof HttpURLConnection ) { 218 219 HttpURLConnection httpConn = (HttpURLConnection ) conn; 220 221 httpConn.setInstanceFollowRedirects(true); 222 HttpHeaderUtils.setUserAgent(httpConn, "Informa Java API"); 225 HttpHeaderUtils.setETagValue(httpConn, this.httpHeaders.getETag()); 226 HttpHeaderUtils.setIfModifiedSince(httpConn, this.httpHeaders 227 .getIfModifiedSince()); 228 httpConn.connect(); 229 if (httpConn.getResponseCode() == HttpURLConnection.HTTP_NOT_MODIFIED) { 230 231 logger.info("cond. GET for feed at url " + feedUrl + ": no change"); 232 this.feed.setLastUpdated(new Date ()); 233 this.lastUpdate = System.currentTimeMillis(); 235 return; 236 } 237 logger.info("cond. GET for feed at url " + feedUrl + ": changed"); 238 logger.debug("feed at url " + feedUrl + " new values : ETag" 239 + HttpHeaderUtils.getETagValue(httpConn) + " if-modified :" 240 + HttpHeaderUtils.getLastModified(httpConn)); 241 242 this.httpHeaders.setETag(HttpHeaderUtils.getETagValue(httpConn)); 243 this.httpHeaders.setIfModifiedSince(HttpHeaderUtils 244 .getLastModified(httpConn)); 245 } 246 247 } catch (java.lang.ClassCastException e) { 248 logger.warn("problem cast to HttpURLConnection (reading from a file?) " 249 + feedUrl, e); 250 } 251 252 ChannelIF channel = null; 253 if (conn == null) { 254 channel = FeedParser.parse(getChannelBuilder(), feedUrl); 255 } else { 256 channel = FeedParser.parse(getChannelBuilder(), conn.getInputStream()); 257 } 258 259 this.feed.setChannel(channel); 260 this.feed.setLastUpdated(new Date ()); 261 this.lastUpdate = System.currentTimeMillis(); 262 logger.info("feed updated " + feedUrl); 263 } catch (IOException e) { 264 throw new FeedManagerException(e); 265 } catch (ParseException e) { 266 throw new FeedManagerException(e); 267 } 268 } 269 270 277 public FeedIF getFeed() throws FeedManagerException { 278 if (isOutOfDate()) { 279 updateChannel(); 280 } 281 return this.feed; 282 } 283 284 public void setWantedTtl(long ms) { 285 this.wantedTtl = ms; 286 this.timeToExpire = this.getTimeToExpire(this.feed.getChannel()); 288 } 289 290 299 private long getTimeToExpire(ChannelIF channel) { 300 long temp = (new CacheSettings()).getTtl(channel, this.wantedTtl); 301 return temp; 302 } 303 304 309 private boolean isOutOfDate() { 310 boolean outOfDate = false; 311 logger.info(this + " isOutOfDate " + this.feedUri + "lupdt: " + lastUpdate 312 + ",tte=" + timeToExpire + "<?" 313 + (System.currentTimeMillis() - lastUpdate)); 314 if ((lastUpdate + timeToExpire) < System.currentTimeMillis()) { 315 outOfDate = true; 316 } 317 return outOfDate; 318 } 319 320 private ChannelBuilderIF getChannelBuilder() { 321 return channelBuilder; 322 } 323 324 } | Popular Tags |