/***************************************************
*
* cismet GmbH, Saarbruecken, Germany
*
* ... and it just works.
*
****************************************************/
package de.cismet.cismap.commons.retrieval;
import org.apache.log4j.Logger;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import de.cismet.cismap.commons.Debug;
import de.cismet.tools.CurrentStackTrace;
/**
* DOCUMENT ME!
*
* @author thorsten.hell@cismet.de
* @version $Revision$, $Date$
*/
public abstract class AbstractRetrievalService implements RetrievalService {
//~ Static fields/initializers ---------------------------------------------
public static final String PROGRESS_PROPERTY = "progress"; // NOI18N
public static final String PROGRESS_REFRESH = "refresh"; // NOI18N
protected static final boolean DEBUG = Debug.DEBUG;
private static final Logger LOG = Logger.getLogger(AbstractRetrievalService.class);
//~ Instance fields --------------------------------------------------------
protected int progress = -1;
protected boolean refreshNeeded = false;
protected List<RetrievalListener> listeners = new ArrayList<RetrievalListener>();
protected PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
protected Object errorObject = null;
final Object fireRetrievalStartedLock = new Object();
final Object fireRetrievalProgressLock = new Object();
final Object fireRetrievalCompleteLock = new Object();
final Object fireRetrievalAbortedLock = new Object();
final Object fireRetrievalErrorLock = new Object();
//~ Constructors -----------------------------------------------------------
/**
* Creates a new instance of AbstractRetrievalService.
*/
public AbstractRetrievalService() {
}
//~ Methods ----------------------------------------------------------------
@Override
public void removeRetrievalListener(final RetrievalListener irl) {
listeners.remove(irl);
}
@Override
public void addRetrievalListener(final RetrievalListener irl) {
if (!(listeners.contains(irl))) {
listeners.add(irl);
}
}
/**
* DOCUMENT ME!
*
* @param e DOCUMENT ME!
*/
public void fireRetrievalStarted(final RetrievalEvent e) {
synchronized (fireRetrievalStartedLock) {
this.setProgress(-1);
e.setRetrievalService(this);
final Iterator it = listeners.iterator();
while (it.hasNext()) {
final Object l = it.next();
if (l instanceof RetrievalListener) {
((RetrievalListener)l).retrievalStarted(e);
}
}
}
}
/**
* DOCUMENT ME!
*
* @param e DOCUMENT ME!
*/
public void fireRetrievalProgress(final RetrievalEvent e) {
synchronized (fireRetrievalProgressLock) {
this.setProgress(e.getPercentageDone());
e.setRetrievalService(this);
final Iterator it = listeners.iterator();
while (it.hasNext()) {
final Object l = it.next();
if (l instanceof RetrievalListener) {
((RetrievalListener)l).retrievalProgress(e);
}
}
}
}
/**
* DOCUMENT ME!
*
* @param e DOCUMENT ME!
*/
public void fireRetrievalComplete(final RetrievalEvent e) {
synchronized (fireRetrievalCompleteLock) {
this.setProgress(100);
e.setRetrievalService(this);
final Iterator it = new ArrayList<RetrievalListener>(listeners).iterator();
while (it.hasNext()) {
final Object l = it.next();
if (l instanceof RetrievalListener) {
((RetrievalListener)l).retrievalComplete(e);
}
}
}
}
/**
* DOCUMENT ME!
*
* @param e DOCUMENT ME!
*/
public void fireRetrievalAborted(final RetrievalEvent e) {
synchronized (fireRetrievalAbortedLock) {
this.setProgress(0);
e.setRetrievalService(this);
final Iterator it = listeners.iterator();
while (it.hasNext()) {
final Object l = it.next();
if (l instanceof RetrievalListener) {
((RetrievalListener)l).retrievalAborted(e);
}
}
}
}
/**
* DOCUMENT ME!
*
* @param e DOCUMENT ME!
*/
public void fireRetrievalError(final RetrievalEvent e) {
synchronized (fireRetrievalErrorLock) {
this.setProgress(0);
LOG.warn("fireRetrievalError: ", new CurrentStackTrace()); // NOI18N
e.setRetrievalService(this);
final Iterator it = listeners.iterator();
while (it.hasNext()) {
final Object l = it.next();
if (l instanceof RetrievalListener) {
((RetrievalListener)l).retrievalError(e);
}
}
}
}
@Override
public abstract void retrieve(boolean forced);
@Override
public abstract Object clone();
/**
* DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public AbstractRetrievalService cloneWithoutRetrievalListeners() {
final AbstractRetrievalService ret = (AbstractRetrievalService)clone();
ret.listeners.clear();
return ret;
}
/**
* DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public List<RetrievalListener> getListeners() {
return listeners;
}
@Override
public int getProgress() {
return progress;
}
@Override
public void setProgress(final int progress) {
final int oldProgress = this.progress;
if ((progress > 100) || (progress < -1)) {
LOG.warn("invalid progress '" + progress + "', setting to -1 (indeterminate)"); // NOI18N
this.progress = -1;
} else {
this.progress = progress;
}
propertyChangeSupport.firePropertyChange(PROGRESS_PROPERTY, oldProgress, this.progress);
}
/**
* DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public Object getErrorObject() {
return errorObject;
}
/**
* DOCUMENT ME!
*
* @param errorObject DOCUMENT ME!
*/
public void setErrorObject(final Object errorObject) {
this.errorObject = errorObject;
}
@Override
public boolean isRefreshNeeded() {
return refreshNeeded;
}
@Override
public void setRefreshNeeded(final boolean refreshNeeded) {
final boolean oldRefreshNeeded = this.refreshNeeded;
this.refreshNeeded = refreshNeeded;
propertyChangeSupport.firePropertyChange(PROGRESS_REFRESH, oldRefreshNeeded, this.refreshNeeded);
}
/**
* DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public boolean hasErrors() {
return errorObject != null;
}
@Override
public void removePropertyChangeListener(final PropertyChangeListener l) {
this.propertyChangeSupport.removePropertyChangeListener(l);
}
@Override
public void addPropertyChangeListener(final PropertyChangeListener l) {
this.propertyChangeSupport.addPropertyChangeListener(l);
}
}