Package org.eclipse.ecf.internal.provider.filetransfer.scp

Source Code of org.eclipse.ecf.internal.provider.filetransfer.scp.ScpFileSystemBrowser

/*******************************************************************************
* Copyright (c) 2014 CohesionForce Inc
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*     CohesionForce Inc - initial API and implementation
*******************************************************************************/

package org.eclipse.ecf.internal.provider.filetransfer.scp;

import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.Session;
import java.io.*;
import java.net.*;
import java.util.*;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.ecf.core.identity.IDFactory;
import org.eclipse.ecf.core.security.IConnectContext;
import org.eclipse.ecf.core.util.Proxy;
import org.eclipse.ecf.filetransfer.IRemoteFile;
import org.eclipse.ecf.filetransfer.IRemoteFileSystemListener;
import org.eclipse.ecf.filetransfer.identity.*;
import org.eclipse.ecf.provider.filetransfer.browse.AbstractFileSystemBrowser;
import org.eclipse.ecf.provider.filetransfer.browse.URLRemoteFile;
import org.eclipse.ecf.provider.filetransfer.identity.FileTransferNamespace;

/**
* The ScpFileSystemBrowser uses the JCraft JSch package to run remote commands
* using SSH to list files in a directory.
*
*/
public class ScpFileSystemBrowser extends AbstractFileSystemBrowser implements
    IScpFileTransfer {

  protected InputStream inputStream;

  protected OutputStream outputStream;

  protected ScpUtil scpUtil;

  protected ChannelExec channel;
  protected String username;

  protected static final String SCP_EXEC = System.getProperty(
      "org.eclipse.ecf.filetransfer.scp.filebrowse.exec", "exec"); //$NON-NLS-1$
  protected static final String LS_START_COMMAND = System.getProperty(
      "org.eclipse.ecf.filetransfer.scp.filebrowse.lscommand.start",
      "IFS=\"$(printf '\n\t\')\"; shopt -s dotglob; for file in "); //$NON-NLS-1$; //$NON-NLS-1$
  protected static final String LS_END_COMMAND = System.getProperty(
      "org.eclipse.ecf.filetransfer.scp.filebrowse.lscommand.end",
      "/*; do stat --format='%F|%s|%Y|%n' $file; done "); //$NON-NLS-1$; //$NON-NLS-1$

  /**
   * Constructor for creating a ScpFileSystemBrowser.
   *
   * @param directoryOrFileID
   *            - ID of the remote location to browse
   * @param listener
   *            - will be called asynchronously with events resulting from
   *            file browsing.
   * @param url
   *            - URL of the parent directory to browse.
   * @param connectContext
   *            - contains username/password to use for the ssh connection
   * @param proxy
   *            - proxy to be used if set.
   */
  public ScpFileSystemBrowser(IFileID directoryOrFileID,
      IRemoteFileSystemListener listener, URL url,
      IConnectContext connectContext, Proxy proxy) {
    super(directoryOrFileID, listener, url, connectContext, proxy);
    username = directoryOrFile.getUserInfo();
  }

  /**
   * Method called from super class to build the list of remote files.
   */
  protected void runRequest() throws Exception {
    scpUtil = new ScpUtil(this);
    final Session s = scpUtil.getSession();
    s.connect();
    if (s.isConnected()) {
      final String targetFileName = scpUtil
          .trimTargetFile(directoryOrFile.getPath());
      final String command = LS_START_COMMAND + targetFileName
          + LS_END_COMMAND;
      channel = (ChannelExec) s.openChannel(SCP_EXEC);
      channel.setCommand(command);
      final OutputStream outs = channel.getOutputStream();
      inputStream = channel.getInputStream();
      channel.connect();

      setOutputStream(outs);

      BufferedReader reader = new BufferedReader(new InputStreamReader(
          inputStream));
      String line = reader.readLine();
      ArrayList strings = new ArrayList();
      while (line != null) {
        strings.add(line);
        line = reader.readLine();
      }
      List remoteFilesList = new ArrayList();
      for (int i = 0; i < strings.size(); i++) {
        try {
          remoteFilesList.add(createRemoteFile((String) strings
              .get(i)));
        } catch (Exception e) {
          Activator
              .getDefault()
              .log(new Status(
                  IStatus.ERROR,
                  Activator.PLUGIN_ID,
                  IStatus.ERROR,
                  "SCPFileBrowser could not convert string '" + ((String) strings.get(i)) + "' to FileID", e)); //$NON-NLS-1$
        }
      }
      remoteFiles = (IRemoteFile[]) remoteFilesList
          .toArray(new IRemoteFile[remoteFilesList.size()]);
    }
  }

  private IRemoteFile createRemoteFile(String string)
      throws URISyntaxException, FileCreateException, SecurityException {
    URLRemoteFile file = null;
    IFileID id = null;
    String[] parts = string.split("\\|");

    // Check to see if this string can be parsed
    if (parts.length < 4) {
      id = FileIDFactory.getDefault().createFileID(
          IDFactory.getDefault().getNamespaceByName(
              FileTransferNamespace.PROTOCOL), "scp://unknown");
      file = new URLRemoteFile(0, 0, id);
    } else {

      // Build the filename back up, since the filename may also contain
      // "|"
      // characters
      StringBuilder builder = new StringBuilder("scp://");
      for (int i = 3; i < parts.length; i++) {
        builder.append(parts[i]);

        // Put the | back into the name
        if (i > 3 && i < parts.length - 1) {
          builder.append("|");
        }
      }

      // If it's a directory, then make sure it ends with /
      if (parts[0].equals("directory")
          && !builder.toString().endsWith("/")) {
        builder.append("/");
      } else if (!parts[0].equals("directory")
          && builder.toString().endsWith("/")) {
        builder.deleteCharAt(builder.length() - 1);
      }

      String originalName = builder.toString();
      String formatedName = originalName.replace(" ", "%20");
      URI uri = new URI(formatedName);

      // Create the FileID
      id = FileIDFactory.getDefault().createFileID(
          IDFactory.getDefault().getNamespaceByName(
              FileTransferNamespace.PROTOCOL),
          new Object[] { uri });
      long size = Long.parseLong(parts[1]);
      long modification = Long.parseLong(parts[2]);
      file = new URLRemoteFile(modification, size, id);
    }
    return file;
  }

  protected void cleanUp() {
    super.cleanUp();
    if (channel != null) {
      channel.disconnect();
      channel = null;
    }
    if (scpUtil != null) {
      scpUtil.dispose();
      scpUtil = null;
    }
    try {
      if (inputStream != null)
        inputStream.close();
    } catch (final IOException e) {
      Activator.getDefault().log(
          new Status(IStatus.ERROR, Activator.PLUGIN_ID,
              IStatus.ERROR, "cleanup", e)); //$NON-NLS-1$
    }
    try {
      if (outputStream != null)
        outputStream.close();
    } catch (final IOException e) {
      Activator.getDefault().log(
          new Status(IStatus.ERROR, Activator.PLUGIN_ID,
              IStatus.ERROR, "cleanup", e)); //$NON-NLS-1$
    }
    inputStream = null;
    outputStream = null;
  }

  protected void setupProxy(Proxy proxy) {
    this.proxy = proxy;
    this.setupProxies();
  }

  protected void setInputStream(InputStream ins) {
    inputStream = ins;
  }

  protected void setOutputStream(OutputStream outs) {
    outputStream = outs;
  }

  public IConnectContext getConnectContext() {
    return connectContext;
  }

  public String getUsername() {
    return username;
  }

  public void setUsername(String username) {
    this.username = username;
  }

  public Proxy getProxy() {
    return proxy;
  }

  public URL getTargetURL() {
    return directoryOrFile;
  }

  public Map getOptions() {
    return null;
  }

}
TOP

Related Classes of org.eclipse.ecf.internal.provider.filetransfer.scp.ScpFileSystemBrowser

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.