org.apache.webdav.ant.taskdefs.Get.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.webdav.ant.taskdefs.Get.java

Source

// vi: set ts=3 sw=3:
/* 
 * $Header$
 * $Revision: 207687 $
 * $Date: 2004-08-20 18:53:22 +0800 (Fri, 20 Aug 2004) $
 * ========================================================================
 * 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.webdav.ant.taskdefs;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.Iterator;

import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpURL;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.types.FilterSet;
import org.apache.tools.ant.types.FilterSetCollection;
import org.apache.tools.ant.util.LineTokenizer;
import org.apache.webdav.ant.CollectionScanner;
import org.apache.webdav.ant.Utils;
import org.apache.webdav.ant.WebdavFileSet;

/**
 * WebDAV task for retrieving resources.
 * 
 * @see <a href="../doc-files/tasks.htm#davget">Task documentation</a>
 */
public class Get extends WebdavMatchingTask {
    private File toDir = null;
    private File toFile = null;
    private boolean overwrite = false;
    private String encoding = null;
    private FilterSetCollection filterSets = new FilterSetCollection();

    private int countWrittenFiles = 0;
    private int countOmittedFiles = 0;

    /* 
     * @see org.apache.tools.ant.Task#execute()
     */
    public void execute() throws BuildException {
        validate();

        try {
            if (this.toFile != null) {
                downloadSingleFile();
            } else {
                log("Downloading from: " + getUrl(), ifVerbose());
                // URL must be a collection
                if (!getUrl().getPath().endsWith("/")) {
                    getUrl().setPath(getUrl().getPath() + "/");
                }
                for (Iterator i = getFileSets(); i.hasNext();) {
                    downloadFileset((WebdavFileSet) i.next());
                }
            }

            if (this.countWrittenFiles > 0) {
                log("Downloaded " + this.countWrittenFiles
                        + (this.countWrittenFiles == 1 ? " resource" : " resources") + " from " + getUrl(),
                        this.countWrittenFiles > 0 ? Project.MSG_INFO : ifVerbose());
            }
        } catch (IOException e) {
            throw Utils.makeBuildException("Error while downloading!", e);
        }
    }

    protected void validate() {
        super.validate();

        if (this.toDir == null && this.toFile == null) {
            throw new BuildException("Missing one of the required attributes toDir" + " or toFile.");
        }
        if (this.toDir != null && this.toFile != null) {
            throw new BuildException("Only one of the attributes toDir and toFile" + " is alowed.");
        }
        if (this.toFile != null && getFileSets().hasNext()) {
            throw new BuildException("Not filesets allowed if toFile is set.");
        }
        if (this.encoding == null && this.filterSets.hasFilters()) {
            log("If filterSets are used a file encoding should be specified!", Project.MSG_WARN);
            this.encoding = "ISO-8859-1"; // TODO what should be the default
        }
    }

    protected void downloadFileset(WebdavFileSet fileSet) throws IOException {
        CollectionScanner scanner = fileSet.getCollectionScanner(getProject(), getHttpClient(), getUrl());
        HttpURL baseUrl = scanner.getBaseURL();

        String[] files = scanner.getIncludedFiles();
        for (int i = 0; i < files.length; i++) {
            HttpURL url = Utils.createHttpURL(baseUrl, files[i]);
            downloadFile(url, files[i], scanner);
        }
    }

    protected void downloadSingleFile() throws IOException {
        long lastMod = Utils.getLastModified(getHttpClient(), getUrl());

        if (shallWeGetIt(this.toFile, lastMod)) {
            getAndStoreResource(getUrl(), this.toFile, lastMod, getUrl().getURI());
        } else {
            log("Omitted: " + getUrl() + " (uptodate)", ifVerbose());
            this.countOmittedFiles++;
        }
    }

    protected void downloadFile(HttpURL url, String relativePath, CollectionScanner scanner) throws IOException {
        File target = new File(this.toDir, relativePath);

        long lastMod = scanner.getProperties().getLastModified(url.toString());

        if (shallWeGetIt(target, lastMod)) {
            getAndStoreResource(url, target, lastMod, relativePath);
        } else {
            log("Omitted: " + relativePath + " (uptodate)", ifVerbose());
            this.countOmittedFiles++;
        }
    }

    private boolean shallWeGetIt(File target, long lastMod) {
        boolean getit = this.overwrite || !target.exists();
        if (!this.overwrite && target.exists()) {
            if (lastMod > target.lastModified()) {
                getit = true;
            }
        }
        return getit;
    }

    /**
     * Retrieves the data of a resource and stores it in a file.
     * 
     * Creates required directories and sets the last modified time of the file.
     * 
     * @param url url of the resource to be retrieved
     * @param target file where the resource data ist stored
     * @param lastMod last modified date of the resource, used to set 
     *        the last modified date of the target file
     * @param relative path og the resource for logging purposes.
     * @throws IOException
     * @throws HttpException
     * @throws FileNotFoundException
     */
    private void getAndStoreResource(HttpURL url, File target, long lastMod, String relative)
            throws IOException, HttpException, FileNotFoundException {
        log("downloading: " + relative, ifVerbose());
        File directory = target.getParentFile();
        if (!directory.exists()) {
            directory.mkdirs();
        }

        InputStream in = Utils.getFile(getHttpClient(), url);

        if (!target.exists()) {
            target.createNewFile();
        }
        FileOutputStream out = new FileOutputStream(target);

        copyStream(in, out, this.filterSets, this.encoding);

        out.close();
        target.setLastModified(lastMod);
        this.countWrittenFiles++;
    }

    protected static void copyStream(InputStream in, OutputStream out, FilterSetCollection filterSets,
            String encoding) throws IOException {
        byte[] b = new byte[1024];
        if (filterSets.hasFilters()) {
            InputStreamReader reader = new InputStreamReader(in, encoding);
            OutputStreamWriter writer = new OutputStreamWriter(out, encoding);

            LineTokenizer tok = new LineTokenizer();
            tok.setIncludeDelims(true);

            for (String l = tok.getToken(reader); l != null; l = tok.getToken(reader)) {
                writer.write(filterSets.replaceTokens(l));
            }
            writer.close();
            reader.close();
        } else {
            while (in.available() > 0) {
                int cnt = in.read(b, 0, b.length);
                if (cnt > -1) {
                    out.write(b, 0, cnt);
                }
            }
        }
    }

    public void setTodir(File directory) {
        this.toDir = directory;
        if (this.toDir.isFile()) {
            throw new BuildException("toDir must not point to a file!");
        }
    }

    public void setTofile(File file) {
        this.toFile = file;
        if (this.toFile.isDirectory()) {
            throw new BuildException("toFile must not point to a directory!");
        }
    }

    public FilterSet createFilterSet() {
        FilterSet filterSet = new FilterSet();
        this.filterSets.addFilterSet(filterSet);
        return filterSet;
    }

    public void setEncoding(String enc) {
        this.encoding = enc;
    }

    public void setOverwrite(boolean b) {
        this.overwrite = b;
    }
}