Skip to content
TypesMapping.java 5.37 KiB
Newer Older
/*
 * _____________________________________________________________________________
 * 
 * INAF - OATS National Institute for Astrophysics - Astronomical Observatory of
 * Trieste INAF - IA2 Italian Center for Astronomical Archives
 * _____________________________________________________________________________
 * 
 * Copyright (C) 2017 Istituto Nazionale di Astrofisica
 * 
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License Version 3 as published by the
 * Free Software Foundation.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc., 51
 * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */
package it.inaf.ia2.tsm.model;

import it.inaf.ia2.tsm.datalayer.ADQL;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import javax.xml.bind.JAXB;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElements;
import javax.xml.bind.annotation.XmlRootElement;

/**
 *
 * @author Sonia Zorba {@literal <zorba at oats.inaf.it>}
 */
public class TypesMapping {

    // For older TAP_SCHEMA versions
    private static final String ADQL_PREFIX = "adql:";

    @XmlRootElement(name = "sql_type_mapping")
    static class TypesWrapper {

        private List<TypeMapping> types;

        @XmlElements({
            @XmlElement(name = "type")
        })
        public List<TypeMapping> getTypes() {
            return types;
        }

        public void setTypes(List<TypeMapping> types) {
            this.types = types;
        }
    }

    private static final List<TypeMapping> TYPES;

    static {
        try (InputStream is = TypeMapping.class.getClassLoader().getResourceAsStream("sql_type_mapping.xml")) {

            TypesWrapper typesWrapper = JAXB.unmarshal(is, TypesWrapper.class);
            TYPES = typesWrapper.types;
        } catch (IOException e) {
            throw new ExceptionInInitializerError(e);
        }
    }

    private static TypeMapping getTypeMappingFromADQLType(String adqlType) {
        for (TypeMapping typeMapping : TYPES) {
            if (adqlType.equals(typeMapping.getAdqlType())) {
                return typeMapping;
            }
        }
        throw new IllegalArgumentException("Unable to retrieve mapping for ADQL type " + adqlType);
    }

    /**
     * returns an ADQL type String compatible with older TAP_SCHEMA versions
     * (for older versions "adql:" prefix is needed).
     */
    private static String getCompatibleADQLType(String adqlType, String tapSchemaVersion) {
        if (tapSchemaVersion.startsWith("1.0")) {
            return ADQL_PREFIX + adqlType;
        }
        return adqlType;
    }

    public static Class getClassFromAdqlType(String adqlType) {
        return getTypeMappingFromADQLType(adqlType).getJavaType();
    }

    public static String getMySQLTypeFromADQLType(String adqlType) {
        return getTypeMappingFromADQLType(adqlType).getMySQLType();
    }

    public static String getPostgresSQLTypeFromADQLType(String adqlType) {
        return getTypeMappingFromADQLType(adqlType).getPgsqlType();
    }

    private static String getADQLTypeFromPostgresType(String pgsqlType) {
        for (TypeMapping typeMapping : TYPES) {
            if (pgsqlType.toUpperCase().startsWith(typeMapping.getPgsqlType().toUpperCase())) {
                return typeMapping.getAdqlType();
            }
        }
        return ADQL.getDataType(pgsqlType);
    }

    public static String getADQLTypeFromPostgresType(String pgsqlType, String tapSchemaVersion) {
        return getCompatibleADQLType(getADQLTypeFromPostgresType(pgsqlType), tapSchemaVersion);
    }

    private static String getADQLTypeFromMySQLType(String mysqlType) {
        for (TypeMapping typeMapping : TYPES) {
            if (mysqlType.toUpperCase().startsWith(typeMapping.getMySQLType().toUpperCase())) {
                return typeMapping.getAdqlType();
            }
        }
        return ADQL.getDataType(mysqlType);
    }

    public static String getADQLTypeFromMySQLType(String mysqlType, String tapSchemaVersion) {
        return getCompatibleADQLType(getADQLTypeFromMySQLType(mysqlType), tapSchemaVersion);
    }

    public static Object parseDefaultValue(String defaultValue, String type) {
        return parseDefaultValue(defaultValue, ADQL.valueOf(type));
    }

    public static Object parseDefaultValue(String defaultValue, ADQL type) {

        switch (type) {
            case VARCHAR:
            case CHAR:
                return defaultValue;
            case INTEGER:
            case SMALLINT:
                return Integer.parseInt(defaultValue);
            case BIGINT:
                return Long.parseLong(defaultValue);
            case REAL:
                return Float.parseFloat(defaultValue);
            case DOUBLE:
                return Double.parseDouble(defaultValue);
            case BOOLEAN:
                return Boolean.parseBoolean(defaultValue);
            default:
                throw new UnsupportedOperationException("Default value for type " + type + " not supported yet.");
        }
    }
}