package au.edu.anu.dcclient.tasks; import static java.text.MessageFormat.*; import gov.loc.repository.bagit.Manifest.Algorithm; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.net.URI; import javax.ws.rs.core.MediaType; import org.apache.commons.io.IOUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import au.edu.anu.dcclient.progress.ProgressInputStream; import com.sun.jersey.api.client.ClientResponse; import com.sun.jersey.api.client.WebResource; public class UploadFileTask extends AbstractDcBagTask<ClientResponse, Void> { private static final Logger LOGGER = LoggerFactory.getLogger(UploadFileTask.class); protected final String pid; protected final String targetFilename; protected final File fileToUpload; public UploadFileTask(String pid, String targetFilename, File fileToUpload) { this.pid = pid; this.targetFilename = targetFilename; this.fileToUpload = fileToUpload; validateParameters(); } @Override protected ClientResponse doInBackground() throws Exception { ClientResponse resp; URI pidUri = getBagFileUri(pid, "data/" + targetFilename); LOGGER.debug("Uploading file to {}", pidUri.toString()); WebResource webResource = client.resource(pidUri); resp = uploadFile(webResource); return resp; } /** * Calculates Message Digest of file fileToUpload. * * @return Message Digest as String * @throws FileNotFoundException */ private String calcMd5() throws FileNotFoundException { CalcMessageDigestTask mdTask = new CalcMessageDigestTask(this.fileToUpload, Algorithm.MD5); mdTask.addPropertyChangeListener(new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { if ("progress".equals(evt.getPropertyName())) { setProgress((Integer) (evt.getNewValue()) / 2); } } }); String md5sum = mdTask.calcMd(); LOGGER.trace("{}, MD5: {}", fileToUpload.getAbsolutePath(), md5sum); return md5sum; } private ClientResponse uploadFile(WebResource webResource) throws FileNotFoundException { ClientResponse resp; ProgressInputStream fileStream = null; try { String md5sum = calcMd5(); fileStream = new ProgressInputStream(new FileInputStream(this.fileToUpload), this.fileToUpload.length()); fileStream.addPropertyChangeListener(new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { if (evt.getPropertyName() != null && evt.getPropertyName().equals("percentComplete")) { setProgress(50 + ((Integer) (evt.getNewValue()) / 2)); } } }); resp = webResource.type(MediaType.APPLICATION_OCTET_STREAM_TYPE).header("Content-MD5", md5sum) .post(ClientResponse.class, fileStream); } finally { IOUtils.closeQuietly(fileStream); } return resp; } /** * Checks if file to upload exists and is a single file. * * @throws IllegalArgumentException * if the file to upload doesn't exist or is not a file. */ private void validateParameters() { if (!fileToUpload.exists()) { throw new IllegalArgumentException(format("File {0} doesn't exist.", fileToUpload.getAbsolutePath())); } if (!fileToUpload.isFile()) { throw new IllegalArgumentException(format("{0} is not a file.", fileToUpload.getAbsolutePath())); } } }