fedora.client.Uploader.java Source code

Java tutorial

Introduction

Here is the source code for fedora.client.Uploader.java

Source

/* The contents of this file are subject to the license and copyright terms
 * detailed in the license directory at the root of the source tree (also
 * available online at http://fedora-commons.org/license/).
 */
package fedora.client;

import java.awt.Dimension;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import java.util.HashMap;

import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.UsernamePasswordCredentials;

import org.apache.log4j.Logger;

import fedora.common.Constants;

import fedora.server.utilities.StreamUtility;

/**
 * A client to a Fedora server's upload facility, accessed via a
 * basic-authenticated multipart POST to the server. See
 * server.management.UploadServlet for protocol details.
 *
 * @author Chris Wilper
 */
public class Uploader {

    private final MultiThreadedHttpConnectionManager m_cManager = new MultiThreadedHttpConnectionManager();

    private final String m_uploadURL;

    private final UsernamePasswordCredentials m_creds;

    private final FedoraClient fc;

    private static final Logger logger = Logger.getLogger(FedoraClient.class.getName());

    /**
     * Construct an uploader to a certain repository as a certain user.
     */
    public Uploader(String host, int port, String context, String user, String pass) throws IOException {
        m_uploadURL = Administrator.getProtocol() + "://" + host + ":" + port + "/" + context
                + "/management/upload";
        m_creds = new UsernamePasswordCredentials(user, pass);
        String baseURL = Administrator.getProtocol() + "://" + host + ":" + port + "/" + context;
        fc = new FedoraClient(baseURL, user, pass);
    }

    /**
     * Construct an uploader to a certain repository as a certain user.
     */
    public Uploader(String protocol, String host, int port, String context, String user, String pass)
            throws IOException {
        m_uploadURL = protocol + "://" + host + ":" + port + context + "/" + "/management/upload";
        m_creds = new UsernamePasswordCredentials(user, pass);
        String baseURL = protocol + "://" + host + ":" + port + "/" + context;
        fc = new FedoraClient(baseURL, user, pass);
    }

    /**
     * Send the data from the stream to the server. This is less efficient than
     * <i>upload(File)</i>, but if you already have a stream, it's convenient.
     * This method takes care of temporarily making a File out of the stream,
     * making the request, and removing the temporary file. Having a File source
     * for the upload is necessary because the content-length must be sent along
     * with the request as per the HTTP Multipart POST protocol spec.
     */
    public String upload(InputStream in) throws IOException {
        File tempFile = File.createTempFile("fedora-upload-", null);
        FileOutputStream out = new FileOutputStream(tempFile);
        try {
            StreamUtility.pipeStream(in, out, 8192);
            return upload(tempFile);
        } finally {
            in.close();
            out.close();
            if (!tempFile.delete()) {
                System.err.println("WARNING: Could not remove temporary file: " + tempFile.getName());
                tempFile.deleteOnExit();
            }
        }
    }

    /**
     * Send a file to the server, getting back the identifier.
     */
    public String upload(File file) throws IOException {
        if (Administrator.INSTANCE == null) {
            return fc.uploadFile(file);
        } else {
            // paint initial status to the progress bar
            String msg = "Uploading " + file.length() + " bytes to " + fc.getUploadURL();
            Dimension d = Administrator.PROGRESS.getSize();
            Administrator.PROGRESS.setString(msg);
            Administrator.PROGRESS.setValue(100);
            Administrator.PROGRESS.paintImmediately(0, 0, (int) d.getWidth() - 1, (int) d.getHeight() - 1);

            // then start the thread, passing parms in
            HashMap<String, Object> PARMS = new HashMap<String, Object>();
            PARMS.put("fc", fc);
            PARMS.put("file", file);
            SwingWorker worker = new SwingWorker(PARMS) {

                @Override
                public Object construct() {
                    try {
                        FedoraClient fc = (FedoraClient) parms.get("fc");
                        File file = (File) parms.get("file");
                        return fc.uploadFile(file);
                    } catch (IOException e) {
                        thrownException = e;
                        return "";
                    }
                }
            };
            worker.start();

            // keep updating status till the worker's finished
            int ms = 200;
            while (!worker.done) {
                try {
                    Administrator.PROGRESS.setValue(ms);
                    Administrator.PROGRESS.paintImmediately(0, 0, (int) d.getWidth() - 1, (int) d.getHeight() - 1);
                    Thread.sleep(100);
                    ms = ms + 100;
                    if (ms >= 2000) {
                        ms = 200;
                    }
                } catch (InterruptedException ie) {
                }
            }

            // reset the status bar to normal
            Administrator.PROGRESS.setValue(2000);
            Administrator.PROGRESS.paintImmediately(0, 0, (int) d.getWidth() - 1, (int) d.getHeight() - 1);
            try {
                Thread.sleep(100);
            } catch (InterruptedException ie) {
            }

            // report if there was an error; otherwise return the response
            if (worker.thrownException != null) {
                throw (IOException) worker.thrownException;
            } else {
                return (String) worker.getValue();
            }

        }
    }

    /**
     * Test this class by uploading the given file three times. First, with the
     * provided credentials, as an InputStream. Second, with the provided
     * credentials, as a File. Third, with bogus credentials, as a File.
     */
    public static void main(String[] args) {
        try {
            if (args.length == 5 || args.length == 6) {
                String protocol = args[0];
                int port = Integer.parseInt(args[1]);
                String user = args[2];
                String password = args[3];
                String fileName = args[4];

                String context = Constants.FEDORA_DEFAULT_APP_CONTEXT;

                if (args.length == 6 && !args[5].equals("")) {
                    context = args[5];
                }

                Uploader uploader = new Uploader(protocol, port, context, user, password);
                File f = new File(fileName);
                System.out.println(uploader.upload(new FileInputStream(f)));
                System.out.println(uploader.upload(f));
                uploader = new Uploader(protocol, port, context, user + "test", password);
                System.out.println(uploader.upload(f));
            } else {
                System.err.println("Usage: Uploader host port user password file [context]");
            }
        } catch (Exception e) {
            System.err.println("ERROR: " + e.getMessage());
        }
    }

}