/*
* 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.support;
import java.util.Map;
import java.util.Set;
import javax.validation.constraints.NotNull;
import org.obiba.magma.Datasource;
import org.obiba.magma.Value;
import org.obiba.magma.ValueTable;
import org.obiba.magma.ValueTableWriter;
import org.obiba.magma.Variable;
import org.obiba.magma.VariableEntity;
import org.obiba.magma.support.DatasourceCopier.MultiplexingStrategy;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
public class MultiplexingValueTableWriter implements ValueTableWriter {
private final ValueTable source;
private final DatasourceCopier copier;
private final Datasource destination;
private final MultiplexingStrategy strategy;
private final Map<String, ValueTableWriter> writers = Maps.newHashMap();
public MultiplexingValueTableWriter(ValueTable source, DatasourceCopier copier, Datasource destination,
MultiplexingStrategy strategy) {
this.source = source;
this.copier = copier;
this.destination = destination;
this.strategy = strategy;
}
@NotNull
@Override
public ValueSetWriter writeValueSet(@NotNull VariableEntity entity) {
return new MultiplexedValueSetWriter(entity);
}
@Override
public VariableWriter writeVariables() {
return new MultiplexedVariableWriter();
}
@Override
public void close() {
for(ValueTableWriter writer : writers.values()) {
writer.close();
}
}
@SuppressWarnings({ "AssignmentToMethodParameter", "PMD.AvoidReassigningParameters" })
private ValueTableWriter lookupWriter(String tableName) {
if(tableName == null) {
tableName = source.getName();
}
ValueTableWriter writer = writers.get(tableName);
if(writer == null) {
copier.notifyListeners(source, tableName, false);
writer = copier.createValueTableWriter(source, tableName, destination);
writers.put(tableName, writer);
}
return writer;
}
private class MultiplexedVariableWriter implements VariableWriter {
private final Map<ValueTableWriter, VariableWriter> writers = Maps.newHashMap();
@Override
public void writeVariable(@NotNull Variable variable) {
ValueTableWriter vtw = lookupWriter(strategy.multiplexVariable(variable));
VariableWriter writer = writers.get(vtw);
if(writer == null) {
writer = vtw.writeVariables();
writers.put(vtw, writer);
}
writer.writeVariable(variable);
}
@Override
public void removeVariable(@NotNull Variable variable) {
throw new UnsupportedOperationException("Variable cannot be removed from a Multiplexing table");
}
@Override
public void close() {
for(VariableWriter vw : writers.values()) {
vw.close();
}
writers.clear();
}
}
public class MultiplexedValueSetWriter implements ValueSetWriter {
private final VariableEntity entity;
private final Map<ValueTableWriter, ValueSetWriter> writers = Maps.newHashMap();
private final Set<String> tables = Sets.newLinkedHashSet();
public MultiplexedValueSetWriter(VariableEntity entity) {
this.entity = entity;
}
public Set<String> getTables() {
return tables;
}
@Override
public void writeValue(@NotNull Variable variable, Value value) {
String tableName = strategy.multiplexValueSet(entity, variable);
tables.add(tableName);
ValueTableWriter vtw = lookupWriter(tableName);
ValueSetWriter writer = writers.get(vtw);
if(writer == null) {
writer = vtw.writeValueSet(entity);
writers.put(vtw, writer);
}
writer.writeValue(variable, value);
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
@Override
public void close() {
for(ValueSetWriter vsw : writers.values()) {
vsw.close();
}
writers.clear();
}
}
}