sh.isaac.api.component.semantic.version.dynamic.DynamicDataType.java Source code

Java tutorial

Introduction

Here is the source code for sh.isaac.api.component.semantic.version.dynamic.DynamicDataType.java

Source

/* 
 * 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.semantic.version.dynamic;

//~--- 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.constants.DynamicConstants;
import sh.isaac.api.component.semantic.version.dynamic.types.DynamicArray;
import sh.isaac.api.component.semantic.version.dynamic.types.DynamicBoolean;
import sh.isaac.api.component.semantic.version.dynamic.types.DynamicByteArray;
import sh.isaac.api.component.semantic.version.dynamic.types.DynamicDouble;
import sh.isaac.api.component.semantic.version.dynamic.types.DynamicFloat;
import sh.isaac.api.component.semantic.version.dynamic.types.DynamicInteger;
import sh.isaac.api.component.semantic.version.dynamic.types.DynamicLong;
import sh.isaac.api.component.semantic.version.dynamic.types.DynamicNid;
import sh.isaac.api.component.semantic.version.dynamic.types.DynamicPolymorphic;
import sh.isaac.api.component.semantic.version.dynamic.types.DynamicSequence;
import sh.isaac.api.component.semantic.version.dynamic.types.DynamicString;
import sh.isaac.api.component.semantic.version.dynamic.types.DynamicUUID;

//~--- enums ------------------------------------------------------------------

/**
 *
 * {@link DynamicDataType}
 *
 * Most types are fairly straight forward.  NIDs, SEQUQENCES and INTEGERS are identical internally.
 * Polymorphic is used when the data type for a dynamic isn't known at dynamic creation time.  In this case, a user of the API
 * will have to examine type types of the actual {@link DynamicData} 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 DynamicData}.
 *
 * {@link DynamicData} will never return a {@link POLYMORPHIC} type.
 *
 * @author kec
 * @author <a href="mailto:daniel.armbrust.list@gmail.com">Dan Armbrust</a>
 */
public enum DynamicDataType {
    /** The nid. */
    NID(101, DynamicNid.class, "Component Nid"),

    /** The string. */
    STRING(102, DynamicString.class, "String"),

    /** The integer. */
    INTEGER(103, DynamicInteger.class, "Integer"),

    /** The boolean. */
    BOOLEAN(104, DynamicBoolean.class, "Boolean"),

    /** The long. */
    LONG(105, DynamicLong.class, "Long"),

    /** The bytearray. */
    BYTEARRAY(106, DynamicByteArray.class, "Arbitrary Data"),

    /** The float. */
    FLOAT(107, DynamicFloat.class, "Float"),

    /** The double. */
    DOUBLE(108, DynamicDouble.class, "Double"),

    /** The uuid. */
    UUID(109, DynamicUUID.class, "UUID"),

    /** The polymorphic. */
    POLYMORPHIC(110, DynamicPolymorphic.class, "Unspecified"),

    /** The array. */
    ARRAY(111, DynamicArray.class, "Array"),

    /** The sequence. */
    SEQUENCE(112, DynamicSequence.class, "Component Sequence"),

    /** The unknown. */
    UNKNOWN(Byte.MAX_VALUE, null, "Unknown");

    /** The externalized token. */
    private int externalizedToken;

    /** The data class. */
    private Class<? extends DynamicData> dataClass;

    /** The display name. */
    private String displayName;

    //~--- constructors --------------------------------------------------------

    /**
     * Instantiates a new dynamic data type.
     *
     * @param externalizedToken the externalized token
     * @param dataClass the data class
     * @param displayName the display name
     */
    private DynamicDataType(int externalizedToken, Class<? extends DynamicData> dataClass, String displayName) {
        this.externalizedToken = externalizedToken;
        this.dataClass = dataClass;
        this.displayName = displayName;
    }

    //~--- methods -------------------------------------------------------------

    /**
     * Class to type.
     *
     * @param c the c
     * @return the dynamic data type
     */
    public static DynamicDataType classToType(Class<?> c) {
        if (DynamicNid.class.isAssignableFrom(c)) {
            return NID;
        }

        if (DynamicString.class.isAssignableFrom(c)) {
            return STRING;
        }

        if (DynamicInteger.class.isAssignableFrom(c)) {
            return INTEGER;
        }

        if (DynamicBoolean.class.isAssignableFrom(c)) {
            return BOOLEAN;
        }

        if (DynamicLong.class.isAssignableFrom(c)) {
            return LONG;
        }

        if (DynamicByteArray.class.isAssignableFrom(c)) {
            return BYTEARRAY;
        }

        if (DynamicFloat.class.isAssignableFrom(c)) {
            return FLOAT;
        }

        if (DynamicDouble.class.isAssignableFrom(c)) {
            return DOUBLE;
        }

        if (DynamicUUID.class.isAssignableFrom(c)) {
            return UUID;
        }

        if (DynamicPolymorphic.class.isAssignableFrom(c)) {
            return POLYMORPHIC;
        }

        if (DynamicArray.class.isAssignableFrom(c)) {
            return ARRAY;
        }

        if (DynamicSequence.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 data type
     */
    public static DynamicDataType 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 DynamicDataType.values()[i];
            }
        } catch (final NumberFormatException e) {
            for (final DynamicDataType x : DynamicDataType.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 DynamicConstants.get().DYNAMIC_DT_BOOLEAN.getUUID();

        case BYTEARRAY:
            return DynamicConstants.get().DYNAMIC_DT_BYTE_ARRAY.getUUID();

        case DOUBLE:
            return DynamicConstants.get().DYNAMIC_DT_DOUBLE.getUUID();

        case FLOAT:
            return DynamicConstants.get().DYNAMIC_DT_FLOAT.getUUID();

        case INTEGER:
            return DynamicConstants.get().DYNAMIC_DT_INTEGER.getUUID();

        case LONG:
            return DynamicConstants.get().DYNAMIC_DT_LONG.getUUID();

        case NID:
            return DynamicConstants.get().DYNAMIC_DT_NID.getUUID();

        case POLYMORPHIC:
            return DynamicConstants.get().DYNAMIC_DT_POLYMORPHIC.getUUID();

        case STRING:
            return DynamicConstants.get().DYNAMIC_DT_STRING.getUUID();

        case UNKNOWN:
            return DynamicConstants.get().UNKNOWN_CONCEPT;

        case UUID:
            return DynamicConstants.get().DYNAMIC_DT_UUID.getUUID();

        case ARRAY:
            return DynamicConstants.get().DYNAMIC_DT_ARRAY.getUUID();

        case SEQUENCE:
            return DynamicConstants.get().DYNAMIC_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 member class.
     *
     * @return the dynamic member class
     */
    public Class<? extends DynamicData> getDynamicMemberClass() {
        return this.dataClass;
    }

    /**
     * Gets the from token.
     *
     * @param type the type
     * @return the from token
     * @throws UnsupportedOperationException the unsupported operation exception
     */
    public static DynamicDataType 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;
    }
}