Commit 8c18e736 authored by Sonia Zorba's avatar Sonia Zorba
Browse files

Big refactoring in order to allow multiple TAP versions (2)

parent d3484c88
......@@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>it.inaf.ia2.tap</groupId>
<artifactId>tasman-core</artifactId>
<version>1.1.0</version>
<version>1.2.0</version>
<packaging>jar</packaging>
<name>tasman-core</name>
<properties>
......
......@@ -22,7 +22,7 @@
*/
package it.inaf.ia2.tsm;
import it.inaf.ia2.tsm.xmlmodel.TableModel;
import it.inaf.ia2.tsm.model.TableModel;
import java.util.Map;
/**
......
......@@ -43,7 +43,7 @@ public class Column extends ChildEntity<Table> {
private static final Logger LOG = LoggerFactory.getLogger(Column.class);
private boolean foreignKeySearched;
private KeyMetadata foreignKey;
private Key foreignKey;
private Table parentTable;
......@@ -58,9 +58,24 @@ public class Column extends ChildEntity<Table> {
setStatus(Status.LOADED);
}
public KeyMetadata getForeignKey() {
public Key getForeignKey() {
if (!foreignKeySearched) { // lazy loading (but the foreignKey value can be null, so we use this boolean)
foreignKey = tapSchema.searchKeyMetadata(parentTable.getParent().getName(), parentTable.getName(), getName());
String fromSchemaName = parentTable.getParent().getName();
String fromTableName = parentTable.getName();
String fromColumnName = getName();
ext:
for (Key key : tapSchema.getAllKeys()) {
if (key.getFromSchemaName().equals(fromSchemaName) && key.getFromTableSimpleName().equals(fromTableName)) {
for (KeyColumn keyColumn : key.getKeyColumns()) {
if (keyColumn.getFromColumn().equals(fromColumnName)) {
foreignKey = key;
break ext;
}
}
}
}
}
return foreignKey;
......
......@@ -74,18 +74,18 @@ public class ConsistencyChecks implements Serializable {
}
private final List<InconsistentValue> inconsistencies;
private final List<String> unexisingSchemas;
private final List<String> unexisingTables;
private final Set<String> unexisingSchemas;
private final Set<String> unexisingTables;
private final Map<String, String> unexisingColumns;
private final List<String> unexistingKeys;
private final Set<String> unexistingKeys;
private final List<UnexistingKeyColumn> unexistingKeyColumns;
public ConsistencyChecks() {
inconsistencies = new ArrayList<>();
unexisingSchemas = new ArrayList<>();
unexisingTables = new ArrayList<>();
unexisingSchemas = new HashSet<>();
unexisingTables = new HashSet<>();
unexisingColumns = new HashMap<>();
unexistingKeys = new ArrayList<>();
unexistingKeys = new HashSet<>();
unexistingKeyColumns = new ArrayList<>();
}
......@@ -97,7 +97,7 @@ public class ConsistencyChecks implements Serializable {
return inconsistencies;
}
public List<String> getUnexisingSchemas() {
public Set<String> getUnexisingSchemas() {
return unexisingSchemas;
}
......@@ -105,7 +105,7 @@ public class ConsistencyChecks implements Serializable {
unexisingSchemas.add(schemaName);
}
public List<String> getUnexisingTables() {
public Set<String> getUnexisingTables() {
return unexisingTables;
}
......@@ -128,7 +128,7 @@ public class ConsistencyChecks implements Serializable {
unexistingKeys.add(keyId);
}
public List<String> getUnexistingKeys() {
public Set<String> getUnexistingKeys() {
return unexistingKeys;
}
......
......@@ -22,7 +22,7 @@
*/
package it.inaf.ia2.tsm;
import it.inaf.ia2.tsm.xmlmodel.PropertyModel;
import it.inaf.ia2.tsm.model.PropertyModel;
import java.io.Serializable;
/**
......@@ -111,4 +111,8 @@ public class EntityProperty<T> implements Serializable {
public void save() {
this.originalValue = value;
}
public Class getType() {
return type;
}
}
......@@ -25,8 +25,11 @@ package it.inaf.ia2.tsm;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.regex.Pattern;
/**
* The main implementation of {@link Key}.
......@@ -41,25 +44,31 @@ public class Key extends TapSchemaEntity implements Serializable {
private static final long serialVersionUID = -8783695875831579336L;
private KeyMetadata keyMetadata;
private List<KeyColumn> keyColumns;
private boolean visible;
private String fromSchema;
private String fromTable;
private String targetSchema;
private String targetTable;
private Key() {
super();
}
public Key(TapSchema tapSchema, KeyMetadata keyMetadata) {
super(tapSchema, tapSchema.getTableModel(TapSchema.KEYS_TABLE), keyMetadata.getKeyMetadata());
public Key(TapSchema tapSchema, Map<String, Object> metadata) {
super(tapSchema, tapSchema.getTableModel(TapSchema.KEYS_TABLE), metadata);
this.keyMetadata = keyMetadata;
keyColumns = new ArrayList<>();
visible = false;
}
public KeyMetadata getKeyMetadata() {
return keyMetadata;
String[] fromSplit = ((String) metadata.get(FROM_TABLE_KEY)).split(Pattern.quote("."));
String[] targetSplit = ((String) metadata.get(TARGET_TABLE_KEY)).split(Pattern.quote("."));
fromSchema = fromSplit[0];
fromTable = fromSplit[1];
targetSchema = targetSplit[0];
targetTable = targetSplit[1];
}
public boolean isVisible() {
......@@ -86,11 +95,11 @@ public class Key extends TapSchemaEntity implements Serializable {
}
public String getFromSchemaName() {
return keyMetadata.getFromSchema();
return fromSchema;
}
public String getFromTableSimpleName() {
return keyMetadata.getFromTable();
return fromTable;
}
public String getFromTableCompleteName() {
......@@ -98,11 +107,11 @@ public class Key extends TapSchemaEntity implements Serializable {
}
public String getTargetSchemaName() {
return keyMetadata.getTargetSchema();
return targetSchema;
}
public String getTargetTableSimpleName() {
return keyMetadata.getTargetTable();
return targetTable;
}
public String getTargetTableCompleteName() {
......@@ -110,13 +119,19 @@ public class Key extends TapSchemaEntity implements Serializable {
}
public KeyColumn addKeyColumn(String fromColumn, String targetColumn) {
KeyColumn keyColumn = new KeyColumn(tapSchema, this, fromColumn, targetColumn);
Map<String, Object> keyColumnMetadata = new HashMap<>();
keyColumnMetadata.put(KeyColumn.FROM_COLUMN_KEY, fromColumn);
keyColumnMetadata.put(KeyColumn.TARGET_COLUMN_KEY, targetColumn);
KeyColumn keyColumn = new KeyColumn(tapSchema, this, keyColumnMetadata);
keyColumns.add(keyColumn);
return keyColumn;
}
@Override
public void save() {
if (!isVisible()) {
initProperty(ID_KEY, null);
}
super.save();
for (KeyColumn keyColumn : keyColumns) {
keyColumn.save();
......
......@@ -22,6 +22,7 @@
*/
package it.inaf.ia2.tsm;
import java.util.Map;
import java.util.Objects;
/**
......@@ -44,8 +45,8 @@ public class KeyColumn extends TapSchemaEntity {
super();
}
protected KeyColumn(TapSchema tapSchema, Key key, String fromColumn, String targetColumn) {
super(tapSchema, tapSchema.getTableModel(TapSchema.KEY_COLUMNS_TABLE), key.getKeyMetadata().getKeyColumnMetadata(fromColumn, targetColumn));
protected KeyColumn(TapSchema tapSchema, Key key, Map<String, Object> keyColumnMetadata) {
super(tapSchema, tapSchema.getTableModel(TapSchema.KEY_COLUMNS_TABLE), keyColumnMetadata);
this.key = key;
}
......
/*
* _____________________________________________________________________________
*
* 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;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
/**
*
* @author Sonia Zorba {@literal <zorba at oats.inaf.it>}
*/
public class KeyMetadata implements Serializable {
public static final String NEW_KEY = "#NEW#";
private static final long serialVersionUID = -30688540834789724L;
private final String fromSchema;
private final String fromTable;
private final List<String> fromColumns;
private final String targetSchema;
private final String targetTable;
private final List<String> targetColumns;
public KeyMetadata(String fromSchema, String fromTable, String targetSchema, String targetTable) {
this.fromSchema = fromSchema;
this.fromTable = fromTable;
this.fromColumns = new ArrayList<>();
this.targetSchema = targetSchema;
this.targetTable = targetTable;
this.targetColumns = new ArrayList<>();
}
public String getFromSchema() {
return fromSchema;
}
public String getFromTable() {
return fromTable;
}
public List<String> getFromColumns() {
return fromColumns;
}
public String getTargetSchema() {
return targetSchema;
}
public String getTargetTable() {
return targetTable;
}
public List<String> getTargetColumns() {
return targetColumns;
}
public void addKeyColumn(String fromColumn, String targetColumn) {
fromColumns.add(fromColumn);
targetColumns.add(targetColumn);
}
public Map<String, Object> getKeyMetadata() {
Map<String, Object> metadata = new HashMap<>();
metadata.put(Key.ID_KEY, NEW_KEY);
metadata.put(Key.FROM_TABLE_KEY, fromSchema + "." + fromTable);
metadata.put(Key.TARGET_TABLE_KEY, targetSchema + "." + targetTable);
return metadata;
}
public Map<String, Object> getKeyColumnMetadata(String fromColumn, String targetColumn) {
Map<String, Object> metadata = new HashMap<>();
metadata.put(KeyColumn.KEY_ID_KEY, NEW_KEY);
metadata.put(KeyColumn.FROM_COLUMN_KEY, fromColumn);
metadata.put(KeyColumn.TARGET_COLUMN_KEY, targetColumn);
return metadata;
}
@Override
public int hashCode() {
int hash = 7;
hash = 17 * hash + Objects.hashCode(this.fromSchema);
hash = 17 * hash + Objects.hashCode(this.fromTable);
for (String fromColumn : fromColumns) {
hash = 17 * hash + Objects.hashCode(fromColumn);
}
hash = 17 * hash + Objects.hashCode(this.targetSchema);
hash = 17 * hash + Objects.hashCode(this.targetTable);
for (String targetColumn : targetColumns) {
hash = 17 * hash + Objects.hashCode(targetColumn);
}
return hash;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final KeyMetadata other = (KeyMetadata) obj;
if (!Objects.equals(this.fromSchema, other.fromSchema)) {
return false;
}
if (!Objects.equals(this.fromTable, other.fromTable)) {
return false;
}
if (!Objects.equals(this.targetSchema, other.targetSchema)) {
return false;
}
if (!Objects.equals(this.targetTable, other.targetTable)) {
return false;
}
if (this.fromColumns.size() != other.fromColumns.size()) {
return false;
}
for (int i = 0; i < fromColumns.size(); i++) {
String fromColumn = fromColumns.get(i);
if (!Objects.equals(fromColumn, other.fromColumns.get(i))) {
return false;
}
}
if (this.targetColumns.size() != other.targetColumns.size()) {
return false;
}
for (int i = 0; i < targetColumns.size(); i++) {
String targetColumn = targetColumns.get(i);
if (!Objects.equals(targetColumn, other.targetColumns.get(i))) {
return false;
}
}
return true;
}
}
......@@ -88,8 +88,6 @@ public class Schema extends ChildEntity<TapSchema> implements EntitiesContainer<
LOG.debug("Adding table {} into schema {}", tableSimpleName, schemaName);
if (!tables.containsKey(tableSimpleName)) {
//throw new IllegalArgumentException("The table " + tableSimpleName + " doesn't exist into the schema " + schemaName + ". Are you sure you are using the simple table name?");
tapSchema.getConsistencyChecks().addUnexistingTable(schemaName, tableSimpleName);
return null;
} else {
......
......@@ -241,7 +241,6 @@ public class TSMUtil {
// column.setDescription(description);
// column.setStd(true);
// }
public static String getNaturalLangueName(TapSchemaEntity entity) {
if (entity instanceof Schema) {
return "schema";
......@@ -307,66 +306,4 @@ public class TSMUtil {
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");
//
// // TABLES
// 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");
//
// // COLUMNS
// 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");
//
// // KEYS
// 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");
//
// // KEY COLUMNS
// 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");
}
}
......@@ -101,7 +101,6 @@ public class Table extends ChildEntity<Schema> implements EntitiesContainer<Colu
LOG.debug("Adding column {} into table {}", columnName, tableCompleteName);
if (!columns.containsKey(columnName)) {
tapSchema.getConsistencyChecks().addUnexistingColumn(getCompleteName(), columnName);
return null;
} else {
Column column = columns.get(columnName);
......
......@@ -22,8 +22,8 @@
*/
package it.inaf.ia2.tsm;
import it.inaf.ia2.tsm.xmlmodel.PropertyModel;
import it.inaf.ia2.tsm.xmlmodel.TableModel;
import it.inaf.ia2.tsm.model.PropertyModel;
import it.inaf.ia2.tsm.model.TableModel;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
......@@ -85,6 +85,15 @@ public abstract class TapSchemaEntity implements Serializable {
properties.get(key).init(value);
}
/**
* Fill saved properties.
*/
public void init(Map<String, Object> props) {
for (Map.Entry<String, Object> entry : props.entrySet()) {
initProperty(entry.getKey(), entry.getValue());
}
}
protected String getVersion() {
return tapSchema.getVersion();
}
......@@ -103,6 +112,14 @@ public abstract class TapSchemaEntity implements Serializable {
}
public Object getValue(String key) {
return properties.get(key).getValue();
}
public Class getPropertyType(String key) {
return properties.get(key).getType();
}
public EntityProperty getProperty(String key) {
return properties.get(key);
}
......@@ -125,7 +142,7 @@ public abstract class TapSchemaEntity implements Serializable {
* @return
*/
public <T> T getOriginalValue(String key, Class<T> type) {
return (T) properties.get(key).getValue();
return (T) properties.get(key).getOriginalValue(type);
}
/**
......
......@@ -22,10 +22,6 @@
*/
package it.inaf.ia2.tsm;
import it.inaf.ia2.tsm.datalayer.DBBroker;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import org.slf4j.Logger;
......@@ -94,20 +90,17 @@ public class UpdateOperations {
keysToAdd = new ArrayList<>();
keysToUpdate = new ArrayList<>();
for (Key key : ((TapSchema) tapSchema).getAllKeys()) {
for (Key key : tapSchema.getAllKeys()) {
if (key.getId() != null) {
if (key.isVisible()) {
String originalKeyId = key.getOriginalValue(Key.ID_KEY, String.class);
if (originalKeyId == null || KeyMetadata.NEW_KEY.equals(originalKeyId)) {
keysToAdd.add(key);
} else if (key.isChanged()) {
keysToUpdate.add(key);
}
} else {
keysToRemove.add(key);
if (key.isVisible()) {
String originalKeyId = key.getOriginalValue(Key.ID_KEY, String.class);
if (originalKeyId == null) {
keysToAdd.add(key);