blob: 773d7a261ca5d1b95603bebbfb067795990aa522 [file] [log] [blame]
/*****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
****************************************************************/
package org.apache.cayenne.modeler.editor.dbimport;
import org.apache.cayenne.dbsync.reverse.dbimport.Catalog;
import org.apache.cayenne.dbsync.reverse.dbimport.ExcludeColumn;
import org.apache.cayenne.dbsync.reverse.dbimport.ExcludeProcedure;
import org.apache.cayenne.dbsync.reverse.dbimport.ExcludeTable;
import org.apache.cayenne.dbsync.reverse.dbimport.IncludeColumn;
import org.apache.cayenne.dbsync.reverse.dbimport.IncludeProcedure;
import org.apache.cayenne.dbsync.reverse.dbimport.IncludeTable;
import org.apache.cayenne.dbsync.reverse.dbimport.ReverseEngineering;
import org.apache.cayenne.dbsync.reverse.dbimport.Schema;
import org.apache.cayenne.modeler.dialog.db.load.DbImportTreeNode;
import javax.swing.tree.TreePath;
import java.awt.Color;
/**
* @since 4.1
*/
class DbImportNodeHandler {
private static final Color ACCEPT_COLOR = new Color(60,179,113);
private static final Color EXCLUDE_COLOR = new Color(178, 0, 0);
static final Color NON_INCLUDE_COLOR = Color.LIGHT_GRAY;
static final Color LABEL_COLOR = Color.BLACK;
private static final int EXCLUDE_TABLE_RATE = -10000;
private boolean existFirstLevelIncludeTable;
private boolean existCatalogsOrSchemas;
private boolean hasEntitiesInEmptyContainer;
private DbImportTreeNode dbSchemaNode;
private DbImportTree reverseEngineeringTree;
private boolean namesIsEqual(DbImportTreeNode reverseEngineeringNode) {
if (isContainer(reverseEngineeringNode)) {
return dbSchemaNode.getSimpleNodeName().equals(reverseEngineeringNode.getSimpleNodeName());
} else {
return (dbSchemaNode.getSimpleNodeName().toLowerCase().matches(reverseEngineeringNode.getSimpleNodeName().toLowerCase()));
}
}
boolean isContainer(DbImportTreeNode node) {
return (node.getUserObject().getClass() == Schema.class) || (node.getUserObject().getClass() == Catalog.class);
}
private boolean isEmptyContainer(DbImportTreeNode rootNode) {
return ((getChildIncludeTableCount(rootNode) == 0) && (!existFirstLevelIncludeTable));
}
boolean isParentIncluded() {
return ((dbSchemaNode.getParent() != null) && (((DbImportTreeNode) dbSchemaNode.getParent()).isColorized()));
}
// Compare node with current rendered node
public boolean nodesIsEqual(DbImportTreeNode reverseEngineeringNode) {
TreePath[] paths = reverseEngineeringTree.getSelectionPaths();
for (TreePath path : paths != null ? paths : new TreePath[0]) {
DbImportTreeNode node = (DbImportTreeNode) path.getLastPathComponent();
if ((nodesClassesComparation(node.getUserObject().getClass(), dbSchemaNode.getUserObject().getClass()))
&& namesIsEqual(node)
&& (dbSchemaNode.getLevel() >= node.getLevel())
&& (dbSchemaNode.parentsIsEqual(node))) {
return true;
}
}
if ((nodesClassesComparation(reverseEngineeringNode.getUserObject().getClass(), dbSchemaNode.getUserObject().getClass()))
&& namesIsEqual(reverseEngineeringNode)
&& (dbSchemaNode.getLevel() >= reverseEngineeringNode.getLevel())
&& (dbSchemaNode.parentsIsEqual(reverseEngineeringNode))) {
return true;
}
return false;
}
public boolean checkTreesLevels(DbImportTree dbTree) {
if (dbTree.getRootNode().getChildCount() == 0) {
return false;
}
DbImportTreeNode dbNode = (DbImportTreeNode) dbTree.getRootNode().getChildAt(0);
int childCount = reverseEngineeringTree.getRootNode().getChildCount();
for (int i = 0; i < childCount; i++) {
if (((DbImportTreeNode) reverseEngineeringTree.getRootNode().getChildAt(i)).
getUserObject().getClass() == Catalog.class) {
if (dbNode.getUserObject().getClass() == Catalog.class || dbNode.getUserObject().getClass() == IncludeTable.class) {
return true;
} else {
return false;
}
}
}
return true;
}
// Compare reverseEngineeringNode with node.getParent()
private boolean compareWithParent(DbImportTreeNode reverseEngineeringNode) {
if ((reverseEngineeringNode == null) || (dbSchemaNode.getParent() == null)) {
return false;
}
if ((((DbImportTreeNode)dbSchemaNode.getParent()).getUserObject().getClass() == reverseEngineeringNode.getUserObject().getClass())
&& (((DbImportTreeNode)dbSchemaNode.getParent()).getSimpleNodeName().equals(reverseEngineeringNode.getSimpleNodeName()))
&& (((DbImportTreeNode)dbSchemaNode.getParent()).getLevel() >= reverseEngineeringNode.getLevel())
&& (((DbImportTreeNode)dbSchemaNode.getParent())).parentsIsEqual(reverseEngineeringNode)) {
return true;
}
return false;
}
// Get child IncludeTable's count in node, if exists
private int getChildIncludeTableCount(DbImportTreeNode parentNode) {
if (parentNode.isIncludeTable()) {
return 1;
}
int childCount = parentNode.getChildCount();
int result = 0;
for (int i = 0; i < childCount; i++) {
DbImportTreeNode tmpNode = (DbImportTreeNode) parentNode.getChildAt(i);
if (tmpNode.isIncludeTable()) {
result++;
}
}
return result;
}
// Find Exclude-node in configuration
private boolean foundExclude(DbImportTreeNode rootNode) {
int childCount = rootNode.getChildCount();
for (int i = 0; i < childCount; i++) {
DbImportTreeNode tmpNode = (DbImportTreeNode) rootNode.getChildAt(i);
if (tmpNode.getChildCount() > 0) {
if (tmpNode.isExcludeTable() || tmpNode.isExcludeProcedure()) {
return true;
}
}
if (dbSchemaNode.getParent() != null) {
if (nodesIsEqual(tmpNode)) {
if (tmpNode.isExcludeTable() || tmpNode.isExcludeProcedure()) {
return true;
}
}
}
}
return false;
}
/*
* Recursively traverse DbImportTree,
* Increment result if rendered node exists in configuration tree,
* Subtract EXCLUDE_TABLE_RATE from result, if found Exclude-node for rendered node,
* Return 0, if rendered node not found.
*/
int traverseTree(DbImportTreeNode rootNode) {
hasEntitiesInEmptyContainer = false;
int traverseResult = 0;
int childCount = rootNode.getChildCount();
boolean hasProcedures = false;
// Case for empty reverse engineering, which has a include/exclude tables/procedures
if ((childCount == 0) && (nodesIsEqual(rootNode))) {
traverseResult++;
}
if (nodesIsEqual(rootNode)) {
traverseResult++;
}
ReverseEngineering reverseEngineering = reverseEngineeringTree.getReverseEngineering();
if ((reverseEngineering.getCatalogs().isEmpty()) && (reverseEngineering.getSchemas().isEmpty())
&& (reverseEngineering.getIncludeTables().isEmpty())
&& (!dbSchemaNode.isIncludeProcedure())) {
traverseResult++;
}
if (nodesIsEqual(rootNode) && isEmptyContainer(rootNode)) {
hasEntitiesInEmptyContainer = true;
if (foundExclude(rootNode)) {
return EXCLUDE_TABLE_RATE;
}
return 1;
}
if (compareWithParent(rootNode) && (!rootNode.isReverseEngineering()) &&
isEmptyContainer(rootNode) && (dbSchemaNode.isIncludeTable())) {
hasEntitiesInEmptyContainer = true;
if (foundExclude(rootNode)) {
return EXCLUDE_TABLE_RATE;
}
return 1;
}
if (hasEntitiesInEmptyContainer) {
for (int i = 0; i < childCount; i++) {
DbImportTreeNode tmpNode = (DbImportTreeNode) rootNode.getChildAt(i);
if (dbSchemaNode.isIncludeProcedure() && (nodesIsEqual(tmpNode))) {
int tmpNodeChildCount = tmpNode.getChildCount();
if (tmpNodeChildCount > 0) {
traverseResult += traverseTree((DbImportTreeNode) rootNode.getChildAt(i));
}
traverseResult++;
hasProcedures = true;
}
}
if ((!rootNode.isExcludeTable()) && (!nodesIsEqual(rootNode))
&& (!dbSchemaNode.isIncludeProcedure()) &&(!dbSchemaNode.isIncludeColumn())) {
traverseResult++;
} else {
if ((!hasProcedures) && (!dbSchemaNode.isIncludeProcedure())) {
traverseResult += EXCLUDE_TABLE_RATE;
}
}
}
for (int i = 0; i < childCount; i++) {
DbImportTreeNode tmpNode = (DbImportTreeNode) rootNode.getChildAt(i);
if (tmpNode.getChildCount() > 0) {
traverseResult += traverseTree(tmpNode);
if (tmpNode.isExcludeTable() || tmpNode.isExcludeProcedure()) {
traverseResult += EXCLUDE_TABLE_RATE;
}
} else if (compareWithParent(tmpNode) && !(existFirstLevelIncludeTable)) {
if (!dbSchemaNode.isIncludeProcedure()) {
traverseResult++;
}
}
if (dbSchemaNode.getParent() != null) {
if (nodesIsEqual(tmpNode)) {
if (tmpNode.isExcludeTable() || tmpNode.isExcludeProcedure()) {
traverseResult += EXCLUDE_TABLE_RATE;
}
traverseResult++;
}
}
}
return traverseResult;
}
Color getColorByNodeType(DbImportTreeNode node) {
if ((reverseEngineeringTree.getSelectionPaths() != null) &&(reverseEngineeringTree.getSelectionPaths().length > 1)) {
for (TreePath path : reverseEngineeringTree.getSelectionPaths()) {
DbImportTreeNode pathNode = (DbImportTreeNode) path.getLastPathComponent();
if (pathNode.getSimpleNodeName().equals(dbSchemaNode.getSimpleNodeName())) {
if (pathNode.isExcludeTable() || pathNode.isExcludeProcedure() || node.isExcludeColumn()) {
return EXCLUDE_COLOR;
} else {
return ACCEPT_COLOR;
}
}
}
}
if (node.isExcludeTable() || node.isExcludeProcedure() || node.isExcludeColumn()) {
return EXCLUDE_COLOR;
} else {
return ACCEPT_COLOR;
}
}
void findFirstLevelIncludeTable() {
DbImportTreeNode root = reverseEngineeringTree.getRootNode();
int childCount = root.getChildCount();
existFirstLevelIncludeTable = false;
existCatalogsOrSchemas = false;
for (int i = 0; i < childCount; i++) {
DbImportTreeNode tmpNode = (DbImportTreeNode) root.getChildAt(i);
if (tmpNode.isIncludeTable()) {
existFirstLevelIncludeTable = true;
}
if (isContainer(tmpNode)) {
existCatalogsOrSchemas = true;
}
}
}
// Check, is DatabaseTree started with IncludeTable or IncludeProcedure
boolean isFirstNodeIsPrimitive(DbImportTree tree) {
final int firstChildIndex = 0;
DbImportTreeNode root = tree.getRootNode();
if (root.getChildCount() == 0) {
return false;
}
DbImportTreeNode firstElement = (DbImportTreeNode) root.getChildAt(firstChildIndex);
if (firstElement.isIncludeTable() || firstElement.isIncludeProcedure()) {
return true;
}
return false;
}
public boolean nodesClassesComparation(Class firstClass, Class secondClass) {
if (firstClass.equals(secondClass)) {
return true;
}
if ((firstClass.equals(IncludeTable.class)) && (secondClass.equals(ExcludeTable.class))) {
return true;
}
if ((firstClass.equals(ExcludeTable.class)) && (secondClass.equals(IncludeTable.class))) {
return true;
}
if ((firstClass.equals(IncludeProcedure.class)) && (secondClass.equals(ExcludeProcedure.class))) {
return true;
}
if ((firstClass.equals(ExcludeProcedure.class)) && (secondClass.equals(IncludeProcedure.class))) {
return true;
}
if ((firstClass.equals(ExcludeColumn.class)) && (secondClass.equals(IncludeColumn.class))) {
return true;
}
if ((firstClass.equals(IncludeColumn.class)) && (secondClass.equals(ExcludeColumn.class))) {
return true;
}
return false;
}
public boolean isExistCatalogsOrSchemas() {
return existCatalogsOrSchemas;
}
public boolean getHasEntitiesInEmptyContainer() {
return hasEntitiesInEmptyContainer;
}
public void setHasEntitiesInEmptyContainer(boolean newFlag) {
hasEntitiesInEmptyContainer = newFlag;
}
public void setDbSchemaNode(DbImportTreeNode dbSchemaNode) {
this.dbSchemaNode = dbSchemaNode;
}
public void setReverseEngineeringTree(DbImportTree reverseEngineeringTree) {
this.reverseEngineeringTree = reverseEngineeringTree;
}
}