All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jivesoftware.smackx.filetransfer.StreamNegotiator Maven / Gradle / Ivy

Go to download

Smack is an Open Source XMPP (Jabber) client library for instant messaging and presence. This library provides the client side functionality as specified in the core XMPP specifications as related to the client side of said specifications.

The newest version!
/**
 * $RCSfile$
 * $Revision: $
 * $Date: $
 *
 * Copyright 2003-2006 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.PacketCollector;
import org.jivesoftware.smack.SmackConfiguration;
import org.jivesoftware.smack.Connection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.filter.PacketFilter;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.packet.XMPPError;
import org.jivesoftware.smackx.Form;
import org.jivesoftware.smackx.FormField;
import org.jivesoftware.smackx.packet.DataForm;
import org.jivesoftware.smackx.packet.StreamInitiation;

import java.io.InputStream;
import java.io.OutputStream;

/**
 * After the file transfer negotiation process is completed according to
 * JEP-0096, the negotiation process is passed off to a particular stream
 * negotiator. The stream negotiator will then negotiate the chosen stream and
 * return the stream to transfer the file.
 *
 * @author Alexander Wenckus
 */
public abstract class StreamNegotiator {

    /**
     * Creates the initiation acceptance packet to forward to the stream
     * initiator.
     *
     * @param streamInitiationOffer The offer from the stream initiator to connect for a stream.
     * @param namespaces            The namespace that relates to the accepted means of transfer.
     * @return The response to be forwarded to the initiator.
     */
    public StreamInitiation createInitiationAccept(
            StreamInitiation streamInitiationOffer, String[] namespaces)
    {
        StreamInitiation response = new StreamInitiation();
        response.setTo(streamInitiationOffer.getFrom());
        response.setFrom(streamInitiationOffer.getTo());
        response.setType(IQ.Type.RESULT);
        response.setPacketID(streamInitiationOffer.getPacketID());

        DataForm form = new DataForm(Form.TYPE_SUBMIT);
        FormField field = new FormField(
                FileTransferNegotiator.STREAM_DATA_FIELD_NAME);
        for (String namespace : namespaces) {
            field.addValue(namespace);
        }
        form.addField(field);

        response.setFeatureNegotiationForm(form);
        return response;
    }


    public IQ createError(String from, String to, String packetID, XMPPError xmppError) {
        IQ iq = FileTransferNegotiator.createIQ(packetID, to, from, IQ.Type.ERROR);
        iq.setError(xmppError);
        return iq;
    }

    Packet initiateIncomingStream(Connection connection, StreamInitiation initiation) throws XMPPException {
        StreamInitiation response = createInitiationAccept(initiation,
                getNamespaces());

        // establish collector to await response
        PacketCollector collector = connection
                .createPacketCollector(getInitiationPacketFilter(initiation.getFrom(), initiation.getSessionID()));
        connection.sendPacket(response);

        Packet streamMethodInitiation = collector
                .nextResult(SmackConfiguration.getPacketReplyTimeout());
        collector.cancel();
        if (streamMethodInitiation == null) {
            throw new XMPPException("No response from file transfer initiator");
        }

        return streamMethodInitiation;
    }

    /**
     * Returns the packet filter that will return the initiation packet for the appropriate stream
     * initiation.
     *
     * @param from     The initiator of the file transfer.
     * @param streamID The stream ID related to the transfer.
     * @return The PacketFilter that will return the packet relatable to the stream
     *         initiation.
     */
    public abstract PacketFilter getInitiationPacketFilter(String from, String streamID);


    abstract InputStream negotiateIncomingStream(Packet streamInitiation) throws XMPPException,
            InterruptedException;

    /**
     * This method handles the file stream download negotiation process. The
     * appropriate stream negotiator's initiate incoming stream is called after
     * an appropriate file transfer method is selected. The manager will respond
     * to the initiator with the selected means of transfer, then it will handle
     * any negotiation specific to the particular transfer method. This method
     * returns the InputStream, ready to transfer the file.
     *
     * @param initiation The initiation that triggered this download.
     * @return After the negotiation process is complete, the InputStream to
     *         write a file to is returned.
     * @throws XMPPException If an error occurs during this process an XMPPException is
     *                       thrown.
     * @throws InterruptedException If thread is interrupted.
     */
    public abstract InputStream createIncomingStream(StreamInitiation initiation)
            throws XMPPException, InterruptedException;

    /**
     * This method handles the file upload stream negotiation process. The
     * particular stream negotiator is determined during the file transfer
     * negotiation process. This method returns the OutputStream to transmit the
     * file to the remote user.
     *
     * @param streamID  The streamID that uniquely identifies the file transfer.
     * @param initiator The fully-qualified JID of the initiator of the file transfer.
     * @param target    The fully-qualified JID of the target or receiver of the file
     *                  transfer.
     * @return The negotiated stream ready for data.
     * @throws XMPPException If an error occurs during the negotiation process an
     *                       exception will be thrown.
     */
    public abstract OutputStream createOutgoingStream(String streamID,
            String initiator, String target) throws XMPPException;

    /**
     * Returns the XMPP namespace reserved for this particular type of file
     * transfer.
     *
     * @return Returns the XMPP namespace reserved for this particular type of
     *         file transfer.
     */
    public abstract String[] getNamespaces();

    /**
     * Cleanup any and all resources associated with this negotiator.
     */
    public abstract void cleanup();

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy