// ============================================================================
//
// 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.designer.core.model.process;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.talend.core.GlobalServiceRegister;
import org.talend.core.PluginChecker;
import org.talend.core.model.components.IComponent;
import org.talend.core.model.process.EConnectionType;
import org.talend.core.model.process.IConnection;
import org.talend.core.model.process.IConnectionCategory;
import org.talend.core.model.process.INode;
import org.talend.core.model.process.INodeConnector;
import org.talend.core.ui.IJobletProviderService;
import org.talend.core.utils.KeywordsValidator;
import org.talend.designer.core.model.components.EParameterName;
import org.talend.designer.core.ui.editor.connections.Connection;
import org.talend.designer.core.ui.editor.nodes.Node;
import org.talend.designer.core.ui.editor.process.Process;
/**
* DOC nrousseau class global comment. Detailled comment <br/>
*
*/
public class ConnectionManager {
private static EConnectionType newlineStyle;
/**
*
* Will return true if the connection can connect or not between source & target.
*
* @param source
* @param target
* @param connType
* @param connectionName
* @return
*/
private static boolean canConnect(INode source, INode target, EConnectionType connType, String connectionName) {
if (source.equals(target)) {
return false;
}
if (!target.isActivate() || !source.isActivate()) {
return false;
}
boolean skipSameProcessTest = false;
if (newlineStyle.equals(EConnectionType.FLOW_MAIN)) {
int nbMain = 0;
for (IConnection connec : target.getIncomingConnections()) {
if (connec.getLineStyle().equals(EConnectionType.FLOW_MAIN)) {
nbMain++;
}
}
int maxFlowInput = 0;
if (target.getConnectorFromName(EConnectionType.FLOW_MAIN.getName()) != null) {
maxFlowInput = target.getConnectorFromName(EConnectionType.FLOW_MAIN.getName()).getMaxLinkInput();
}
if (maxFlowInput > 1 && nbMain >= 1 && (nbMain <= maxFlowInput || maxFlowInput == -1)) {
// if the component accept several connections on the input, all inputs must come from the same process
boolean isExtensionComponent = false;
AbstractProcessProvider findProcessProviderFromPID = AbstractProcessProvider
.findProcessProviderFromPID(IComponent.JOBLET_PID);
if (findProcessProviderFromPID != null) {
isExtensionComponent = findProcessProviderFromPID.isExtensionComponent(target);
}
if (!isExtensionComponent && !source.sameProcessAs(target, false)) {
return false;
}
skipSameProcessTest = true;
}
}
if (!skipSameProcessTest && source.sameProcessAs(target, false)) {
return false;
}
// limit the use of the tUnite, avoid a conflict in case source link is in a merge part, and target use merge.
if (!source.getLinkedMergeInfo().isEmpty()
&& (!target.getLinkedMergeInfo().isEmpty() || target.getComponent().useMerge())) {
return false;
}
// Check existing connections to avoid to have more than one link
// no matter the type of the connection and the direction
List<Connection> connections = new ArrayList<Connection>((List<Connection>) source.getOutgoingConnections());
connections.removeAll(source.getOutgoingConnections(EConnectionType.FLOW_MAIN));
// connections = source.getOutgoingConnections();
for (int i = 0; i < connections.size(); i++) {
if ((connections.get(i)).getTarget().equals(target)) {
return false;
}
}
connections = new ArrayList<Connection>((List<Connection>) source.getIncomingConnections());
connections.removeAll(source.getIncomingConnections(EConnectionType.FLOW_MAIN));
// connections = source.getIncomingConnections();
for (int i = 0; i < connections.size(); i++) {
if ((connections.get(i)).getSource().equals(target)) {
return false;
}
}
if (connType.hasConnectionCategory(IConnectionCategory.DEPENDENCY)) {
if (!(Boolean) target.getPropertyValue(EParameterName.STARTABLE.getName())) {
return false;
}
boolean isJoblet = false;
if (PluginChecker.isJobLetPluginLoaded()) {
IJobletProviderService service = (IJobletProviderService) GlobalServiceRegister.getDefault().getService(
IJobletProviderService.class);
if (service != null) {
if (service.isJobletComponent(target) && !connType.hasConnectionCategory(IConnectionCategory.FLOW)) {
List<INodeConnector> freeTriggerBuiltConnectors = service.getFreeTriggerBuiltConnectors(target, connType,
true);
if (freeTriggerBuiltConnectors.isEmpty()) {
return false;
}
isJoblet = true;
}
// for bug 10973
if (service.isTriggerNode(target) && target.getIncomingConnections() != null
&& target.getIncomingConnections().size() >= 1) {
return false;
}
}
}
if (!isJoblet && !target.isELTComponent() && !target.isSubProcessStart()) {
return false;
}
}
connections = (List<Connection>) target.getIncomingConnections();
for (int i = 0; i < connections.size(); i++) {
if (connType.equals(EConnectionType.TABLE)) {
if ((connections.get(i)).isActivate()) {
if ((connections.get(i)).getName().equals(connectionName)) {
return false;
}
}
}
}
boolean targetHasHashLinks = ((Process) target.getProcess()).isThereLinkWithHash(target)
| newlineStyle.hasConnectionCategory(IConnectionCategory.USE_HASH);
if (connType.hasConnectionCategory(IConnectionCategory.CONDITION)) {
if (targetHasHashLinks) {
return false;
}
}
if (targetHasHashLinks && source.hasRunIfLink()) {
return false;
}
// if (testIfNoStartAfterAddConnection(source, target)) {
// return false;
// }
return true;
}
private static boolean canConnect(INode source, INode target, EConnectionType connType, String connectionName,
boolean refactorJoblet) {
if (source.equals(target)) {
return false;
}
if (!refactorJoblet && (!target.isActivate() || !source.isActivate())) {
return false;
}
boolean skipSameProcessTest = false;
if (newlineStyle.equals(EConnectionType.FLOW_MAIN)) {
int nbMain = 0;
for (IConnection connec : target.getIncomingConnections()) {
if (connec.getLineStyle().equals(EConnectionType.FLOW_MAIN)) {
nbMain++;
}
}
int maxFlowInput = 0;
if (target.getConnectorFromName(EConnectionType.FLOW_MAIN.getName()) != null) {
maxFlowInput = target.getConnectorFromName(EConnectionType.FLOW_MAIN.getName()).getMaxLinkInput();
}
if (maxFlowInput > 1 && nbMain >= 1 && (nbMain <= maxFlowInput || maxFlowInput == -1)) {
// if the component accept several connections on the input, all inputs must come from the same process
boolean isExtensionComponent = false;
AbstractProcessProvider findProcessProviderFromPID = AbstractProcessProvider
.findProcessProviderFromPID(IComponent.JOBLET_PID);
if (findProcessProviderFromPID != null) {
isExtensionComponent = findProcessProviderFromPID.isExtensionComponent(target);
}
if (!isExtensionComponent && !source.sameProcessAs(target, false)) {
return false;
}
skipSameProcessTest = true;
}
}
if (!skipSameProcessTest && source.sameProcessAs(target, false)) {
return false;
}
// limit the use of the tUnite, avoid a conflict in case source link is in a merge part, and target use merge.
if (!source.getLinkedMergeInfo().isEmpty()
&& (!target.getLinkedMergeInfo().isEmpty() || target.getComponent().useMerge())) {
return false;
}
// Check existing connections to avoid to have more than one link
// no matter the type of the connection and the direction
List<Connection> connections = new ArrayList<Connection>((List<Connection>) source.getOutgoingConnections());
connections.removeAll(source.getOutgoingConnections(EConnectionType.FLOW_MAIN));
// connections = source.getOutgoingConnections();
for (int i = 0; i < connections.size(); i++) {
if ((connections.get(i)).getTarget().equals(target)) {
return false;
}
}
connections = new ArrayList<Connection>((List<Connection>) source.getIncomingConnections());
connections.removeAll(source.getIncomingConnections(EConnectionType.FLOW_MAIN));
// connections = source.getIncomingConnections();
for (int i = 0; i < connections.size(); i++) {
if ((connections.get(i)).getSource().equals(target)) {
return false;
}
}
if (connType.hasConnectionCategory(IConnectionCategory.DEPENDENCY)) {
if (!(Boolean) target.getPropertyValue(EParameterName.STARTABLE.getName())) {
return false;
}
boolean isJoblet = false;
if (PluginChecker.isJobLetPluginLoaded()) {
IJobletProviderService service = (IJobletProviderService) GlobalServiceRegister.getDefault().getService(
IJobletProviderService.class);
if (service != null) {
if (service.isJobletComponent(target) && !connType.hasConnectionCategory(IConnectionCategory.FLOW)) {
List<INodeConnector> freeTriggerBuiltConnectors = service.getFreeTriggerBuiltConnectors(target, connType,
true);
if (freeTriggerBuiltConnectors.isEmpty()) {
return false;
}
isJoblet = true;
}
// for bug 10973
if (service.isTriggerNode(target) && target.getIncomingConnections() != null
&& target.getIncomingConnections().size() >= 1) {
return false;
}
}
}
if (!isJoblet && !target.isELTComponent() && !target.isSubProcessStart()) {
return false;
}
}
connections = (List<Connection>) target.getIncomingConnections();
for (int i = 0; i < connections.size(); i++) {
if (connType.equals(EConnectionType.TABLE)) {
if ((connections.get(i)).isActivate()) {
if ((connections.get(i)).getName().equals(connectionName)) {
return false;
}
}
}
}
boolean targetHasHashLinks = ((Process) target.getProcess()).isThereLinkWithHash(target)
| newlineStyle.hasConnectionCategory(IConnectionCategory.USE_HASH);
if (connType.hasConnectionCategory(IConnectionCategory.CONDITION)) {
if (targetHasHashLinks) {
return false;
}
}
if (targetHasHashLinks && source.hasRunIfLink()) {
return false;
}
// if (testIfNoStartAfterAddConnection(source, target)) {
// return false;
// }
return true;
}
private static boolean testIfNoStartAfterAddConnection(Node source, Node target) {
// connection is added only to test if there is still a start
// it will be removed after the test
INode targetStartNode = target.getProcessStartNode(true);
INode sourceStartNode = source.getProcessStartNode(true);
Connection connection = new Connection(source, target, newlineStyle, false);
((List<IConnection>) source.getOutgoingConnections()).add(connection);
((List<IConnection>) target.getIncomingConnections()).add(connection);
boolean noStart = (!((Node) sourceStartNode).checkIfCanBeStart())
&& ((targetStartNode == null) || (!((Node) targetStartNode).checkIfCanBeStart()));
((List<IConnection>) source.getOutgoingConnections()).remove(connection);
((List<IConnection>) target.getIncomingConnections()).remove(connection);
return noStart;
}
private static int countNbMergeOutgoing(INode node) {
return countNbMergeOutgoing(node, new HashSet<INode>());
}
private static int countNbMergeOutgoing(INode node, Set<INode> checkedNode) {
int curNb = 0;
if (checkedNode.contains(node)) {
return 0;
}
checkedNode.add(node);
if (node.getComponent().useMerge()) {
// if the component use merge even if there is no connection, then add one merge.
curNb++;
}
for (IConnection curConnec : node.getOutgoingConnections()) {
if (curConnec.getLineStyle().equals(EConnectionType.FLOW_MERGE)) {
curNb++;
} else if (curConnec.getLineStyle().equals(EConnectionType.FLOW_MAIN)) {
// if main, then test the next component to check if there is a merge
curNb += countNbMergeOutgoing(curConnec.getTarget(), checkedNode);
}
}
return curNb;
}
private static int countNbMerge(Node source, Node target) {
// Map<INode, Integer> infoSource = source.getSubProcessStartNode(false).getLinkedMergeInfo();
// Map<INode, Integer> infoTarget = target.getSubProcessStartNode(false).getLinkedMergeInfo();
return countNbMergeOutgoing(source.getSubProcessStartNode(false))
+ countNbMergeOutgoing(target.getSubProcessStartNode(false));
}
/**
* Will return true if the connection can connect or not between source & target.
*
* @param oldSource
* @param newSource
* @param target
* @param connType
* @param connectionName
* @return
*/
public static boolean canConnectToSource(INode oldSource, INode newSource, INode target, EConnectionType lineStyle,
String connectorName, String connectionName) {
if (newSource.getConnectorFromName(connectorName) == null) {
// if the new source don't contain the kind of link, then we can't connect the link.
return false;
}
if (PluginChecker.isJobLetPluginLoaded()) {
IJobletProviderService service = (IJobletProviderService) GlobalServiceRegister.getDefault().getService(
IJobletProviderService.class);
if (service != null) {
// can't connect to joblet's node, , bug 21411
if (service.isJobletComponent(oldSource.getJobletNode()) || service.isJobletComponent(target.getJobletNode())) {
return false;
}
}
}
int maxOutput = newSource.getConnectorFromName(connectorName).getMaxLinkOutput();
if (maxOutput != -1 && (newSource.getConnectorFromName(connectorName).getCurLinkNbOutput() >= maxOutput)) {
return false;
}
// fix bug 0004935: Error on job save
if (checkCircle(newSource, target)) {
return false;
}
newlineStyle = lineStyle;
if (!canConnect(newSource, target, lineStyle, connectionName)) {
return false;
}
// if (!newConnectionType.equals(EConnectionType.LOOKUP)) {
// INodeConnector nodeConnectorSource;
// nodeConnectorSource = newSource.getConnectorFromType(newConnectionType);
// if (nodeConnectorSource.getMaxLinkOutput() != -1) {
// if (nodeConnectorSource.getCurLinkNbOutput() >= nodeConnectorSource.getMaxLinkOutput()) {
// return false;
// }
// }
// }
return true;
}
/**
* Will return true if the connection can connect or not between source & target.
*
* @param source
* @param oldTarget
* @param newTarget
* @param connType
* @param connectionName
* @return
*/
public static boolean canConnectToTarget(INode source, INode oldTarget, INode newTarget, EConnectionType lineStyle,
String connectorName, String connectionName) {
newlineStyle = lineStyle;
if (source.equals(newTarget)) {
return false;
}
if (PluginChecker.isJobLetPluginLoaded()) {
IJobletProviderService service = (IJobletProviderService) GlobalServiceRegister.getDefault().getService(
IJobletProviderService.class);
if (service != null) {
if (service.isTriggerNode(newTarget) && !service.canConnectTriggerNode(newTarget, lineStyle)) {
return false;
}
// can't connect from joblet's node, bug 21411
if (service.isJobletComponent(source.getJobletNode())) {
return false;
}
}
}
INode processStartNode = source.getProcessStartNode(true);
// if the target is the start of the (source) process, then can't connect.
if (processStartNode.equals(newTarget)) {
return false;
}
// to avoid different db elt input link to map.
if (newTarget.isELTComponent() && newTarget.getComponent().getName().endsWith("Map")) {
String targetName = newTarget.getComponent().getOriginalFamilyName();
String sourceName = processStartNode.getComponent().getOriginalFamilyName();
if (!targetName.equals(sourceName) && !(lineStyle.hasConnectionCategory(IConnectionCategory.DEPENDENCY))) {
return false;
}
}
// fix bug 0004935: Error on job save
if (checkCircle(source, newTarget)) {
return false;
}
if (newTarget.isFileScaleComponent()) {
if (newlineStyle.hasConnectionCategory(IConnectionCategory.FLOW) && !connectorName.equals("FSCOMBINE")) { //$NON-NLS-1$
return false;
}
}
// for bug 10378
// if (PluginChecker.isJobLetPluginLoaded()) {
// if (EComponentType.JOBLET_INPUT_OUTPUT.equals(newTarget.getComponent().getComponentType())) {
// if (newlineStyle.hasConnectionCategory(IConnectionCategory.FLOW)) {
// boolean isFilterRowComponent = "tFilterRow".equals(source.getComponent().getName());
// if (isFilterRowComponent && connectorName != null
// && (connectorName.equals("FILTER") || connectorName.equals("REJECT"))) {//$NON-NLS-1$//$NON-NLS-1$
// return false;
// }
// }
// }
// }
// Modify Connection Type depending old and new target.
if (newlineStyle.hasConnectionCategory(IConnectionCategory.FLOW)) {
// if the connection type is not the default one, then we don't change automatically.
// && newlineStyle.getName().equals(newConnectionType)) {
newlineStyle = EConnectionType.FLOW_MAIN;
if (newTarget.getComponent().useLookup()) {
int nbMain = 0;
for (IConnection connec : newTarget.getIncomingConnections()) {
if (connec.getLineStyle().equals(EConnectionType.FLOW_MAIN)) {
nbMain++;
}
}
if (nbMain >= 1) {
newlineStyle = EConnectionType.FLOW_REF;
} else {
newlineStyle = EConnectionType.FLOW_MAIN;
}
} else if (newTarget.getComponent().useMerge()) {
newlineStyle = EConnectionType.FLOW_MERGE;
}
}
boolean isJoblet = false;
if (PluginChecker.isJobLetPluginLoaded()) {
IJobletProviderService service = (IJobletProviderService) GlobalServiceRegister.getDefault().getService(
IJobletProviderService.class);
if (service != null && service.isJobletComponent(newTarget)
&& !lineStyle.hasConnectionCategory(IConnectionCategory.FLOW)) {
List<INodeConnector> inputConnector = service.getFreeTriggerBuiltConnectors(newTarget, lineStyle, true);
if (inputConnector.isEmpty()) {
return false;
}
isJoblet = true;
}
}
if (!isJoblet) {
INodeConnector connectorFromType = newTarget.getConnectorFromType(newlineStyle);
int maxInput = connectorFromType.getMaxLinkInput();
if (maxInput != -1 && (connectorFromType.getCurLinkNbInput() >= maxInput)) {
return false;
}
}
if (!canConnect(source, newTarget, lineStyle, connectionName)) {
return false;
}
// if (!newConnectionType.equals(EConnectionType.LOOKUP)) {
// INodeConnector nodeConnectorTarget;
// nodeConnectorTarget = newTarget.getConnectorFromType(newConnectionType);
// if (nodeConnectorTarget.getMaxLinkInput() != -1) {
// if (nodeConnectorTarget.getCurLinkNbInput() >= nodeConnectorTarget.getMaxLinkInput()) {
// return false;
// }
// }
// }
return true;
}
public static boolean canConnectToTarget(INode source, INode oldTarget, INode newTarget, EConnectionType lineStyle,
String connectorName, String connectionName, boolean refactorJoblet) {
newlineStyle = lineStyle;
if (source.equals(newTarget)) {
return false;
}
if (PluginChecker.isJobLetPluginLoaded()) {
IJobletProviderService service = (IJobletProviderService) GlobalServiceRegister.getDefault().getService(
IJobletProviderService.class);
if (service != null) {
if (service.isTriggerNode(newTarget) && !service.canConnectTriggerNode(newTarget, lineStyle)) {
return false;
}
// can't connect from joblet's node, bug 21411
if (service.isJobletComponent(source.getJobletNode())) {
return false;
}
}
}
INode processStartNode = source.getProcessStartNode(true);
// if the target is the start of the (source) process, then can't connect.
if (processStartNode.equals(newTarget)) {
return false;
}
// to avoid different db elt input link to map.
if (newTarget.isELTComponent() && newTarget.getComponent().getName().endsWith("Map")) {
String targetName = newTarget.getComponent().getOriginalFamilyName();
String sourceName = processStartNode.getComponent().getOriginalFamilyName();
if (!targetName.equals(sourceName) && !(lineStyle.hasConnectionCategory(IConnectionCategory.DEPENDENCY))) {
return false;
}
}
// fix bug 0004935: Error on job save
if (checkCircle(source, newTarget)) {
return false;
}
if (newTarget.isFileScaleComponent()) {
if (newlineStyle.hasConnectionCategory(IConnectionCategory.FLOW) && !connectorName.equals("FSCOMBINE")) { //$NON-NLS-1$
return false;
}
}
// for bug 10378
// if (PluginChecker.isJobLetPluginLoaded()) {
// if (EComponentType.JOBLET_INPUT_OUTPUT.equals(newTarget.getComponent().getComponentType())) {
// if (newlineStyle.hasConnectionCategory(IConnectionCategory.FLOW)) {
// boolean isFilterRowComponent = "tFilterRow".equals(source.getComponent().getName());
// if (isFilterRowComponent && connectorName != null
// && (connectorName.equals("FILTER") || connectorName.equals("REJECT"))) {//$NON-NLS-1$//$NON-NLS-1$
// return false;
// }
// }
// }
// }
// Modify Connection Type depending old and new target.
if (newlineStyle.hasConnectionCategory(IConnectionCategory.FLOW)) {
// if the connection type is not the default one, then we don't change automatically.
// && newlineStyle.getName().equals(newConnectionType)) {
newlineStyle = EConnectionType.FLOW_MAIN;
if (newTarget.getComponent().useLookup()) {
int nbMain = 0;
for (IConnection connec : newTarget.getIncomingConnections()) {
if (connec.getLineStyle().equals(EConnectionType.FLOW_MAIN)) {
nbMain++;
}
}
if (nbMain >= 1) {
newlineStyle = EConnectionType.FLOW_REF;
} else {
newlineStyle = EConnectionType.FLOW_MAIN;
}
} else if (newTarget.getComponent().useMerge()) {
newlineStyle = EConnectionType.FLOW_MERGE;
}
}
boolean isJoblet = false;
if (PluginChecker.isJobLetPluginLoaded()) {
IJobletProviderService service = (IJobletProviderService) GlobalServiceRegister.getDefault().getService(
IJobletProviderService.class);
if (service != null && service.isJobletComponent(newTarget)
&& !lineStyle.hasConnectionCategory(IConnectionCategory.FLOW)) {
List<INodeConnector> inputConnector = service.getFreeTriggerBuiltConnectors(newTarget, lineStyle, true);
if (inputConnector.isEmpty()) {
return false;
}
isJoblet = true;
}
}
if (!isJoblet) {
INodeConnector connectorFromType = newTarget.getConnectorFromType(newlineStyle);
int maxInput = connectorFromType.getMaxLinkInput();
if (maxInput != -1 && (connectorFromType.getCurLinkNbInput() >= maxInput)) {
return false;
}
}
if (!canConnect(source, newTarget, lineStyle, connectionName, refactorJoblet)) {
return false;
}
// if (!newConnectionType.equals(EConnectionType.LOOKUP)) {
// INodeConnector nodeConnectorTarget;
// nodeConnectorTarget = newTarget.getConnectorFromType(newConnectionType);
// if (nodeConnectorTarget.getMaxLinkInput() != -1) {
// if (nodeConnectorTarget.getCurLinkNbInput() >= nodeConnectorTarget.getMaxLinkInput()) {
// return false;
// }
// }
// }
return true;
}
/**
* To call after the canConnect only, this will give the new connection type after connect.
*
* @return the newConnectionType
*/
public static EConnectionType getNewConnectionType() {
return newlineStyle;
}
/**
*
* Not used yet.
*
* @param source
* @param target
* @param connType
* @param connectionName
* @return
*/
public static boolean canRename(INode source, INode target, EConnectionType connType, String connectionName) {
boolean canRename = true;
if (connType.hasConnectionCategory(IConnectionCategory.UNIQUE_NAME)) {
if (!(source.getProcess().checkValidConnectionName(connectionName)) || KeywordsValidator.isKeyword(connectionName)
|| "ErrorReject".equals(connectionName) || "context".equals(connectionName)) {//$NON-NLS-N$ //$NON-NLS-N$
canRename = false;
}
} else if (connType.equals(EConnectionType.TABLE)) {
if (connectionName.equals("")) { //$NON-NLS-1$
canRename = false;
} else {
canRename = checkConnectionValue(connectionName);
if (canRename) {
List<? extends IConnection> cons = target.getIncomingConnections();
for (Iterator iter = cons.iterator(); iter.hasNext();) {
Connection conn = (Connection) iter.next();
if (conn.getName().equals(connectionName)) {
canRename = false;
break;
}
}
}
}
}
return canRename;
}
private static boolean checkConnectionValue(String value) {
if (KeywordsValidator.isKeyword(value) || KeywordsValidator.isSqlKeyword(value)) {
return false;
}
if (value.contains(".")) { //$NON-NLS-1$
int indexOf = value.indexOf("."); //$NON-NLS-1$
String preString = value.substring(0, indexOf);
if (KeywordsValidator.isKeyword(preString) || KeywordsValidator.isSqlKeyword(preString)) {
return false;
} else {
String postString = value.substring(indexOf + 1);
return checkConnectionValue(postString);
}
}
return true;
}
/**
* DOC bqian Comment method "checkCircle".
*
* @param newTarget
* @param source
* @return
*/
private static boolean checkCircle(INode source, INode newTarget) {
// get All the source nodes of the source
List<INode> list = new ArrayList<INode>();
getAllSourceNode(source, list);
if (list.contains(newTarget)) {
return true;
}
return false;
}
/**
* DOC bqian Comment method "getAllSourceNode".
*
* @param source
* @param list
*/
private static void getAllSourceNode(INode source, List<INode> list) {
List<? extends IConnection> connections = source.getIncomingConnections();
for (IConnection connection : connections) {
INode node = connection.getSource();
list.add(node);
getAllSourceNode(node, list);
}
}
}