Package org.apache.hivemind.build

Source Code of org.apache.hivemind.build.Grabber

//  Copyright 2004 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package org.apache.hivemind.build;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;

/**
* Ant task for conditionally downloading a file and checking its md5 sum. MD5 checking occurs only
* if a download occurs. This is very similar to Ant's <code>Get</code> task, with a few
* differences:
* <ul>
* <li>Always does a timestamp comparison, where possible
* <li>Has additional parameter for specifying where the MD5 sum is stored
* <li>Less verbose --- no output if the file isn't downloaded
* </ul>
*
* @author Howard Lewis Ship
*/
public class Grabber extends Task
{
    private URL _src;
    private File _dest;
    private URL _md5;

    public void execute() throws BuildException
    {
        if (_src == null)
            throw new BuildException("src is required", getLocation());

        if (_dest == null)
            throw new BuildException("dest is required", getLocation());

        if (_dest.exists())
        {

            if (_dest.isDirectory())
                throw new BuildException("The specified destination is a directory", getLocation());

            if (isNonZeroLength(_dest))
                return;

            if (!_dest.canWrite())
                throw new BuildException(
                    "Can't write to " + _dest.getAbsolutePath(),
                    getLocation());
        }

        try
        {

            URLConnection connection = _src.openConnection();

            connection.connect();

            MessageDigest digest = copyConnectionToFile(connection);

            if (_md5 != null)
                compareMD5(digest);
        }
        catch (IOException ex)
        {
            log("Failure accessing " + _src + ": " + ex.getMessage(), Project.MSG_ERR);
        }
    }

    private boolean isNonZeroLength(File file)
    {
        return file.length() > 0;
    }

    private MessageDigest copyConnectionToFile(URLConnection connection) throws IOException
    {
        log("Downloading " + _src + " to " + _dest);

        MessageDigest result = null;

        if (_md5 != null)
        {
            try
            {
                result = MessageDigest.getInstance("MD5");
            }
            catch (NoSuchAlgorithmException ex)
            {
                throw new BuildException(
                    "No MD5 message digest provider: " + ex.getMessage(),
                    ex,
                    getLocation());
            }
        }

        InputStream is = open(connection);

        if (result != null)
            is = new DigestInputStream(is, result);

        FileOutputStream fos = new FileOutputStream(_dest);
        OutputStream os = new BufferedOutputStream(fos);

        byte[] buffer = new byte[100 * 1024];

        while (true)
        {
            int bytesRead = is.read(buffer);

            if (bytesRead < 0)
                break;

            os.write(buffer, 0, bytesRead);
        }

        is.close();
        os.close();

        return result;
    }

    private void compareMD5(MessageDigest digest) throws IOException
    {
        String downloadedDigest = createDigestString(digest);

        URLConnection connection = _md5.openConnection();

        InputStream is = open(connection);

        InputStreamReader reader = new InputStreamReader(is);

        StringBuffer buffer = new StringBuffer();

        while (true)
        {
            int ch = reader.read();

            if (ch < 0)
                break;

            buffer.append((char) ch);
        }

        reader.close();

        String recordedDigest = buffer.toString().trim();

        // Sometimes a digest has a string identifying the file after the hex string; discard
        // that.

        int firstSpace = recordedDigest.indexOf(' ');
        if (firstSpace > 0)
            recordedDigest = recordedDigest.substring(0, firstSpace);

        if (downloadedDigest.equals(recordedDigest))
            return;

        throw new BuildException(
            "Downloaded file had an MD5 sum of "
                + downloadedDigest
                + " but the expected sum was "
                + recordedDigest,
            getLocation());
    }

    private InputStream open(URLConnection connection)
    {
        InputStream result = null;

        int i = 0;
        while (true)
        {
            try
            {
                result = connection.getInputStream();
                break;
            }
            catch (IOException ex)
            {
                if (i++ == 3)
                    throw new BuildException(
                        "Unable to open " + _src + ": " + ex.getMessage(),
                        ex,
                        getLocation());
            }
        }

        if (result == null)
            throw new BuildException("Unable to open " + _src, getLocation());

        return result;
    }

    private String createDigestString(MessageDigest digest)
    {
        byte[] bytes = digest.digest();

        StringBuffer buffer = new StringBuffer();
        for (int i = 0; i < bytes.length; i++)
        {
            String hex = Integer.toHexString(0x00ff & bytes[i]);
            if (hex.length() < 2)
                buffer.append("0");

            buffer.append(hex);
        }

        return buffer.toString();
    }

    public void setDest(File file)
    {
        _dest = file;
    }

    public void setMd5(String url)
    {
        if (url == null || url.length() == 0)
            return;

        try
        {
            _md5 = new URL(url);
        }
        catch (MalformedURLException ex)
        {
            log("Error in md5: " + ex.getMessage());
        }
    }

    public void setSrc(URL url)
    {
        _src = url;
    }

}
TOP

Related Classes of org.apache.hivemind.build.Grabber

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.