| /******************************************************************************** |
| * Copyright (c) 2015-2019 Contributors to the Eclipse Foundation |
| * |
| * See the NOTICE file(s) distributed with this work for additional |
| * information regarding copyright ownership. |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v. 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0. |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| ********************************************************************************/ |
| |
| package org.eclipse.mdm.api.odsadapter.utils; |
| |
| import java.lang.reflect.Array; |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import org.eclipse.mdm.api.base.model.AxisType; |
| import org.eclipse.mdm.api.base.model.EnumRegistry; |
| import org.eclipse.mdm.api.base.model.Enumeration; |
| import org.eclipse.mdm.api.base.model.EnumerationValue; |
| import org.eclipse.mdm.api.base.model.Interpolation; |
| import org.eclipse.mdm.api.base.model.ScalarType; |
| import org.eclipse.mdm.api.base.model.SequenceRepresentation; |
| import org.eclipse.mdm.api.base.model.TypeSpecification; |
| import org.eclipse.mdm.api.base.model.VersionState; |
| |
| /** |
| * Utility class for enumeration constant conversions from/to ODS types. |
| * |
| * @since 1.0.0 |
| * @author Viktor Stoehr, Gigatronik Ingolstadt GmbH |
| */ |
| public final class ODSEnumerations { |
| |
| // ====================================================================== |
| // Class variables |
| // ====================================================================== |
| |
| private static final String SCALAR_TYPE_NAME = "datatype_enum"; |
| private static final String STATE_NAME = "valid_enum"; |
| private static final String INTERPOLATION_NAME = "interpolation_enum"; |
| private static final String AXIS_TYPE_NAME = "axistype"; |
| private static final String TYPE_SPECIFICATION_NAME = "typespec_enum"; |
| private static final String SEQUENCE_REPRESENTATION_NAME = "seq_rep_enum"; |
| |
| // ====================================================================== |
| // Constructors |
| // ====================================================================== |
| |
| /** |
| * Constructor. |
| */ |
| private ODSEnumerations() { |
| } |
| |
| // ====================================================================== |
| // Public methods |
| // ====================================================================== |
| |
| /** |
| * Returns the enumeration class identified by given name. |
| * |
| * @param <E> The enumeration type. |
| * @param name The ODS name of the requested enumeration class. |
| * @return The corresponding enumeration class is returned. |
| * @throws IllegalArgumentException Thrown if ODS enumeration name is unknown. |
| */ |
| // FIXME (Florian Schmitt): can we do this simpler? |
| public static Enumeration<? extends EnumerationValue> getEnumObj(String name) { |
| EnumRegistry er = EnumRegistry.getInstance(); |
| if (SCALAR_TYPE_NAME.equals(name)) { |
| return (er.get(EnumRegistry.SCALAR_TYPE)); |
| } else if (STATE_NAME.equals(name)) { |
| return (er.get(EnumRegistry.VERSION_STATE)); |
| } else if (INTERPOLATION_NAME.equals(name)) { |
| return (er.get(EnumRegistry.INTERPOLATION)); |
| } else if (AXIS_TYPE_NAME.equals(name)) { |
| return (er.get(EnumRegistry.AXIS_TYPE)); |
| } else if (TYPE_SPECIFICATION_NAME.equals(name)) { |
| return (er.get(EnumRegistry.TYPE_SPECIFICATION)); |
| } else if (SEQUENCE_REPRESENTATION_NAME.equals(name)) { |
| return (er.get(EnumRegistry.SEQUENCE_REPRESENTATION)); |
| } else { |
| return er.get(name); |
| } |
| } |
| |
| /** |
| * Returns the ODS enumeration name for given enumeration class. |
| * |
| * @param enumObj The enumeration object. |
| * @return The corresponding ODS enumeration name is returned. |
| * @throws IllegalArgumentException Thrown if enumeration class is unknown. |
| */ |
| public static String getEnumName(Enumeration<?> enumObj) { |
| if (enumObj == null) { |
| throw new IllegalArgumentException("EnumerationValue class is not allowed to be null."); |
| } else if (EnumRegistry.SCALAR_TYPE.equals(enumObj.getName())) { |
| return SCALAR_TYPE_NAME; |
| } else if (EnumRegistry.VERSION_STATE.equals(enumObj.getName())) { |
| return STATE_NAME; |
| } else if (EnumRegistry.INTERPOLATION.equals(enumObj.getName())) { |
| return INTERPOLATION_NAME; |
| } else if (EnumRegistry.AXIS_TYPE.equals(enumObj.getName())) { |
| return AXIS_TYPE_NAME; |
| } else if (EnumRegistry.TYPE_SPECIFICATION.equals(enumObj.getName())) { |
| return TYPE_SPECIFICATION_NAME; |
| } else if (EnumRegistry.SEQUENCE_REPRESENTATION.equals(enumObj.getName())) { |
| return SEQUENCE_REPRESENTATION_NAME; |
| } else { |
| return enumObj.getName(); |
| } |
| } |
| |
| // ====================================================================== |
| // Package methods |
| // ====================================================================== |
| |
| /** |
| * Converts given ODS enumeration value using given enumeration class to the |
| * corresponding enumeration constant. |
| * |
| * @param <E> The enumeration type. |
| * @param enumClass The enumeration class. |
| * @param value The ODS enumeration value. |
| * @return The corresponding enumeration constant is returned. |
| * @throws IllegalArgumentException Thrown if conversion not possible. |
| */ |
| @SuppressWarnings("unchecked") |
| // FIXME: cant we have this easier? |
| static <E extends EnumerationValue> E fromODSEnum(Enumeration<E> enumObj, int value) { |
| if (enumObj == null) { |
| throw new IllegalArgumentException("EnumerationValue class is not allowed to be null."); |
| } else if (EnumRegistry.SCALAR_TYPE.equals(enumObj.getName())) { |
| return (E) fromODSScalarType(value); |
| } else if (EnumRegistry.SEQUENCE_REPRESENTATION.equals(enumObj.getName())) { |
| return (E) fromODSSequenceRepresentation(value); |
| } else { |
| return (E) fromODSEnumByOrdinal(enumObj, value); |
| } |
| } |
| |
| /** |
| * Converts given ODS enumeration values using given enumeration class to the |
| * corresponding enumeration constants. |
| * |
| * @param <E> The enumeration type. |
| * @param enumClass The enumeration class. |
| * @param values The ODS enumeration values. |
| * @return The corresponding enumeration constants are returned. |
| * @throws IllegalArgumentException Thrown if conversion not possible. |
| */ |
| @SuppressWarnings("unchecked") |
| static <E extends EnumerationValue> E[] fromODSEnumSeq(Enumeration<?> enumObj, int[] values) { |
| if (enumObj == null) { |
| throw new IllegalArgumentException("EnumerationValue class is not allowed to be null."); |
| } else if (EnumRegistry.SCALAR_TYPE.equals(enumObj.getName())) { |
| List<E> scalarTypes = new ArrayList<>(values.length); |
| for (int value : values) { |
| scalarTypes.add((E) fromODSScalarType(value)); |
| } |
| return (E[]) scalarTypes.toArray(new ScalarType[values.length]); |
| } else if (EnumRegistry.SEQUENCE_REPRESENTATION.equals(enumObj.getName())) { |
| List<E> sequenceRepresentations = new ArrayList<>(values.length); |
| for (int value : values) { |
| sequenceRepresentations.add((E) fromODSSequenceRepresentation(value)); |
| } |
| return (E[]) sequenceRepresentations.toArray(new SequenceRepresentation[values.length]); |
| } else { |
| return (E[]) fromODSEnumSeqByOrdinal(enumObj, values); |
| } |
| } |
| |
| /** |
| * Converts given enumeration constant to the corresponding ODS enumeration |
| * value. |
| * |
| * @param <E> The enumeration type. |
| * @param constant The enumeration constant. |
| * @return The corresponding ODS enumeration value is returned. |
| * @throws IllegalArgumentException Thrown if conversion not possible. |
| */ |
| static <E extends EnumerationValue> int toODSEnum(E constant) { |
| if (constant == null) { |
| return 0; |
| } else if (constant instanceof ScalarType) { |
| return toODSScalarType((ScalarType) constant); |
| } else if (constant instanceof VersionState || constant instanceof Interpolation || constant instanceof AxisType |
| || constant instanceof TypeSpecification) { |
| // NOTE: Ordinal numbers map directly to the corresponding ODS |
| // enumeration constant value. |
| return constant.ordinal(); |
| } else if (constant instanceof SequenceRepresentation) { |
| return toODSSequenceRepresentation((SequenceRepresentation) constant); |
| } |
| |
| throw new IllegalArgumentException( |
| "EnumerationValue mapping for type '" + constant.getClass().getSimpleName() + "' does not exist."); |
| } |
| |
| /** |
| * Converts given enumeration constants to the corresponding ODS enumeration |
| * values. |
| * |
| * @param <E> The enumeration type. |
| * @param constants The enumeration constants. |
| * @return The corresponding ODS enumeration values are returned. |
| * @throws IllegalArgumentException Thrown if conversion not possible. |
| */ |
| static <E extends EnumerationValue> int[] toODSEnumSeq(E[] constants) { |
| if (constants == null) { |
| return new int[0]; |
| } |
| |
| int[] values = new int[constants.length]; |
| if (constants instanceof ScalarType[]) { |
| for (int i = 0; i < values.length; i++) { |
| values[i] = toODSScalarType((ScalarType) constants[i]); |
| } |
| } else if (constants instanceof VersionState[] || constants instanceof Interpolation[] |
| || constants instanceof AxisType[] || constants instanceof TypeSpecification[]) { |
| for (int i = 0; i < values.length; i++) { |
| // NOTE: Ordinal numbers directly map to the corresponding ODS |
| // enumeration constant value. |
| // FIXME: do we really want this? |
| values[i] = ((EnumerationValue) constants[i]).ordinal(); |
| } |
| } else if (constants instanceof SequenceRepresentation[]) { |
| for (int i = 0; i < values.length; i++) { |
| values[i] = toODSSequenceRepresentation((SequenceRepresentation) constants[i]); |
| } |
| } else { |
| throw new IllegalArgumentException("EnumerationValue mapping for type '" |
| + constants.getClass().getComponentType().getSimpleName() + "' does not exist."); |
| } |
| |
| return values; |
| } |
| |
| // ====================================================================== |
| // Private methods |
| // ====================================================================== |
| |
| /** |
| * Converts given ODS enumeration value to the corresponding {@link ScalarType} |
| * constant. |
| * |
| * @param value The ODS enumeration value. |
| * @return The corresponding {@code ScalarType} constant is returned. |
| * @throws IllegalArgumentException Thrown if conversion not possible. |
| */ |
| private static ScalarType fromODSScalarType(int value) { |
| if (value == 0) { |
| return ScalarType.UNKNOWN; |
| } else if (value == 1) { |
| return ScalarType.STRING; |
| } else if (value == 2) { |
| return ScalarType.SHORT; |
| } else if (value == 3) { |
| return ScalarType.FLOAT; |
| } else if (value == 4) { |
| return ScalarType.BOOLEAN; |
| } else if (value == 5) { |
| return ScalarType.BYTE; |
| } else if (value == 6) { |
| return ScalarType.INTEGER; |
| } else if (value == 7) { |
| return ScalarType.DOUBLE; |
| } else if (value == 8) { |
| return ScalarType.LONG; |
| } else if (value == 10) { |
| return ScalarType.DATE; |
| } else if (value == 11) { |
| return ScalarType.BYTE_STREAM; |
| } else if (value == 12) { |
| return ScalarType.BLOB; |
| } else if (value == 13) { |
| return ScalarType.FLOAT_COMPLEX; |
| } else if (value == 14) { |
| return ScalarType.DOUBLE_COMPLEX; |
| } else if (value == 28) { |
| return ScalarType.FILE_LINK; |
| } else if (value == 30) { |
| return ScalarType.ENUMERATION; |
| } |
| |
| throw new IllegalArgumentException("Unable to map ODS enumeration vaue '" + value + "' to constant of type '" |
| + ScalarType.class.getSimpleName() + "'."); |
| } |
| |
| /** |
| * Converts given {@link ScalarType} to the corresponding ODS enumeration value. |
| * |
| * @param scalarType The {@code ScalarType}. |
| * @return The corresponding ODS enumeration value is returned. |
| * @throws IllegalArgumentException Thrown if conversion not possible. |
| */ |
| private static int toODSScalarType(ScalarType scalarType) { |
| if (ScalarType.UNKNOWN == scalarType) { |
| return 0; |
| } else if (ScalarType.STRING == scalarType) { |
| return 1; |
| } else if (ScalarType.SHORT == scalarType) { |
| return 2; |
| } else if (ScalarType.FLOAT == scalarType) { |
| return 3; |
| } else if (ScalarType.BOOLEAN == scalarType) { |
| return 4; |
| } else if (ScalarType.BYTE == scalarType) { |
| return 5; |
| } else if (ScalarType.INTEGER == scalarType) { |
| return 6; |
| } else if (ScalarType.DOUBLE == scalarType) { |
| return 7; |
| } else if (ScalarType.LONG == scalarType) { |
| return 8; |
| } else if (ScalarType.DATE == scalarType) { |
| return 10; |
| } else if (ScalarType.BYTE_STREAM == scalarType) { |
| return 11; |
| } else if (ScalarType.BLOB == scalarType) { |
| return 12; |
| } else if (ScalarType.FLOAT_COMPLEX == scalarType) { |
| return 13; |
| } else if (ScalarType.DOUBLE_COMPLEX == scalarType) { |
| return 14; |
| } else if (ScalarType.FILE_LINK == scalarType) { |
| return 28; |
| } else if (ScalarType.ENUMERATION == scalarType) { |
| return 30; |
| } |
| |
| throw new IllegalArgumentException("Unable to map enumeration constant '" + scalarType + "' of type '" |
| + ScalarType.class.getSimpleName() + "' to ODS enumeration value."); |
| } |
| |
| /** |
| * Converts given ODS enumeration value to the corresponding |
| * {@link SequenceRepresentation} constant. |
| * |
| * @param value The ODS enumeration value. |
| * @return The corresponding {@code SequenceRepresentation} constant is |
| * returned. |
| * @throws IllegalArgumentException Thrown if conversion not possible. |
| */ |
| private static SequenceRepresentation fromODSSequenceRepresentation(int value) { |
| if (value == 0) { |
| return SequenceRepresentation.EXPLICIT; |
| } else if (value == 1) { |
| return SequenceRepresentation.IMPLICIT_CONSTANT; |
| } else if (value == 2) { |
| return SequenceRepresentation.IMPLICIT_LINEAR; |
| } else if (value == 3) { |
| return SequenceRepresentation.IMPLICIT_SAW; |
| } else if (value == 4) { |
| return SequenceRepresentation.RAW_LINEAR; |
| } else if (value == 5) { |
| return SequenceRepresentation.RAW_POLYNOMIAL; |
| } else if (value == 7) { |
| return SequenceRepresentation.EXPLICIT_EXTERNAL; |
| } else if (value == 8) { |
| return SequenceRepresentation.RAW_LINEAR_EXTERNAL; |
| } else if (value == 9) { |
| return SequenceRepresentation.RAW_POLYNOMIAL_EXTERNAL; |
| } else if (value == 10) { |
| return SequenceRepresentation.RAW_LINEAR_CALIBRATED; |
| } else if (value == 11) { |
| return SequenceRepresentation.RAW_LINEAR_CALIBRATED_EXTERNAL; |
| } |
| |
| throw new IllegalArgumentException("Unable to map ODS enumeration vaue '" + value + "' to constant of type '" |
| + SequenceRepresentation.class.getSimpleName() + "'."); |
| } |
| |
| /** |
| * Converts given {@link SequenceRepresentation} to the corresponding ODS |
| * enumeration value. |
| * |
| * @param sequenceRepresentation The {@code SequenceRepresentation}. |
| * @return The corresponding ODS enumeration value is returned. |
| * @throws IllegalArgumentException Thrown if conversion not possible. |
| */ |
| private static int toODSSequenceRepresentation(SequenceRepresentation sequenceRepresentation) { |
| if (SequenceRepresentation.EXPLICIT == sequenceRepresentation) { |
| return 0; |
| } else if (SequenceRepresentation.IMPLICIT_CONSTANT == sequenceRepresentation) { |
| return 1; |
| } else if (SequenceRepresentation.IMPLICIT_LINEAR == sequenceRepresentation) { |
| return 2; |
| } else if (SequenceRepresentation.IMPLICIT_SAW == sequenceRepresentation) { |
| return 3; |
| } else if (SequenceRepresentation.RAW_LINEAR == sequenceRepresentation) { |
| return 4; |
| } else if (SequenceRepresentation.RAW_POLYNOMIAL == sequenceRepresentation) { |
| return 5; |
| } else if (SequenceRepresentation.EXPLICIT_EXTERNAL == sequenceRepresentation) { |
| return 7; |
| } else if (SequenceRepresentation.RAW_LINEAR_EXTERNAL == sequenceRepresentation) { |
| return 8; |
| } else if (SequenceRepresentation.RAW_POLYNOMIAL_EXTERNAL == sequenceRepresentation) { |
| return 9; |
| } else if (SequenceRepresentation.RAW_LINEAR_CALIBRATED == sequenceRepresentation) { |
| return 10; |
| } else if (SequenceRepresentation.RAW_LINEAR_CALIBRATED_EXTERNAL == sequenceRepresentation) { |
| return 11; |
| } |
| |
| throw new IllegalArgumentException("Unable to map enumeration constant '" + sequenceRepresentation |
| + "' of type '" + SequenceRepresentation.class.getSimpleName() + "' to ODS enumeration value."); |
| } |
| |
| /** |
| * Converts given ODS enumeration value to the corresponding enumeration |
| * constant. The ODS enumeration value is used as the ordinal number of the |
| * requested enumeration constant. |
| * |
| * @param <E> The enumeration type. |
| * @param enumClass The enumeration class. |
| * @param value The ODS enumeration value. |
| * @return The corresponding enumeration constant is returned. |
| * @throws IllegalArgumentException Thrown if conversion not possible. |
| */ |
| private static <E extends EnumerationValue> E fromODSEnumByOrdinal(Enumeration<E> enumObj, int value) { |
| // NOTE: Ordinal numbers directly map to the corresponding ODS |
| // enumeration constant value. |
| E enumvalue = enumObj.valueOf(value); |
| if (enumvalue == null) { |
| throw new IllegalArgumentException(); |
| } |
| return enumvalue; |
| } |
| |
| /** |
| * Converts given ODS enumeration values to the corresponding enumeration |
| * constants. The ODS enumeration values are used as the ordinal numbers of the |
| * requested enumeration constants. |
| * |
| * @param <E> The enumeration type. |
| * @param enumClass The enumeration class. |
| * @param values The ODS enumeration values. |
| * @return The corresponding enumeration constants are returned. |
| * @throws IllegalArgumentException Thrown if conversion not possible. |
| */ |
| @SuppressWarnings("unchecked") |
| private static <E extends EnumerationValue> E[] fromODSEnumSeqByOrdinal(Enumeration<E> enumObj, int[] values) { |
| List<E> enumValues = new ArrayList<>(values.length); |
| |
| for (int value : values) { |
| // NOTE: Ordinal numbers directly map to the corresponding ODS |
| // enumeration constant value. |
| E enumvalue = enumObj.valueOf(value); |
| if (enumvalue == null) { |
| throw new IllegalArgumentException(); |
| } |
| enumValues.add(enumvalue); |
| } |
| |
| return enumValues.toArray((E[]) Array.newInstance(enumObj.getClass(), values.length)); |
| } |
| |
| } |