/* * JBoss, Home of Professional Open Source. * * See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing. * * See the AUTHORS.txt file distributed with this work for a full listing of individual contributors. */ package org.teiid.designer.metamodels.relational.util; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.IStatus; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.resource.Resource; import org.teiid.core.designer.ModelerCoreException; import org.teiid.designer.core.ModelerCore; import org.teiid.designer.core.resource.xmi.MtkXmiResourceImpl; import org.teiid.designer.core.util.ModelVisitor; import org.teiid.designer.core.util.ModelVisitorProcessor; import org.teiid.designer.core.workspace.DotProjectUtils; import org.teiid.designer.core.workspace.ModelResource; import org.teiid.designer.core.workspace.ModelUtil; import org.teiid.designer.core.workspace.ModelWorkspaceException; import org.teiid.designer.extension.ExtensionPlugin; import org.teiid.designer.extension.registry.ModelExtensionRegistry; import org.teiid.designer.metamodels.relational.AccessPattern; import org.teiid.designer.metamodels.relational.BaseTable; import org.teiid.designer.metamodels.relational.Catalog; import org.teiid.designer.metamodels.relational.Column; import org.teiid.designer.metamodels.relational.ForeignKey; import org.teiid.designer.metamodels.relational.Index; import org.teiid.designer.metamodels.relational.LogicalRelationship; import org.teiid.designer.metamodels.relational.LogicalRelationshipEnd; import org.teiid.designer.metamodels.relational.PrimaryKey; import org.teiid.designer.metamodels.relational.Procedure; import org.teiid.designer.metamodels.relational.ProcedureParameter; import org.teiid.designer.metamodels.relational.ProcedureResult; import org.teiid.designer.metamodels.relational.RelationalPackage; import org.teiid.designer.metamodels.relational.RelationalPlugin; import org.teiid.designer.metamodels.relational.Schema; import org.teiid.designer.metamodels.relational.Table; import org.teiid.designer.metamodels.relational.UniqueConstraint; import org.teiid.designer.metamodels.relational.UniqueKey; import org.teiid.designer.metamodels.relational.extension.RelationalModelExtensionAssistant; import org.teiid.designer.metamodels.relational.extension.RelationalModelExtensionConstants; /** * RelationalUtil * * @since 8.0 */ public class RelationalUtil { /** * Prevent allocation */ private RelationalUtil() { super(); } protected static void executeVisitor( final Object container, final ModelVisitor visitor, final int depth ) { final ModelVisitorProcessor processor = new ModelVisitorProcessor(visitor); try { if (container instanceof Resource) { processor.walk((Resource)container, depth); } else if (container instanceof EObject) { processor.walk((EObject)container, depth); } } catch (ModelerCoreException e) { ModelerCore.Util.log(e); } } /** * Add any {@link UniqueKey} instances found under the supplied container * * @param container the EObject or Resource under which the keys are to be found; may not be null * @return the keys that were found; may not be null */ public static List findUniqueKeys( final Object container ) { return findUniqueKeys(container, ModelVisitorProcessor.DEPTH_INFINITE); } /** * Add any {@link UniqueKey} instances found under the supplied container * * @param container the EObject or Resource under which the keys are to be found; may not be null * @param depth how deep to search beneath the container, see {@link ModelVisitorProcessor} * @return the keys that were found; may not be null */ @SuppressWarnings({ "unused", "rawtypes", "unchecked" }) public static List findUniqueKeys( final Object container, final int depth ) { final UniqueKeyFinder finder = new UniqueKeyFinder(); // TODO: TEIIDDES-2660 // Foreign keys can now reference PK/UC outside of a resource (i.e. another model) // So need to get the "project" for the initial container (if MtkXmiResourceImpl) and find other resources of like metamodel // i.e. source or view models and add any other PK/UC's in like models that can be referenced. // if( container instanceof MtkXmiResourceImpl ) { List allObjects = new ArrayList(); try { Collection<MtkXmiResourceImpl> allProjectRelationalModels = getProjectsOtherModels((MtkXmiResourceImpl)container); for( MtkXmiResourceImpl nextContainer : allProjectRelationalModels ) { List tempObjects = findObjects(finder, nextContainer, depth); allObjects.addAll(tempObjects); } } catch (ModelWorkspaceException e) { // TODO Auto-generated catch block e.printStackTrace(); } return allObjects; } return findObjects(finder, container, depth); } /** * Add any {@link ForeignKey} instances found under the supplied container * * @param container the EObject or Resource under which the keys are to be found; may not be null * @return the keys that were found; may not be null */ public static List findForeignKeys( final Object container ) { return findForeignKeys(container, ModelVisitorProcessor.DEPTH_INFINITE); } /** * Add any {@link ForeignKey} instances found under the supplied container * * @param container the EObject or Resource under which the keys are to be found; may not be null * @param depth how deep to search beneath the container, see {@link ModelVisitorProcessor} * @return the keys that were found; may not be null */ public static List findForeignKeys( final Object container, final int depth ) { final ForeignKeyFinder finder = new ForeignKeyFinder(); return findObjects(finder, container, depth); } /** * Add any {@link ForeignKey} or {@link UniqueKey} instances found under the supplied container * * @param container the EObject or Resource under which the keys are to be found; may not be null * @return the keys that were found; may not be null */ public static List findKeys( final Object container ) { // NO_UCD return findKeys(container, ModelVisitorProcessor.DEPTH_INFINITE); } /** * Add any {@link ForeignKey} or {@link UniqueKey} instances found under the supplied container * * @param container the EObject or Resource under which the keys are to be found; may not be null * @param depth how deep to search beneath the container, see {@link ModelVisitorProcessor} * @return the keys that were found; may not be null */ public static List findKeys( final Object container, final int depth ) { final KeyFinder finder = new KeyFinder(); return findObjects(finder, container, depth); } /** * Add any {@link Index} instances found under the supplied container * * @param container the EObject or Resource under which the indexes are to be found; may not be null * @return the indexes that were found; may not be null */ public static List findIndexes( final Object container ) { return findIndexes(container, ModelVisitorProcessor.DEPTH_INFINITE); } /** * Add any {@link Index} instances found under the supplied container * * @param container the EObject or Resource under which the indexes are to be found; may not be null * @param depth how deep to search beneath the container, see {@link ModelVisitorProcessor} * @return the indexes that were found; may not be null */ public static List findIndexes( final Object container, final int depth ) { final IndexFinder finder = new IndexFinder(); return findObjects(finder, container, depth); } /** * Add any {@link Table} instances found under the supplied container * * @param container the EObject or Resource under which the tables are to be found; may not be null * @return the tables that were found; may not be null */ public static List findTables( final Object container ) { return findTables(container, ModelVisitorProcessor.DEPTH_INFINITE); } /** * Add any {@link Table} instances found under the supplied container * * @param container the EObject or Resource under which the tables are to be found; may not be null * @param depth how deep to search beneath the container, see {@link ModelVisitorProcessor} * @return the tables that were found; may not be null */ public static List findTables( final Object container, final int depth ) { final TableFinder finder = new TableFinder(); return findObjects(finder, container, depth); } /** * Add any {@link Procedure} instances found under the supplied container * * @param container the EObject or Resource under which the procedures are to be found; may not be null * @return the procedures that were found; may not be null */ public static List findProcedures( final Object container ) { // NO_UCD return findProcedures(container, ModelVisitorProcessor.DEPTH_INFINITE); } /** * Add any {@link Procedure} instances found under the supplied container * * @param container the EObject or Resource under which the procedures are to be found; may not be null * @param depth how deep to search beneath the container, see {@link ModelVisitorProcessor} * @return the procedures that were found; may not be null */ public static List findProcedures( final Object container, final int depth ) { final ProcedureFinder finder = new ProcedureFinder(); return findObjects(finder, container, depth); } /** * Add any {@link ProcedureParameter} instances found under the supplied container * * @param container the EObject or Resource under which the procedure parameters are to be found; may not be null * @return the procedures parameters that were found; may not be null */ public static List findProcedureParameters( final Object container ) { // NO_UCD return findProcedureParameters(container, ModelVisitorProcessor.DEPTH_INFINITE); } /** * Add any {@link ProcedureParameter} instances found under the supplied container * * @param container the EObject or Resource under which the procedure parameters are to be found; may not be null * @param depth how deep to search beneath the container, see {@link ModelVisitorProcessor} * @return the procedures parameters that were found; may not be null */ public static List findProcedureParameters( final Object container, final int depth ) { final ProcedureParameterFinder finder = new ProcedureParameterFinder(); return findObjects(finder, container, depth); } /** * Add any {@link BaseTable} instances found under the supplied container * * @param container the EObject or Resource under which the tables are to be found; may not be null * @return the tables that were found; may not be null */ public static List findBaseTables( final Object container ) { // NO_UCD return findBaseTables(container, ModelVisitorProcessor.DEPTH_INFINITE); } /** * Add any {@link BaseTable} instances found under the supplied container * * @param container the EObject or Resource under which the tables are to be found; may not be null * @param depth how deep to search beneath the container, see {@link ModelVisitorProcessor} * @return the tables that were found; may not be null */ public static List findBaseTables( final Object container, final int depth ) { final BaseTableFinder finder = new BaseTableFinder(); return findObjects(finder, container, depth); } /** * Add any {@link Column} instances found under the supplied container. * * @param container the EObject or Resource under which the columns are to be found; may not be null * @return the columns that were found; may not be null */ public static List findColumns( final Object container ) { // NO_UCD return findColumns(container, ModelVisitorProcessor.DEPTH_INFINITE); } /** * Add any {@link Column} instances found under the supplied container. * * @param container the EObject or Resource under which the columns are to be found; may not be null * @param depth how deep to search beneath the container, see {@link ModelVisitorProcessor} * @return the columns that were found; may not be null */ public static List findColumns( final Object container, final int depth ) { final ColumnFinder finder = new ColumnFinder(); return findObjects(finder, container, depth); } /** * Add any {@link Column} instances found under the supplied container but that are also contained by a {@link BaseTable}. * * @param container the EObject or Resource under which the columns are to be found; may not be null * @return the columns that were found; may not be null */ public static List findBaseTableColumns( final Object container ) { return findBaseTableColumns(container, ModelVisitorProcessor.DEPTH_INFINITE); } /** * Add any {@link Column} instances found under the supplied container but that are also contained by a {@link BaseTable}. * * @param container the EObject or Resource under which the columns are to be found; may not be null * @param depth how deep to search beneath the container, see {@link ModelVisitorProcessor} * @return the columns that were found; may not be null */ public static List findBaseTableColumns( final Object container, final int depth ) { final BaseTableColumnFinder finder = new BaseTableColumnFinder(); return findObjects(finder, container, depth); } /** * Add any {@link LogicalRelationship} instances found under the supplied container * * @param container the EObject or Resource under which the tables are to be found; may not be null * @return the tables that were found; may not be null */ public static List findLogicalRelationships( final Object container ) { // NO_UCD return findLogicalRelationships(container, ModelVisitorProcessor.DEPTH_INFINITE); } /** * Add any {@link LogicalRelationship} instances found under the supplied container * * @param container the EObject or Resource under which the tables are to be found; may not be null * @param depth how deep to search beneath the container, see {@link ModelVisitorProcessor} * @return the tables that were found; may not be null */ public static List findLogicalRelationships( final Object container, final int depth ) { final LogicalRelationshipFinder finder = new LogicalRelationshipFinder(); return findObjects(finder, container, depth); } /** * Add any {@link LogicalRelationshipEnd} instances found under the supplied container * * @param container the EObject or Resource under which the tables are to be found; may not be null * @return the tables that were found; may not be null */ public static List findLogicalRelationshipEnds( final Object container ) { return findLogicalRelationshipEnds(container, ModelVisitorProcessor.DEPTH_INFINITE); } /** * Add any {@link LogicalRelationshipEnd} instances found under the supplied container * * @param container the EObject or Resource under which the tables are to be found; may not be null * @param depth how deep to search beneath the container, see {@link ModelVisitorProcessor} * @return the tables that were found; may not be null */ public static List findLogicalRelationshipEnds( final Object container, final int depth ) { final LogicalRelationshipEndFinder finder = new LogicalRelationshipEndFinder(); return findObjects(finder, container, depth); } /** * Add any {@link Table} instances found under the supplied container * * @param container the EObject or Resource under which the tables are to be found; may not be null * @return the tables that were found; may not be null */ public static List findSchemas( final Object container ) { // NO_UCD return findSchemas(container, ModelVisitorProcessor.DEPTH_INFINITE); } /** * Add any {@link Table} instances found under the supplied container * * @param container the EObject or Resource under which the tables are to be found; may not be null * @param depth how deep to search beneath the container, see {@link ModelVisitorProcessor} * @return the tables that were found; may not be null */ public static List findSchemas( final Object container, final int depth ) { final SchemaFinder finder = new SchemaFinder(); return findObjects(finder, container, depth); } /** * Add any {@link Catalog} instances found under the supplied container * * @param container the EObject or Resource under which the tables are to be found; may not be null * @return the tables that were found; may not be null */ public static List findCatalogs( final Object container ) { // NO_UCD return findCatalogs(container, ModelVisitorProcessor.DEPTH_INFINITE); } /** * Add any {@link Catalog} instances found under the supplied container * * @param container the EObject or Resource under which the tables are to be found; may not be null * @param depth how deep to search beneath the container, see {@link ModelVisitorProcessor} * @return the tables that were found; may not be null */ public static List findCatalogs( final Object container, final int depth ) { final CatalogFinder finder = new CatalogFinder(); return findObjects(finder, container, depth); } /** * Add any objects found under the supplied container * * @param container the EObject or Resource under which the objects are to be found; may not be null * @return the objects that were found; may not be null */ private static List findObjects( final RelationalEntityFinder finder, final Object container, final int depth ) { executeVisitor(container, finder, depth); // the container is collected along with childre // remove the container from results finder.removeContainer(container); return finder.getObjects(); } public static boolean addChildToParent( final EObject child, final EObject parent ) { if (parent instanceof BaseTable) { if (child instanceof Column) { ((BaseTable)parent).getColumns().add(child); } else if (child instanceof PrimaryKey) { ((BaseTable)parent).setPrimaryKey((PrimaryKey)child); } else if (child instanceof ForeignKey) { ((BaseTable)parent).getForeignKeys().add(child); } else if (child instanceof UniqueConstraint) { ((BaseTable)parent).getUniqueConstraints().add((UniqueConstraint) child); } else if (child instanceof AccessPattern) { ((BaseTable)parent).getAccessPatterns().add(child); } else { return false; } } else if (parent instanceof Schema) { if (child instanceof Table) { ((Schema)parent).getTables().add(child); } else if (child instanceof Index) { ((Schema)parent).getIndexes().add(child); } else if (child instanceof Procedure) { ((Schema)parent).getProcedures().add(child); } else { return false; } } else if (parent instanceof Catalog) { if (child instanceof Table) { ((Catalog)parent).getTables().add(child); } else if (child instanceof Index) { ((Catalog)parent).getIndexes().add(child); } else if (child instanceof Schema) { ((Catalog)parent).getSchemas().add(child); } else if (child instanceof Procedure) { ((Schema)parent).getProcedures().add(child); } else { return false; } } else if (parent instanceof Procedure) { if (child instanceof ProcedureParameter) { ((Procedure)parent).getParameters().add(child); } else if (child instanceof ProcedureResult) { ((Procedure)parent).setResult((ProcedureResult)child); } else { return false; } } else if (parent instanceof ProcedureResult) { if (child instanceof Column) { ((ProcedureResult)parent).getColumns().add(child); } else { return false; } } else { return false; } return true; } public static boolean isGlobalTempTable(final EObject eObject) { final ModelExtensionRegistry registry = ExtensionPlugin.getInstance().getRegistry(); final String prefix = RelationalModelExtensionConstants.NAMESPACE_PROVIDER.getNamespacePrefix(); final RelationalModelExtensionAssistant assistant = (RelationalModelExtensionAssistant)registry.getModelExtensionAssistant(prefix); // Check to see if the table has extension property for isGlobalTemporaryTable == TRUE boolean result = false; if( assistant != null ) { try { String resultString = assistant.getPropertyValue(eObject, RelationalModelExtensionConstants.PropertyIds.GLOBAL_TEMP_TABLE); if( resultString != null ) { result = Boolean.parseBoolean(resultString); } } catch (Exception ex) { RelationalPlugin.Util.log(IStatus.ERROR, ex, ex.getMessage()); } } return result; } public static RelationalModelExtensionAssistant getRelationalExtensionAssistant() { final ModelExtensionRegistry registry = ExtensionPlugin.getInstance().getRegistry(); final String prefix = RelationalModelExtensionConstants.NAMESPACE_PROVIDER.getNamespacePrefix(); final RelationalModelExtensionAssistant assistant = (RelationalModelExtensionAssistant)registry.getModelExtensionAssistant(prefix); return assistant; } private static Collection<MtkXmiResourceImpl> getProjectsOtherModels(MtkXmiResourceImpl containerModel) throws ModelWorkspaceException { List<MtkXmiResourceImpl> projectRelationalModels = new ArrayList<MtkXmiResourceImpl>(); ModelResource mr = ModelUtil.getModel(containerModel); IProject proj = mr.getCorrespondingResource().getProject(); Collection<IFile> allProjectFiles = DotProjectUtils.getAllProjectResources(proj); for( IFile res : allProjectFiles ) { if ( ModelUtil.isModelFile(res) ) { ModelResource theMR = ModelUtil.getModel(res); if( theMR != null && theMR.getPrimaryMetamodelUri().equals(RelationalPackage.eNS_URI)) { projectRelationalModels.add((MtkXmiResourceImpl)theMR.getEmfResource()); } } } return projectRelationalModels; } }