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.
*/
Sonia Zorba
committed
package it.inaf.ia2.tsm.api;
Sonia Zorba
committed
import it.inaf.ia2.tsm.api.contract.DatabaseType;
import it.inaf.ia2.tsm.api.contract.ChildEntity;
import it.inaf.ia2.tsm.api.contract.Column;
import it.inaf.ia2.tsm.api.contract.Key;
import it.inaf.ia2.tsm.api.contract.KeyColumn;
import it.inaf.ia2.tsm.api.contract.Schema;
import it.inaf.ia2.tsm.api.contract.Status;
import it.inaf.ia2.tsm.api.contract.Table;
import it.inaf.ia2.tsm.api.contract.TapSchema;
import it.inaf.ia2.tsm.api.contract.TapSchemaEntity;
import it.inaf.ia2.tsm.api.contract.TapSchemaVersion;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Map;
import javax.sql.DataSource;
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);
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) {
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;
}
}
return null;
}
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");
if (rs.wasNull()) {
return null;
}
return ret;
* 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");
if (rs.wasNull()) {
return null;
}
return ret;
}
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
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(TapSchemaVersion version, String unsupportedFeature) {
return new UnsupportedOperationException("Version \"" + version.name() + "\" doesn't support " + unsupportedFeature);
}
protected static boolean is1_1(TapSchemaVersion version) {
return version == TapSchemaVersion.TAP_SCHEMA_1_1 || version == TapSchemaVersion.TAP_SCHEMA_1_1_IA2;
}
protected static boolean isIA2(TapSchemaVersion version) {
return version == TapSchemaVersion.TAP_SCHEMA_1_IA2 || version == TapSchemaVersion.TAP_SCHEMA_1_1_IA2;
}
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());
return null;
private static void setTSColumnDescription(Table table, String columnName, String description) {
Column column = table.getChild(columnName);
column.setDescription(description);
column.setStd(true);
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
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();
}
/**
* Fill descriptions of the TAP_SCHEMA schema entities.
*
* @param schema the TAP_SCHEMA schema <code>SchemaEntity</code>.
*/
protected static void putInfoIntoTapSchemaSchema(Schema schema) {
schema.setDescription("a special schema to describe a TAP tableset");
// SCHEMAS
Table schemasTable = schema.getChild("schemas");
schemasTable.setDescription("description of schemas in this tableset");
setTSColumnDescription(schemasTable, "schema_name", "schema name for reference to TAP_SCHEMA.schemas");
setTSColumnDescription(schemasTable, "utype", "lists the utypes of schemas in the tableset");
setTSColumnDescription(schemasTable, "description", "describes schemas in the tableset");
Table tablesTable = schema.getChild("tables");
tablesTable.setDescription("description of tables in this tableset");
setTSColumnDescription(tablesTable, "schema_name", "the schema this table belongs to");
setTSColumnDescription(tablesTable, "table_name", "the fully qualified table name");
setTSColumnDescription(tablesTable, "table_type", "one of: table view");
setTSColumnDescription(tablesTable, "utype", "lists the utype of tables in the tableset");
setTSColumnDescription(tablesTable, "description", "describes tables in the tableset");
Table columnsTable = schema.getChild("columns");
columnsTable.setDescription("description of columns in this tableset");
setTSColumnDescription(columnsTable, "table_name", "the table this column belongs to");
setTSColumnDescription(columnsTable, "column_name", "the column name");
setTSColumnDescription(columnsTable, "utype", "lists the utypes of columns in the tableset");
setTSColumnDescription(columnsTable, "ucd", "lists the UCDs of columns in the tableset");
setTSColumnDescription(columnsTable, "unit", "lists the unit used for column values in the tableset");
setTSColumnDescription(columnsTable, "description", "describes the columns in the tableset");
setTSColumnDescription(columnsTable, "datatype", "lists the ADQL datatype of columns in the tableset");
setTSColumnDescription(columnsTable, "size", "lists the size of variable-length columns in the tableset");
setTSColumnDescription(columnsTable, "principal", "a principal column; 1 means 1, 0 means 0");
setTSColumnDescription(columnsTable, "indexed", "an indexed column; 1 means 1, 0 means 0");
setTSColumnDescription(columnsTable, "std", "a standard column; 1 means 1, 0 means 0");
Table keysTable = schema.getChild("keys");
keysTable.setDescription("description of foreign keys in this tableset");
setTSColumnDescription(keysTable, "key_id", "unique key to join to TAP_SCHEMA.key_columns");
setTSColumnDescription(keysTable, "from_table", "the table with the foreign key");
setTSColumnDescription(keysTable, "target_table", "the table with the primary key");
setTSColumnDescription(keysTable, "utype", "lists the utype of keys in the tableset");
setTSColumnDescription(keysTable, "description", "describes keys in the tableset");
Table keyColumnsTable = schema.getChild("key_columns");
keyColumnsTable.setDescription("description of foreign key columns in this tableset");
setTSColumnDescription(keyColumnsTable, "key_id", "key to join to TAP_SCHEMA.keys");
setTSColumnDescription(keyColumnsTable, "from_column", "column in the from_table");
setTSColumnDescription(keyColumnsTable, "target_column", "column in the target_table");