All Downloads are FREE. Search and download functionalities are using the official Maven repository.

fluximpl.HttpFileTransferActionImpl Maven / Gradle / Ivy

The newest version!
package fluximpl;

import flux.EngineException;
import flux.FlowContext;
import flux.HttpFileTransferAction;

import java.io.*;
import java.net.URL;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.concurrent.TimeUnit;

/**
 * Implementation for HttpFileTransferAction.
 *
 * @author [email protected]
 */
public class HttpFileTransferActionImpl extends ActionImpl implements HttpFileTransferAction {
  private static final String ACTION_VARIABLE = "HTTP_FILE_TRANSFER_ACTION_VARIABLE";
  private static final int DEFAULT_BUFFER_SIZE = 1024 * 8;

  public HttpFileTransferActionImpl() {
    super(new FlowChartImpl(), "Http File Transfer Action");
  }

  public HttpFileTransferActionImpl(FlowChartImpl fc, String name) {
    super(fc, name);
  }

  public Set getHiddenVariableNames() {
    // The returned raw type is a Set of String.
    @SuppressWarnings("unchecked")
    Set set = super.getHiddenVariableNames();
    set.add(ACTION_VARIABLE);
    return set;
  }

  @Override
  public void setSource(String source) {
    HttpFileTransferActionVariable var = getVariable();
    var.setSource(source);
    putVariable(var);
  }

  public String getSource() {
    return getVariable().getSource();
  }

  @Override
  public void setDestination(String destination) {
    HttpFileTransferActionVariable var = getVariable();
    var.setDestination(destination);
    putVariable(var);
  }

  public String getDestination() {
    return getVariable().getDestination();
  }

  @Override
  public void verify() throws EngineException {
    if (StringUtil.isNullOrEmpty(getSource())) {
      throw new EngineException("Expected \"Source file\" to be non-null or non-empty, but it was null or empty.");
    } // if
    if (StringUtil.isNullOrEmpty(getDestination())) {
      throw new EngineException("Expected \"Destination file\" to be non-null or non-empty, but it was null or empty.");
    } // if
  }

  @Override
  public Object execute(FlowContext flowContext) throws Exception {
    URL url = new URL(getSource());
    String defaultFilename = null;
    StringTokenizer st = new StringTokenizer(url.getFile(), "/");
    while (st.hasMoreTokens())
      defaultFilename = st.nextToken();

    String destinationFilename = getDestinationFilename(getDestination());
    if (StringUtil.isNullOrEmpty(destinationFilename)) {
      destinationFilename = defaultFilename;
    }

    String destinationDirectory = getDestinationPath(getDestination());

    flowContext.getLogger().info("Transferring file " + destinationFilename + " to " + destinationDirectory);
    File file = new File(destinationDirectory);
    if (!file.exists()) {
      file.mkdirs();
    }
    long start = System.currentTimeMillis();
    OutputStream os = null;
    try {
      InputStream is = url.openStream();
      os = new FileOutputStream(destinationDirectory + File.separator + destinationFilename);
      int transferredBytes = transfer(is, os, DEFAULT_BUFFER_SIZE);
      long elapsed = (System.currentTimeMillis() - start);
      flowContext.getLogger().info("Transferred " + humanReadableBytes(transferredBytes, true) + " in " + humanReadableTime(elapsed));
    } finally {
      if (os != null) {
        os.close();
      }
    }
    return null;
  }

  /**
   * Utility from SOF http://stackoverflow.com/a/3758880/794988
   *
   * @param bytes Input in bytes
   * @param si    SI unit or Binary unit
   * @return Human readable format
   */
  private String humanReadableBytes(long bytes, boolean si) {
    int unit = si ? 1000 : 1024;
    if (bytes < unit) return bytes + " B";
    int exp = (int) (Math.log(bytes) / Math.log(unit));
    String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp - 1) + (si ? "" : "i");
    return String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre);
  }

  private String humanReadableTime(long millis) {
    return String.format("%d min, %d sec",
        TimeUnit.MILLISECONDS.toMinutes(millis),
        TimeUnit.MILLISECONDS.toSeconds(millis) -
        TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis))
    );
  }

  private String getDestinationFilename(String destinationFile) {
    return FilenameUtils.getName(destinationFile);
  }

  private String getDestinationPath(String destinationFile) {
    return FilenameUtils.getFullPath(destinationFile);
  }

  private int transfer(final InputStream input, final OutputStream output, int bufferSize)
      throws IOException {
    int avail = input.available();
    if (avail > 262144) {
      avail = 262144;
    }
    if (avail > bufferSize) {
      bufferSize = avail;
    }
    final byte[] buffer = new byte[bufferSize];
    int n = 0;
    n = input.read(buffer);
    int total = 0;
    while (-1 != n) {
      if (n == 0) {
        throw new IOException("0 bytes read in violation of InputStream.read(byte[])");
      }
      output.write(buffer, 0, n);
      total += n;
      n = input.read(buffer);
    }
    return total;
  }

  private HttpFileTransferActionVariable getVariable() {
    if (!getVariableManager().contains(ACTION_VARIABLE)) {
      getVariableManager().put(ACTION_VARIABLE, new HttpFileTransferActionVariable());
    }
    return (HttpFileTransferActionVariable) getVariableManager().get(ACTION_VARIABLE);
  }

  private void putVariable(HttpFileTransferActionVariable variable) {
    getVariableManager().put(ACTION_VARIABLE, variable);
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy