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;
037
038/**
039 * Message requesting a file from a bitarchive. Messages is forwarded through arcrepository, but reponds directly to
040 * sender.
041 */
042@SuppressWarnings({"serial"})
043public class GetFileMessage extends ArchiveMessage {
044
045    private static final Logger log = LoggerFactory.getLogger(GetFileMessage.class);
046
047    /** the file to retrieve. */
048    private String arcfileName;
049
050    /** The actual data. */
051    private RemoteFile remoteFile;
052    /** This replica id. */
053    private String replicaId;
054
055    /**
056     * Constructor for get file message.
057     *
058     * @param to Recipient
059     * @param replyTo Original sender
060     * @param arcfileName The file to retrieve
061     * @param replicaId The bitarchive replica id to retrieve it from.
062     */
063    public GetFileMessage(ChannelID to, ChannelID replyTo, String arcfileName, String replicaId) {
064        super(to, replyTo);
065        this.arcfileName = arcfileName;
066        this.replicaId = replicaId;
067    }
068
069    /**
070     * Set the file this message should return. Note: This will make a remote file handle fopr the file.
071     *
072     * @param data Content of the file to retrieve
073     */
074    public void setFile(File data) {
075        remoteFile = RemoteFileFactory.getCopyfileInstance(data);
076    }
077
078    /**
079     * Writes the the content of the retrieved file into a local file. Note: This is transferred through a remote file
080     * handle, and then the handle is invalidated. This method may only be called once.
081     *
082     * @param toFile where to write the content
083     * @throws IOFailure on error reading the remote file or writing the local file
084     * @throws ArgumentNotValid If the file is null.
085     */
086    public void getData(File toFile) throws ArgumentNotValid, IOFailure {
087        ArgumentNotValid.checkNotNull(toFile, "toFile");
088        if (remoteFile == null) {
089            throw new IOFailure("No file present in message to get file '" + arcfileName + "'");
090        }
091        remoteFile.copyTo(toFile);
092        try {
093            remoteFile.cleanup();
094        } catch (IOFailure e) {
095            // Just log errors on deleting. They are fairly harmless.
096            // Can't make Logger a field, as this class is Serializable
097            log.warn("Could not delete remote file {}", remoteFile.getName());
098        }
099        remoteFile = null;
100    }
101
102    /**
103     * Retrieve the replica id.
104     *
105     * @return replica id
106     */
107    public String getReplicaId() {
108        return replicaId;
109    }
110
111    /**
112     * Get name of the file to retrieve.
113     *
114     * @return file name
115     */
116    public String getArcfileName() {
117        return arcfileName;
118    }
119
120    /**
121     * Clear content buffer.
122     */
123    public void clearBuffer() {
124        remoteFile = null;
125    }
126
127    /**
128     * Should be implemented as a part of the visitor pattern. fx.: public void accept(ArchiveMessageVisitor v) {
129     * v.visit(this); }
130     *
131     * @param v A message visitor
132     */
133    public void accept(ArchiveMessageVisitor v) {
134        v.visit(this);
135    }
136
137    /**
138     * Retrieval of a string representation of this instance.
139     *
140     * @return The string representing this instance.
141     * @see dk.netarkivet.common.distribute.NetarkivetMessage#toString()
142     */
143    public String toString() {
144        return super.toString() + " Arcfile: " + arcfileName;
145    }
146
147}