Package net.sf.jml.message.p2p

Source Code of net.sf.jml.message.p2p.FileTransferWorker

/*
* Copyright 2004-2005 the original author or authors.
*
* 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 net.sf.jml.message.p2p;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.ByteBuffer;
import net.sf.jml.MsnFileTransferState;
import net.sf.jml.MsnSwitchboard;
import net.sf.jml.impl.AbstractMessenger;
import net.sf.jml.impl.MsnFileTransferImpl;
import net.sf.jml.protocol.MsnIncomingMessage;
import net.sf.jml.protocol.MsnSession;
import net.sf.jml.protocol.msnslp.MsnslpMessage;
import net.sf.jml.protocol.msnslp.MsnslpRequest;
import net.sf.jml.protocol.msnslp.MsnslpResponse;
import net.sf.jml.protocol.outgoing.OutgoingMSG;
import net.sf.jml.util.Charset;
import net.sf.jml.util.JmlConstants;
import net.sf.jml.util.NumberUtils;
import net.sf.jml.util.StringHolder;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.logging.Log;

/**
* Manages start and stopping filetransfers. Also sending filetransfers.
* @author Damian Minkov
*/
public class FileTransferWorker
{
    private static final Log logger =
        LogFactory.getLog(FileTransferWorker.class);

    private MsnFileTransferImpl fileTransfer;

    /**
   * Base identifier for the messages.
   */
  private int baseId = NumberUtils.getIntRandom();

    private int baseP2PId;

    private MsnSwitchboard switchboard = null;

    private FileInputStream fileInput = null;
    private long fileOffset = 0;


    public FileTransferWorker(MsnFileTransferImpl fileTransfer)
    {
        this.fileTransfer = fileTransfer;
    }

    /**
     * @return the fileTransfer
     */
    public MsnFileTransferImpl getFileTransfer()
    {
        return fileTransfer;
    }

  /**
   * Retrieves the next identifier to send a message.
   *
   * @return Next identifier to send messages.
   */
  private int getNextIdentifier()
    {
    return ++baseId;
  }

    /**
   * Retrieves the last generated identifier.
   *
   * @return Last generated identifier.
   */
  private int getLastIdentifier()
    {
    return baseId;
  }

    private int nextP2PBaseId()
    {
    baseP2PId = MsnP2PBaseIdGenerator.getInstance().getNextId();
    return baseP2PId;
  }

    public void startFileTransfer()
    {
        if(fileTransfer.isReceiver())
        {
            MsnslpMessage msnslpRequest = fileTransfer.getReqMessage().getSlpMessage();
            MsnslpResponse okSlpMessage = new MsnslpResponse();
            okSlpMessage.setTo(msnslpRequest.getFrom());
            okSlpMessage.setFrom(msnslpRequest.getTo());
            okSlpMessage.setVia(msnslpRequest.getVia());
            okSlpMessage.setCSeq(msnslpRequest.getCSeq() + 1);
            okSlpMessage.setCallId(msnslpRequest.getCallId());
            okSlpMessage.setMaxForwards(msnslpRequest.getMaxForwards());
            okSlpMessage.setContentType(msnslpRequest.getContentType());

            StringHolder body = new StringHolder();
            body.setProperty("SessionID", fileTransfer.getID());

            okSlpMessage.setBody(body.toString() + JmlConstants.LINE_SEPARATOR
                    + "\0");

            int okSlpMessageLength = Charset.encodeAsByteArray(okSlpMessage
                    .toString()).length;

            MsnP2PSlpMessage okMessage = new MsnP2PSlpMessage();
            okMessage.setSlpMessage(okSlpMessage);
            okMessage.setIdentifier(getNextIdentifier());
            okMessage.setTotalLength(okSlpMessageLength);
            okMessage.setCurrentLength(okSlpMessageLength);
            okMessage.setField7(NumberUtils.getIntRandom());
            okMessage.setFlag(MsnP2PMessage.FLAG_OLD_NONE);
            okMessage.setP2PDest(fileTransfer.getEmail().getEmailAddress());

            OutgoingMSG[] outgoingOkMessages = okMessage.toOutgoingMsg(
                fileTransfer.getSession().getMessenger().getActualMsnProtocol());
            for (OutgoingMSG outgoingOkMessage : outgoingOkMessages)
            {
                fileTransfer.getSession().sendSynchronousMessage(outgoingOkMessage);
            }
        }
        else
        {
            try
            {
                if(fileInput == null)
                {
                    fileInput = new FileInputStream(fileTransfer.getFile());
                    // increase identifier
                    getNextIdentifier();
                }

                int remaining = (int)(fileTransfer.getFile().length() - fileOffset);

                int dataLength = remaining > MsnP2PDataMessage.MAX_DATA_LENGTH ?
                    MsnP2PDataMessage.MAX_DATA_LENGTH : remaining;

                byte data[] = new byte[dataLength];
                fileInput.read(data);

                MsnP2PDataMessage dataMessage = new MsnP2PDataMessage(
                        Integer.parseInt(fileTransfer.getID()),
                        getLastIdentifier(),
                        (int)fileOffset,
                        (int)fileTransfer.getFileTotalSize(),
                        data,
                        fileTransfer.getEmail().getEmailAddress())
                {
                    protected void receivedResponse(MsnSession session,
                        MsnIncomingMessage response)
                    {
                        try
                        {
                            int remaining =
                                (int)(fileTransfer.getFile().length() - fileOffset);

                            if(remaining == 0)
                            {
                                fileTransfer.setState(
                                    MsnFileTransferState.COMPLETED);

                                 ((AbstractMessenger)fileTransfer.getSession().
                                     getMessenger()).
                                        fireFileTransferFinished(fileTransfer);
                                 return;
                            }

                            if(fileTransfer.getState()
                                    == MsnFileTransferState.CANCELED)
                                return;

                            binaryHeader.rewind();

                            int dataLength = remaining > MsnP2PDataMessage.MAX_DATA_LENGTH ?
                                MsnP2PDataMessage.MAX_DATA_LENGTH : remaining;

                            byte data[] = new byte[dataLength];
                            fileInput.read(data);

                            setCurrentLength(data.length);
                            parseP2PBody(ByteBuffer.wrap(data));

                            setOffset(fileOffset);

                            fileOffset += data.length;

                            fileTransfer.setTransferredSize(getOffset());
                            ((AbstractMessenger)fileTransfer.getSession().getMessenger()).
                                fireFileTransferProcess(fileTransfer);

                            OutgoingMSG[] outgoingMessages = toOutgoingMsg(
                                session.getMessenger().getActualMsnProtocol());
                            for (OutgoingMSG outgoingMessage : outgoingMessages)
                            {
                                switchboard.send(outgoingMessage);
                            }
                        }
                        catch (IOException e)
                        {
                            logger.info("Cannot send file", e);
                        }
                    }
                };
                dataMessage.setFlag(MsnP2PMessage.FLAG_OLD_DATA);
                fileOffset += data.length;

                fileTransfer.setTransferredSize(fileOffset);
                ((AbstractMessenger)fileTransfer.getSession().getMessenger()).
                    fireFileTransferProcess(fileTransfer);

                OutgoingMSG[] outgoingDataMessages = dataMessage
                        .toOutgoingMsg(fileTransfer.getSession().getMessenger()
                                .getActualMsnProtocol());
                for (OutgoingMSG outgoingDataMessage : outgoingDataMessages)
                {
                    switchboard.send(outgoingDataMessage);
                }
            }
            catch (FileNotFoundException ex)
            {
                logger.error("Cannot open file", ex);
            }
            catch (IOException ex)
            {
                logger.error("Cannot read from file", ex);
            }
        }
    }

    private void sendBye()
    {
        MsnslpRequest req = new MsnslpRequest();
        MsnFileByeMessage bye = new MsnFileByeMessage();
        bye.setSlpMessage(req);
        int lastRandomIdentifier = NumberUtils.getIntRandom();

        // Set the destination for the message (the MsnObject creator)
        bye.setP2PDest(fileTransfer.getEmail().getEmailAddress());

        // Set the binary Header
        bye.setSessionId(Integer.parseInt(fileTransfer.getID()));
        bye.setIdentifier(getNextIdentifier());
        bye.setFlag(MsnP2PMessage.FLAG_OLD_NONE);
        bye.setField7(lastRandomIdentifier);
        bye.setField8(0);
        bye.setField9(0);

        // Set body
        req.setRequestMethod(MsnP2PByeMessage.METHOD_BYE);
        req.setRequestURI("MSNMSGR:" + fileTransfer.getSession().getMessenger().getOwner().getEmail().getEmailAddress());
        req.setTo("<msnmsgr:" + fileTransfer.getEmail().getEmailAddress() + ">");
        req.setFrom("<msnmsgr:" +
            fileTransfer.getSession().getMessenger().getOwner().getEmail().getEmailAddress() + ">");
        req.setVia(
            "MSNSLP/1.0/TLP ;branch={A0D624A6-6C0C-4283-A9E0-BC97B4B46D32}");
        req.setCSeq(0);
        req.setCallId(fileTransfer.getReqMessage().getSlpMessage().getCallId());
        req.setMaxForwards(0);
        req.setContentType("application/x-msnmsgr-sessionclosebody");
        req.setBody(JmlConstants.LINE_SEPARATOR + "\0");

        // Get the size of the message to be setted
        int slpMessageLength = Charset.encodeAsByteArray(req.toString()).length;
        bye.setTotalLength(slpMessageLength);
        bye.setCurrentLength(slpMessageLength);

        OutgoingMSG[] outgoingOkMessages = bye.toOutgoingMsg(
            fileTransfer.getSession().getMessenger().getActualMsnProtocol());
        for (OutgoingMSG outgoingOkMessage : outgoingOkMessages)
        {
            if(switchboard != null)
                switchboard.send(outgoingOkMessage);
            else
                fileTransfer.getSession().sendAsynchronousMessage(outgoingOkMessage);
        }
    }

    private void sendDecline()
    {
        MsnslpMessage msnslpRequest =
            fileTransfer.getReqMessage().getSlpMessage();

        MsnslpResponse okSlpMessage = new MsnslpResponse();
        okSlpMessage.setStatusCode(603);
        okSlpMessage.setReasonPhrase("Decline");
        okSlpMessage.setTo(msnslpRequest.getFrom());
        okSlpMessage.setFrom(msnslpRequest.getTo());
        okSlpMessage.setVia(msnslpRequest.getVia());
        okSlpMessage.setCSeq(msnslpRequest.getCSeq() + 1);
        okSlpMessage.setCallId(msnslpRequest.getCallId());
        okSlpMessage.setMaxForwards(msnslpRequest.getMaxForwards());
        okSlpMessage.setContentType(msnslpRequest.getContentType());

        StringHolder body = new StringHolder();
        body.setProperty("SessionID", fileTransfer.getID());
        okSlpMessage.setBody(body.toString() + JmlConstants.LINE_SEPARATOR
                + "\0");

        int okSlpMessageLength = Charset.encodeAsByteArray(okSlpMessage
                .toString()).length;

        MsnP2PSlpMessage okMessage = new MsnP2PSlpMessage();
        okMessage.setSlpMessage(okSlpMessage);
        okMessage.setIdentifier(getNextIdentifier());
        okMessage.setTotalLength(okSlpMessageLength);
        okMessage.setCurrentLength(okSlpMessageLength);
        okMessage.setFlag(MsnP2PMessage.FLAG_OLD_NONE);
        okMessage.setField7(NumberUtils.getIntRandom());
        okMessage.setP2PDest(fileTransfer.getEmail().getEmailAddress());

        OutgoingMSG[] outgoingOkMessages = okMessage.toOutgoingMsg(
            fileTransfer.getSession().getMessenger().getActualMsnProtocol());
        for (OutgoingMSG outgoingOkMessage : outgoingOkMessages)
        {
            fileTransfer.getSession().sendSynchronousMessage(outgoingOkMessage);
        }
    }

    public void cancelFileTransfer()
    {
        if(fileTransfer.isSender())
        {
            sendBye();
        }
        else if(!fileTransfer.isSender() && !fileTransfer.isStarted())
        {
            sendDecline();
        }
        else
        {
            sendBye();
        }
    }

    /**
   * Send a P2P ACK message for a received P2P message.
   *
   * @param message Received P2P message.
   * @param sessionIdFlag True if the session Id must be setted.
   */
  public void sendP2PAck(MsnP2PMessage msg, boolean sessionIdFlag)
    {
    // Create the ACK message
    MsnP2PAckMessage ack = new MsnP2PAckMessage(
        getNextIdentifier(),
                fileTransfer.getEmail().getEmailAddress(),
        msg);
    if (sessionIdFlag)
        {
      ack.setSessionId(Integer.valueOf(fileTransfer.getID()));
    }

    // Send the message
    OutgoingMSG[] outgoingOkMessages = ack.toOutgoingMsg(
            fileTransfer.getSession().getMessenger().getActualMsnProtocol());

        for (OutgoingMSG outgoingOkMessage : outgoingOkMessages)
        {
            fileTransfer.getSession().sendSynchronousMessage(outgoingOkMessage);
        }
  }

    public void sendDeny(MsnP2PSlpMessage msg)
    {
        MsnslpRequest msnslpRequest = (MsnslpRequest)msg.getSlpMessage();
        MsnslpResponse okSlpMessage = new MsnslpResponse();
        okSlpMessage.setStatusCode(405);
        okSlpMessage.setReasonPhrase("Not supported");
        okSlpMessage.setTo(msnslpRequest.getFrom());
        okSlpMessage.setFrom(msnslpRequest.getTo());
        okSlpMessage.setVia(msnslpRequest.getVia());
        okSlpMessage.setCSeq(msnslpRequest.getCSeq() + 1);
        okSlpMessage.setCallId(msnslpRequest.getCallId());
        okSlpMessage.setMaxForwards(msnslpRequest.getMaxForwards());
        okSlpMessage.setContentType(msnslpRequest.getContentType());

        StringHolder body = new StringHolder();
        body.setProperty("SessionID", fileTransfer.getID());
        okSlpMessage.setBody(body.toString() + JmlConstants.LINE_SEPARATOR
                + "\0");

        int okSlpMessageLength = Charset.encodeAsByteArray(okSlpMessage
                .toString()).length;

        MsnP2PSlpMessage okMessage = new MsnP2PSlpMessage();
        okMessage.setSlpMessage(okSlpMessage);
        okMessage.setIdentifier(getNextIdentifier());
        okMessage.setTotalLength(okSlpMessageLength);
        okMessage.setCurrentLength(okSlpMessageLength);
        okMessage.setField7(NumberUtils.getIntRandom());
        okMessage.setP2PDest(fileTransfer.getEmail().getEmailAddress());

        OutgoingMSG[] outgoingOkMessages = okMessage.toOutgoingMsg(
            fileTransfer.getSession()
                .getMessenger().getActualMsnProtocol());
        for (OutgoingMSG outgoingOkMessage : outgoingOkMessages)
        {
            fileTransfer.getSession().sendSynchronousMessage(outgoingOkMessage);
        }
    }

    /**
     * @return the switchboard
     */
    public MsnSwitchboard getSwitchboard()
    {
        return switchboard;
    }

    /**
     * @param switchboard the switchboard to set
     */
    public void setSwitchboard(MsnSwitchboard switchboard)
    {
        this.switchboard = switchboard;
    }
}
TOP

Related Classes of net.sf.jml.message.p2p.FileTransferWorker

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.