/*
* 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.impl;
import org.teiid.core.designer.util.CoreArgCheck;
import org.teiid.designer.jdbc.JdbcImportSettings;
import org.teiid.designer.jdbc.metadata.JdbcCatalog;
import org.teiid.designer.jdbc.metadata.JdbcDatabase;
import org.teiid.designer.jdbc.metadata.JdbcNode;
import org.teiid.designer.jdbc.metadata.JdbcNodeVisitor;
import org.teiid.designer.jdbc.metadata.JdbcSchema;
/**
* The ImportSettingsSelectionVisitor navigates a tree and records which nodes were selected, saving this information to the
* supplied {@link org.teiid.designer.jdbc.JdbcImportSettings JdbcImportSettings} object.
* <p>
* Note that upon visiting the first node, this visitor ensures that the existing
* {@link org.teiid.designer.jdbc.JdbcImportSettings JdbcImportSettings} are cleared of
* {@link JdbcImportSettings#getIncludedCatalogPaths() included catalog paths},
* {@link JdbcImportSettings#getIncludedSchemaPaths() included schema paths}, and
* {@link JdbcImportSettings#getExcludedObjectPaths() excluded object paths}.
* </p>
* <p>
* When this visitor visits the tree, it will navigate down branches that are either partially selected or selected. So if such
* branches were not navigated to yet, the act of visiting will cause the loading of those nodes. However, because they are
* selected (or partially selected), those nodes will have to be loaded anyway to get the metadata to be imported.
* </p>
*
* @since 8.0
*/
public class ImportSettingsSelectionVisitor implements JdbcNodeVisitor {
private final JdbcImportSettings settings;
private boolean settingsHaveBeenCleared = false;
/**
* Construct an instance of ImportSettingsSelectionVisitor.
*/
public ImportSettingsSelectionVisitor( final JdbcImportSettings settings ) {
super();
CoreArgCheck.isNotNull(settings);
this.settings = settings;
}
/* (non-Javadoc)
* @See org.teiid.designer.jdbc.metadata.JdbcNodeVisitor#visit(org.teiid.designer.jdbc.metadata.JdbcNode)
*/
@Override
public boolean visit( final JdbcNode node ) {
if (node == null) {
return false;
}
if (!this.settingsHaveBeenCleared) {
this.settings.getIncludedCatalogPaths().clear();
this.settings.getIncludedSchemaPaths().clear();
this.settings.getExcludedObjectPaths().clear();
settingsHaveBeenCleared = true;
}
// If the node is the database node
if (node instanceof JdbcDatabase) {
// do nothing with it and return true so that its children are processed
return true;
}
// If the node is a catalog or schema, then record whether it was selected ...
if (node instanceof JdbcCatalog) {
if (node.getSelectionMode() == JdbcNode.UNSELECTED) {
return false; // nothing more to see below this!
}
// It is selected or partially selected, so record that
final String pathStr = node.getPath().toString();
settings.getIncludedCatalogPaths().add(pathStr);
return true;
}
if (node instanceof JdbcSchema) {
if (node.getSelectionMode() == JdbcNode.UNSELECTED) {
return false; // nothing more to see below this!
}
// It is selected or partially selected, so record that
final String pathStr = node.getPath().toString();
settings.getIncludedSchemaPaths().add(pathStr);
return true;
}
// If the node allows children, then it is not a leaf node so it should be ignored ...
if (node.allowsChildren()) {
// However, first determine whether we should skip this branch completely
if (node.getSelectionMode() == JdbcNode.UNSELECTED) {
return false; // no need to visit branch
}
// Otherwise, it is either SELECTED or PARTIALLY_SELECTED
// so we should visit this branch. Note that this may actually cause
// branches that have not yet been loaded to be loaded. That's okay,
// since those branches were selected and will have to be loaded anyway
// during the import.
return true;
}
// At this point, we know the node is a leaf node (i.e., JdbcTable or JdbcProcedure, although we have
// to handle unknown types, too). For leaf nodes, we only need to record
// those nodes that are NOT selected. The reason is that we will then by default
// import the other nodes. So if any new tables, procedures, etc. show up,
// they will by default be imported.
final int selectionMode = node.getSelectionMode();
if (selectionMode != JdbcNode.SELECTED) {
final String pathStr = node.getPath().toString();
settings.getExcludedObjectPaths().add(pathStr);
}
return false;
}
}