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 */
023package dk.netarkivet.archive.checksum.distribute;
024
025import java.io.File;
026
027import org.slf4j.Logger;
028import org.slf4j.LoggerFactory;
029
030import dk.netarkivet.archive.distribute.ArchiveMessage;
031import dk.netarkivet.archive.distribute.ArchiveMessageVisitor;
032import dk.netarkivet.common.distribute.ChannelID;
033import dk.netarkivet.common.distribute.RemoteFile;
034import dk.netarkivet.common.distribute.RemoteFileFactory;
035import dk.netarkivet.common.exceptions.ArgumentNotValid;
036import dk.netarkivet.common.exceptions.IOFailure;
037
038/**
039 * The GetChecksumMessage has the purpose to retrieve the checksum of all the files. The output is in the form of a file
040 * corresponding to the reply file of a ChecksumJob.
041 * <p>
042 * This is checksum replica alternative to sending a ChecksumBatchJob.
043 */
044@SuppressWarnings({"serial"})
045public class GetAllChecksumsMessage extends ArchiveMessage {
046
047    private static final Logger log = LoggerFactory.getLogger(GetAllChecksumsMessage.class);
048
049    /** The file containing the output. */
050    private RemoteFile rf;
051    /** The id for the replica where this message should be sent. */
052    private String replicaId;
053
054    /**
055     * Constructor.
056     *
057     * @param to Where this message is headed.
058     * @param replyTo Where the reply on this message is sent.
059     * @param repId The replica where the job involved in this message is to be performed.
060     */
061    public GetAllChecksumsMessage(ChannelID to, ChannelID replyTo, String repId) {
062        super(to, replyTo);
063        this.replicaId = repId;
064    }
065
066    /**
067     * Method for setting the resulting file. This file will be retrieved from the caller of this message. This should
068     * be a movable instance since the temporary file should be removed after is has been retrieved.
069     * <p>
070     * TODO cleanup if remoteFile already has been set.
071     *
072     * @param file The file with the checksum message.
073     * @throws ArgumentNotValid If <b>file</b> is null.
074     */
075    public void setFile(File file) throws ArgumentNotValid {
076        ArgumentNotValid.checkNotNull(file, "File file");
077
078        rf = RemoteFileFactory.getMovefileInstance(file);
079    }
080
081    /**
082     * Method for retrieving the resulting file. This method can only be called once, since the remoteFile is cleaned up
083     * and set to null.
084     *
085     * @param toFile The file for the remotely retrieved content.
086     * @throws IOFailure If the data in the remoteFile already has be retrieved.
087     * @throws ArgumentNotValid If <b>toFile</b> is null.
088     */
089    public void getData(File toFile) throws IOFailure, ArgumentNotValid {
090        ArgumentNotValid.checkNotNull(toFile, "File toFile");
091        if (rf == null) {
092            throw new IOFailure("The remote file is not valid. Data cannot be retrieved.");
093        }
094        rf.copyTo(toFile);
095        try {
096            rf.cleanup();
097        } catch (IOFailure e) {
098            // Just log errors on deleting. They are fairly harmless.
099            // Can't make Logger a field, as this class is Serializable
100            log.warn("Could not delete remote file {}", rf.getName());
101        }
102        rf = null;
103    }
104
105    /**
106     * Method for retrieving the id for the replica where this message should be sent.
107     *
108     * @return The id for the replica.
109     */
110    public String getReplicaId() {
111        return replicaId;
112    }
113
114    /**
115     * Generate String representation of this object.
116     *
117     * @return String representation of this object
118     */
119    public String toString() {
120        return super.toString() + " replicaid: " + replicaId;
121    }
122
123    /**
124     * Accept visitation.
125     *
126     * @param v The ArchiveMessageVisitor which accepts this message.
127     */
128    public void accept(ArchiveMessageVisitor v) {
129        v.visit(this);
130    }
131
132}