/* * Jitsi, the OpenSource Java VoIP and Instant Messaging client. * * Copyright @ 2015 Atlassian Pty Ltd * * 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.java.sip.communicator.impl.protocol.jabber; import java.io.*; import java.util.*; import net.java.sip.communicator.impl.protocol.jabber.extensions.thumbnail.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.FileTransfer; import net.java.sip.communicator.service.protocol.event.*; import net.java.sip.communicator.util.*; import org.jivesoftware.smack.*; import org.jivesoftware.smack.filter.*; import org.jivesoftware.smack.packet.*; import org.jivesoftware.smack.util.StringUtils; import org.jivesoftware.smackx.filetransfer.*; /** * Jabber implementation of the incoming file transfer request * * @author Nicolas Riegel * @author Yana Stamcheva */ public class IncomingFileTransferRequestJabberImpl implements IncomingFileTransferRequest { /** * The logger for this class. */ private static final Logger logger = Logger.getLogger(IncomingFileTransferRequestJabberImpl.class); private String id; /** * The Jabber file transfer request. */ private final FileTransferRequest fileTransferRequest; private final OperationSetFileTransferJabberImpl fileTransferOpSet; private final ProtocolProviderServiceJabberImpl jabberProvider; private Contact sender; private String thumbnailCid; private byte[] thumbnail; /** * Creates an IncomingFileTransferRequestJabberImpl based on the * given fileTransferRequest, coming from the Jabber protocol. * * @param jabberProvider the protocol provider * @param fileTransferOpSet file transfer operation set * @param fileTransferRequest the request coming from the Jabber protocol */ public IncomingFileTransferRequestJabberImpl( ProtocolProviderServiceJabberImpl jabberProvider, OperationSetFileTransferJabberImpl fileTransferOpSet, FileTransferRequest fileTransferRequest) { this.jabberProvider = jabberProvider; this.fileTransferOpSet = fileTransferOpSet; this.fileTransferRequest = fileTransferRequest; String fromUserID = fileTransferRequest.getRequestor(); OperationSetPersistentPresenceJabberImpl opSetPersPresence = (OperationSetPersistentPresenceJabberImpl) jabberProvider .getOperationSet(OperationSetPersistentPresence.class); sender = opSetPersPresence.findContactByID(fromUserID); if(sender == null) { ChatRoom privateContactRoom = null; OperationSetMultiUserChatJabberImpl mucOpSet = (OperationSetMultiUserChatJabberImpl)jabberProvider .getOperationSet(OperationSetMultiUserChat.class); if(mucOpSet != null) privateContactRoom = mucOpSet .getChatRoom(StringUtils.parseBareAddress(fromUserID)); if(privateContactRoom != null) { sender = ((OperationSetPersistentPresenceJabberImpl) jabberProvider.getOperationSet( OperationSetPersistentPresence.class)) .createVolatileContact(fromUserID, true); privateContactRoom.updatePrivateContactPresenceStatus(sender); } } this.id = String.valueOf( System.currentTimeMillis()) + String.valueOf(hashCode()); } /** * Returns the Contact making this request. * * @return the Contact making this request */ public Contact getSender() { return sender; } /** * Returns the description of the file corresponding to this request. * * @return the description of the file corresponding to this request */ public String getFileDescription() { return fileTransferRequest.getDescription(); } /** * Returns the name of the file corresponding to this request. * * @return the name of the file corresponding to this request */ public String getFileName() { return fileTransferRequest.getFileName(); } /** * Returns the size of the file corresponding to this request. * * @return the size of the file corresponding to this request */ public long getFileSize() { return fileTransferRequest.getFileSize(); } /** * Accepts the file and starts the transfer. * * @return a boolean : false if the transfer fails, * true otherwise */ public FileTransfer acceptFile(File file) { AbstractFileTransfer incomingTransfer = null; IncomingFileTransfer jabberTransfer = fileTransferRequest.accept(); try { incomingTransfer = new IncomingFileTransferJabberImpl( id, sender, file, jabberTransfer); FileTransferCreatedEvent event = new FileTransferCreatedEvent(incomingTransfer, new Date()); fileTransferOpSet.fireFileTransferCreated(event); jabberTransfer.recieveFile(file); new OperationSetFileTransferJabberImpl .FileTransferProgressThread( jabberTransfer, incomingTransfer, getFileSize()).start(); } catch (XMPPException e) { if (logger.isDebugEnabled()) logger.debug("Receiving file failed.", e); } return incomingTransfer; } /** * Refuses the file transfer request. */ public void rejectFile() { fileTransferRequest.reject(); fileTransferOpSet.fireFileTransferRequestRejected( new FileTransferRequestEvent(fileTransferOpSet, this, new Date())); } /** * The unique id. * @return the id. */ public String getID() { return id; } /** * Returns the thumbnail contained in this request. * * @return the thumbnail contained in this request */ public byte[] getThumbnail() { return thumbnail; } /** * Sets the thumbnail content-ID. * @param cid the thumbnail content-ID */ public void createThumbnailListeners(String cid) { this.thumbnailCid = cid; if (jabberProvider.getConnection() != null) { jabberProvider.getConnection().addPacketListener( new ThumbnailResponseListener(), new AndFilter( new PacketTypeFilter(IQ.class), new IQTypeFilter(IQ.Type.RESULT))); } } /** * The ThumbnailResponseListener listens for events triggered by * the reception of a ThumbnailIQ packet. The packet is examined * and a file transfer request event is fired when the thumbnail is * extracted. */ private class ThumbnailResponseListener implements PacketListener { public void processPacket(Packet packet) { // If this is not an IQ packet, we're not interested. if (!(packet instanceof ThumbnailIQ)) return; if (logger.isDebugEnabled()) logger.debug("Thumbnail response received."); ThumbnailIQ thumbnailResponse = (ThumbnailIQ) packet; if (thumbnailResponse.getCid() != null && thumbnailResponse.getCid().equals(thumbnailCid)) { thumbnail = thumbnailResponse.getData(); // Create an event associated to this global request. FileTransferRequestEvent fileTransferRequestEvent = new FileTransferRequestEvent( fileTransferOpSet, IncomingFileTransferRequestJabberImpl.this, new Date()); // Notify the global listener that a request has arrived. fileTransferOpSet.fireFileTransferRequest( fileTransferRequestEvent); } else { //TODO: RETURN } if (jabberProvider.getConnection() != null) { jabberProvider.getConnection() .removePacketListener(this); } } } }