/*
* Copyright (C) 2006-2016 DLR, Germany
*
* All rights reserved
*
* http://www.rcenvironment.de/
*/
package de.rcenvironment.core.datamodel.internal;
import de.rcenvironment.core.datamodel.api.DataType;
import de.rcenvironment.core.datamodel.api.DataTypeException;
import de.rcenvironment.core.datamodel.api.TypedDatum;
import de.rcenvironment.core.datamodel.api.TypedDatumConverter;
import de.rcenvironment.core.datamodel.types.api.BooleanTD;
import de.rcenvironment.core.datamodel.types.api.DateTimeTD;
import de.rcenvironment.core.datamodel.types.api.FloatTD;
import de.rcenvironment.core.datamodel.types.api.IntegerTD;
import de.rcenvironment.core.datamodel.types.api.MatrixTD;
import de.rcenvironment.core.datamodel.types.api.SmallTableTD;
import de.rcenvironment.core.datamodel.types.api.VectorTD;
import de.rcenvironment.core.datamodel.types.internal.MatrixTDImpl;
import de.rcenvironment.core.datamodel.types.internal.SmallTableTDImpl;
import de.rcenvironment.core.utils.common.StringUtils;
/**
* Default {@link TypedDatumConverter} implementation.
*
* @author Robert Mischke
* @author Jan Flink
* @author Sascha Zur
*/
public class DefaultTypedDatumConverter implements TypedDatumConverter {
private static final String STRING_CAN_NOT_CONVERT = "Can not convert from %s to %s";
private static DefaultTypedDatumFactory factory = new DefaultTypedDatumFactory();
@SuppressWarnings("unchecked")
@Override
public <T extends TypedDatum> T castOrConvert(TypedDatum input, Class<T> targetClass) throws DataTypeException {
return (T) castOrConvert(input, DataType.byTDClass(targetClass));
}
@Override
public TypedDatum castOrConvert(TypedDatum input, DataType targetType) throws DataTypeException {
DataType inputType = input.getDataType();
if (inputType.equals(targetType)) {
return input;
}
if (!isConvertibleTo(input, targetType)) {
throw new DataTypeException(StringUtils.format(STRING_CAN_NOT_CONVERT, input.getDataType().toString(), targetType.toString()));
}
if (targetType.equals(DataType.SmallTable)) {
switch (inputType) {
case Vector:
case Matrix:
// will be converted in second switch statement
break;
default:
// creates a new table with the input object in cell(0,0)
SmallTableTD smallTable = factory.createSmallTable(1, 1);
smallTable.setTypedDatumForCell(input, 0, 0);
return smallTable;
}
}
switch (inputType) {
case Boolean:
BooleanTD boolDatum = (BooleanTD) input;
if (boolDatum.getBooleanValue()) {
return castOrConvert(factory.createInteger(1), targetType);
} else {
return castOrConvert(factory.createInteger(0), targetType);
}
case Integer:
IntegerTD integerDatum = (IntegerTD) input;
return castOrConvert(factory.createFloat((double) integerDatum.getIntValue()), targetType);
case Float:
FloatTD floatDatum = (FloatTD) input;
VectorTD vector = factory.createVector(1);
vector.setFloatTDForElement(floatDatum, 0);
return castOrConvert(vector, targetType);
case Vector:
VectorTD vectorDatum = (VectorTD) input;
FloatTD[][] matrixEntries = new FloatTD[vectorDatum.getRowDimension()][1];
for (int i = 0; i < vectorDatum.getRowDimension(); i++) {
matrixEntries[i][0] = vectorDatum.getFloatTDOfElement(i);
}
return castOrConvert(new MatrixTDImpl(matrixEntries), targetType);
case Matrix:
MatrixTD matrixDatum = (MatrixTD) input;
return castOrConvert(new SmallTableTDImpl(matrixDatum.toArray()), targetType);
case DateTime:
IntegerTD integer = factory.createInteger(((DateTimeTD) input).getDateTimeInMilliseconds());
return castOrConvert(integer, targetType);
default:
throw new DataTypeException(StringUtils.format(STRING_CAN_NOT_CONVERT, inputType.toString(), targetType.toString()));
}
}
@Override
public boolean isConvertibleTo(TypedDatum input, Class<? extends TypedDatum> targetType) {
return isConvertibleTo(input, DataType.byTDClass(targetType));
}
@Override
public boolean isConvertibleTo(TypedDatum input, DataType targetType) {
return TypedDatumConversionTable.getTable()[TypedDatumConversionTable.getIndexOfType(input.getDataType())][TypedDatumConversionTable
.getIndexOfType(targetType)] == TypedDatumConversionTable.IS_CONVERTIBLE;
}
@Override
public boolean isConvertibleTo(DataType sourceType, DataType targetType) {
return TypedDatumConversionTable.getTable()[TypedDatumConversionTable.getIndexOfType(sourceType)][TypedDatumConversionTable
.getIndexOfType(targetType)] == TypedDatumConversionTable.IS_CONVERTIBLE;
}
@SuppressWarnings("unchecked")
@Override
public <T extends TypedDatum> T castOrConvertUnsafe(TypedDatum input, Class<T> targetClass) throws DataTypeException {
return (T) castOrConvertUnsafe(input, DataType.byTDClass(targetClass));
}
@Override
public TypedDatum castOrConvertUnsafe(TypedDatum input, DataType targetType) throws DataTypeException {
DataType inputType = input.getDataType();
if (inputType.equals(targetType)) {
return input;
}
if (!isUnsafeConvertibleTo(input, targetType)) {
throw new DataTypeException(StringUtils.format(STRING_CAN_NOT_CONVERT, inputType.toString(), targetType.toString()));
}
// currently, only conversions to ShortText are unsafe possible.
switch (inputType) {
case Empty:
return factory.createShortText("");
case Boolean:
return factory.createShortText(input.toString());
case Integer:
return factory.createShortText(input.toString());
case Float:
return factory.createShortText(input.toString());
default:
throw new DataTypeException(StringUtils.format(STRING_CAN_NOT_CONVERT, inputType.toString(), targetType.toString()));
}
}
@Override
public boolean isUnsafeConvertibleTo(TypedDatum input, Class<? extends TypedDatum> targetType) {
return isUnsafeConvertibleTo(input, DataType.byTDClass(targetType));
}
@Override
public boolean isUnsafeConvertibleTo(TypedDatum input, DataType targetType) {
return TypedDatumConversionTable.getTable()[TypedDatumConversionTable.getIndexOfType(input.getDataType())][TypedDatumConversionTable
.getIndexOfType(targetType)] == TypedDatumConversionTable.IS_UNSAFE_CONVERTIBLE;
}
@Override
public boolean isUnsafeConvertibleTo(DataType sourceType, DataType targetType) {
return TypedDatumConversionTable.getTable()[TypedDatumConversionTable.getIndexOfType(sourceType)][TypedDatumConversionTable
.getIndexOfType(targetType)] == TypedDatumConversionTable.IS_UNSAFE_CONVERTIBLE;
}
}