/* * 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.jdbc.metadata; 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.core.runtime.IPath; /** * This QualifiedNameRequirementVisitor class is used to determine whether the selected nodes under a {@link JdbcDatabase} require * at least some of the namespaces to exist in a model, or whether it is possible to remove schemas and/or catalogs from a model. * <p> * The current policy is that all database objects (regardless type) have to be uniquely identifiable by a (short or * fully-qualified) name. * </p> * * @since 8.0 */ public class QualifiedNameRequirementVisitor implements JdbcNodeVisitor { private final boolean includeCatalogs; private final boolean includeSchemas; private final Map jdbcNodesWithSamePathByPath; private final Set pathsWithClashes; /** * Construct an instance of QualifiedNameCheckVisitor. */ public QualifiedNameRequirementVisitor( final boolean includeCatalogs, final boolean includeSchemas ) { super(); this.includeCatalogs = includeCatalogs; this.includeSchemas = includeSchemas; this.jdbcNodesWithSamePathByPath = new HashMap(); this.pathsWithClashes = new HashSet(); } /** * @see org.teiid.designer.jdbc.metadata.JdbcNodeVisitor#visit(org.teiid.designer.jdbc.metadata.JdbcNode) */ @Override public boolean visit( final JdbcNode node ) { if (node == null || node.getSelectionMode() == JdbcNode.UNSELECTED) { return false; // no need to process further ... } final IPath pathInModel = node.getPathInSource(this.includeCatalogs, this.includeSchemas); if (pathInModel == null) { return true; // nothing to do with this node, but evaluate children } // There is a path in the model, so see if something has used it already ... List jdbcNodesWithSamePath = (List)jdbcNodesWithSamePathByPath.get(pathInModel); if (jdbcNodesWithSamePath == null) { jdbcNodesWithSamePath = new ArrayList(); this.jdbcNodesWithSamePathByPath.put(pathInModel, jdbcNodesWithSamePath); } // Put the object in the list jdbcNodesWithSamePath.add(node); // If there is more than one node with the same path, mark it if (jdbcNodesWithSamePath.size() > 1) { this.pathsWithClashes.add(pathInModel); } return false; } /** * Return the {@link IPath} instances that reflect more than one model object. * * @return the list of IPath instances that are ambiguous; never null */ public Collection getAmbiguousPaths() { return this.pathsWithClashes; } /** * Return the list of {@link JdbcNode nodes} that would have the same path within the model. * * @param path the path * @return the list of JdbcNode instances; never null, but possibly empty */ public List getNodesWithPath( final IPath path ) { final List jdbcNodesWithSamePath = (List)jdbcNodesWithSamePathByPath.get(path); return (jdbcNodesWithSamePath != null ? new ArrayList(jdbcNodesWithSamePath) : new ArrayList()); } }