jvanzyl 02/04/11 04:57:40
Added: src/java/org/apache/maven/util HttpUtils.java
Log:
HttpUtils util class, would like to move to using httpclient.
Revision Changes Path
1.1
jakarta-turbine-maven/src/java/org/apache/maven/util/HttpUtils.java
Index: HttpUtils.java
===================================================================
package org.apache.maven.util;
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000-2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Ant", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import java.net.HttpURLConnection;
import java.util.Date;
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;
import java.util.HashMap;
import java.io.BufferedReader;
import java.io.FileReader;
/**
* Http utils for retrieving files.
*
* @author [EMAIL PROTECTED]
* @author [EMAIL PROTECTED] (Added Java 1.1 style HTTP basic auth)
* @author <a href="mailto:[EMAIL PROTECTED]">Jason van Zyl</a>
*/
public class HttpUtils
{
public static void getFile(URL source, File destinationFile, String file,
boolean verbose, boolean ignoreErrors, boolean
useTimestamp,
String uname, String pword)
{
try
{
logx("Getting: " + source);
//set the timestamp to the file date.
long timestamp = 0;
boolean hasTimestamp = false;
if (useTimestamp && destinationFile.exists())
{
timestamp = destinationFile.lastModified();
if (verbose)
{
Date t = new Date(timestamp);
logx("local file date : " + t.toString());
}
hasTimestamp = true;
}
//set up the URL connection
URLConnection connection = source.openConnection();
//modify the headers
//NB: things like user authentication could go in here too.
if (useTimestamp && hasTimestamp)
{
connection.setIfModifiedSince(timestamp);
}
// prepare Java 1.1 style credentials
if (uname != null || pword != null)
{
String up = uname + ":" + pword;
String encoding = null;
// check to see if sun's Base64 encoder is available.
try
{
sun.misc.BASE64Encoder encoder =
(sun.misc.BASE64Encoder) Class.forName(
"sun.misc.BASE64Encoder").newInstance();
encoding = encoder.encode(up.getBytes());
}
catch (Exception ex)
{
// Do nothing, as for Maven we will never use
// auth and we will eventually move over httpclient
// in the commons.
}
connection.setRequestProperty("Authorization", "Basic " + encoding);
}
//connect to the remote site (may take some time)
connection.connect();
//next test for a 304 result (HTTP only)
if (connection instanceof HttpURLConnection)
{
HttpURLConnection httpConnection = (HttpURLConnection) connection;
if (httpConnection.getResponseCode() ==
HttpURLConnection.HTTP_NOT_MODIFIED)
{
//not modified so no file download. just return instead
//and trace out something so the user doesn't think that the
//download happened when it didnt
logx("Not modified - so not downloaded");
return;
}
// test for 401 result (HTTP only)
if (httpConnection.getResponseCode() ==
HttpURLConnection.HTTP_UNAUTHORIZED)
{
logx("Not authorized - check " + destinationFile + " for
details");
return;
}
}
//REVISIT: at this point even non HTTP connections may support the
if-modified-since
//behaviour -we just check the date of the content and skip the write if
it is not
//newer. Some protocols (FTP) dont include dates, of course.
FileOutputStream fos = new FileOutputStream(destinationFile);
logx("Writing " + destinationFile);
InputStream is = null;
for (int i = 0; i < 3; i++)
{
try
{
is = connection.getInputStream();
break;
}
catch (IOException ex)
{
logx("Error opening connection " + ex);
}
}
if (is == null)
{
logx("Can't get " + file + " to " + destinationFile);
if (ignoreErrors)
{
return;
}
throw new Exception(
"Can't get " + file + " to " + destinationFile);
}
byte[] buffer = new byte[100 * 1024];
int length;
while ((length = is.read(buffer)) >= 0)
{
fos.write(buffer, 0, length);
System.out.print(".");
}
System.out.println();
fos.close();
is.close();
//if (and only if) the use file time option is set, then the
//saved file now has its timestamp set to that of the downloaded file
if (useTimestamp)
{
long remoteTimestamp = connection.getLastModified();
if (verbose)
{
Date t = new Date(remoteTimestamp);
logx("last modified = " + t.toString() +
((remoteTimestamp == 0) ? " - using current time instead" :
""));
}
if (remoteTimestamp != 0)
{
touchFile(destinationFile, remoteTimestamp);
}
}
}
catch (IOException ioe)
{
ioe.printStackTrace();
logx("Error getting " + file + " to " + destinationFile);
if (ignoreErrors)
{
return;
}
// We don't ever really want to throw an exception
// just want to truck along.
//throw new Exception(ioe.getMessage());
}
catch (Exception e)
{
e.printStackTrace();
}
}
/**
* set the timestamp of a named file to a specified time.
*
* @param file
* @param timemillis in milliseconds since the start of the era
* @return true if it succeeded. False means that this is a java1.1 system
* and that file times can not be set
* @exception Exception Thrown in unrecoverable error. Likely this
* comes from file access failures.
*/
private static boolean touchFile(File file, long timemillis)
throws Exception
{
long modifiedTime;
if (timemillis < 0)
{
modifiedTime = System.currentTimeMillis();
}
else
{
modifiedTime = timemillis;
}
file.setLastModified(modifiedTime);
return true;
}
// We need to move to the commons-logging goodies here.
private static void logx(String message)
{
System.out.println(message);
}
}