/* ==============================================
* Simtools : The tools library used in JSynoptic
* ==============================================
*
* Project Info: http://jsynoptic.sourceforge.net/index.html
*
* This library is free software; you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Foundation;
* either version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*
* (C) Copyright 2001-2003, by :
* Corporate:
* Astrium SAS
* EADS CRC
* Individual:
* Nicolas Brodu
*
* $Id: DataSourcePool.java,v 1.22 2009/02/02 10:34:15 ogor Exp $
*
* Changes
* -------
* 25-Sep-2003 : Initial public release (NB);
*
*/
package simtools.data;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import simtools.data.buffer.Buffer;
import simtools.data.buffer.BufferedDataSource;
import simtools.util.ListenerManager;
/**
* Pool of data source: holds a certain number of data sources, and can send
* action events to listeners in case the pool is modified.
*
* @author Nicolas Brodu
*
* @version 1.0 2001
*/
public class DataSourcePool implements DataSourceCollectionListener {
/**
* A global pool for all to use
*/
public static final DataSourcePool global = new DataSourcePool();
protected ListenerManager listeners = new ListenerManager();
protected Vector providers;
protected NotifySet sources;
protected NotifySet collections;
protected Hashtable translations;
protected boolean notification;
protected ArrayList localEmptySources;
/**
* A looger to dump error or warning messages in a soket, an output stream,
* a file...
*/
static Logger _logger = simtools.util.LogConfigurator.getLogger(DataSourcePool.class.getName());
public DataSourcePool() {
providers = new Vector();
sources = new NotifySet();
collections = new NotifySet();
translations = new Hashtable();
localEmptySources = new ArrayList();
setNotify(true);
}
public void addListener(DataSourcePoolListener l) {
listeners.add(l);
}
public void removeListener(DataSourcePoolListener l) {
listeners.remove(l);
}
/**
* Adds a datasource provider. Providers are especially used to get
* datasource references back from ids, during internalization, and to get
* optional information (if any) about the datasources, during
* serialization. The new provider takes precedence over the existing ones
* in case of conflict for an id
*/
public void addProvider(DataSourceProvider p) {
providers.add(0, p);
}
public DataSourceProvider getProviderFor(DataSource ds, DataSourceCollection dsc) {
Object option = null;
for (Iterator it = providers.iterator(); it.hasNext();) {
DataSourceProvider dsp = (DataSourceProvider) it.next();
option = dsp.getOptionalInformation(ds, dsc);
if (option != null) {
return dsp;
}
}
return null;
}
/**
* Removes a datasource provider
*
* @return true if the provider was registered.
*/
public boolean removeProvider(DataSourceProvider p) {
return providers.remove(p);
}
public void addDataSource(DataSource ds) {
sources.add(ds);
}
public void addDataSourceCollection(DataSourceCollection dsc) {
collections.add(dsc);
dsc.addListener(this);
}
/**
* Remove all elements contained inside the pool
* @return
*/
public boolean removeAllSources(){
boolean res = true;
Set c = (Set)collections.clone();
Iterator it = c.iterator();
while(it.hasNext() && res){
res &=removeDataSourceCollection( ((DataSourceCollection)it.next()));
}
Set d = (Set)sources.clone();
it = d.iterator();
while(it.hasNext() && res){
res &=removeDataSourceCollection( ((DataSourceCollection)it.next()));
}
return res;
}
public boolean removeDataSource(DataSource ds) {
if (ds != null) {
// Notify data sources listeners, that data has been removed
ds.notifyListenersForDataReplaced(null);
}
return sources.remove(ds);
}
public boolean removeDataSourceCollection(DataSourceCollection dsc) {
if (dsc != null) {
dsc.removeAllElements();
}
return collections.remove(dsc);
}
/**
* Data source collections
*/
public Set dataSourceCollections() {
return collections;
}
/**
* Data sources
*/
public Set dataSources() {
return sources;
}
/**
* Apply a buffer to a datasource. Notify the listeners of the change.
*
* @param ds
* The datasource to act on
* @param buffer
* The buffer. Its data provider will be set to the datasource
* @return the bufferized data source if the operation succeded, or null
*/
public DataSource bufferize(DataSource ds, Buffer buffer) {
if (ds instanceof BufferedDataSource) {
return ds;
}
buffer.setProvider(ds);
// temporary stop notification => can remove and add safely
setNotify(false);
if (sources.remove(ds)) { // true if it was present
DataSource ret = new BufferedDataSource(buffer);
sources.add(ret);
// reactivate notification and send a 'change' message
setNotify(true);
notifyListeners(DataSourcePoolEvent.CHANGE, ret, ds);
return ret;
}
setNotify(true);
// is in a collection
for (Iterator it = collections.iterator(); it.hasNext();) {
DataSourceCollection col = (DataSourceCollection) it.next();
if (!col.contains(ds)) {
continue;
}
int index = col.indexOf(ds);
if (index == -1) {
continue; // ???
}
try {
col.bufferize(index, buffer);
notifyListeners(DataSourcePoolEvent.CHANGE, col, col);
return (DataSource) col.get(index);
} catch (Exception e) {
}
}
// Should not happen if ds is one of our sources
return null;
}
/**
* Apply a buffer to a datasource collection. Notify the listeners of the
* change.
*
* @param ds
* The datasource collection to act on
* @param buffer
* The buffer. See DataSourceCollection.bufferize().
* @return the bufferized data source collection if the operation succeded,
* or null
*/
public DataSourceCollection bufferize(DataSourceCollection dsc, Buffer buffer) {
buffer.setProvider(null);
for (Iterator it = collections.iterator(); it.hasNext();) {
DataSourceCollection col = (DataSourceCollection) it.next();
if (col != dsc) {
continue;
}
try {
col.bufferize(buffer);
notifyListeners(DataSourcePoolEvent.CHANGE, col, dsc);
return col;
} catch (Exception e) {
}
}
// Should not happen if dsc is one of our collections
return null;
}
/**
* Utility. Look in the datasource and collection sets for the given
* datasource.
*/
public boolean contains(DataSource ds) {
if (sources.contains(ds)) {
return true;
}
for (Iterator it = collections.iterator(); it.hasNext();) {
if (((DataSourceCollection) it.next()).contains(ds)) {
return true;
}
}
return false;
}
/**
* Utility. Look in the datasource and collection sets for the given
* datasource.
*/
public boolean contains(DataSourceCollection dsc) {
return collections.contains(dsc);
}
/**
* Utility. Look in the datasource and collection sets for the given
* datasource id.
*
* @return null if this pool doesn't contain a datasource with the given id,
* or if multiple source have the same id (for example, in different
* collections)
* @throws DuplicateIdException
* when two or more datasource have the given Id
*/
public DataSource getDataSourceWithId(String id) throws DuplicateIdException {
if (id == null) {
return null;
}
Vector ret = new Vector();
try {
DataSource ds = lookForId(sources, id);
if (ds != null) {
ret.add(ds);
}
} catch (DuplicateIdException e) {
ret.addAll(e.conflicts);
}
for (Iterator it = collections.iterator(); it.hasNext();) {
DataSource ds = lookForId((DataSourceCollection) it.next(), id);
if (ds != null) {
ret.add(ds);
}
}
if (ret.size() == 0) {
return null;
}
if (ret.size() == 1) {
return (DataSource) ret.get(0);
}
throw new DuplicateIdException(id, ret);
}
// avoid code dup
private DataSource lookForId(Collection c, String id) throws DuplicateIdException {
if (id == null) {
return null;
}
Vector ret = new Vector();
for (Iterator it = c.iterator(); it.hasNext();) {
DataSource ds = (DataSource) it.next();
if (id.equals(DataInfo.getId(ds))) {
ret.add(ds);
}
}
if (ret.size() == 0) {
return null;
}
if (ret.size() == 1) {
return (DataSource) ret.get(0);
}
throw new DuplicateIdException(id, ret);
}
/**
* Utility. Look in the datasource and collection sets for the given
* datasource label.
*
* @return null if this pool doesn't contain a datasource with the given
* label, or if multiple source have the same label, (for example,
* in different collections)
* @throws DuplicateIdException
* when two or more datasource have the given alias
*/
public DataSource getDataSourceWithLabel(String name) throws DuplicateIdException {
if (name == null) {
return null;
}
Vector ret = new Vector();
try {
DataSource ds = lookForLabel(sources, name);
if (ds != null) {
ret.add(ds);
}
} catch (DuplicateIdException e) {
ret.addAll(e.conflicts);
}
for (Iterator it = collections.iterator(); it.hasNext();) {
DataSource ds = lookForLabel((DataSourceCollection) it.next(), name);
if (ds != null) {
ret.add(ds);
}
}
if (ret.size() == 0) {
return null;
}
if (ret.size() == 1) {
return (DataSource) ret.get(0);
}
throw new DuplicateIdException(name, ret);
}
// avoid code dup
private DataSource lookForLabel(Collection c, String name) throws DuplicateIdException {
if (name == null) {
return null;
}
Vector ret = new Vector();
for (Iterator it = c.iterator(); it.hasNext();) {
DataSource ds = (DataSource) it.next();
if (name.equals(DataInfo.getLabel(ds))) {
ret.add(ds);
}
}
if (ret.size() == 0) {
return null;
}
if (ret.size() == 1) {
return (DataSource) ret.get(0);
}
throw new DuplicateIdException(name, ret);
}
/**
* Utility. Look in the datasource and collection sets for the given
* datasource alias.
*
* @return null if this pool doesn't contain a datasource with the given
* alias, or if multiple source have the same alias, (for example,
* in different collections)
* @throws DuplicateIdException
* when two or more datasource have the given alias
*/
public DataSource getDataSourceWithAlias(String name) throws DuplicateIdException {
if (name == null) {
return null;
}
Vector ret = new Vector();
try {
DataSource ds = lookForAlias(sources, name);
if (ds != null) {
ret.add(ds);
}
} catch (DuplicateIdException e) {
ret.addAll(e.conflicts);
}
for (Iterator it = collections.iterator(); it.hasNext();) {
DataSource ds = lookForAlias((DataSourceCollection) it.next(), name);
if (ds != null) {
ret.add(ds);
}
}
if (ret.size() == 0) {
return null;
}
if (ret.size() == 1) {
return (DataSource) ret.get(0);
}
throw new DuplicateIdException(name, ret);
}
// avoid code dup
private DataSource lookForAlias(Collection c, String name) throws DuplicateIdException {
if (name == null) {
return null;
}
Vector ret = new Vector();
for (Iterator it = c.iterator(); it.hasNext();) {
DataSource ds = (DataSource) it.next();
if (name.equals(DataInfo.getAlias(ds))) {
ret.add(ds);
}
}
if (ret.size() == 0) {
return null;
}
if (ret.size() == 1) {
return (DataSource) ret.get(0);
}
throw new DuplicateIdException(name, ret);
}
/**
* Utility. Look in the datasource and collection sets for the given
* datasource name.
*
* @return null if this pool doesn't contain a datasource with the given
* alias, or if multiple source have the same alias, (for example,
* in different collections)
* @throws DuplicateIdException
* when two or more datasource have the given alias
*/
public DataSource getDataSourceWithIDOrLabelOrAlias(String name) throws DuplicateIdException {
DataSource ds = getDataSourceWithId(name);
if (ds != null) {
return ds;
}
ds = getDataSourceWithLabel(name);
if (ds != null) {
return ds;
}
ds = getDataSourceWithAlias(name);
if (ds != null) {
return ds;
}
return null;
}
/**
* Utility. Look in the datasource collection set for the given datasource
* collection id.
*
* @return null if this pool doesn't contain a datasource collection with
* the given id
*/
public DataSourceCollection getDataSourceCollectionWithId(String id) throws DuplicateIdException {
if (id == null) {
return null;
}
Vector ret = new Vector();
for (Iterator it = collections.iterator(); it.hasNext();) {
DataSourceCollection dsc = (DataSourceCollection) it.next();
if (id.equals(DataInfo.getId(dsc))) {
ret.add(dsc);
}
}
if (ret.size() == 0) {
return null;
}
if (ret.size() == 1) {
return (DataSourceCollection) ret.get(0);
}
throw new DuplicateIdException(id, ret);
}
/**
* Utility. Look in the datasource collection set for a collection
* containing the given datasource id.
*
* @return null if this pool doesn't contain such a datasource collection
* @throws DuplicateIdException
* when two or more collections contain a datasource with the
* given Id
*/
public DataSourceCollection getCollectionForDataSourceId(String id) throws DuplicateIdException {
if (id == null) {
return null;
}
Vector ret = new Vector();
for (Iterator it = collections.iterator(); it.hasNext();) {
DataSourceCollection dsc = (DataSourceCollection) it.next();
try {
if (lookForId(dsc, id) == null) {
continue;
}
} catch (DuplicateIdException e) {
// The collection may contain multiple sources with the same ID
}
ret.add(dsc);
}
if (ret.size() == 0) {
return null;
}
if (ret.size() == 1) {
return (DataSourceCollection) ret.get(0);
}
throw new DuplicateIdException(id, ret);
}
/**
* Asks the providers to resolve a symbolic datasource reference.
*
* @param id
* The symbolic id of a datasource
* @param dscId
* The symbolic id of a datasourceCollection. May be null
* @param optionalInformation
* Can be set to help the providers. May be null
* @param add
* If set to true, the datasource will be added to the pool if it
* could be found, together with its collection if it belongs to
* a collection. True by default.
* @return The desired datasource if it could be found, or null.
*/
public DataSource provide(String id, String dscId, Object optionalInformation, boolean add) {
DataSourcePool argPool = add ? this : null;
for (Iterator it = providers.iterator(); it.hasNext();) {
DataSource ds = ((DataSourceProvider) it.next()).provide(id, dscId, optionalInformation, argPool);
if (ds != null) {
if (ds instanceof EmptyDataSource) {
String reason = "Data source cannot be restored with this reference: " + dscId;
addLocalEmptySource(id, reason);
}
return ds;
}
}
String reason = "This reference cannot be resolved: " + dscId;
addLocalEmptySource(id, reason);
return null;
}
/**
* Those are markers we can recognize without any confusion possible for the
* serialized stream
*/
protected static final class BufferMarker implements Serializable {
static final long serialVersionUID = 6047866471365207251L;
}
protected static final class DataSourceCollectionMarker implements Serializable {
static final long serialVersionUID = 8302914329862128731L;
}
protected static final class SourceDependenciesMarker implements Serializable {
static final long serialVersionUID = 4581013092140237821L;
}
/**
* DataSource serialization helper
*/
public void writeDataSource(ObjectOutputStream out, DataSource ds) throws IOException {
boolean ourDS = false;
DataSourceCollection dsc = null;
if (ds == null) {
out.writeObject(null);
return;
}
// In case data source is empty: serialize original data source info
if (ds instanceof EmptyDataSource) {
String id = ((EmptyDataSource) ds).getDataSourceId();
out.writeObject(id);
if (id == null) {
return; // And that's the end of it, won't be restored.
}
if (ds instanceof BufferedEmptyDataSource) {
out.writeObject(BufferMarker.class);
out.writeObject(((BufferedEmptyDataSource) ds).getBuffer());
}
// Collection ID
if (((EmptyDataSource) ds).getDataSourceCollectionId() != null) {
out.writeObject(DataSourceCollectionMarker.class);
out.writeObject(((EmptyDataSource) ds).getDataSourceCollectionId());
}
// optional info
out.writeObject(((EmptyDataSource) ds).getDataSourceOptionalInformation()); // may
// be
// null
} else {
if (sources.contains(ds)) {
ourDS = true;
} else {
for (Iterator it = collections.iterator(); it.hasNext();) {
dsc = (DataSourceCollection) it.next();
if (dsc.contains(ds)) {
ourDS = true;
break;
}
}
}
if (!ourDS) {
out.writeObject(null);
return;
}
String id = DataInfo.getId(ds);
out.writeObject(id);
if (id == null) {
return; // And that's the end of it, won't be restored.
}
// Take care of recursive writing in case of sources depending on
// other sources
DataSource[] dependencies = ds.getSourceDependencies();
if (dependencies != null) {
out.writeObject(SourceDependenciesMarker.class);
out.writeInt(dependencies.length);
for (int i = 0; i < dependencies.length; ++i) {
writeDataSource(out, dependencies[i]);
}
}
// Buffered data source => same Id, so save the buffer too
if (ds instanceof BufferedDataSource) {
out.writeObject(BufferMarker.class);
out.writeObject(((BufferedDataSource) ds).getBuffer());
}
// If it belongs to a collection, write DataSourceCollection.Class
// as
// optional information, so we can recognize it during the read.
// Don't write the dsc's class itself, in case it could not be
// found.
// If a caller really needs it, then it should include the
// collection
// class name in the id and use Class.forName. The same is true for
// the datasource id.
// Write the dsc's id just after the marker
if (dsc != null) {
out.writeObject(DataSourceCollectionMarker.class);
out.writeObject(DataInfo.getId(dsc));
}
// Now run through the providers for one that can provide optional
// info
Object option = null;
for (Iterator it = providers.iterator(); it.hasNext();) {
option = ((DataSourceProvider) it.next()).getOptionalInformation(ds, dsc);
if (option != null) {
break;
}
}
out.writeObject(option); // may be null
}
}
protected DataSourceCollection getTranslateCollection(String dscId) {
DataSourceCollection dsc = (DataSourceCollection) translations.get(dscId);
if (dsc == null) {
try {
dsc = getDataSourceCollectionWithId(dscId); // try directly
} catch (DuplicateIdException e) {
}
}
return dsc;
}
protected void setTranslateCollection(String dscId, DataSource ds) {
if ((dscId == null) || (ds == null)) {
return;
}
DataSourceCollection dsc = null;
for (Iterator it = collections.iterator(); it.hasNext();) {
DataSourceCollection col = (DataSourceCollection) it.next();
if (col.contains(ds)) {
dsc = col;
break;
}
}
if (dsc == null) {
return; // no translation possible
}
translations.put(dscId, dsc); // store the new translation
}
public DataSource readDataSource(ObjectInputStream in) throws IOException {
DataSource ds = null;
/// Stream reading ///////////////
Object o = null;
try {
o = in.readObject();
if (o == null) {
return null; // OK, no data more written to the stream
}
} catch (ClassNotFoundException cnfe1) {
// continue to read the stream so it is not corrupted
}
String id = (String) o;
// Get optional info
Object option = null;
try {
option = in.readObject();
} catch (ClassNotFoundException cnfe2) {
// continue to read the stream so it is not corrupted
}
// Take care of recursive reading in case of sources depending on other
// sources
if (SourceDependenciesMarker.class.equals(option)) {
int len = in.readInt();
for (int i = 0; i < len; ++i) {
readDataSource(in);
}
// Now it is guarantied that the provider can get the sources it
// needs using
// getDataSourceWithId => this also handle collection translations
try {
option = in.readObject();
} catch (ClassNotFoundException cnfe2) {
// continue to read the stream so it is not corrupted
}
}
// If optional info is a buffer marker, take it in account
Buffer buffer = null;
if (BufferMarker.class.equals(option)) {
try {
buffer = (Buffer) in.readObject();
} catch (ClassNotFoundException cnfe2) {
// continue to read the stream so it is not corrupted
}
try {
option = in.readObject();
} catch (ClassNotFoundException cnfe2) {
// continue to read the stream so it is not corrupted
}
}
// If optional info is a collection marker, take it in account
String dscId = null;
if (DataSourceCollectionMarker.class.equals(option)) {
try {
dscId = (String) in.readObject();
} catch (ClassNotFoundException cnfe2) {
// continue to read the stream so it is not corrupted
}
try {
option = in.readObject();
} catch (ClassNotFoundException cnfe2) {
// continue to read the stream so it is not corrupted
}
}
if (_logger.isLoggable(Level.FINE)) {
_logger.fine("id=" + id + ", dscId=" + dscId + ", buffer=" + buffer + ", option=" + option);
}
/// End of Stream reading ///////////////
// No data source collection ID --> Look up in all pool
if (dscId == null) {
try {
ds = getDataSourceWithId(id);
} catch (DuplicateIdException e) {
}
// Data source collection ID -> Get the collection related to the data
} else {
DataSourceCollection dsc = getTranslateCollection(dscId);
if (dsc != null) { // We have loaded the collection already. Does it contain the source id?
try {
ds = lookForId(dsc, id);
} catch (DuplicateIdException e) {
}
}
}
if (ds != null) {
if ((buffer != null) && !(ds instanceof BufferedDataSource)) {
ds = bufferize(ds, buffer);
}
if (_logger.isLoggable(Level.FINE)) {
_logger.fine("DataSource=>" + ( (buffer!=null)? "buffer" : "" ) + ds);
}
} else {
// No source found in the pool --> ask the providers
ds = provide(id, dscId, option, true);
if (ds == null) {
if (_logger.isLoggable(Level.FINE)) {
_logger.fine("DataSource=null");
}
} else {
// If data source is empty, return it.
if (ds instanceof EmptyDataSource) {
EmptyDataSource eds = (EmptyDataSource) ds;
if (_logger.isLoggable(Level.FINE)) {
_logger.fine("EmptyDataSource=" + ds);
}
if (buffer != null) {
ds = new BufferedEmptyDataSource(eds.getDataSourceId(), eds.getDataSourceCollectionId(), eds.getDataSourceOptionalInformation(), buffer);
// Empty buffer shall be added to the pool of empty sources
EmptyDataSourcePool.global.addEmptyDaSource(id, (EmptyDataSource) ds);
}
} else {
// If we had a collection, apply translation
setTranslateCollection(dscId, ds);
// Bufferize data source
if (buffer != null) {
ds = bufferize(ds, buffer);
}
if (_logger.isLoggable(Level.FINE)) {
_logger.fine("DataSource==>" + ((buffer!=null)? "buffer" : "") + ds);
}
}
}
}
return ds;
}
/**
* Notify the listeners a change occured
*
* @param action
* as defined in DataSourcePoolEvent
* @param o
* the target object. Must be a DataSource or
* DataSourceCollection
*/
protected void notifyListeners(int action, Object o, Object old) {
if (!notification) {
return;
}
DataSourcePoolEvent e;
if (o instanceof DataSource) {
if (old instanceof DataSource) {
e = new DataSourcePoolEvent(this, action, (DataSource) o, (DataSource) old);
} else {
e = new DataSourcePoolEvent(this, action, (DataSource) o);
}
} else {
if (old instanceof DataSourceCollection) {
e = new DataSourcePoolEvent(this, action, (DataSourceCollection) o, (DataSourceCollection) old);
} else {
e = new DataSourcePoolEvent(this, action, (DataSourceCollection) o);
}
}
synchronized (listeners) {
int n = listeners.size(); // only one call outside loop
for (int i = 0; i < n; ++i) {
DataSourcePoolListener dspl = (DataSourcePoolListener) listeners.get(i);
if (dspl != null) {
dspl.dataSourcePoolNotification(e);
}
}
}
}
/**
* Sets the notification on or off
*
* @param state
* the new state
*/
protected void setNotify(boolean state) {
notification = state;
}
/**
* A specific set that notifies the listeners when it changes See HashSet,
* this implementation is not synchronized.
*/
protected class NotifySet extends HashSet {
public boolean add(Object o) {
boolean ret = super.add(o);
if (ret) {
notifyListeners(DataSourcePoolEvent.ADD, o, null);
}
return ret;
}
public boolean remove(Object o) {
boolean ret = super.remove(o);
if (ret) {
if (o instanceof DataSourceCollection) {
translations.remove(DataInfo.getId(o));
}
notifyListeners(DataSourcePoolEvent.REMOVE, o, null);
}
return ret;
}
}
/*
* (non-Javadoc)
*
* @see simtools.data.DataSourceCollectionListener#DataSourceCollectionInfoChanged(simtools.data.DataSourceCollection,
* simtools.data.DataInfo)
*/
public void DataSourceCollectionInfoChanged(DataSourceCollection dsc, DataInfo newInfo) {
notifyListeners(DataSourcePoolEvent.CHANGE_COLLECTION, dsc, dsc);
}
/*
* (non-Javadoc)
*
* @see simtools.data.DataSourceCollectionListener#DataSourceCollectionDataSourceAdded(simtools.data.DataSourceCollection,
* simtools.data.DataSource)
*/
public void DataSourceCollectionDataSourceAdded(DataSourceCollection dsc, DataSource ds) {
notifyListeners(DataSourcePoolEvent.CHANGE_COLLECTION, dsc, dsc);
}
/*
* (non-Javadoc)
*
* @see simtools.data.DataSourceCollectionListener#DataSourceCollectionDataSourceRemoved(simtools.data.DataSourceCollection,
* simtools.data.DataSource)
*/
public void DataSourceCollectionDataSourceRemoved(DataSourceCollection dsc, DataSource ds) {
notifyListeners(DataSourcePoolEvent.REMOVE_SOURCE, dsc, dsc);
dsc.removeListener(this);
}
/*
* (non-Javadoc)
*
* @see simtools.data.DataSourceCollectionListener#DataSourceCollectionRemoved(simtools.data.DataSourceCollection)
*/
public void DataSourceCollectionRemoved(DataSourceCollection dsc) {
notifyListeners(DataSourcePoolEvent.REMOVE_COLLECTION, dsc, null);
}
/**
* @return true if this pool has no source and no collections in it
*/
public boolean isEmpty() {
int size = (sources == null) ? 0 : sources.size();
size += (collections == null) ? 0 : collections.size();
return size == 0;
}
/**
* Called after a synoptic loading
*
* @return a list of data sources that could'nt be restored during a
* synoptic loading.
*/
public String[][] getEmptySourcesDump() {
String[][] ret = new String[localEmptySources.size()][2];
for (int i = 0; i < localEmptySources.size(); i++) {
ret[i][0] = ((String[]) localEmptySources.get(i))[0];
ret[i][1] = ((String[]) localEmptySources.get(i))[1];
}
return ret;
}
/**
* Called after a synoptic loading.
*
* @return the column names of the table that dumps all data sources
* restoring problems
*/
public String[] getEmptySourcesDumpColumnNames() {
String[] columnNames = { "Data source", "Problem" };
return columnNames;
}
protected void addLocalEmptySource(String source, String reason) {
String[] emptyElement = new String[2];
emptyElement[0] = source;
emptyElement[1] = reason;
localEmptySources.add(emptyElement);
}
/**
* Called before a synoptic loading.
*/
public void clearLocalEmptySources() {
localEmptySources.clear();
}
public boolean localEmptySourcesIsEmpty() {
return localEmptySources.isEmpty();
}
}