Package org.eclipse.ecf.provider.filetransfer.browse

Source Code of org.eclipse.ecf.provider.filetransfer.browse.AbstractFileSystemBrowser$RemoteFileSystemRequest

/****************************************************************************
* Copyright (c) 2007, 2010 Composent, Inc., IBM and others.
* 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:
*    Composent, Inc. - initial API and implementation
*    Henrich Kraemer - bug 263613, [transport] Update site contacting / downloading is not cancelable
*****************************************************************************/

package org.eclipse.ecf.provider.filetransfer.browse;

import java.net.URL;
import java.util.Arrays;
import java.util.List;
import org.eclipse.core.net.proxy.IProxyData;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
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.IRemoteFileSystemRequest;
import org.eclipse.ecf.filetransfer.UserCancelledException;
import org.eclipse.ecf.filetransfer.events.IRemoteFileSystemBrowseEvent;
import org.eclipse.ecf.filetransfer.events.IRemoteFileSystemEvent;
import org.eclipse.ecf.filetransfer.identity.IFileID;
import org.eclipse.ecf.internal.provider.filetransfer.Activator;
import org.eclipse.ecf.internal.provider.filetransfer.Messages;
import org.eclipse.ecf.provider.filetransfer.util.ProxySetupHelper;

/**
* Abstract class for browsing an efs file system.
*/
public abstract class AbstractFileSystemBrowser {

  protected IFileID fileID = null;
  protected IRemoteFileSystemListener listener = null;

  private Exception exception = null;
  protected IRemoteFile[] remoteFiles = null;

  protected Proxy proxy;
  protected URL directoryOrFile;

  protected IConnectContext connectContext;

  protected DirectoryJob job = null;

  Object lock = new Object();

  protected class DirectoryJob extends Job {

    private IRemoteFileSystemRequest request;

    public DirectoryJob() {
      super(fileID.getName());
    }

    protected IStatus run(IProgressMonitor monitor) {
      try {
        if (monitor.isCanceled())
          throw newUserCancelledException();
        runRequest();
      } catch (Exception e) {
        AbstractFileSystemBrowser.this.setException(e);
      } finally {
        listener.handleRemoteFileEvent(createRemoteFileEvent());
        cleanUp();
      }
      return Status.OK_STATUS;
    }

    public void setRequest(IRemoteFileSystemRequest request) {
      this.request = request;
    }

    public IRemoteFileSystemRequest getRequest() {
      return request;
    }

    protected void canceling() {
      request.cancel();
    }

  }

  protected void cancel() {
    synchronized (lock) {
      if (job != null) {
        job.cancel();
      }
    }

  }

  protected void cleanUp() {
    synchronized (lock) {
      job = null;
    }
  }

  /**
   * Run the actual request.  This method is called within the job created to actually get the
   * directory or file information.
   * @throws Exception if some problem with making the request or receiving response to the request.
   */
  protected abstract void runRequest() throws Exception;

  public AbstractFileSystemBrowser(IFileID directoryOrFileID, IRemoteFileSystemListener listener, URL url, IConnectContext connectContext, Proxy proxy) {
    Assert.isNotNull(directoryOrFileID);
    this.fileID = directoryOrFileID;
    Assert.isNotNull(listener);
    this.listener = listener;
    this.directoryOrFile = url;
    this.connectContext = connectContext;
    this.proxy = proxy;
  }

  public abstract class RemoteFileSystemRequest implements IRemoteFileSystemRequest {
    public void cancel() {
      synchronized (lock) {
        if (job != null)
          job.cancel();
      }
    }

    public IFileID getFileID() {
      return fileID;
    }

    public IRemoteFileSystemListener getRemoteFileListener() {
      return listener;
    }

  }

  public IRemoteFileSystemRequest sendBrowseRequest() {
    job = new DirectoryJob();

    IRemoteFileSystemRequest request = createRemoteFileSystemRequest();
    job.setRequest(request);

    job.schedule();
    return request;
  }

  protected IRemoteFileSystemRequest createRemoteFileSystemRequest() {
    return new RemoteFileSystemRequest() {
      public Object getAdapter(Class adapter) {
        if (adapter == null) {
          return null;
        }
        if (adapter.isInstance(this)) {
          return this;
        }
        return null;
      }

    };
  }

  /**
   * @return file system directory event
   */
  protected IRemoteFileSystemEvent createRemoteFileEvent() {
    return new IRemoteFileSystemBrowseEvent() {

      public IFileID getFileID() {
        return fileID;
      }

      public Exception getException() {
        return exception;
      }

      public String toString() {
        StringBuffer buf = new StringBuffer("RemoteFileSystemBrowseEvent["); //$NON-NLS-1$
        buf.append("fileID=").append(fileID).append(";"); //$NON-NLS-1$ //$NON-NLS-2$
        List list = (remoteFiles != null) ? Arrays.asList(remoteFiles) : null;
        buf.append("files=").append(list).append("]"); //$NON-NLS-1$ //$NON-NLS-2$
        return buf.toString();
      }

      public IRemoteFile[] getRemoteFiles() {
        return remoteFiles;
      }
    };
  }

  protected abstract void setupProxy(Proxy proxy);

  /**
   * Select a single proxy from a set of proxies available for the given host.  This implementation
   * selects in the following manner:  1) If proxies provided is null or array of 0 length, null
   * is returned.  If only one proxy is available (array of length 1) then the entry is returned.
   * If proxies provided is length > 1, then if the type of a proxy in the array matches the given
   * protocol (e.g. http, https), then the first matching proxy is returned.  If the protocol does
   * not match any of the proxies, then the *first* proxy (i.e. proxies[0]) is returned.  Subclasses may
   * override if desired.
   *
   * @param protocol the target protocol (e.g. http, https, scp, etc).  Will not be <code>null</code>.
   * @param proxies the proxies to select from.  May be <code>null</code> or array of length 0.
   * @return proxy data selected from the proxies provided. 
   */
  protected IProxyData selectProxyFromProxies(String protocol, IProxyData[] proxies) {
    try {
      return ProxySetupHelper.selectProxyFromProxies(protocol, proxies);
    } catch (NoClassDefFoundError e) {
      // If the proxy API is not available a NoClassDefFoundError will be thrown here.
      // If that happens then we just want to continue on.
      Activator.logNoProxyWarning(e);
      return null;
    }
  }

  protected void setupProxies() {
    // If it's been set directly (via ECF API) then this overrides platform settings
    if (proxy == null) {
      try {
        proxy = ProxySetupHelper.getProxy(directoryOrFile.toExternalForm());
      } catch (NoClassDefFoundError e) {
        // If the proxy API is not available a NoClassDefFoundError will be thrown here.
        // If that happens then we just want to continue on.
        Activator.logNoProxyWarning(e);
      }
    }
    if (proxy != null)
      setupProxy(proxy);
  }

  protected synchronized void setException(Exception exception) {
    this.exception = exception;
  }

  protected synchronized Exception getException() {
    return this.exception;
  }

  protected synchronized boolean isCanceled() {
    return exception instanceof UserCancelledException;
  }

  protected synchronized void setCanceled(Exception e) {
    if (e instanceof UserCancelledException) {
      exception = e;
    } else {
      exception = newUserCancelledException();
    }
  }

  protected UserCancelledException newUserCancelledException() {
    return new UserCancelledException(Messages.AbstractRetrieveFileTransfer_Exception_User_Cancelled);
  }

}
TOP

Related Classes of org.eclipse.ecf.provider.filetransfer.browse.AbstractFileSystemBrowser$RemoteFileSystemRequest

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.