com.hfg.util.io.HTTPRemoteFile Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of com_hfg Show documentation
Show all versions of com_hfg Show documentation
com.hfg xml, html, svg, and bioinformatics utility library
package com.hfg.util.io;
import java.io.*;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.net.URL;
import java.net.HttpURLConnection;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.hfg.util.StringUtil;
//------------------------------------------------------------------------------
/**
* Implementation of RemoteFile for HTTP files
*
* @author J. Alex Taylor, hairyfatguy.com
*/
//------------------------------------------------------------------------------
// com.hfg XML/HTML Coding Library
//
// This library 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 library 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 library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com
// [email protected]
//------------------------------------------------------------------------------
public class HTTPRemoteFile extends AbstractRemoteFile
{
//###########################################################################
// PRIVATE FIELDS
//###########################################################################
private String mURL;
private Long mSize;
private Calendar mTimestamp;
private int mNumRedirects;
private String mUserAgentString = sDefaultUserAgentString;
private String mRequestedPath;
private static String sDefaultUserAgentString;
private static final int MAX_REDIRECTS = 10;
// Some places don't like to talk to or don't recognize Java. Pretend we're IE
private static final String USER_AGENT = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)";
private final static Logger LOGGER = Logger.getLogger(HTTPRemoteFile.class.getName());
//###########################################################################
// CONSTRUCTORS
//###########################################################################
//---------------------------------------------------------------------------
public HTTPRemoteFile(String inURL)
{
mURL = inURL;
}
//###########################################################################
// PUBLIC METHODS
//###########################################################################
//---------------------------------------------------------------------------
public static void setDefaultUserAgentString(String inValue)
{
sDefaultUserAgentString = inValue;
}
//---------------------------------------------------------------------------
public static String getDefaultUserAgentString()
{
return sDefaultUserAgentString;
}
//---------------------------------------------------------------------------
public HTTPRemoteFile setUserAgentString(String inValue)
{
mUserAgentString = inValue;
return this;
}
//---------------------------------------------------------------------------
public String geUserAgentString()
{
return mUserAgentString;
}
//---------------------------------------------------------------------------
public static Logger getLogger()
{
return LOGGER;
}
//---------------------------------------------------------------------------
@Override
public String getURL()
{
return mURL;
}
//---------------------------------------------------------------------------
@Override
public String getName()
{
String name;
int index = mURL.lastIndexOf('/');
if (index > 0)
{
name = mURL.substring(index + 1);
}
else
{
name = mURL;
}
// Don't include arguments in the name
index = name.indexOf('?');
if (index > 0)
{
name = name.substring(0, index);
}
return name;
}
//---------------------------------------------------------------------------
@Override
public String getPath()
{
String path;
// Remove http://
int index = mURL.indexOf("//");
if (index > 0)
{
path = mURL.substring(index + 2);
}
else
{
path = mURL;
}
// Remove the server or server:port
index = path.indexOf("/");
if (index > 0)
{
path = path.substring(index + 1);
}
// Don't include arguments in the path
index = path.indexOf('?');
if (index > 0)
{
path = path.substring(0, index);
}
return path;
}
//---------------------------------------------------------------------------
public HTTPRemoteFile setRequestedPath(String inValue)
{
mRequestedPath = inValue;
return this;
}
//---------------------------------------------------------------------------
@Override
public String getRequestedPath()
{
return mRequestedPath != null ? mRequestedPath : getPath();
}
//---------------------------------------------------------------------------
@Override
public long getSize()
{
if (null == mSize)
{
getFileInfo();
}
return mSize != null ? mSize.longValue() : -1;
}
//---------------------------------------------------------------------------
@Override
public Calendar getTimestamp()
{
if (null == mTimestamp)
{
getFileInfo();
}
return mTimestamp;
}
//---------------------------------------------------------------------------
@Override
public InputStream getInputStream()
throws IOException
{
HttpURLConnection conn = (HttpURLConnection) new URL(mURL).openConnection();
conn.setRequestProperty("User-Agent", USER_AGENT);
conn.connect();
return new BufferedInputStream(conn.getInputStream());
}
//---------------------------------------------------------------------------
@Override
public boolean writeToLocalDir(File inLocalDir)
throws IOException
{
boolean result = super.writeToLocalDir(inLocalDir);
if (null == mSize
|| mSize < 0)
{
mSize = new File(inLocalDir, getName()).length();
}
return result;
}
//---------------------------------------------------------------------------
@Override
public boolean copyLocallyPreservingPath(File inLocalDir)
throws IOException
{
boolean result = super.copyLocallyPreservingPath(inLocalDir);
if (null == mSize
|| mSize < 0)
{
mSize = new File(inLocalDir, getPath()).length();
}
return result;
}
//---------------------------------------------------------------------------
@Override
public long writeToStream(OutputStream stream)
throws IOException
{
long fileSize = super.writeToStream(stream);
if (null == mSize
|| mSize < 0)
{
mSize = fileSize;
}
return fileSize;
}
//---------------------------------------------------------------------------
@Override
public boolean writeToLocalFile(File inLocalFile)
throws IOException
{
boolean result = super.writeToLocalFile(inLocalFile);
if (null == mSize
|| mSize < 0)
{
mSize = inLocalFile.length();
}
return result;
}
//###########################################################################
// PRIVATE METHODS
//###########################################################################
//---------------------------------------------------------------------------
private void getFileInfo()
{
HttpURLConnection conn = null;
try
{
conn = (HttpURLConnection) new URL(mURL).openConnection();
conn.setRequestMethod("HEAD");
conn.setUseCaches(false);
conn.setInstanceFollowRedirects(false);
if (StringUtil.isSet(geUserAgentString()))
{
conn.setRequestProperty("User-Agent", geUserAgentString());
}
conn.connect();
if (getLogger().isLoggable(Level.FINE))
{
LOGGER.log(Level.FINE, "RESPONSE CODE: " + conn.getResponseCode());
LOGGER.log(Level.FINE, "RESPONSE MSG: " + conn.getResponseMessage());
LOGGER.log(Level.FINE, "CONTENT LENGTH: " + conn.getContentLength());
LOGGER.log(Level.FINE, "LAST MODIFIED: " + conn.getLastModified());
}
final int responseCode = conn.getResponseCode();
if ( responseCode == HttpURLConnection.HTTP_MOVED_PERM
|| responseCode == HttpURLConnection.HTTP_MOVED_TEMP
|| responseCode == HttpURLConnection.HTTP_SEE_OTHER)
{
final String newLocation = conn.getHeaderField("Location");
final String msg = getURL() + (responseCode == HttpURLConnection.HTTP_MOVED_PERM ? " permanently" : "") + " moved to " + newLocation;
LOGGER.log(Level.INFO, msg);
mNumRedirects++;
if (mNumRedirects > MAX_REDIRECTS)
{
throw new IOException("More than " + MAX_REDIRECTS + " redirects!");
}
final URL newURL = new URL(new URL(getURL()), newLocation);
conn.disconnect();
mURL = newURL.toString();
getFileInfo(); // Recurse
}
else if (responseCode == HttpURLConnection.HTTP_OK)
{
mSize = new Long(conn.getContentLength());
long lastModifiedMilliseconds = conn.getLastModified();
if (lastModifiedMilliseconds > 0)
{
mTimestamp = new GregorianCalendar();
mTimestamp.setTime(new Date(conn.getLastModified()));
}
}
}
catch (IOException e)
{
throw new RuntimeException(e.toString());
}
finally
{
if (conn != null) conn.disconnect();
}
}
}