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.bitarchive.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;
037import dk.netarkivet.common.utils.FileUtils;
038
039/**
040 * Message requesting a file to be removed and returned from a bitarchive. Messages is forwarded through arcrepository,
041 * but reponds directly to sender.
042 */
043@SuppressWarnings({"serial"})
044public class RemoveAndGetFileMessage extends ArchiveMessage {
045
046    private static final Logger log = LoggerFactory.getLogger(RemoveAndGetFileMessage.class);
047
048    /** The file to retrieve. */
049    private String fileName;
050    /** The actual data. */
051    private RemoteFile remoteFile;
052    /** This replica id. */
053    private String replicaId;
054
055    /** The checksum of the file to remove. */
056    private String checksum;
057
058    /** The bitarchive credentials. */
059    private String credentials;
060
061    /**
062     * Constructor.
063     *
064     * @param to Where to send the message.
065     * @param replyTo Where the reply of the message should be sent.
066     * @param fileName The name of the file to remove and retrieve.
067     * @param replicaId The id of the replica to sent it to.
068     * @param checksum The checksum of the bad file to remove and retrieve.
069     * @param credentials The right credentials for the operation.
070     */
071    public RemoveAndGetFileMessage(ChannelID to, ChannelID replyTo, String fileName, String replicaId, String checksum,
072            String credentials) {
073        super(to, replyTo);
074        this.fileName = fileName;
075        this.replicaId = replicaId;
076        this.checksum = checksum;
077        this.credentials = credentials;
078    }
079
080    /**
081     * Set the file this message should remove and return. Note: This will make a remote file handle for the file.
082     *
083     * @param data Content of the file to retrieve
084     * @throws ArgumentNotValid If the data file is null.
085     */
086    public void setFile(File data) throws ArgumentNotValid {
087        ArgumentNotValid.checkNotNull(data, "File data");
088
089        remoteFile = RemoteFileFactory.getCopyfileInstance(data);
090    }
091
092    /**
093     * Writes the the content of the retrieved file into a local file. Note: This is transferred through a remote file
094     * handle, and then the handle is invalidated. This method may only be called once.
095     *
096     * @return file content
097     * @throws IOFailure on error reading the file
098     */
099    public File getData() throws IOFailure {
100        // ensure that the remote file exists.
101        if (remoteFile == null) {
102            throw new IOFailure("No file present in message");
103        }
104        // Retrieve the remote file and put it into a temporary file.
105        File file = new File(FileUtils.getTempDir(), remoteFile.getName());
106        remoteFile.copyTo(file);
107        try {
108            remoteFile.cleanup();
109        } catch (IOFailure e) {
110            // Just log errors on deleting. They are fairly harmless.
111            // Note: Do not make a field of this logger, or if you do, remember
112            // to make it transient and reinitialise it in readObject
113            log.warn("Could not delete" + " remote file " + remoteFile.getName());
114        }
115        return file;
116    }
117
118    /**
119     * Returns the remote file.
120     *
121     * @return The remote file.
122     */
123    public RemoteFile getRemoteFile() {
124        return remoteFile;
125    }
126
127    /**
128     * Retrieve the replica id.
129     *
130     * @return replica id
131     */
132    public String getReplicaId() {
133        return replicaId;
134    }
135
136    /**
137     * Get name of the file to retrieve.
138     *
139     * @return file name
140     */
141    public String getFileName() {
142        return fileName;
143    }
144
145    /**
146     * Get the checksum of the file to remove.
147     *
148     * @return the checksum of the file to remove
149     */
150    public String getCheckSum() {
151        return checksum;
152    }
153
154    /**
155     * Get the credentials for the remove operation.
156     *
157     * @return the credentials for the remove operation
158     */
159    public String getCredentials() {
160        return credentials;
161    }
162
163    /**
164     * Clear content buffer.
165     */
166    public void clearBuffer() {
167        remoteFile = null;
168    }
169
170    /**
171     * Should be implemented as a part of the visitor pattern. fx.: public void accept(ArchiveMessageVisitor v) {
172     * v.visit(this); }
173     *
174     * @param v A message visitor
175     */
176    public void accept(ArchiveMessageVisitor v) {
177        v.visit(this);
178    }
179
180    /**
181     * Retrieval of a string representation of this instance.
182     *
183     * @return The string representation of this instance.
184     * @see dk.netarkivet.common.distribute.NetarkivetMessage#toString()
185     */
186    public String toString() {
187        return super.toString() + " file: " + fileName;
188    }
189
190}