/* * Licensed under the Apache License, Version 2.0 (the "License"); * * You may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * limitations under the License. * * Contributions from 2013-2017 where performed either by US government * employees, or under US Veterans Health Administration contracts. * * US Veterans Health Administration contributions by government employees * are work of the U.S. Government and are not subject to copyright * protection in the United States. Portions contributed by government * employees are USGovWork (17USC ยง105). Not subject to copyright. * * Contribution by contractors to the US Veterans Health Administration * during this period are contractually contributed under the * Apache License, Version 2.0. * * See: https://www.usa.gov/government-works * * Contributions prior to 2013: * * Copyright (C) International Health Terminology Standards Development Organisation. * Licensed under the Apache License, Version 2.0. * */ package sh.isaac.api.component.sememe.version.dynamicSememe; //~--- JDK imports ------------------------------------------------------------ import java.security.InvalidParameterException; import java.util.Locale; import java.util.UUID; //~--- non-JDK imports -------------------------------------------------------- import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import sh.isaac.api.component.sememe.version.dynamicSememe.dataTypes.DynamicSememeArray; import sh.isaac.api.component.sememe.version.dynamicSememe.dataTypes.DynamicSememeBoolean; import sh.isaac.api.component.sememe.version.dynamicSememe.dataTypes.DynamicSememeByteArray; import sh.isaac.api.component.sememe.version.dynamicSememe.dataTypes.DynamicSememeDouble; import sh.isaac.api.component.sememe.version.dynamicSememe.dataTypes.DynamicSememeFloat; import sh.isaac.api.component.sememe.version.dynamicSememe.dataTypes.DynamicSememeInteger; import sh.isaac.api.component.sememe.version.dynamicSememe.dataTypes.DynamicSememeLong; import sh.isaac.api.component.sememe.version.dynamicSememe.dataTypes.DynamicSememeNid; import sh.isaac.api.component.sememe.version.dynamicSememe.dataTypes.DynamicSememePolymorphic; import sh.isaac.api.component.sememe.version.dynamicSememe.dataTypes.DynamicSememeSequence; import sh.isaac.api.component.sememe.version.dynamicSememe.dataTypes.DynamicSememeString; import sh.isaac.api.component.sememe.version.dynamicSememe.dataTypes.DynamicSememeUUID; import sh.isaac.api.constants.DynamicSememeConstants; //~--- enums ------------------------------------------------------------------ /** * * {@link DynamicSememeDataType} * * Most types are fairly straight forward. NIDs, SEQUQENCES and INTEGERS are identical internally. * Polymorphic is used when the data type for a dynamic sememe isn't known at dynamic sememe creation time. In this case, a user of the API * will have to examine type types of the actual {@link DynamicSememeData} objects returned, to look at the type. * * For all other types, the data type reported within the Refex Definition should exactly match the data type returned with * a {@link DynamicSememeData}. * * {@link DynamicSememeData} will never return a {@link POLYMORPHIC} type. * * @author kec * @author <a href="mailto:daniel.armbrust.list@gmail.com">Dan Armbrust</a> */ public enum DynamicSememeDataType { /** The nid. */ NID(101, DynamicSememeNid.class, "Component Nid"), /** The string. */ STRING(102, DynamicSememeString.class, "String"), /** The integer. */ INTEGER(103, DynamicSememeInteger.class, "Integer"), /** The boolean. */ BOOLEAN(104, DynamicSememeBoolean.class, "Boolean"), /** The long. */ LONG(105, DynamicSememeLong.class, "Long"), /** The bytearray. */ BYTEARRAY(106, DynamicSememeByteArray.class, "Arbitrary Data"), /** The float. */ FLOAT(107, DynamicSememeFloat.class, "Float"), /** The double. */ DOUBLE(108, DynamicSememeDouble.class, "Double"), /** The uuid. */ UUID(109, DynamicSememeUUID.class, "UUID"), /** The polymorphic. */ POLYMORPHIC(110, DynamicSememePolymorphic.class, "Unspecified"), /** The array. */ ARRAY(111, DynamicSememeArray.class, "Array"), /** The sequence. */ SEQUENCE(112, DynamicSememeSequence.class, "Component Sequence"), /** The unknown. */ UNKNOWN(Byte.MAX_VALUE, null, "Unknown"); /** The externalized token. */ private int externalizedToken; /** The data class. */ private Class<? extends DynamicSememeData> dataClass; /** The display name. */ private String displayName; //~--- constructors -------------------------------------------------------- /** * Instantiates a new dynamic sememe data type. * * @param externalizedToken the externalized token * @param dataClass the data class * @param displayName the display name */ private DynamicSememeDataType(int externalizedToken, Class<? extends DynamicSememeData> dataClass, String displayName) { this.externalizedToken = externalizedToken; this.dataClass = dataClass; this.displayName = displayName; } //~--- methods ------------------------------------------------------------- /** * Class to type. * * @param c the c * @return the dynamic sememe data type */ public static DynamicSememeDataType classToType(Class<?> c) { if (DynamicSememeNid.class.isAssignableFrom(c)) { return NID; } if (DynamicSememeString.class.isAssignableFrom(c)) { return STRING; } if (DynamicSememeInteger.class.isAssignableFrom(c)) { return INTEGER; } if (DynamicSememeBoolean.class.isAssignableFrom(c)) { return BOOLEAN; } if (DynamicSememeLong.class.isAssignableFrom(c)) { return LONG; } if (DynamicSememeByteArray.class.isAssignableFrom(c)) { return BYTEARRAY; } if (DynamicSememeFloat.class.isAssignableFrom(c)) { return FLOAT; } if (DynamicSememeDouble.class.isAssignableFrom(c)) { return DOUBLE; } if (DynamicSememeUUID.class.isAssignableFrom(c)) { return UUID; } if (DynamicSememePolymorphic.class.isAssignableFrom(c)) { return POLYMORPHIC; } if (DynamicSememeArray.class.isAssignableFrom(c)) { return ARRAY; } if (DynamicSememeSequence.class.isAssignableFrom(c)) { return SEQUENCE; } LogManager.getLogger() .warn("Couldn't map class {} to type!", c); return UNKNOWN; } /** * Parses the. * * @param nameOrTokenOrEnumId the name or token or enum id * @param exceptionOnParseFail the exception on parse fail * @return the dynamic sememe data type */ public static DynamicSememeDataType parse(String nameOrTokenOrEnumId, boolean exceptionOnParseFail) { if (nameOrTokenOrEnumId == null) { return null; } final String clean = nameOrTokenOrEnumId.toLowerCase(Locale.ENGLISH) .trim(); if (StringUtils.isBlank(clean)) { return null; } try { final int i = Integer.parseInt(clean); if (i > 100) { return getFromToken(i); } else { // enumId return DynamicSememeDataType.values()[i]; } } catch (final NumberFormatException e) { for (final DynamicSememeDataType x: DynamicSememeDataType.values()) { if (x.displayName.equalsIgnoreCase(clean) || x.name().toLowerCase().equals(clean)) { return x; } } } if (exceptionOnParseFail) { throw new InvalidParameterException("Could not determine DynamicSememeDataType from " + nameOrTokenOrEnumId); } else { return UNKNOWN; } } //~--- get methods --------------------------------------------------------- /** * Gets the data type concept. * * @return the data type concept */ public UUID getDataTypeConcept() { /* * Implementation note - these used to be defined in the constructor, and stored in a local variable - but * that lead to a circular loop between the references of static elements in this class and DynamicSememe, * specifically in the constructors - which would throw maven / surefire for a loop - resulting in a * class not found exception... which was a PITA to track down. So, don't do that.... */ switch (this) { case BOOLEAN: return DynamicSememeConstants.get().DYNAMIC_SEMEME_DT_BOOLEAN .getUUID(); case BYTEARRAY: return DynamicSememeConstants.get().DYNAMIC_SEMEME_DT_BYTE_ARRAY .getUUID(); case DOUBLE: return DynamicSememeConstants.get().DYNAMIC_SEMEME_DT_DOUBLE .getUUID(); case FLOAT: return DynamicSememeConstants.get().DYNAMIC_SEMEME_DT_FLOAT .getUUID(); case INTEGER: return DynamicSememeConstants.get().DYNAMIC_SEMEME_DT_INTEGER .getUUID(); case LONG: return DynamicSememeConstants.get().DYNAMIC_SEMEME_DT_LONG .getUUID(); case NID: return DynamicSememeConstants.get().DYNAMIC_SEMEME_DT_NID .getUUID(); case POLYMORPHIC: return DynamicSememeConstants.get().DYNAMIC_SEMEME_DT_POLYMORPHIC .getUUID(); case STRING: return DynamicSememeConstants.get().DYNAMIC_SEMEME_DT_STRING .getUUID(); case UNKNOWN: return DynamicSememeConstants.get().UNKNOWN_CONCEPT; case UUID: return DynamicSememeConstants.get().DYNAMIC_SEMEME_DT_UUID .getUUID(); case ARRAY: return DynamicSememeConstants.get().DYNAMIC_SEMEME_DT_ARRAY .getUUID(); case SEQUENCE: return DynamicSememeConstants.get().DYNAMIC_SEMEME_DT_SEQUENCE .getUUID(); default: throw new RuntimeException("Implementation error"); } } /** * Gets the display name. * * @return the display name */ public String getDisplayName() { return this.displayName; } /** * Gets the dynamic sememe member class. * * @return the dynamic sememe member class */ public Class<? extends DynamicSememeData> getDynamicSememeMemberClass() { return this.dataClass; } /** * Gets the from token. * * @param type the type * @return the from token * @throws UnsupportedOperationException the unsupported operation exception */ public static DynamicSememeDataType getFromToken(int type) throws UnsupportedOperationException { switch (type) { case 101: return NID; case 102: return STRING; case 103: return INTEGER; case 104: return BOOLEAN; case 105: return LONG; case 106: return BYTEARRAY; case 107: return FLOAT; case 108: return DOUBLE; case 109: return UUID; case 110: return POLYMORPHIC; case 111: return ARRAY; case 112: return SEQUENCE; default: return UNKNOWN; } } /** * Gets the type token. * * @return the type token */ public int getTypeToken() { return this.externalizedToken; } }