/* * _____________________________________________________________________________ * * 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.oats.ia2.tapschemamanager.api; import it.inaf.oats.ia2.tapschemamanager.api.contract.Key; import it.inaf.oats.ia2.tapschemamanager.api.contract.Schema; import it.inaf.oats.ia2.tapschemamanager.api.contract.Status; import it.inaf.oats.ia2.tapschemamanager.api.contract.Table; import it.inaf.oats.ia2.tapschemamanager.api.contract.TapSchema; import java.sql.SQLException; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.TreeMap; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * The main implementation of {@link Schema}. * * @author Sonia Zorba {@literal } */ public class SchemaImpl extends ChildEntityImpl implements Schema { private static final long serialVersionUID = 8828583158332877855L; private static final Logger log = LoggerFactory.getLogger(SchemaImpl.class); private final Map tables; private Map tablesTypes; private SchemaImpl() { // for serialization super(); tables = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); } public SchemaImpl(DBWrapper dbWrapper, TapSchema tapSchema, String name) throws SQLException { super(dbWrapper, tapSchema); tables = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); tablesTypes = DaoTable.getTablesTypes(dbWrapper, tapSchema, name); for (String tableName : DaoTable.getAllTablesNames(dbWrapper, tapSchema, name)) { tables.put(tableName, null); } log.debug("Schema {} contains {} tables", name, tables.size()); addProperty(SCHEMA_NAME_KEY, new FixedEntityProperty<>(name)); addProperty(UTYPE_KEY, new EditableProperty()); addProperty(DESCRIPTION_KEY, new EditableProperty()); addProperty(SCHEMA_ID, new EditableProperty()); setStatus(Status.LOADED); } /** * {@inheritDoc} * The value in the {@code schema_name} column. */ @Override public String getName() { return getValue(SCHEMA_NAME_KEY, String.class); } /** * @param tableSimpleName the name of the table, without the schema name. * @return */ @Override public Table addChild(String tableSimpleName) throws SQLException { String schemaName = getName(); 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?"); } Table table = tables.get(tableSimpleName); if (table == null) { table = new TableImpl(dbWrapper, tapSchema, this, tableSimpleName, tablesTypes.get(tableSimpleName)); // Adding fromKeys and targetKeys to the table. The keys could be hidden, // their status is not important here. We are adding all tables keys. // It is the method {@link #TableImpl.checkKeys()} that set their visibility. // We have to loop on all keys of all schemas to retrieve also the // target keys. for (Key key : ((TapSchemaImpl) tapSchema).getAllKeys()) { if (key.getFromTableCompleteName().equals(table.getCompleteName())) { ((TableImpl) table).addFromKey(key); } if (key.getTargetTableCompleteName().equals(table.getCompleteName())) { ((TableImpl) table).addTargetKey(key); } } tables.put(tableSimpleName, table); table.setStatus(Status.ADDED_NOT_PERSISTED); } else { switch (table.getStatus()) { case TO_REMOVE: table.setStatus(Status.ADDED_PERSISTED); break; case REMOVED_NOT_PERSISTED: table.setStatus(Status.ADDED_NOT_PERSISTED); break; default: throw new IllegalArgumentException("Invalid table status. The status for " + table.getCompleteName() + " is " + table.getStatus()); } } ((TapSchemaImpl) tapSchema).checkKeys(); return table; } /** * {@inheritDoc} */ @Override public void removeChild(String tableSimpleName) { String schemaName = getName(); log.debug("Removing table {} from 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?"); } Table table = tables.get(tableSimpleName); if (table == null) { throw new IllegalArgumentException("The table " + tableSimpleName + " has never been loaded into the schema " + schemaName + ". Are you sure you are using the simple table name?"); } if (table.getStatus() == Status.LOADED || table.getStatus() == Status.TO_REMOVE) { throw new IllegalArgumentException("Invalid table status. The status for " + table.getCompleteName() + " is " + table.getStatus()); } if (table.getStatus() == Status.ADDED_NOT_PERSISTED) { table.setStatus(Status.REMOVED_NOT_PERSISTED); } else if (table.getStatus() == Status.ADDED_PERSISTED) { table.setStatus(Status.TO_REMOVE); } ((TapSchemaImpl) tapSchema).checkKeys(); } /** * {@inheritDoc} */ @Override public Table getChild(String childName, Status... statuses) { return TSMUtil.getChild(tables, childName, statuses); } /** * {@inheritDoc} */ @Override public List getChildren(Status... statuses) { return TSMUtil.getChildrenByStatus(tables.values(), statuses); } /** * {@inheritDoc} */ @Override public List getAddableChildrenNames() { return TSMUtil.getAddableChildrenNames(tables); } /** * {@inheritDoc} */ @Override public List
getAddedChildren() { return getChildren(Status.ADDED_PERSISTED, Status.ADDED_NOT_PERSISTED); } /** * {@inheritDoc} */ @Override public List
getAddedOrRemovedChildren() { return getChildren(Status.ADDED_PERSISTED, Status.ADDED_NOT_PERSISTED, Status.TO_REMOVE, Status.REMOVED_NOT_PERSISTED); } /** * {@inheritDoc} */ @Override public String getUtype() { return getValue(UTYPE_KEY, String.class); } @Override public void setUtype(String utype) { setValue(UTYPE_KEY, utype); } /** * {@inheritDoc} */ @Override public String getDescription() { return getValue(DESCRIPTION_KEY, String.class); } @Override public void setDescription(String description) { setValue(DESCRIPTION_KEY, description); } /** * {@inheritDoc} */ @Override public Long getSchemaID() { return getValue(SCHEMA_ID, Long.class); } @Override public void setSchemaID(Long schemaID) { setValue(SCHEMA_ID, schemaID); } @Override public int hashCode() { int hash = 5; hash = 53 * hash + Objects.hashCode(this.getName()); return hash; } @Override public boolean equals(Object obj) { if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final SchemaImpl other = (SchemaImpl) obj; if (!Objects.equals(this.getName(), other.getName())) { return false; } return true; } /** * This method has to be used after TAP_SCHEMA modifications are committed * to the database, in order to remove from the memory the tables with * status {@code Status.TO_REMOVE} or {@code Status.REMOVED_NOT_PERSISTED}. */ protected void cleanTable(String tableSimpleName) { if (!tables.containsKey(tableSimpleName)) { throw new IllegalArgumentException("Schema " + getName() + "doesn't contain the table " + tableSimpleName); } tables.put(tableSimpleName, null); } /** * {@inheritDoc} */ @Override public TapSchema getParent() { return tapSchema; } }