diff options
Diffstat (limited to 'src/net/java/sip/communicator/impl/protocol/yahoo/OperationSetFileTransferYahooImpl.java')
-rw-r--r-- | src/net/java/sip/communicator/impl/protocol/yahoo/OperationSetFileTransferYahooImpl.java | 407 |
1 files changed, 407 insertions, 0 deletions
diff --git a/src/net/java/sip/communicator/impl/protocol/yahoo/OperationSetFileTransferYahooImpl.java b/src/net/java/sip/communicator/impl/protocol/yahoo/OperationSetFileTransferYahooImpl.java new file mode 100644 index 0000000..f213951 --- /dev/null +++ b/src/net/java/sip/communicator/impl/protocol/yahoo/OperationSetFileTransferYahooImpl.java @@ -0,0 +1,407 @@ +/* + * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client. + * + * Distributable under LGPL license. + * See terms of license at gnu.org. + */ +package net.java.sip.communicator.impl.protocol.yahoo; + +import java.io.*; +import java.util.*; + +import net.java.sip.communicator.service.protocol.*; +import net.java.sip.communicator.service.protocol.event.*; +import net.java.sip.communicator.util.*; + +import ymsg.network.event.*; + +/** + * The Yahoo protocol filetransfer OperationSet. + * + * @author Damian Minkov + */ +public class OperationSetFileTransferYahooImpl + implements OperationSetFileTransfer, + SessionFileTransferListener +{ + /** + * The logger for this class. + */ + private static final Logger logger = + Logger.getLogger(OperationSetFileTransferYahooImpl.class); + + /** + * The provider that created us. + */ + private final ProtocolProviderServiceYahooImpl yahooProvider; + + /** + * A list of listeners registered for file transfer events. + */ + private ArrayList<FileTransferListener> fileTransferListeners + = new ArrayList<FileTransferListener>(); + + /** + * A list of active fileTransfers. + */ + private Hashtable<String, Object> activeFileTransfers + = new Hashtable<String, Object>(); + + /** + * Constructor + * @param provider is the provider that created us + */ + public OperationSetFileTransferYahooImpl( + ProtocolProviderServiceYahooImpl provider) + { + this.yahooProvider = provider; + + provider.addRegistrationStateChangeListener( + new RegistrationStateListener()); + } + + /** + * Sends a file transfer request to the given <tt>toContact</tt> by + * specifying the local and remote file path and the <tt>fromContact</tt>, + * sending the file. + * + * @param toContact the contact that should receive the file + * @param file the file to send + * + * @return the transfer object + * + * @throws IllegalStateException if the protocol provider is not registered + * or connected + * @throws IllegalArgumentException if some of the arguments doesn't fit the + * protocol requirements + */ + public FileTransfer sendFile( Contact toContact, + File file) + throws IllegalStateException, + IllegalArgumentException + { + try + { + assertConnected(); + + ArrayList<String> filesToSend = new ArrayList<String>(); + filesToSend.add(file.getCanonicalPath()); + Date sentDate = new Date(); + String id = yahooProvider.getYahooSession().sendFiles( + filesToSend, toContact.getAddress()); + + FileTransferImpl ft = + new FileTransferImpl(yahooProvider, + id, toContact, file, FileTransfer.OUT); + + // Notify all interested listeners that a file transfer has been + // created. + FileTransferCreatedEvent event + = new FileTransferCreatedEvent(ft, sentDate); + + fireFileTransferCreated(event); + + ft.fireStatusChangeEvent(FileTransferStatusChangeEvent.PREPARING); + + return ft; + } + catch(IOException e) + { + logger.error("Cannot send fileTransfer", e); + return null; + } + } + + /** + * Sends a file transfer request to the given <tt>toContact</tt> by + * specifying the local and remote file path and the <tt>fromContact</tt>, + * sending the file. + * + * @param toContact the contact that should receive the file + * @param fromContact the contact sending the file + * @param remotePath the remote file path + * @param localPath the local file path + * + * @return the transfer object + * + * @throws IllegalStateException if the protocol provider is not registered + * or connected + * @throws IllegalArgumentException if some of the arguments doesn't fit the + * protocol requirements + */ + public FileTransfer sendFile( Contact toContact, + Contact fromContact, + String remotePath, + String localPath) + throws IllegalStateException, + IllegalArgumentException + { + return this.sendFile(toContact, new File(localPath)); + } + + /** + * Adds the given <tt>FileTransferListener</tt> that would listen for + * file transfer requests and created file transfers. + * + * @param listener the <tt>FileTransferListener</tt> to add + */ + public void addFileTransferListener( + FileTransferListener listener) + { + synchronized(fileTransferListeners) + { + if(!fileTransferListeners.contains(listener)) + { + this.fileTransferListeners.add(listener); + } + } + } + + /** + * Removes the given <tt>FileTransferListener</tt> that listens for + * file transfer requests and created file transfers. + * + * @param listener the <tt>FileTransferListener</tt> to remove + */ + public void removeFileTransferListener( + FileTransferListener listener) + { + synchronized(fileTransferListeners) + { + this.fileTransferListeners.remove(listener); + } + } + + /** + * Utility method throwing an exception if the stack is not properly + * initialized. + * @throws java.lang.IllegalStateException if the underlying stack is + * not registered and initialized. + */ + private void assertConnected() + throws IllegalStateException + { + if (yahooProvider == null) + throw new IllegalStateException( + "The provider must be non-null and signed on the " + +"service before being able to send a file."); + else if (!yahooProvider.isRegistered()) + throw new IllegalStateException( + "The provider must be signed on the service before " + +"being able to send a file."); + } + + /** + * Delivers the file transfer to all registered listeners. + * + * @param fileTransfer the <tt>FileTransfer</tt> that we'd like delivered to + * all registered file transfer listeners. + */ + void fireFileTransferCreated(FileTransferCreatedEvent event) + { + activeFileTransfers.put( + event.getFileTransfer().getID(), event.getFileTransfer()); + + Iterator<FileTransferListener> listeners = null; + synchronized (fileTransferListeners) + { + listeners = new ArrayList<FileTransferListener> + (fileTransferListeners).iterator(); + } + + while (listeners.hasNext()) + { + FileTransferListener listener = listeners.next(); + listener.fileTransferCreated(event); + } + } + + /** + * Delivers the specified event to all registered file transfer listeners. + * + * @param event the <tt>EventObject</tt> that we'd like delivered to all + * registered file transfer listeners. + */ + void fireFileTransferRequestRejected(FileTransferRequestEvent event) + { + Iterator<FileTransferListener> listeners = null; + synchronized (fileTransferListeners) + { + listeners = new ArrayList<FileTransferListener> + (fileTransferListeners).iterator(); + } + + while (listeners.hasNext()) + { + FileTransferListener listener = listeners.next(); + + listener.fileTransferRequestRejected(event); + } + } + + /** + * Delivers the specified event to all registered file transfer listeners. + * + * @param event the <tt>EventObject</tt> that we'd like delivered to all + * registered file transfer listeners. + */ + private void fireFileTransferRequest(FileTransferRequestEvent event) + { + Iterator<FileTransferListener> listeners = null; + synchronized (fileTransferListeners) + { + listeners = new ArrayList<FileTransferListener> + (fileTransferListeners).iterator(); + } + + while (listeners.hasNext()) + { + FileTransferListener listener = listeners.next(); + + listener.fileTransferRequestReceived(event); + } + } + + private int getStateMapping(int s) + { + switch(s) + { + case SessionFileTransferEvent.REFUSED : + return FileTransferStatusChangeEvent.REFUSED; + case SessionFileTransferEvent.CANCEL : + return FileTransferStatusChangeEvent.CANCELED; + case SessionFileTransferEvent.FAILED : + return FileTransferStatusChangeEvent.FAILED; + case SessionFileTransferEvent.IN_PROGRESS : + return FileTransferStatusChangeEvent.IN_PROGRESS; + case SessionFileTransferEvent.RECEIVED : + return FileTransferStatusChangeEvent.COMPLETED; + case SessionFileTransferEvent.SENT : + return FileTransferStatusChangeEvent.COMPLETED; + default: return FileTransferStatusChangeEvent.WAITING; + } + } + + /** + * Starting point for incoming filetransfer. + * @param ev + */ + public void fileTransferRequestReceived(SessionFileTransferEvent ev) + { + OperationSetPersistentPresenceYahooImpl opSetPersPresence + = (OperationSetPersistentPresenceYahooImpl) + yahooProvider.getOperationSet( + OperationSetPersistentPresence.class); + + Contact sender = opSetPersPresence.findContactByID(ev.getFrom()); + + if(sender == null) + return; + + Date recvDate = new Date(); + + for(int i = 0; i < ev.getFileNames().size(); i++) + { + String fileName = ev.getFileNames().get(i); + String fileSize = ev.getFileSizes().get(i); + + IncomingFileTransferRequest req = + new IncomingFileTransferRequestYahooImpl( + yahooProvider, this, sender, recvDate, + fileName, fileSize, + ev.getId()); + + activeFileTransfers.put(ev.getId(), req); + fireFileTransferRequest( + new FileTransferRequestEvent(req, recvDate)); + + } + } + + /** + * Status changed for filetransfer. + * @param ev + */ + public void statusChanged(SessionFileTransferEvent ev) + { + if(ev.getId() == null) + return; + + Object ftObj = activeFileTransfers.get(ev.getId()); + + if(ftObj == null) + { + logger.warn("File Transfer or request not found. " + ev.getId() + "/ " + ev.getState()); + return; + } + + int newState = ev.getState(); + + if(ftObj instanceof IncomingFileTransferRequest) + { + if(newState == SessionFileTransferEvent.REFUSED) + { + IncomingFileTransferRequestYahooImpl req = + (IncomingFileTransferRequestYahooImpl)ftObj; + fireFileTransferRequestRejected( + new FileTransferRequestEvent(req, req.getDate())); + return; + } + } + + if(!(ftObj instanceof FileTransferImpl)) + { + logger.warn("File Transfer not found." + ftObj); + return; + } + + FileTransferImpl ft = (FileTransferImpl)ftObj; + + if( newState == SessionFileTransferEvent.IN_PROGRESS) + { + // if we start sending progress fire that we are in progress + if(ev.getProgress() == 0) + ft.fireStatusChangeEvent( + FileTransferStatusChangeEvent.IN_PROGRESS); + + ft.setTransferedBytes(ev.getProgress()); + ft.fireProgressChangeEvent((int)ev.getProgress()); + } + else + ft.fireStatusChangeEvent(getStateMapping(newState)); + } + + /** + * Our listener that will tell us when we're registered to + */ + private class RegistrationStateListener + implements RegistrationStateChangeListener + { + /** + * The method is called by a ProtocolProvider implementation whenever + * a change in the registration state of the corresponding provider had + * occurred. + * @param evt ProviderStatusChangeEvent the event describing the status + * change. + */ + public void registrationStateChanged(RegistrationStateChangeEvent evt) + { + logger.debug("The provider changed state from: " + + evt.getOldState() + + " to: " + evt.getNewState()); + + if (evt.getNewState() == RegistrationState.REGISTERED) + { + yahooProvider.getYahooSession().addSessionFileListener( + OperationSetFileTransferYahooImpl.this); + } + else if (evt.getNewState() == RegistrationState.UNREGISTERED) + { + YahooSession ys = yahooProvider.getYahooSession(); + if(ys != null) + ys.removeSessionFileListener( + OperationSetFileTransferYahooImpl.this); + } + } + } +} |