Package org.jivesoftware.smackx.filetransfer

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

/**
* $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 org.jivesoftware.smack.*;
import org.jivesoftware.smack.packet.*;
import org.jivesoftware.smack.filter.PacketFilter;
import org.jivesoftware.smack.filter.PacketTypeFilter;
import org.jivesoftware.smackx.packet.*;
import java.io.*;
import java.util.*;
import java.security.*;

/**

* Manages sending and receiving files.
* <br>
* Socks5 and IBB are supported.<br>
* Socks5 bytestreams are preferred over IBB because they are faster and create less
* traffic on the server.
* <br><br>
* An example for receiving a file:<br>
* <pre>
*
* FileTransferManager ft = new FileTransferManager(connection);
* ft.addFileReceiveListener(new ReceiveListener()
* {
*   public void receiveFile(FileReceive r)
*     {
*     try {
*       r.save(new File(r.getName()));
*     }
*     catch(XMPPException e)
*     {
*       // error receiving file
*     }
*     catch(IOException e)
*     {
*       // error saving file
*     }
*
*     // Optionally, you can reject the file by using r.reject();
*   }
* } );
*
* </pre>
* <br>
* And an example sending a file:
* <br>
* <pre>
* FileTransferManager ft = new FileTransferManager(connection);
* try {
*   ft.getFileSend(new File("somefile"), "This is a nice file").send("user@host");
* }
* catch(XMPPException e) {
*   // error sending file
* }
* catch(IOException e)
* {
*   // error reading file
* }
* </pre>
*/
public class FileTransferManager {
    protected XMPPConnection connection;
    private ArrayList receiveListeners = new ArrayList();
    private int timeout = 90000;
    private ArrayList hosts = new ArrayList();

    /**
     * Used when sending via Socks5
     */
    public static final int TYPE_SOCKS5 = 1;

    /**
     * Used when sending via IBB
    */
    public static final int TYPE_IBB = 2;
   
    private int preferred = -1;

    /**
     * Creates an instance of FileTransferManager.
     *
     * @param connection The connection associated with this manager
     */
    public FileTransferManager(XMPPConnection connection) {
        this.setConnection(connection);
        PacketFilter filter = new PacketTypeFilter(StreamInitiation.class);
        connection.addPacketListener(new InitiationListener(), filter);
    }

    /**
     * Sets the timeout for file transfers.  Default is 90 seconds.
     * We don't use Smack's packet timeout settings because file transfers
     * usually require higher timeout values
     * @param timeout  The time, in milleseconds, before it times out
     */
    public void setTimeout(int timeout) {
        this.timeout = timeout;
    }
   
    /**
     * Returns the preferred type, or -1 if it doesn't matter
     * @return the preferred type
    */
    public int getPreferredType() { return preferred; }
   
    /**
     * Sets the preferred transfer type
     * @param type  The preferred transfer type, or -1 if it doesn't matter
    */
    public void setPreferredType(int type) { this.preferred = type; }

    /**
     * Adds a possible streamhost to be use for bytestreams
     *
     *@param host   The new streamhost in the format "host:port"
     */
    public synchronized void addStreamHost(String host) {
        hosts.add(host);
    }
   
    /**
     * Clears the current proxy hosts
    */
    public void clearHosts()
    {
        hosts.clear();
    }

    /**
     * Removes a streamhost
     *
     *@param host   The host to remove
     */
    public synchronized void removeStreamHost(String host) {
        for(int i = 0; i < hosts.size(); i++)
        {
            String h = (String)hosts.get(i);
            if(host.equals(h))
            {
                hosts.remove(i);
                break;
            }
        }
    }

    /**
     * Returns a list of useable streamhosts
     *@return ArrayList of useable streamhosts
     */
    public synchronized ArrayList getStreamHosts() { return hosts; }

    public int getTimeout() { return timeout; }

    /**
     * Adds a receive listener that will be called when a file request is received
     *
     * @param listener a listener interested in receiving file requests
     */
    public void addFileReceiveListener(FileReceiveListener listener) {
        receiveListeners.add(listener);
    }

    /**
     * Returns the SHA-1 digest of a given string
     *@param string The string to hash
     *@return the SHA-1 hash of the given string
     */
    public static String getDigest(String string) {

        MessageDigest sha=null;
        try {
            sha = MessageDigest.getInstance("SHA");
            sha.update(string.getBytes());
        } catch (NoSuchAlgorithmException e) {
        }

        return stringValue(sha.digest());
    }

    /**
     * Returns a HEX String representation of a byte array
     *@param bytes    The bytes to convert
     *@return the converted String
     */
    private static String stringValue(byte[] bytes) {
        StringBuffer b = new StringBuffer(bytes.length * 2);

        for(int i = 0; i < bytes.length; i++) {
            int h = bytes[i];
            if (h < 0) h = 256 + h;
            if (h >=16) b.append(Integer.toHexString(h));
            else {
                b.append('0');
                b.append(Integer.toHexString(h));
            }
        }
        return b.toString().toLowerCase();
    }


    /**
     * Listens for stream initiation events
     * @author Adam Olsen
     */
    class InitiationListener extends StreamInitiationListener {

        public void processPacket(Packet packet) {

            StreamInitiation si = (StreamInitiation) packet;
            StreamInitiation.Feature feature = si.getFeature();
            if(!feature.providesIBBOption() && !feature.providesBytestreamOption()) {
                StreamInitiation iq = si.createConfirmationMessage(preferred);
                iq.setType(IQ.Type.ERROR);
                iq.setError(new XMPPError(501));
                connection.sendPacket(iq);

                return;
            }

            if (si.getType() == IQ.Type.SET) {
                FileReceive receive = new FileReceive(FileTransferManager.this, si);
                for (int i = 0; i < receiveListeners.size(); i++) {
                    FileReceiveListener l = (FileReceiveListener) receiveListeners.get(i);
                    l.receiveFile(receive);
                }
            }
        }
    }

    /**
     * Returns a FileSend request instance
     *
     * @param file the file you want to send
     * @param desc the description of the file
     */
    public FileSend getFileSend(File file, String desc)
    throws IOException, XMPPException {
        FileSend send = new FileSend(this, file, desc);
        return send;
    }

    public FileSend getFileSend(InputStream stream, String name,
    String desc, long size)
    throws IOException, XMPPException {
        FileSend send = new FileSend(this, stream, name, desc, size);
        return send;
    }


    /**
     *  Sends progress updates to all interested listeners
     *
     *@param  event      The type of event
     *@param  listeners  the interested listeners
     *@param  percent    percent complete
     *@param  bytes     Number of bytes transferred
     */
    static void update(String event, ArrayList listeners, double percent, long bytes) {

        for (int i = 0; i < listeners.size(); i++) {
            FileProgressListener listener = (FileProgressListener) listeners.get(i);
            listener.update(event, (int)(percent*100), bytes);
        }
    }


    /**
     *  Various events that can be sent to progress listeners
     */
    public static class Event {
        /**
         *  Used when the connection is being made
         */
        public final static String CONNECTING = "Connecting";
        /**
         *  Used when data is being transferred
         */
        public final static String TRANSFERRING = "Transferring";
        /**
         *  Used when the transfer has completed
         */
        public final static String DONE = "Done";

        /**
         * Used when an error occurs during transfer or connect
         */
        public final static String ERROR = "Error";
       
        /**
         * Used when the transfer has been cancelled
         */
        public final static String CANCELLED = "Cancelled";       
    }

    protected XMPPConnection getConnection() {
        return connection;
    }

    protected void setConnection(XMPPConnection connection) {
        this.connection = connection;
    }
}
TOP

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

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.