001: // Copyright 2004, 2005 The Apache Software Foundation
002: //
003: // Licensed under the Apache License, Version 2.0 (the "License");
004: // you may not use this file except in compliance with the License.
005: // You may obtain a copy of the License at
006: //
007: // http://www.apache.org/licenses/LICENSE-2.0
008: //
009: // Unless required by applicable law or agreed to in writing, software
010: // distributed under the License is distributed on an "AS IS" BASIS,
011: // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012: // See the License for the specific language governing permissions and
013: // limitations under the License.
014:
015: package org.apache.hivemind.build;
016:
017: import java.io.BufferedOutputStream;
018: import java.io.File;
019: import java.io.FileOutputStream;
020: import java.io.IOException;
021: import java.io.InputStream;
022: import java.io.OutputStream;
023: import java.net.URL;
024: import java.net.URLConnection;
025:
026: import org.apache.tools.ant.BuildException;
027: import org.apache.tools.ant.Project;
028: import org.apache.tools.ant.Task;
029:
030: /**
031: * Ant task for conditionally downloading a file and checking its md5 sum. MD5 checking occurs only
032: * if a download occurs. This is very similar to Ant's <code>Get</code> task, with a few
033: * differences:
034: * <ul>
035: * <li>Always does a timestamp comparison, where possible
036: * <li>Has additional parameter for specifying where the MD5 sum is stored
037: * <li>Less verbose --- no output if the file isn't downloaded
038: * </ul>
039: *
040: * @author Howard Lewis Ship
041: */
042: public class Grabber extends Task {
043: private URL _src;
044:
045: private File _dest;
046:
047: public void execute() throws BuildException {
048: if (_src == null)
049: throw new BuildException("src is required", getLocation());
050:
051: if (_dest == null)
052: throw new BuildException("dest is required", getLocation());
053:
054: if (_dest.exists()) {
055:
056: if (_dest.isDirectory())
057: throw new BuildException(
058: "The specified destination is a directory",
059: getLocation());
060:
061: if (isNonZeroLength(_dest))
062: return;
063:
064: if (!_dest.canWrite())
065: throw new BuildException("Can't write to "
066: + _dest.getAbsolutePath(), getLocation());
067: }
068:
069: try {
070:
071: URLConnection connection = _src.openConnection();
072:
073: connection.connect();
074:
075: copyConnectionToFile(connection);
076: } catch (IOException ex) {
077: log("Failure accessing " + _src + ": " + ex.getMessage(),
078: Project.MSG_ERR);
079: }
080: }
081:
082: private boolean isNonZeroLength(File file) {
083: return file.length() > 0;
084: }
085:
086: private void copyConnectionToFile(URLConnection connection)
087: throws IOException {
088: log("Downloading " + _src + " to " + _dest);
089:
090: InputStream is = open(connection);
091:
092: FileOutputStream fos = new FileOutputStream(_dest);
093: OutputStream os = new BufferedOutputStream(fos);
094:
095: byte[] buffer = new byte[100 * 1024];
096:
097: while (true) {
098: int bytesRead = is.read(buffer);
099:
100: if (bytesRead < 0)
101: break;
102:
103: os.write(buffer, 0, bytesRead);
104: }
105:
106: is.close();
107: os.close();
108: }
109:
110: private InputStream open(URLConnection connection) {
111: InputStream result = null;
112:
113: int i = 0;
114: while (true) {
115: try {
116: result = connection.getInputStream();
117: break;
118: } catch (IOException ex) {
119: if (i++ == 3)
120: throw new BuildException("Unable to open " + _src
121: + ": " + ex.getMessage(), ex, getLocation());
122: }
123: }
124:
125: if (result == null)
126: throw new BuildException("Unable to open " + _src,
127: getLocation());
128:
129: return result;
130: }
131:
132: public void setDest(File file) {
133: _dest = file;
134: }
135:
136: public void setSrc(URL url) {
137: _src = url;
138: }
139:
140: }
|