/*
* Copyright (c) 2017 OBiBa. All rights reserved.
*
* This program and the accompanying materials
* are made available under the terms of the GNU Public License v3.0.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.obiba.magma.spring;
import java.util.Set;
import org.obiba.magma.NoSuchValueTableException;
import org.obiba.magma.ValueTable;
import org.obiba.magma.support.AbstractDatasource;
import org.obiba.magma.support.Initialisables;
import org.springframework.beans.factory.annotation.Autowired;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
public class SpringContextScanningDatasource extends AbstractDatasource {
@Autowired
@SuppressWarnings("MismatchedQueryAndUpdateOfCollection")
private Set<ValueTableFactoryBeanProvider> valueTableFactoryBeanProviders;
@Autowired
private Set<ValueTableFactoryBean> valueTableFactoryBeans;
public SpringContextScanningDatasource(String name) {
super(name, "spring-context");
}
/*
* Added to fix ONYX-1436. This method allows reloading a ValueTable. It's implemented here because this instance
* holds a ValueTableFactory which should be able to re-create the instance when required.
*/
public void reloadValueTable(String name) throws NoSuchValueTableException {
if(hasValueTable(name)) {
removeValueTable(name);
}
ValueTable table = initialiseValueTable(name);
Initialisables.initialise(table);
addValueTable(table);
}
/*
* Added to fix ONYX-1436. This method allows adding a new ValueTable that was not present in the spring-context when
* starting.
*/
public void addValueTable(ValueTableFactoryBean tableFactory) {
// Make a copy: we don't know if the injected set is mutable.
Set<ValueTableFactoryBean> newTables = Sets.newLinkedHashSet(valueTableFactoryBeans);
newTables.add(tableFactory);
valueTableFactoryBeans = newTables;
reloadValueTable(tableFactory.getValueTableName());
}
public void dropValueTable(final String name) {
if(hasValueTable(name)) {
removeValueTable(name);
}
valueTableFactoryBeans = Sets
.newLinkedHashSet(Iterables.filter(valueTableFactoryBeans, new Predicate<ValueTableFactoryBean>() {
@Override
public boolean apply(ValueTableFactoryBean input) {
return !input.getValueTableName().equals(name);
}
}));
// We cannot remove the table from the ValueTableFactoryBeanProvider instances.
}
@Override
protected Set<String> getValueTableNames() {
Set<String> names = Sets.newHashSet();
for(ValueTableFactoryBean factory : getAllValueTableFactoryBeans()) {
names.add(factory.getValueTableName());
}
return names;
}
@Override
protected ValueTable initialiseValueTable(String tableName) {
for(ValueTableFactoryBean factory : getAllValueTableFactoryBeans()) {
if(factory.getValueTableName().equals(tableName)) {
return factory.buildValueTable(this);
}
}
throw new NoSuchValueTableException(tableName);
}
private Iterable<ValueTableFactoryBean> getAllValueTableFactoryBeans() {
Set<ValueTableFactoryBean> allValueTableFactoryBeans = Sets.newHashSet();
// Include injected factory beans.
allValueTableFactoryBeans.addAll(valueTableFactoryBeans);
// Include factory beans from injected providers.
for(ValueTableFactoryBeanProvider provider : valueTableFactoryBeanProviders) {
allValueTableFactoryBeans.addAll(provider.getValueTableFactoryBeans());
}
return allValueTableFactoryBeans;
}
}