// ============================================================================ // // Copyright (C) 2006-2012 Talend Inc. - www.talend.com // // This source code is available under agreement available at // %InstallDIR%\features\org.talend.rcp.branding.%PRODUCTNAME%\%PRODUCTNAME%license.txt // // You should have received a copy of the agreement // along with this program; if not, write to Talend SA // 9 rue Pages 92150 Suresnes, France // // ============================================================================ package org.talend.cwm.helper; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EObject; import org.talend.core.model.metadata.builder.connection.Connection; import org.talend.core.model.metadata.builder.connection.MetadataColumn; import org.talend.core.model.metadata.builder.connection.MetadataTable; import org.talend.core.model.metadata.builder.connection.SAPFunctionUnit; import org.talend.cwm.relational.TdColumn; import org.talend.cwm.relational.TdTable; import orgomg.cwm.foundation.softwaredeployment.DataManager; import orgomg.cwm.objectmodel.core.ModelElement; import orgomg.cwm.objectmodel.core.Namespace; import orgomg.cwm.objectmodel.core.Package; import orgomg.cwm.objectmodel.core.StructuralFeature; import orgomg.cwm.objectmodel.core.TaggedValue; import orgomg.cwm.resource.relational.ColumnSet; import orgomg.cwm.resource.relational.ForeignKey; import orgomg.cwm.resource.relational.PrimaryKey; import orgomg.cwm.resource.relational.Table; import orgomg.cwm.resource.relational.impl.RelationalFactoryImpl; /** * @author scorreia * * Helper for Table class. */ public final class TableHelper extends SubItemHelper { private TableHelper() { } /** * Method "getTables" extracts the tables from the list. * * @param elements any elements that could contain TdTables * @return the list of TdTables found in the given list (never null, but can be empty). */ public static List<TdTable> getTables(Collection<? extends EObject> elements) { List<TdTable> tables = new ArrayList<TdTable>(); for (EObject elt : elements) { TdTable table = SwitchHelpers.TABLE_SWITCH.doSwitch(elt); if (table != null) { tables.add(table); } } return tables; } /** * Method "getColumns" returns the columns of a table. * * @param table a table * @return the list of TdColumn contained in the table */ public static List<TdColumn> getColumns(TdTable table) { return ColumnHelper.getColumns(table.getFeature()); } /** * Method "addColumns". * * @param table the table in which to add the columns (must not be null) * @param columns the columns to add (must not be null) * @return true if the content of the table changed as a result of the call. */ public static boolean addColumns(TdTable table, Collection<TdColumn> columns) { return ColumnSetHelper.addColumns(table, columns); } /** * Method "addColumn" adds a column to the given table. * * @param table the table in which the column is added (must not be null) * @param column the column to add (must not be null) * @return true if the content of the table changed as a result of the call. */ public static boolean addColumn(TdTable table, TdColumn column) { assert table != null; assert column != null; return table.getFeature().add(column); } /** * Method "getParentTable". * * @param column a column * @return the table containing this column or null * @deprecated use ColumnHelper.getTdTableOwner(); */ public static TdTable getParentTable(TdColumn column) { return ColumnHelper.getColumnOwnerAsTdTable(column); } /** * Method "addPrimaryKey". * * @param table * @param pk the primary key of the table */ public static PrimaryKey addPrimaryKey(TdTable table, PrimaryKey pk) { assert table != null; assert pk != null; PrimaryKey primaryKey = getPrimaryKey(table); // PrimaryKey thePrimaryKey = getPrimaryKey(table); // MOD zshen for bug 12842 String newPrimaryKeyName = pk.getName(); if (primaryKey != null) { if (primaryKey.getName().equals(newPrimaryKeyName)) primaryKey.getFeature().addAll(pk.getFeature()); StructuralFeature[] structuralFeaturethe = primaryKey.getFeature().toArray( new StructuralFeature[primaryKey.getFeature().size()]); for (StructuralFeature primaryKeyColumn : structuralFeaturethe) { TdColumn theColumn = (TdColumn) (primaryKeyColumn); theColumn.getUniqueKey().clear(); theColumn.getUniqueKey().add(primaryKey); } return primaryKey; } table.getOwnedElement().add(pk); return pk; } /** * Method "addPrimaryKey". * * @param table * @param pk the primary key of the table */ public static PrimaryKey addPrimaryKey(TdTable table, TdColumn col) { assert table != null; assert col != null; PrimaryKey primaryKey = getPrimaryKey(table); if (primaryKey == null) { primaryKey = RelationalFactoryImpl.eINSTANCE.createPrimaryKey(); table.getOwnedElement().add(primaryKey); } primaryKey.getFeature().add(col); StructuralFeature[] structuralFeaturethe = primaryKey.getFeature().toArray( new StructuralFeature[primaryKey.getFeature().size()]); for (StructuralFeature primaryKeyColumn : structuralFeaturethe) { TdColumn theColumn = (TdColumn) (primaryKeyColumn); theColumn.getUniqueKey().clear(); theColumn.getUniqueKey().add(primaryKey); } return primaryKey; } /** * removes the key from the table and eventually removes all references from the key referenced colums <br> * //TODO handle the foreign key that may reference this primary key * * @param columnSet the table in which the key is to be removed * @param key the key to be removed * @return true if the PK existed in the table */ public static boolean removeTableKey(ColumnSet columnSet, PrimaryKey key) { assert columnSet != null; assert key != null; assert columnSet.getOwnedElement().contains(key); List<TdColumn> primaryKeyColumns = KeyHelper.getKeyRelatedColumns(key); for (TdColumn column : primaryKeyColumns) { ColumnHelper.removeKeyFromColumn(key, column); } return columnSet.getOwnedElement().remove(key); } /** * removes the key from the table and eventually removes all references from the key referenced colums <br> * * @param columnSet the table in which the key is to be removed * @param key the key to be removed * @return true if the PK existed in the table */ public static boolean removeTableKey(ColumnSet columnSet, ForeignKey key) { assert columnSet != null; assert key != null; assert columnSet.getOwnedElement().contains(key); List<TdColumn> primaryKeyColumns = KeyHelper.getKeyRelatedColumns(key); for (TdColumn column : primaryKeyColumns) { ColumnHelper.removeKeyFromColumn(key, column); } return columnSet.getOwnedElement().remove(key); } /** * Method "removeForeignKey". * * @param table * @param foreignKey * @return true if the FK existed in the table */ public static boolean removeForeignKey(Table table, ForeignKey foreignKey) { assert table != null; assert foreignKey != null; return table.getOwnedElement().remove(foreignKey); } /** * Method "addAllPrimaryKeys". * * @param table * @param primaryKeys the primary keys of the table. * @deprecated because there can only be one PrimaryKey on same one table, so use addPrimaryKey instead */ public static void addPrimaryKeys(ColumnSet table, List<PrimaryKey> primaryKeys) { assert table != null; assert primaryKeys != null; for (PrimaryKey primaryKey : primaryKeys) { addPrimaryKey((TdTable) table, primaryKey); } } /** * Method "addForeignKey". * * @param table * @param foreignKey the foreign key of the given table */ public static ForeignKey addForeignKey(TdTable table, ForeignKey foreignKey) { assert table != null; assert foreignKey != null; List<ForeignKey> foreignKeyList = getForeignKeys(table); String newForeignKeyName = foreignKey.getName(); for (ForeignKey theForeignKey : foreignKeyList) { if (theForeignKey.getName().equals(newForeignKeyName)) { theForeignKey.getFeature().addAll(foreignKey.getFeature()); StructuralFeature[] structuralFeaturethe = theForeignKey.getFeature().toArray( new StructuralFeature[theForeignKey.getFeature().size()]); for (StructuralFeature foreignKeyColumn : structuralFeaturethe) { TdColumn theColumn = (TdColumn) (foreignKeyColumn); theColumn.getKeyRelationship().remove(foreignKey); theColumn.getKeyRelationship().add(theForeignKey); } return theForeignKey; } } table.getOwnedElement().add(foreignKey); return foreignKey; } /** * Method "addForeignKeys". * * @param table * @param foreignKeys the foreign keys of this table * @deprecated cause only working on TdTable and not on ColumnSet use addForeignKeys(Table, List<ForeignKey>) */ public static void addForeignKeys(ColumnSet table, List<ForeignKey> foreignKeys) { assert table != null; assert foreignKeys != null; for (ForeignKey foreignKey : foreignKeys) { addForeignKey((TdTable) table, foreignKey); } } /** * Method "addForeignKeys". * * @param table * @param foreignKeys the foreign keys of this table */ public static boolean addForeignKeys(TdTable table, List<ForeignKey> foreignKeys) { assert table != null; assert foreignKeys != null; return table.getOwnedElement().addAll(foreignKeys); } /** * Method "addForeignKey". * * @param table * @param foreignKey the foreign key of the given table */ public static ForeignKey addForeignKey(TdTable table, ForeignKey foreignKey, TdColumn column) { assert table != null; assert foreignKey != null; List<ForeignKey> foreignKeyList = getForeignKeys(table); String newForeignKeyName = foreignKey.getName(); for (ForeignKey theForeignKey : foreignKeyList) { if (theForeignKey.getName().equals(newForeignKeyName)) { theForeignKey.getFeature().add(column); StructuralFeature[] structuralFeaturethe = theForeignKey.getFeature().toArray( new StructuralFeature[theForeignKey.getFeature().size()]); for (StructuralFeature foreignKeyColumn : structuralFeaturethe) { TdColumn theColumn = (TdColumn) (foreignKeyColumn); theColumn.getKeyRelationship().remove(foreignKey); theColumn.getKeyRelationship().add(theForeignKey); } return theForeignKey; } } table.getOwnedElement().add(foreignKey); return foreignKey; } /** * Method "getPrimaryKeys". * * @param table a table * @return a list of all primary keys of the given table * @deprecated use getPrimaryKey() instead */ public static List<PrimaryKey> getPrimaryKeys(Table table) { List<PrimaryKey> primarykeys = new ArrayList<PrimaryKey>(); EList<ModelElement> ownedElements = table.getOwnedElement(); for (ModelElement modelElement : ownedElements) { PrimaryKey pk = SwitchHelpers.PRIMARY_KEY_SWITCH.doSwitch(modelElement); if (pk != null) { primarykeys.add(pk); } } return primarykeys; } /** * Method "getForeignKeys". * * @param table a table * @return a list of all foreign keys of the given table */ public static List<ForeignKey> getForeignKeys(TdTable table) { List<ForeignKey> foreignkeys = new ArrayList<ForeignKey>(); EList<ModelElement> ownedElements = table.getOwnedElement(); for (ModelElement modelElement : ownedElements) { ForeignKey pk = SwitchHelpers.FOREIGN_KEY_SWITCH.doSwitch(modelElement); if (pk != null) { foreignkeys.add(pk); } } return foreignkeys; } /** * Method "getParentCatalogOrSchema" returns the owner of the element (Catalog or Schema). * * @param element (can be null) * @return the Catalog or of Schema or null * @deprecated use PackageHelper.getParentPackage() */ public static Package getParentCatalogOrSchema(ModelElement element) { if (element == null) { return null; } Namespace namespace = element.getNamespace(); return PackageHelper.getCatalogOrSchema(namespace); } /** * return the primary key associated with this table or null if there is none * * @param table to search in for a PK * @return the PK found or null */ public static PrimaryKey getPrimaryKey(TdTable table) { PrimaryKey result = null; EList<ModelElement> ownedElements = table.getOwnedElement(); // look for the first primaryKey in the owned element list for (ModelElement modelElement : ownedElements) { PrimaryKey pk = SwitchHelpers.PRIMARY_KEY_SWITCH.doSwitch(modelElement); if (pk != null) { result = pk; break; } } return result; } /** * removes the column from the MetadataTable, if it is a TdColumn then try to remove it from the primary key and the * foreign key that contains it. this eventually removes the private key and foreign key from the table if the are * no more refering to any column * * @param column to be removed * @param metadataTable the set to remove the column from */ public static void removeColumn(MetadataColumn column, MetadataTable metadataTable) { if (column instanceof TdColumn) {// if of DbColumn then check for TdColumn tdColumn = (TdColumn) column; // first remove PK if it exists if (ColumnHelper.isPrimaryKey(tdColumn)) { ColumnHelper.removeColumnFromTablePrimaryKey(tdColumn); } // remove foreign key if it exists if (ColumnHelper.isForeignKey(tdColumn)) { ColumnHelper.removeColumnFromTableForeignKey(tdColumn); } }// else not a db column so simply removes the reference metadataTable.getFeature().remove(column); } /** * * DOC mzhao 2009-03-12 Remove all columns from this column set. * * @param column * @param metadataTable * @return true if remove successfully, false or else. */ public static void clearAllColumns(MetadataTable metadataTable) { // convert to an array because we cannon remove elements from a collection during a for loop MetadataColumn[] columns = metadataTable.getColumns().toArray(new MetadataColumn[metadataTable.getColumns().size()]); for (MetadataColumn col : columns) { removeColumn(col, metadataTable); } } /** * Method "addColumns". * * @param metadataTable the column set in which to add the columns (must not be null) * @param columns the columns to add (must not be null) * @return true if the content of the table changed as a result of the call. */ public static boolean addColumns(MetadataTable metadataTable, Collection<? extends TdColumn> columns) { assert metadataTable != null; assert columns != null; return metadataTable.getFeature().addAll(columns); } /** * Method "setColumns" replaces the previous columns by the new ones. * * @param metadataTable the column set in which to add the columns (must not be null) * @param columns the columns to add (must not be null) * @return true if the content of the table changed as a result of the call. * @deprecate use MetadataTable.getColumns.add() */ public static boolean setColumns(MetadataTable metadataTable, Collection<? extends TdColumn> columns) { assert metadataTable != null; assert columns != null; metadataTable.getColumns().clear(); return metadataTable.getColumns().addAll(columns); } // /** // * Method "getTableNames". // * // * @param metadataTable a set of columns (that could come from several Tables or views) // * @return the list of container names (tables, views) which the columns belong to (not null). // */ // public static String[] getColumnSetNames(Collection<? extends MetadataColumn> columns) { // List<String> tableNames = new ArrayList<String>(); // for (MetadataColumn tdColumn : columns) { // String tableName = ColumnHelper.getTableFullName(tdColumn); // if (tableName != null) { // tableNames.add(tableName); // } // } // return tableNames.toArray(new String[tableNames.size()]); // } /** * DOC bZhou Comment method "isFromSamePackage". * * this method is used to judge columnset whether from same package. * * @param sets * @return */ public static boolean isFromSamePackage(MetadataTable... sets) { Set<Package> container = new HashSet<Package>(); for (MetadataTable set : sets) { container.add(PackageHelper.getParentPackage(set)); } return container.size() == 1; } /** * DOC bZhou Comment method "getTableFilter". * * @param element * @return */ public static String getTableFilter(ModelElement element) { TaggedValue taggedValue = TaggedValueHelper.getTaggedValue(TaggedValueHelper.TABLE_FILTER, element.getTaggedValue()); if (taggedValue == null) { return ""; } return taggedValue.getValue(); } /** * DOC zshen Comment method "getTableOwner". * * @param element * @return */ public static String getTableOwner(ModelElement element) { TaggedValue taggedValue = TaggedValueHelper.getTaggedValue(TaggedValueHelper.TABLE_OWNER, element.getTaggedValue()); if (taggedValue == null) { return null; } return taggedValue.getValue(); } /** * DOC bZhou Comment method "setTableFilter". * * @param filter * @param element */ public static void setTableFilter(String filter, ModelElement element) { TaggedValueHelper.setTaggedValue(element, TaggedValueHelper.TABLE_FILTER, filter); } /** * DOC bZhou Comment method "getViewFilter". * * @param element * @return */ public static String getViewFilter(ModelElement element) { TaggedValue taggedValue = TaggedValueHelper.getTaggedValue(TaggedValueHelper.VIEW_FILTER, element.getTaggedValue()); if (taggedValue == null) { return ""; } return taggedValue.getValue(); } /** * DOC bZhou Comment method "setViewFilter". * * @param filter * @param element */ public static void setViewFilter(String filter, ModelElement element) { TaggedValueHelper.setTaggedValue(element, TaggedValueHelper.VIEW_FILTER, filter); } /** * DOC zshen Comment method "setTableOwner". * * @param filter * @param element */ public static void setTableOwner(String filter, ModelElement element) { TaggedValueHelper.setTaggedValue(element, TaggedValueHelper.TABLE_OWNER, filter); } /** * DOC bZhou Comment method "getComment". * * @param element * @return */ public static String getComment(ModelElement element) { TaggedValue taggedValue = TaggedValueHelper.getTaggedValue(TaggedValueHelper.COMMENT, element.getTaggedValue()); if (taggedValue == null) { return ""; } return taggedValue.getValue(); } /** * DOC bZhou Comment method "setComment". * * @param comment * @param element */ public static void setComment(String comment, ModelElement element) { TaggedValueHelper.setTaggedValue(element, TaggedValueHelper.COMMENT, comment); } /** * return the first connection available that refers to this table by moving up to the last Package instance that * hold this table and finding the connection linked to it * * @param metadataTable * @return */ public static Connection getFirstConnection(MetadataTable metadataTable) { assert metadataTable != null; Connection result = null; if (metadataTable.getNamespace() != null) { Package thePackage = SwitchHelpers.PACKAGE_SWITCH.doSwitch(metadataTable.getNamespace()); if (thePackage != null) { result = getFirstPackageConnection(thePackage); } }// else class is not linked to any package return result; } /** * DOC sgandon Comment method "getPackageDataProvider". * * @param result * @param thePackage * @return */ private static Connection getFirstPackageConnection(Package thePackage) { assert thePackage != null; Connection connection = null; // check that package does not belong to another package Namespace parentNS = thePackage.getNamespace(); if (parentNS != null) { Package parentPackage = SwitchHelpers.PACKAGE_SWITCH.doSwitch(thePackage.getNamespace()); if (parentPackage != null) { connection = getFirstPackageConnection(parentPackage); }// else class is not linked to any package so get it's Connection } if (connection == null) { for (DataManager dm : thePackage.getDataManager()) { Connection conn = SwitchHelpers.CONNECTION_SWITCH.doSwitch(dm); if (conn != null) { connection = conn; break; }// else keep going } } // else connection as been found in recurstive call return connection; } /** * DOC tguiu Comment method "doGetTableNames". * * @param connection * @return */ private static List<String> doGetTableNames(Connection connection) { List<String> result = new ArrayList<String>(15); for (MetadataTable table : ConnectionHelper.getTables(connection)) { if (table == null) { continue; } result.add(table.getLabel()); } return result; } private static List<String> doGetTableNames(SAPFunctionUnit functionUnit) { List<String> result = new ArrayList<String>(15); for (Object table : functionUnit.getTables()) { result.add(((MetadataTable) table).getLabel()); } return result; } /** * * DOC tguiu Comment method "findByLabel". * * @deprecated it would be better to use find with some unique identifier * @param connection * @param label * @return */ public static MetadataTable findByLabel(Connection connection, String label) { if (connection == null) throw new IllegalArgumentException("null connection"); //$NON-NLS-1$ if (label == null || "".equals(label)) //$NON-NLS-1$ throw new IllegalArgumentException("null/empty label"); //$NON-NLS-1$ Set<MetadataTable> tables = ConnectionHelper.getTables(connection); for (MetadataTable table : tables) { if (label.equals(table.getLabel())) return table; } return null; } public static MetadataTable findByLabel(SAPFunctionUnit functionUnit, String label) { if (functionUnit == null) throw new IllegalArgumentException("null connection"); //$NON-NLS-1$ if (label == null || "".equals(label)) //$NON-NLS-1$ throw new IllegalArgumentException("null/empty label"); //$NON-NLS-1$ EList tables = functionUnit.getTables(); for (int i = 0; i < tables.size(); i++) { MetadataTable table = (MetadataTable) tables.get(i); if (label.equals(table.getLabel())) return table; } return null; } public static String[] getTableNames(Connection connection) { List<String> result = doGetTableNames(connection); return result.toArray(new String[result.size()]); } public static String[] getTableNames(Connection connection, String discardedValued) { List<String> result = doGetTableNames(connection); result.remove(discardedValued); return result.toArray(new String[result.size()]); } public static String[] getTableNames(SAPFunctionUnit functionUnit) { List<String> result = doGetTableNames(functionUnit); return result.toArray(new String[result.size()]); } public static String[] getTableNames(SAPFunctionUnit functionUnit, String discardedValued) { List<String> result = doGetTableNames(functionUnit); result.remove(discardedValued); return result.toArray(new String[result.size()]); } public static Map<String, Integer> getForeignKeysInformation(TdTable table) { Map<String, Integer> info = new HashMap<String, Integer>(); for (ForeignKey foreign : getForeignKeys(table)) { info.put(foreign.getName(), foreign.getFeature().size()); } return info; } }