001/*
002 * #%L
003 * Netarchivesuite - archive
004 * %%
005 * Copyright (C) 2005 - 2014 The Royal Danish Library, the Danish State and University Library,
006 *             the National Library of France and the Austrian National Library.
007 * %%
008 * This program is free software: you can redistribute it and/or modify
009 * it under the terms of the GNU Lesser General Public License as
010 * published by the Free Software Foundation, either version 2.1 of the
011 * License, or (at your option) any later version.
012 * 
013 * This program is distributed in the hope that it will be useful,
014 * but WITHOUT ANY WARRANTY; without even the implied warranty of
015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
016 * GNU General Lesser Public License for more details.
017 * 
018 * You should have received a copy of the GNU General Lesser Public
019 * License along with this program.  If not, see
020 * <http://www.gnu.org/licenses/lgpl-2.1.html>.
021 * #L%
022 */
023
024package dk.netarkivet.archive.tools;
025
026import java.io.File;
027import java.util.ArrayList;
028import java.util.List;
029
030import dk.netarkivet.common.distribute.JMSConnectionFactory;
031import dk.netarkivet.common.distribute.arcrepository.ArcRepositoryClientFactory;
032import dk.netarkivet.common.distribute.arcrepository.HarvesterArcRepositoryClient;
033import dk.netarkivet.common.exceptions.IOFailure;
034import dk.netarkivet.common.utils.FileUtils;
035
036/**
037 * A tool to force upload of given arc or warc files into the ArcRepository found in settings.xml. All successfully
038 * uploaded files are deleted locally.
039 * <p>
040 * Usage: java dk.netarkivet.archive.tools.Upload file1 [file2 ...]
041 */
042public class Upload {
043    /**
044     * Private constructor, to prevent instantiation of this tool.
045     */
046    private Upload() {
047    }
048
049    /**
050     * Main method, uploads given arc files to the ArcRepository. If some file does not exist or is not an arc file, the
051     * methods prints out an error and calls System.exit(). Successfully uploaded files are deleted locally. If some arc
052     * file cannot be uploaded, the method continues to upload the rest of the files and does not delete that file.
053     *
054     * @param argv A list of absolute paths to the arc files that should be uploaded.
055     */
056    public static void main(String[] argv) {
057        if (argv.length == 0) {
058            System.err.println("No files given to upload");
059            dieWithUsage();
060        }
061        List<File> files = checkExistenceAndArcNess(argv);
062        // Connect to ArcRepository
063        HarvesterArcRepositoryClient arcrep = null;
064        try {
065            System.out.println("Connecting to ArcRepository");
066            arcrep = ArcRepositoryClientFactory.getHarvesterInstance();
067            // Upload each input file
068            for (File f : files) {
069                System.out.println("Uploading file '" + f + "'...");
070                boolean success = uploadSingleFile(arcrep, f);
071                if (success) {
072                    System.out.println("Uploading file '" + f + "' succeeded");
073                } else {
074                    System.out.println("Uploading file '" + f + "' failed");
075
076                }
077            }
078            System.out.println("All files processed, closing connection to ArcRepository");
079        } finally {
080            // Close connections
081            if (arcrep != null) {
082                arcrep.close();
083            }
084            JMSConnectionFactory.getInstance().cleanup();
085        }
086    }
087
088    /**
089     * Checks existence and arcness of all input files.
090     *
091     * @param fileNames The input files as a String array
092     * @return If all files existed and were arc or warc files, a list of Files that is 1-1 with the input files.
093     */
094    private static List<File> checkExistenceAndArcNess(String[] fileNames) {
095        List<File> files = new ArrayList<File>();
096        for (String arg : fileNames) {
097            try {
098                File file = FileUtils.makeValidFileFromExisting(arg);
099                if (!FileUtils.ARCS_FILTER.accept(file.getParentFile(), file.getName())
100                        && !FileUtils.WARCS_FILTER.accept(file.getParentFile(), file.getName())) {
101                    dieWithException("Error checking input file: ", new IOFailure(file.getAbsolutePath()
102                            + " is not an arc or warc file"));
103                }
104                files.add(file);
105            } catch (IOFailure e) {
106                dieWithException("Error concerning file '" + arg + "':", e);
107            }
108        }
109        return files;
110    }
111
112    /**
113     * Attempts to upload a given file.
114     *
115     * @param arcRep The repository to contact
116     * @param f The file to upload. Should exist and be an arc file.
117     * @return true if the upload succeeded, false otherwise.
118     */
119    private static boolean uploadSingleFile(HarvesterArcRepositoryClient arcRep, File f) {
120        boolean success = false;
121        try {
122            arcRep.store(f);
123            success = true;
124        } catch (Exception e) {
125            System.err.println("Error while storing file: " + e);
126            e.printStackTrace(System.err);
127        }
128        return success;
129    }
130
131    /**
132     * Output a message and a stack trace before exiting with a failure code.
133     *
134     * @param msg The message to output
135     * @param e The Exception containing the relevant stack trace
136     */
137    private static void dieWithException(String msg, Exception e) {
138        System.err.println(msg + e);
139        e.printStackTrace(System.err);
140        System.exit(1);
141    }
142
143    /**
144     * Output proper way to call main() and exit with an error code.
145     */
146    private static void dieWithUsage() {
147        System.err.println("Usage: java " + Upload.class.getName() + " files...");
148        System.exit(1);
149    }
150}