Java tutorial
/******************************************************************************* * Copyright (C) 2007 The University of Manchester * * Modifications to the initial code base are copyright of their * respective authors, or their employers as appropriate. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 ******************************************************************************/ package net.sf.taverna.t2.reference.impl.external.http; import static java.lang.System.currentTimeMillis; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.util.Date; import net.sf.taverna.t2.reference.AbstractExternalReference; import net.sf.taverna.t2.reference.DereferenceException; import net.sf.taverna.t2.reference.ExternalReferenceSPI; import net.sf.taverna.t2.reference.ExternalReferenceValidationException; import net.sf.taverna.t2.reference.ReferenceContext; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.methods.HeadMethod; /** * Implementation of ExternalReference used to refer to data held in a locally * accessible file. Inherits from * {@link net.sf.taverna.t2.reference.AbstractExternalReference * AbstractExternalReference} to enable hibernate based persistence. * * @author Tom Oinn */ public class HttpReference extends AbstractExternalReference implements ExternalReferenceSPI { private String httpUrlString = null; private URL httpUrl = null; private String charsetName = null; private boolean charsetFetched = false; private transient Long cachedLength; private transient Date cacheTime; /** * Explicitly declare default constructor, will be used by hibernate when * constructing instances of this bean from the database. */ public HttpReference() { super(); } /** * Return the data at the {@link URL} represented by this external reference */ @Override public InputStream openStream(ReferenceContext context) throws DereferenceException { try { return httpUrl.openStream(); } catch (IOException e) { throw new DereferenceException(e); } } @Override public String getCharset() throws DereferenceException { if (charsetFetched) return charsetName; charsetFetched = true; if (!httpUrl.getProtocol().equals("http") && !httpUrl.getProtocol().equals("https")) { charsetName = null; return null; } HeadMethod method = new HeadMethod(httpUrl.toExternalForm()); HttpClient httpClient = new HttpClient(); try { httpClient.executeMethod(method); charsetName = method.getResponseCharSet(); return charsetName; } catch (HttpException e) { // throw new DereferenceException(e); } catch (IOException e) { // throw new DereferenceException(e); } finally { method.releaseConnection(); } charsetName = null; return null; } /** * Setter used by hibernate to set the file path property of the file * reference * * @throws ExternalReferenceValidationException * if there is some problem parsing the supplied string as a URL */ public void setHttpUrlString(String httpUrlString) { try { this.httpUrlString = httpUrlString; this.httpUrl = new URL(httpUrlString); } catch (MalformedURLException e) { throw new ExternalReferenceValidationException(e); } } /** * Getter used by hibernate to retrieve the file path string property */ public String getHttpUrlString() { return this.httpUrlString; } /** * Human readable string form for debugging, should not be regarded as * stable. */ @Override public String toString() { return "http{" + httpUrl.toExternalForm() + "}"; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((httpUrl == null) ? 0 : httpUrl.toExternalForm().hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (!(obj instanceof HttpReference)) return false; final HttpReference other = (HttpReference) obj; if (httpUrl == null) { if (other.httpUrl != null) return false; } else if (!httpUrl.toExternalForm().equals(other.httpUrl.toExternalForm())) return false; return true; } // One minute private static final int CACHE_TIMEOUT = 60000; @Override public Long getApproximateSizeInBytes() { long now = currentTimeMillis(); if (cachedLength != null && cacheTime != null && cacheTime.getTime() + CACHE_TIMEOUT > now) return cachedLength; try { HttpURLConnection c = (HttpURLConnection) httpUrl.openConnection(); c.setRequestMethod("HEAD"); c.connect(); String lenString = c.getHeaderField("Content-Length"); if (lenString != null && !lenString.isEmpty()) { cachedLength = new Long(lenString); cacheTime = new Date(now); return cachedLength; } // there is no Content-Length field so we cannot know the size } catch (Exception e) { // something went wrong, but we don't care what } cachedLength = null; cacheTime = null; return new Long(-1); } /** * @return the httpUrl */ public final URL getHttpUrl() { return httpUrl; } @Override public float getResolutionCost() { return (float) 200.0; } public void deleteData() { throw new UnsupportedOperationException("Cannot delete data referenced by a URL"); } @Override public HttpReference clone() { HttpReference result = new HttpReference(); result.setHttpUrlString(this.getHttpUrlString()); return result; } }