/* * 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.Set; import javax.annotation.Nullable; import javax.validation.constraints.NotNull; import org.obiba.magma.ValueTable; import org.obiba.magma.VariableEntity; import org.obiba.magma.transform.BijectiveFunction; import org.obiba.magma.transform.BijectiveFunctions; import org.obiba.magma.views.AbstractTransformingValueTableWrapper; import com.google.common.collect.Sets; /** * Transforming value table that limit the number of entities reported by the wrapped @{link ValueTable} */ public class BatchValueTable extends AbstractTransformingValueTableWrapper { private final ValueTable wrapped; private final BijectiveFunction<VariableEntity, VariableEntity> variableEntityMappingFunction; public BatchValueTable(ValueTable sourceTable, int limit) { wrapped = sourceTable; variableEntityMappingFunction = limit < 0 ? BijectiveFunctions.<VariableEntity>identity() : new BatchFunction(limit); } @Override public ValueTable getWrappedValueTable() { return wrapped; } @Override public int getVariableEntityCount() { // get the exact batch size if (getVariableEntityMappingFunction() instanceof BatchFunction) { BatchFunction batchFunction = (BatchFunction) getVariableEntityMappingFunction(); if (!batchFunction.isApplied()) { getVariableEntities(); } return batchFunction.getCount(); } return super.getVariableEntityCount(); } @NotNull @Override public BijectiveFunction<VariableEntity, VariableEntity> getVariableEntityMappingFunction() { return variableEntityMappingFunction; } private static class BatchFunction implements BijectiveFunction<VariableEntity, VariableEntity> { private final int limit; private final Set<VariableEntity> entities = Sets.newHashSet(); private boolean applied = false; private BatchFunction(int limit) { this.limit = limit; } private boolean isApplied() { return applied; } public int getCount() { return entities.size(); } @Override public VariableEntity unapply(VariableEntity from) { return entities.contains(from) ? from : null; } @Nullable @Override public VariableEntity apply(@Nullable VariableEntity input) { applied = true; if(entities.size() < limit) { entities.add(input); return input; } if(entities.contains(input)) { return input; } return null; } } }