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

Source Code of org.eclipse.ecf.internal.provider.xmpp.filetransfer.XMPPOutgoingFileTransfer

/****************************************************************************
* Copyright (c) 2004 Composent, Inc. 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
*****************************************************************************/
package org.eclipse.ecf.internal.provider.xmpp.filetransfer;

import java.io.File;
import java.io.FileInputStream;
import org.eclipse.core.runtime.IAdapterManager;
import org.eclipse.ecf.core.identity.ID;
import org.eclipse.ecf.core.identity.IDCreateException;
import org.eclipse.ecf.core.identity.IDFactory;
import org.eclipse.ecf.filetransfer.FileTransferJob;
import org.eclipse.ecf.filetransfer.IFileTransferInfo;
import org.eclipse.ecf.filetransfer.IFileTransferListener;
import org.eclipse.ecf.filetransfer.IOutgoingFileTransfer;
import org.eclipse.ecf.filetransfer.UserCancelledException;
import org.eclipse.ecf.filetransfer.events.IFileTransferEvent;
import org.eclipse.ecf.filetransfer.events.IOutgoingFileTransferResponseEvent;
import org.eclipse.ecf.filetransfer.events.IOutgoingFileTransferSendDoneEvent;
import org.eclipse.ecf.internal.provider.xmpp.XmppPlugin;
import org.eclipse.ecf.provider.xmpp.identity.XMPPID;
import org.eclipse.osgi.util.NLS;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smackx.filetransfer.FileTransfer;
import org.jivesoftware.smackx.filetransfer.FileTransfer.Status;
import org.jivesoftware.smackx.filetransfer.FileTransferManager;
import org.jivesoftware.smackx.filetransfer.OutgoingFileTransfer;

public class XMPPOutgoingFileTransfer implements IOutgoingFileTransfer {

  private final ID sessionID;
  private final XMPPID remoteTarget;
  private final IFileTransferListener listener;

  private File localFile;

  private long fileSize;

  private final OutgoingFileTransfer outgoingFileTransfer;

  private Status status;

  private Exception exception;

  private int originalOutputRequestTimeout = -1;

  private boolean localCancelled = false;

  public XMPPOutgoingFileTransfer(FileTransferManager manager,
      XMPPID remoteTarget, IFileTransferInfo fileTransferInfo,
      IFileTransferListener listener, int outgoingRequestTimeout) {
    this.remoteTarget = remoteTarget;
    this.listener = listener;
    this.sessionID = createSessionID();
    final String fullyQualifiedName = remoteTarget.getFQName();
    // Set request timeout if we have a new value
    if (outgoingRequestTimeout != -1) {
      originalOutputRequestTimeout = OutgoingFileTransfer
          .getResponseTimeout();
      OutgoingFileTransfer.setResponseTimeout(outgoingRequestTimeout);
    }
    outgoingFileTransfer = manager
        .createOutgoingFileTransfer(fullyQualifiedName);
  }

  private ID createSessionID() {
    try {
      return IDFactory.getDefault().createGUID();
    } catch (final IDCreateException e) {
      throw new NullPointerException(
          "cannot create id for XMPPOutgoingFileTransfer"); //$NON-NLS-1$
    }
  }

  public synchronized ID getRemoteTargetID() {
    return remoteTarget;
  }

  public ID getID() {
    return sessionID;
  }

  private void fireTransferListenerEvent(IFileTransferEvent event) {
    listener.handleTransferEvent(event);
  }

  private void setStatus(Status s) {
    this.status = s;
  }

  private void setException(Exception e) {
    this.exception = e;
  }

  private Status getStatus() {
    return this.status;
  }

  private void setErrorStatus(Exception e) {
    setStatus(FileTransfer.Status.error);
    setException(e);
  }

  public synchronized void startSend(File localFile, String description)
      throws XMPPException {
    this.localFile = localFile;
    this.fileSize = localFile.length();
    setStatus(Status.initial);

    outgoingFileTransfer.sendFile(localFile, description);

    final Thread transferThread = new Thread(new Runnable() {
      public void run() {
        setStatus(outgoingFileTransfer.getStatus());
        boolean negotiation = true;
        try {
          while (negotiation && !localCancelled) {
            // check the state of the progress
            try {
              Thread.sleep(300);
            } catch (final InterruptedException e) {
              setErrorStatus(e);
              return;
            }
            final Status s = outgoingFileTransfer.getStatus();
            setStatus(s);
            final boolean negotiated = getStatus().equals(
                Status.negotiated);
            if (s.equals(Status.negotiated)
                || s.equals(Status.cancelled)
                || s.equals(Status.complete)
                || s.equals(Status.error)
                || s.equals(Status.refused)) {
              fireTransferListenerEvent(new IOutgoingFileTransferResponseEvent() {
                public boolean requestAccepted() {
                  return negotiated;
                }

                public IOutgoingFileTransfer getSource() {
                  return XMPPOutgoingFileTransfer.this;
                }

                public String toString() {
                  final StringBuffer buf = new StringBuffer(
                      "OutgoingFileTransferResponseEvent["); //$NON-NLS-1$
                  buf.append("requestAccepted=").append(requestAccepted()).append("]"); //$NON-NLS-1$ //$NON-NLS-2$
                  return buf.toString();
                }

                public void setFileTransferJob(
                    FileTransferJob job) {
                  // does nothing with this implementation
                }
              });
              // And negotiation is over
              negotiation = false;
            }
          }

          if (localCancelled) {
            setErrorStatus(new UserCancelledException(
                "Transfer cancelled by sender")); //$NON-NLS-1$
            return;
          }

          outgoingFileTransfer.sendStream(new FileInputStream(
              XMPPOutgoingFileTransfer.this.localFile),
              XMPPOutgoingFileTransfer.this.localFile.getName(),
              fileSize, "Ein File");
          setStatus(Status.complete);
        } catch (final Exception e) {
          setStatus(FileTransfer.Status.error);
          setException(e);
        } finally {
          // Reset request timeout
          if (originalOutputRequestTimeout != -1) {
            OutgoingFileTransfer
                .setResponseTimeout(originalOutputRequestTimeout);
          }
          // Then notify that the sending is done
          fireTransferListenerEvent(new IOutgoingFileTransferSendDoneEvent() {
            public IOutgoingFileTransfer getSource() {
              return XMPPOutgoingFileTransfer.this;
            }

            public String toString() {
              final StringBuffer buf = new StringBuffer(
                  "IOutgoingFileTransferSendDoneEvent["); //$NON-NLS-1$
              buf.append("isDone=" + getSource().isDone()); //$NON-NLS-1$
              buf.append(";bytesSent=").append(getSource().getBytesSent()); //$NON-NLS-1$
              buf.append(";exception=").append(getException()).append("]"); //$NON-NLS-1$ //$NON-NLS-2$
              return buf.toString();
            }
          });
        }
      }
    }, NLS.bind("XMPP send {0}", remoteTarget.toExternalForm())); //$NON-NLS-1$

    transferThread.start();
  }

  public synchronized void cancel() {
    localCancelled = true;
  }

  public synchronized File getLocalFile() {
    return localFile;
  }

  /*
   * (non-Javadoc)
   *
   * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
   */
  public Object getAdapter(Class adapter) {
    if (adapter == null)
      return null;
    if (adapter.isInstance(this))
      return this;
    final IAdapterManager adapterManager = XmppPlugin.getDefault()
        .getAdapterManager();
    return (adapterManager == null) ? null : adapterManager.loadAdapter(
        this, adapter.getName());
  }

  public long getBytesSent() {
    return outgoingFileTransfer.getBytesSent();
  }

  public Exception getException() {
    return exception;
  }

  public double getPercentComplete() {
    return (fileSize <= 0) ? 1.0 : (((double) outgoingFileTransfer
        .getAmountWritten()) / ((double) fileSize));
  }

  public boolean isDone() {
    return status == Status.cancelled || status == Status.error
        || status == Status.complete;
  }

  public ID getSessionID() {
    return sessionID;
  }

  /*
   * (non-Javadoc)
   *
   * @see org.eclipse.ecf.filetransfer.IFileTransfer#getFileLength()
   */
  public long getFileLength() {
    return fileSize;
  }

}
TOP

Related Classes of org.eclipse.ecf.internal.provider.xmpp.filetransfer.XMPPOutgoingFileTransfer

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.