/*
Copyright (C) 2003 EBI, GRL
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
*/
package org.ensembl.mart.lib.config;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.ensembl.mart.lib.DetailedDataSource;
/**
* A composite DSConfigAdaptor that combines the datasets from all contained
* DSConfigAdaptors.
*/
public class CompositeDSConfigAdaptor implements MultiDSConfigAdaptor, Comparable {
//instanceCount for default adaptorName
private static int count = 0;
private final String DEFAULT_ADAPTOR_NAME = "Composite";
protected Set adaptors = new HashSet();
protected Set adaptorNameMap = new HashSet();
protected String adaptorName = null;
/**
* Creates instance of CompositeDSConfigAdaptor.
*/
public CompositeDSConfigAdaptor() {
adaptorName = DEFAULT_ADAPTOR_NAME + count++;
}
/**
* Adds adaptor.
* @param adaptor adaptor to be added. Do not add an ancestor CompositeDSConfigAdaptor
* to this instance or you will cause circular references when the getXXX() methods are called.
*/
public void add(DSConfigAdaptor adaptor) {
if (adaptor.getName() != null)
adaptorNameMap.add(adaptor.getName());
adaptors.add(adaptor);
}
/**
* Remove adaptor if present.
* @param adaptor adaptor to be removed
* @return true if adaptor was removed, otherwise false.
*/
public boolean remove(DSConfigAdaptor adaptor) {
if (adaptorNameMap.contains(adaptor.getName()))
adaptorNameMap.remove(adaptor.getName());
return adaptors.remove(adaptor);
}
/**
* Removes all adaptors.
*/
public void clear() {
adaptorNameMap.clear();
adaptors.clear();
}
/**
* Gets currently available adaptors.
* @return all adaptors currently managed by this instance. Empty array
* if non available.
*/
public DSConfigAdaptor[] getLeafAdaptors() throws ConfigurationException {
List leafAdaptors = new ArrayList();
for (Iterator iter = adaptors.iterator(); iter.hasNext();) {
Object adaptor = iter.next();
if (adaptor instanceof LeafDSConfigAdaptor)
leafAdaptors.add(adaptor);
else {
leafAdaptors.addAll( Arrays.asList( ( (DSConfigAdaptor) adaptor).getLeafAdaptors() ) );
}
}
DSConfigAdaptor[] ret = new DSConfigAdaptor[leafAdaptors.size()];
leafAdaptors.toArray(ret);
return ret;
}
/* (non-Javadoc)
* @see org.ensembl.mart.lib.config.DSConfigAdaptor#getDatasetConfigs()
*/
public DatasetConfigIterator getDatasetConfigs() throws ConfigurationException {
DatasetConfigIterator dsviter = null;
for (Iterator iter = adaptors.iterator(); iter.hasNext();) {
DSConfigAdaptor adaptor = (DSConfigAdaptor) iter.next();
if (dsviter == null)
dsviter = new DatasetConfigIterator(adaptor.getDatasetConfigs());
else
dsviter.addDatasetConfigIterator(adaptor.getDatasetConfigs());
}
if (dsviter == null)
dsviter = new DatasetConfigIterator(new ArrayList().iterator()); //empty iterator
return dsviter;
}
/**
* @see org.ensembl.mart.lib.config.DSConfigAdaptor#update()
*/
public void update() throws ConfigurationException {
for (Iterator iter = adaptors.iterator(); iter.hasNext();) {
DSConfigAdaptor adaptor = (DSConfigAdaptor) iter.next();
adaptor.update();
}
}
/* (non-Javadoc)
* @see org.ensembl.mart.lib.config.DSConfigAdaptor#lazyLoad(org.ensembl.mart.lib.config.DatasetConfig)
*/
public void lazyLoad(DatasetConfig dsv) throws ConfigurationException {
for (Iterator iter = adaptors.iterator(); iter.hasNext();) {
DSConfigAdaptor adaptor = (DSConfigAdaptor) iter.next();
if (adaptor.supportsDataset(dsv.getDataset())) {
adaptor.lazyLoad(dsv);
break;
}
}
}
/* (non-Javadoc)
* @see org.ensembl.mart.lib.config.MultiDSConfigAdaptor#removeDatasetConfig(org.ensembl.mart.lib.config.DatasetConfig)
*/
public boolean removeDatasetConfig(DatasetConfig dsv) throws ConfigurationException {
boolean removed = false;
for (Iterator iter = adaptors.iterator(); !removed && iter.hasNext();) {
DSConfigAdaptor adaptor = (DSConfigAdaptor) iter.next();
if (adaptor.supportsDataset(dsv.getDataset())) {
if (adaptor instanceof MultiDSConfigAdaptor) {
removed =
((MultiDSConfigAdaptor) adaptor).removeDatasetConfig(
adaptor.getDatasetConfigByDatasetInternalName(dsv.getDataset(), dsv.getInternalName()));
} else {
DatasetConfig thisDSV = adaptor.getDatasetConfigByDatasetInternalName(dsv.getDataset(), dsv.getInternalName());
if (thisDSV.equals(dsv))
removed = adaptors.remove(adaptor);
}
}
}
return removed;
}
/* (non-Javadoc)
* @see org.ensembl.mart.lib.config.DSConfigAdaptor#getMartLocations()
*/
public MartLocation[] getMartLocations() throws ConfigurationException {
List locations = new ArrayList();
for (Iterator iter = adaptors.iterator(); iter.hasNext();) {
DSConfigAdaptor adaptor = (DSConfigAdaptor) iter.next();
locations.addAll(Arrays.asList(adaptor.getMartLocations()));
}
MartLocation[] retlocs = new MartLocation[locations.size()];
locations.toArray(retlocs);
return retlocs;
}
/**
* Allows Equality Comparisons manipulation of DSConfigAdaptor objects. Although
* any DSConfigAdaptor object can be compared with any other DSConfigAdaptor object, to provide
* consistency with the compareTo method, in practice, it is almost impossible for different DSVIewAdaptor
* implimentations to equal.
*/
public boolean equals(Object o) {
return o instanceof DSConfigAdaptor && hashCode() == o.hashCode();
}
/**
* Calculated from all included adaptor hashCodes.
*/
public int hashCode() {
int hsh = (adaptorName != null) ? adaptorName.hashCode() : 0;
for (Iterator iter = adaptors.iterator(); iter.hasNext();) {
DSConfigAdaptor adaptor = (DSConfigAdaptor) iter.next();
int h = adaptor.hashCode();
hsh += h;
}
return hsh;
}
/**
* allows any DSConfigAdaptor implimenting object to be compared to any other
* DSConfigAdaptor implimenting object, based on their hashCode.
* @see java.lang.Comparable#compareTo(java.lang.Object)
*/
public int compareTo(Object o) {
return hashCode() - ((DSConfigAdaptor) o).hashCode();
}
/**
* @see org.ensembl.mart.lib.config.DSConfigAdaptor#supportsDataset(java.lang.String)
*/
public boolean supportsDataset(String dataset) throws ConfigurationException {
return getNumDatasetConfigsByDataset(dataset) > 0;
}
/* (non-Javadoc)
* @see org.ensembl.mart.lib.config.DSConfigAdaptor#getDatasetConfigsByDataset(java.lang.String)
*/
public DatasetConfigIterator getDatasetConfigsByDataset(String dataset) throws ConfigurationException {
DatasetConfigIterator dsviter = null;
for (Iterator iter = adaptors.iterator(); iter.hasNext();) {
DSConfigAdaptor adaptor = (DSConfigAdaptor) iter.next();
if (adaptor.supportsDataset(dataset)) {
if (dsviter == null)
dsviter = new DatasetConfigIterator(adaptor.getDatasetConfigsByDataset(dataset));
else
dsviter.addDatasetConfigIterator(adaptor.getDatasetConfigsByDataset(dataset));
}
}
if (dsviter == null)
dsviter = new DatasetConfigIterator(new ArrayList().iterator()); //empty iterator
return dsviter;
}
/**
* @return "Composite"
* @see org.ensembl.mart.lib.config.DSConfigAdaptor#getDisplayName()
*/
public String getDisplayName() {
return "Composite";
}
/**
* @see org.ensembl.mart.lib.config.DSConfigAdaptor#getDatasetConfigByDatasetInternalName(java.lang.String, java.lang.String)
*/
public DatasetConfig getDatasetConfigByDatasetInternalName(String dataset, String internalName)
throws ConfigurationException {
DatasetConfig view = null;
for (Iterator iter = adaptors.iterator(); iter.hasNext();) {
DSConfigAdaptor adaptor = (DSConfigAdaptor) iter.next();
if (adaptor.supportsDataset(dataset)) {
view = adaptor.getDatasetConfigByDatasetInternalName(dataset, internalName);
if (view != null)
break;
}
}
return view;
}
/* (non-Javadoc)
* @see org.ensembl.mart.lib.config.DSConfigAdaptor#getDatasetConfigByDatasetDisplayName(java.lang.String, java.lang.String)
*/
public DatasetConfig getDatasetConfigByDatasetDisplayName(String dataset, String displayName)
throws ConfigurationException {
DatasetConfig view = null;
for (Iterator iter = adaptors.iterator(); iter.hasNext();) {
DSConfigAdaptor adaptor = (DSConfigAdaptor) iter.next();
if (adaptor.supportsDataset(dataset)) {
view = adaptor.getDatasetConfigByDatasetDisplayName(dataset, displayName);
if (view != null)
break;
}
}
return view;
}
/* (non-Javadoc)
* @see org.ensembl.mart.lib.config.DSConfigAdaptor#getDatasetNames()
*/
public String[] getDatasetNames(boolean includeHidden) throws ConfigurationException {
List l = new ArrayList();
for (Iterator iter = adaptors.iterator(); iter.hasNext();) {
DSConfigAdaptor adaptor = (DSConfigAdaptor) iter.next();
l.addAll(Arrays.asList( adaptor.getDatasetNames(includeHidden) ));
}
return (String[]) l.toArray(new String[l.size()]);
}
/* (non-Javadoc)
* @see org.ensembl.mart.lib.config.DSConfigAdaptor#getAdaptorByName(java.lang.String)
*/
public DSConfigAdaptor getAdaptorByName(String adaptorName) throws ConfigurationException {
DSConfigAdaptor dsva = null;
if (adaptorNameMap.contains(adaptorName)) {
for (Iterator iter = adaptors.iterator(); iter.hasNext();) {
DSConfigAdaptor element = (DSConfigAdaptor) iter.next();
if (element.getName().equals(adaptorName)) {
dsva = element;
break;
} else if (element.supportsAdaptor(adaptorName))
dsva = element.getAdaptorByName(adaptorName);
}
}
return dsva;
}
/* (non-Javadoc)
* @see org.ensembl.mart.lib.config.DSConfigAdaptor#getAdaptorNames()
*/
public String[] getAdaptorNames() throws ConfigurationException {
return (String[]) adaptorNameMap.toArray(new String[adaptorNameMap.size()]);
}
/* (non-Javadoc)
* @see org.ensembl.mart.lib.config.DSConfigAdaptor#getDatasetNames(java.lang.String)
*/
public String[] getDatasetNames(String adaptorName, boolean includeHidden) throws ConfigurationException {
List l = new ArrayList();
if (adaptorNameMap.contains(adaptorName)) {
for (Iterator iter = adaptors.iterator(); iter.hasNext();) {
DSConfigAdaptor element = (DSConfigAdaptor) iter.next();
if (element.getName().equals(adaptorName)) {
l.addAll(Arrays.asList(element.getDatasetNames(includeHidden)));
break;
} else if (element.supportsAdaptor(adaptorName)) {
l.addAll(Arrays.asList(element.getDatasetNames(adaptorName, includeHidden)));
break;
}
}
}
return (String[]) l.toArray(new String[l.size()]);
}
/* (non-Javadoc)
* @see org.ensembl.mart.lib.config.DSConfigAdaptor#getName()
*/
public String getName() {
return adaptorName;
}
/* (non-Javadoc)
* @see org.ensembl.mart.lib.config.DSConfigAdaptor#setName(java.lang.String)
*/
public void setName(String adaptorName) {
this.adaptorName = adaptorName;
}
/* (non-Javadoc)
* @see org.ensembl.mart.lib.config.DSConfigAdaptor#getDatasetConfigDisplayNamesByDataset(java.lang.String)
*/
public String[] getDatasetConfigDisplayNamesByDataset(String dataset) throws ConfigurationException {
List l = new ArrayList();
for (Iterator iter = adaptors.iterator(); iter.hasNext();) {
DSConfigAdaptor adaptor = (DSConfigAdaptor) iter.next();
if (adaptor.supportsDataset(dataset)) {
l.addAll(Arrays.asList(adaptor.getDatasetConfigDisplayNamesByDataset(dataset)));
}
}
return (String[]) l.toArray(new String[l.size()]);
}
/* (non-Javadoc)
* @see org.ensembl.mart.lib.config.DSConfigAdaptor#getDatasetConfigInternalNamesByDataset(java.lang.String)
*/
public String[] getDatasetConfigInternalNamesByDataset(String dataset) throws ConfigurationException {
List l = new ArrayList();
for (Iterator iter = adaptors.iterator(); iter.hasNext();) {
DSConfigAdaptor adaptor = (DSConfigAdaptor) iter.next();
if (adaptor.supportsDataset(dataset)) {
l.addAll(Arrays.asList(adaptor.getDatasetConfigInternalNamesByDataset(dataset)));
}
}
return (String[]) l.toArray(new String[l.size()]);
}
/* (non-Javadoc)
* @see org.ensembl.mart.lib.config.DSConfigAdaptor#supportsAdaptor(java.lang.String)
*/
public boolean supportsAdaptor(String adaptorName) throws ConfigurationException {
boolean supports = adaptorNameMap.contains(adaptorName);
if (!supports) {
for (Iterator iter = adaptors.iterator(); !supports && iter.hasNext();) {
DSConfigAdaptor element = (DSConfigAdaptor) iter.next();
supports = element.supportsAdaptor(adaptorName);
}
}
return supports;
}
/**
* This adapytor is not associated with a data source so it returns null.
* @return null.
* @see org.ensembl.mart.lib.config.DSConfigAdaptor#getDataSource()
*/
public DetailedDataSource getDataSource() {
return null;
}
/* (non-Javadoc)
* @see org.ensembl.mart.lib.config.DSConfigAdaptor#getNumDatasetConfigs()
*/
public int getNumDatasetConfigs(boolean visibleOnly) {
int ret = 0;
for (Iterator iter = adaptors.iterator(); iter.hasNext();) {
DSConfigAdaptor adaptor = (DSConfigAdaptor) iter.next();
ret += adaptor.getNumDatasetConfigs(visibleOnly);
}
return ret;
}
/* (non-Javadoc)
* @see org.ensembl.mart.lib.config.DSConfigAdaptor#getNumDatasetConfigsByDataset(java.lang.String)
*/
public int getNumDatasetConfigsByDataset(String dataset) {
int ret = 0;
for (Iterator iter = adaptors.iterator(); iter.hasNext();) {
DSConfigAdaptor adaptor = (DSConfigAdaptor) iter.next();
ret += adaptor.getNumDatasetConfigsByDataset(dataset);
}
return ret;
}
/* (non-Javadoc)
* @see org.ensembl.mart.lib.config.MultiDSConfigAdaptor#containsDatasetConfig(org.ensembl.mart.lib.config.DatasetConfig)
*/
public boolean containsDatasetConfig(DatasetConfig dsv) throws ConfigurationException {
boolean ret = false;
for (Iterator iter = adaptors.iterator(); iter.hasNext();) {
DSConfigAdaptor adaptor = (DSConfigAdaptor) iter.next();
ret = adaptor.containsDatasetConfig(dsv);
if (ret)
break;
}
return ret;
}
public void clearCache() {
for (Iterator iter = adaptors.iterator(); iter.hasNext();) {
DSConfigAdaptor adaptor = (DSConfigAdaptor) iter.next();
adaptor.clearCache();
}
}
}