/* * 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.datasource.spss.support; import com.google.common.collect.Lists; import org.obiba.magma.MagmaRuntimeException; import org.obiba.magma.Value; import org.obiba.magma.ValueSequence; import org.obiba.magma.ValueType; import org.obiba.magma.type.TextType; import org.opendatafoundation.data.spss.SPSSVariable; import java.util.List; import static org.obiba.magma.datasource.spss.support.CharacterSetValidator.validate; public abstract class SpssValueFactory { private final boolean withValidation; private final List<Integer> valuesIndex; protected final SPSSVariable spssVariable; private final ValueType valueType; protected final boolean repeatable; private SpssTypeFormatter valueFormatter; public SpssValueFactory(List<Integer> valuesIndex, SPSSVariable spssVariable, ValueType valueType, boolean withValidation, boolean repeatable) { this.valuesIndex = valuesIndex; this.spssVariable = spssVariable; this.valueType = valueType; this.withValidation = withValidation; this.repeatable = repeatable; initializeVariableTypeFormatter(); } public Value create() { if (repeatable) { List<Value> values = Lists.newArrayListWithCapacity(valuesIndex.size()); valuesIndex.forEach(index -> values.add(createValue(index))); return valueType.sequenceOf(values); } else { return createValue(valuesIndex.get(0)); } } private Value createValue(int index) { String value = getValue(index); if (withValidation) { try { validate(value); } catch(SpssInvalidCharacterException e) { String variableName = spssVariable.getName(); throw new SpssDatasourceParsingException("Invalid characters in variable value.", "InvalidCharsetCharacter", index, e.getSource()).dataInfo(variableName, index).extraInfo(e); } catch(MagmaRuntimeException e) { String variableName = spssVariable.getName(); throw new SpssDatasourceParsingException("Failed to create variable value", "SpssFailedToCreateVariable", variableName, index).dataInfo(variableName, index).extraInfo(e.getMessage()); } } return valueType.valueOf(valueFormatter.format(value)); } protected abstract String getValue(int index); @SuppressWarnings("PMD.NcssMethodCount") private void initializeVariableTypeFormatter() { if(valueType instanceof TextType) { valueFormatter = new SpssDefaultTypeFormatter(); return; } switch(SpssVariableTypeMapper.getSpssNumericDataType(spssVariable)) { case DOT: valueFormatter = new SpssDotTypeFormatter(); break; case COMMA: valueFormatter = new SpssCommaTypeFormatter(); break; case DOLLAR: valueFormatter = new SpssDollarTypeFormatter(); break; case FIXED: case SCIENTIFIC: valueFormatter = new SpssNumberTypeFormatter(); break; default: valueFormatter = new SpssDefaultTypeFormatter(); } } // // Inner classes // private interface SpssTypeFormatter { String format(String value); } private static class SpssDefaultTypeFormatter implements SpssTypeFormatter { @Override public String format(String value) { String trimmed = value.trim(); return trimmed.isEmpty() ? null : trimmed; } } private static class SpssNumberTypeFormatter extends SpssDefaultTypeFormatter { @Override public String format(String value) { return super.format(value.replaceAll("\\*", "")); // removes overflow delimeter if any } } private static class SpssDotTypeFormatter extends SpssNumberTypeFormatter { @Override public String format(String value) { return super.format(value.replaceAll("\\.", "").replaceAll(",", ".")); } } private static class SpssCommaTypeFormatter extends SpssNumberTypeFormatter { @Override public String format(String value) { return super.format(value.replaceAll(",", "")); } } private static class SpssDollarTypeFormatter extends SpssNumberTypeFormatter { @Override public String format(String value) { return super.format(value.replaceAll("\\$|,", "")); } } }