/*
* 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.service.protocol;
import java.util.*;
import net.java.sip.communicator.service.protocol.event.*;
import net.java.sip.communicator.util.*;
/**
* An abstract implementation of the <tt>FileTransfer</tt> interface providing
* implementation of status and progress events related methods and leaving all
* protocol specific methods abstract. A protocol specific implementation could
* extend this class and implement only <tt>cancel()</tt> and
* <tt>getTransferredBytes()</tt>.
*
* @author Yana Stamcheva
*/
public abstract class AbstractFileTransfer
implements FileTransfer
{
private static final Logger logger =
Logger.getLogger(AbstractFileTransfer.class);
/**
* A list of listeners registered for file transfer status events.
*/
private Vector<FileTransferStatusListener> statusListeners
= new Vector<FileTransferStatusListener>();
/**
* A list of listeners registered for file transfer status events.
*/
private Vector<FileTransferProgressListener> progressListeners
= new Vector<FileTransferProgressListener>();
private int status;
/**
* Cancels this file transfer. When this method is called transfer should
* be interrupted.
*/
abstract public void cancel();
/**
* Returns the number of bytes already transfered through this file transfer.
*
* @return the number of bytes already transfered through this file transfer
*/
abstract public long getTransferedBytes();
/**
* Adds the given <tt>FileTransferProgressListener</tt> to listen for
* status changes on this file transfer.
*
* @param listener the listener to add
*/
public void addProgressListener(FileTransferProgressListener listener)
{
synchronized(progressListeners)
{
if(!progressListeners.contains(listener))
{
this.progressListeners.add(listener);
}
}
}
/**
* Adds the given <tt>FileTransferStatusListener</tt> to listen for
* status changes on this file transfer.
*
* @param listener the listener to add
*/
public void addStatusListener(FileTransferStatusListener listener)
{
synchronized(statusListeners)
{
if(!statusListeners.contains(listener))
{
this.statusListeners.add(listener);
}
}
}
/**
* Removes the given <tt>FileTransferProgressListener</tt>.
*
* @param listener the listener to remove
*/
public void removeProgressListener(FileTransferProgressListener listener)
{
synchronized(progressListeners)
{
this.progressListeners.remove(listener);
}
}
/**
* Removes the given <tt>FileTransferStatusListener</tt>.
*
* @param listener the listener to remove
*/
public void removeStatusListener(FileTransferStatusListener listener)
{
synchronized(statusListeners)
{
this.statusListeners.remove(listener);
}
}
/**
* Returns the current status of the transfer. This information could be
* used from the user interface to show a progress bar indicating the
* file transfer status.
*
* @return the current status of the transfer
*/
public int getStatus()
{
return status;
}
/**
* Notifies all status listeners that a new
* <tt>FileTransferStatusChangeEvent</tt> occured.
* @param newStatus the new status
*/
public void fireStatusChangeEvent(int newStatus)
{
this.fireStatusChangeEvent(newStatus, null);
}
/**
* Notifies all status listeners that a new
* <tt>FileTransferStatusChangeEvent</tt> occured.
* @param newStatus the new status
* @param reason the reason of the status change
*/
public void fireStatusChangeEvent(int newStatus, String reason)
{
// ignore if status is the same
if(this.status == newStatus)
return;
Collection<FileTransferStatusListener> listeners = null;
synchronized (statusListeners)
{
listeners
= new ArrayList<FileTransferStatusListener>(statusListeners);
}
if (logger.isDebugEnabled())
logger.debug("Dispatching a FileTransfer Event to" + listeners.size()
+ " listeners. Status=" + status);
FileTransferStatusChangeEvent statusEvent
= new FileTransferStatusChangeEvent(
this, status, newStatus, reason);
// Updates the status.
this.status = newStatus;
Iterator<FileTransferStatusListener> listenersIter
= listeners.iterator();
while (listenersIter.hasNext())
{
FileTransferStatusListener statusListener = listenersIter.next();
statusListener.statusChanged(statusEvent);
}
}
/**
* Notifies all status listeners that a new
* <tt>FileTransferProgressEvent</tt> occured.
* @param timestamp the date on which the event occured
* @param progress the bytes representing the progress of the transfer
*/
public void fireProgressChangeEvent(long timestamp, long progress)
{
Collection<FileTransferProgressListener> listeners = null;
synchronized (progressListeners)
{
listeners
= new ArrayList<FileTransferProgressListener>(progressListeners);
}
FileTransferProgressEvent progressEvent
= new FileTransferProgressEvent(this, timestamp, progress);
Iterator<FileTransferProgressListener> listenersIter
= listeners.iterator();
while (listenersIter.hasNext())
{
FileTransferProgressListener statusListener = listenersIter.next();
statusListener.progressChanged(progressEvent);
}
}
}