Package org.jivesoftware.smackx.filetransfer

Source Code of org.jivesoftware.smackx.filetransfer.IBBSend

/**
* $RCSfile$
* $Revision: 2495 $
* $Date: 2005-05-30 10:14:25 -0500 (Mon, 30 May 2005) $
*
* Copyright 2003-2004 Jive Software.
*
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.jivesoftware.smackx.filetransfer;

import java.io.*;
import org.jivesoftware.smack.*;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.filter.*;
import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smackx.packet.*;
import org.jivesoftware.smack.packet.*;
import java.util.*;

/**
*  Provides a method to send IBB data
*
*@author    Adam Olsen
*/
public class IBBSend extends FileTransfer {
    private FileSend send = null;
    private InputStream stream = null;
    private XMPPConnection connection;
    private String sid = null;
    private boolean ft = false;
    private IBBOpen request = null;
    private long total = 0;
    private long totalBytes = 0;
    private ArrayList progress = new ArrayList();
    private boolean cancelled = false;


    /**
     *  Constructer used when using IBB to send a file
     *
     *@param  send    The FileSend wrapper of this stream
     *@param  stream  The stream to read from
     */
    public IBBSend(FileSend send, InputStream stream) {
        this.send = send;
        this.stream = stream;
        this.total = send.getSize();
        this.connection = send.getManager().getConnection();
        this.sid = send.getSI().getSid();
        ft = true;
    }


    /**
     *  Constructer used when you want to make a standalone IBB stream
     *
     *@param  connection  The connection to use for this stream
     *@param  req         The request to use for this stream
     */
    public IBBSend(XMPPConnection connection, IBBOpen req) {
        this.connection = connection;
        this.request = req;
        this.sid = req.getSid();

    }

    /**
     * Cancels the transfer
    */
    public void cancel() { cancelled = true; }

    /**
     *  Sets the progress listeners interested in the progress of this stream
     *
     *@param  list  The listeners interested in this stream
     */
    void setProgressListeners(ArrayList list) {
        this.progress = list;
    }


    /**
     *  Reads a chunk of data from the input stream and base64 encodes it
     *
     *@return                  Description of the Return Value
     *@throws  IOException  Description of the Exception
     */
    private IBBChunk readChunk() throws IOException {
        byte buf[] = new byte[4096];
        int read = 0;

        if ((read = stream.read(buf)) == -1) {
            return null;
        }

        totalBytes += read;
        if (ft) {
            FileTransferManager.update(FileTransferManager.Event.TRANSFERRING,
            progress, (float) totalBytes / (float) total, totalBytes);
        }

        if (read != 4096) {
            byte n[] = new byte[read];
            for (int i = 0; i < read; i++) {
                n[i] = buf[i];
            }

            buf = n;
        }

        IBBChunk chunk = new IBBChunk();
        chunk.setData(new String(StringUtils.encodeBase64(buf)));

        return chunk;
    }


    /**
     *  Use this method to send the stream when you are using standalone IBB. It
     *  will be sent to the person in the "to" field of the IBB request
     *
     *@throws  IOException    When an error reading the InputStream occurs
     *@throws  XMPPException  When an error sending occurs
     */
    public void send() throws IOException, XMPPException {
        send(request.getTo());
    }


    /**
     *  Sends the file to the specified recipient
     *
     *@param  to              The JID of the person you want to send the file
     *@throws  IOException    When an error reading the InputStream occurs
     *@throws  XMPPException  When an error sending occurs
     */
    public void send(String to) throws IOException, XMPPException {
        if (request == null) {
            request = new IBBOpen();
            request.setType(IQ.Type.SET);
            request.setSid(sid);
            request.setFrom(connection.getUser());
        }

        int timeout = SmackConfiguration.getPacketReplyTimeout();
        if (ft) {
            timeout = send.getManager().getTimeout();
        }

        request.setTo(to);

        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(request.getPacketID()));
        connection.sendPacket(request);

        IQ result = (IQ) collector.nextResult(timeout);
        collector.cancel();

        if (result == null || result.getType() == IQ.Type.ERROR) {
            if(result != null && result.getError() != null) {
                throw new XMPPException(result.getError());
            }
            throw new XMPPException("File transfer could not be initiated.");
        }

        IBBChunk chunk = null;
        int seq = 0;
        while ((chunk = readChunk()) != null) {
            if (seq > 65535) {
                seq = 0;
            }

            Message m = new Message(to);
            m.setFrom(connection.getUser());

            if(cancelled)
            {
                if(ft)
                {
                    FileTransferManager.update(FileTransferManager.Event.CANCELLED, progress,
                        (float) totalBytes / (float) total, totalBytes);
                }

                m.setError(new XMPPError(403, "Cancelled"));
                stream.close();
                connection.sendPacket(m);
                return;
            }

            m.addExtension(chunk);
            chunk.setSid(sid);
            chunk.setSeq(seq);

            connection.sendPacket(m);
            seq++;
        }

        IBBClose close = new IBBClose();
        close.setTo(to);
        close.setType(IQ.Type.SET);
        close.setFrom(connection.getUser());
        close.setSid(sid);

        connection.sendPacket(close);
        if (ft) {
            FileTransferManager.update(FileTransferManager.Event.DONE, progress, 1, totalBytes);
        }
    }
}
TOP

Related Classes of org.jivesoftware.smackx.filetransfer.IBBSend

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.