Skip to content
TSMUtil.java 11.2 KiB
Newer Older
/* 
 * _____________________________________________________________________________
 * 
 * INAF - OATS National Institute for Astrophysics - Astronomical Observatory of
 * Trieste INAF - IA2 Italian Center for Astronomical Archives
 * _____________________________________________________________________________
 * 
 * Copyright (C) 2016 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;
import it.inaf.ia2.tsm.datalayer.Credentials;
import it.inaf.ia2.tsm.datalayer.DatabaseType;
import it.inaf.ia2.tsm.datalayer.DBWrapper;
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import org.postgresql.ds.PGPoolingDataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 * Utility class that contains some static methods to manage various operations
 * with the TAP_SCHEMA entities.
 * @author Sonia Zorba {@literal <zorba at oats.inaf.it>}
public class TSMUtil {
    private static final Logger LOG = LoggerFactory.getLogger(TSMUtil.class);
    public static DataSource createDataSource(Credentials credentials) {

        switch (credentials.getDatabaseType()) {

            case MYSQL:
                MysqlDataSource myds = new MysqlDataSource();

                myds.setServerName(credentials.getHostname());
                myds.setPortNumber(credentials.getPort());
                myds.setUser(credentials.getUsername());
                myds.setPassword(credentials.getPassword());

                return myds;

            case POSTGRES:
                PGPoolingDataSource pgds = new PGPoolingDataSource();

                pgds.setServerName(credentials.getHostname());
                pgds.setPortNumber(credentials.getPort());
                pgds.setUser(credentials.getUsername());
                pgds.setPassword(credentials.getPassword());
                pgds.setDatabaseName(credentials.getDatabase());

                return pgds;

            default:
                throw new UnsupportedOperationException(credentials.getDatabaseType() + " not supported yet.");
        }
    }

    protected static List<String> sortStringsList(List<String> list) {
        Collections.sort(list, String.CASE_INSENSITIVE_ORDER);
        return list;
    }

    protected static <T extends ChildEntity> List<T> getChildrenByStatus(Iterable<T> entities, Status... statuses) {
        List<T> ret = new ArrayList<>();
        for (T child : entities) {
            if (statuses == null || statuses.length == 0) {
Sonia Zorba's avatar
Sonia Zorba committed
                if (child != null) {
                    ret.add(child);
                }
            } else {
                for (Status status : statuses) {
                    if (child != null && child.getStatus().equals(status)) {
                        ret.add(child);
                        break;
                    }
                }
            }
        }
        return Collections.unmodifiableList(ret);
    }

    protected static <T extends ChildEntity> T getChild(Map<String, T> children, String childName, Status... statuses) {
        T child = children.get(childName);
        if (child == null) {
            return null;
        }
        if (statuses == null || statuses.length == 0) {
            return child;
        }
        for (Status status : statuses) {
            if (child.getStatus().equals(status)) {
                return child;
    protected static <T extends ChildEntity> List<String> getAddableChildrenNames(Map<String, T> children) {
        List<String> list = new ArrayList<>();

        for (Map.Entry<String, T> entry : children.entrySet()) {
            T entity = entry.getValue();
            if (entity == null || entity.getStatus() == Status.LOADED) {
                list.add(entry.getKey());
            }
        }
        return Collections.unmodifiableList(list);
    }

     * This method is thought for avoiding various problem encountered using the
     * standard {@code ResultSet} {@code getObject()} method.
     * In particular:
     * <ul>
     * <li>In some cases the {@code getObject()} method (e.g. with
     * {@code Integer.class}) returns 0 instead of null.
     * </li>
     * <li>
     * Method
     * {@code org.postgresql.jdbc4.Jdbc4ResultSet.getObject(int, Class<T>)} is
     * not yet implemented.
     * </li>
     * </ul>
    protected static <T> T getObject(ResultSet rs, String key, Class<T> type) throws SQLException {
        T ret;
        if (type == String.class) {
            ret = (T) rs.getString(key);
        } else if (type == Integer.class) {
            ret = (T) (Integer) rs.getInt(key);
        } else if (type == Long.class) {
            ret = (T) (Long) rs.getLong(key);
        } else if (type == Boolean.class) {
            ret = (T) (Boolean) rs.getBoolean(key);
        } else {
            throw new UnsupportedOperationException("Type " + type.getCanonicalName() + " not supported by " + TSMUtil.class.getCanonicalName() + " getObject() method");
     * Same as {@link DLUtil.getObject(ResultSet, String, Class<T>)}.
    protected static <T> T getObject(ResultSet rs, int i, Class<T> type) throws SQLException {
        T ret;
        if (type == String.class) {
            ret = (T) rs.getString(i);
        } else if (type == Integer.class) {
            ret = (T) (Integer) rs.getInt(i);
        } else if (type == Long.class) {
            ret = (T) (Long) rs.getLong(i);
        } else if (type == Boolean.class) {
            ret = (T) (Boolean) rs.getBoolean(i);
        } else {
            throw new UnsupportedOperationException("Type " + type.getCanonicalName() + " not supported by " + TSMUtil.class.getCanonicalName() + " getObject() method");
    protected static DataSource getSchemaDataSource(DBWrapper dbWrapper, TapSchema tapSchema, String schemaName) {
        return schemaName.equals(tapSchema.getName()) ? dbWrapper.getTapSchemaDataSource() : dbWrapper.getSourceDataSource();
    }

    protected static DatabaseType getSchemaDatabaseType(DBWrapper dbWrapper, TapSchema tapSchema, String schemaName) {
        return schemaName.equals(tapSchema.getName()) ? dbWrapper.getTapSchemaDatabaseType() : dbWrapper.getSourceDatabaseType();
    }

    protected static boolean isTapSchema(TapSchema tapSchema, String schemaName) {
        return schemaName.equals(tapSchema.getName());
    }

    protected static UnsupportedOperationException getUnsupportedOperationException(String version, String unsupportedFeature) {
        return new UnsupportedOperationException("Version \"" + version + "\" doesn't support " + unsupportedFeature);
    }

    protected static String escapeName(String name, DatabaseType dbType) {
        char escapeChar;
        switch (dbType) {
            case MYSQL:
                escapeChar = '`';
                break;
            case POSTGRES:
                escapeChar = '"';
                break;
            default:
                throw new UnsupportedOperationException("Database type " + dbType + " not supported");
        }

        return String.format("%s%s%s", escapeChar, name, escapeChar);
    }

    protected static String getTapSchemaTableNameFromEntity(TapSchemaEntity entity) {
        if (entity instanceof Schema) {
            return TapSchema.SCHEMAS_TABLE;
        } else if (entity instanceof Table) {
            return TapSchema.TABLES_TABLE;
        } else if (entity instanceof Column) {
            return TapSchema.COLUMNS_TABLE;
        } else if (entity instanceof Key) {
            return TapSchema.KEYS_TABLE;
        } else if (entity instanceof KeyColumn) {
            return TapSchema.KEY_COLUMNS_TABLE;
        }
        LOG.warn("getTapSchemaTableNameFromEntity returns null for {}" + entity.getClass().getCanonicalName());
//    private static void setTSColumnDescription(Table table, String columnName, String description) {
//        Column column = table.getChild(columnName);
//        column.setDescription(description);
//        column.setStd(true);
//    }
    public static String getNaturalLangueName(TapSchemaEntity entity) {
        if (entity instanceof Schema) {
            return "schema";
        } else if (entity instanceof Table) {
            return "table";
        } else if (entity instanceof Column) {
            return "column";
        } else if (entity instanceof Key) {
            return "key";
        } else if (entity instanceof KeyColumn) {
            return "key_column";
        } else {
            throw new UnsupportedOperationException("entity class " + entity.getClass().getCanonicalName() + " not supported yet");
        }
    }

    public static String getName(TapSchemaEntity entity) {
        if (entity instanceof Schema) {
            return ((Schema) entity).getName();
        } else if (entity instanceof Table) {
            return ((Table) entity).getCompleteName();
        } else if (entity instanceof Column) {
            Column column = (Column) entity;
            return column.getParent().getCompleteName() + "." + column.getName();
        } else if (entity instanceof Key) {
            return printKeyInfo((Key) entity);
        } else if (entity instanceof KeyColumn) {
            KeyColumn keyColumn = (KeyColumn) entity;
            return String.format("%s -> %s [key: %s]",
                    keyColumn.getFromColumn(), keyColumn.getTargetColumn(),
                    printKeyInfo(keyColumn.getParent()));
        } else {
            throw new UnsupportedOperationException("entity class " + entity.getClass().getCanonicalName() + " not supported yet");
        }
    }

    public static String printKeyInfo(Key key) {
        StringBuilder sb = new StringBuilder();

        sb.append(String.format("[%s] %s(", key.getId(), key.getFromTableCompleteName()));

        boolean first = true;
        for (KeyColumn keyColumn : key.getKeyColumns()) {
            if (!first) {
                sb.append(",");
            }
            first = false;
            sb.append(keyColumn.getFromColumn());
        }

        sb.append(String.format(") -> %s(", key.getTargetTableCompleteName()));

        first = true;
        for (KeyColumn keyColumn : key.getKeyColumns()) {
            if (!first) {
                sb.append(",");
            }
            first = false;
            sb.append(keyColumn.getTargetColumn());
        }

        sb.append(")");

        return sb.toString();
    }