001: /*
002: * The contents of this file are subject to the terms of the Common Development
003: * and Distribution License (the License). You may not use this file except in
004: * compliance with the License.
005: *
006: * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
007: * or http://www.netbeans.org/cddl.txt.
008: *
009: * When distributing Covered Code, include this CDDL Header Notice in each file
010: * and include the License file at http://www.netbeans.org/cddl.txt.
011: * If applicable, add the following below the CDDL Header, with the fields
012: * enclosed by brackets [] replaced by your own identifying information:
013: * "Portions Copyrighted [year] [name of copyright owner]"
014: *
015: * The Original Software is NetBeans. The Initial Developer of the Original
016: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
017: * Microsystems, Inc. All Rights Reserved.
018: */
019: package org.netbeans.modules.xslt.mapper.view;
020:
021: import java.util.HashSet;
022: import java.util.Set;
023: import org.netbeans.modules.soa.mapper.basicmapper.BasicMapperRule;
024: import org.netbeans.modules.soa.mapper.common.IMapperGroupNode;
025: import org.netbeans.modules.soa.mapper.common.IMapperLink;
026: import org.netbeans.modules.soa.mapper.common.IMapperNode;
027: import org.netbeans.modules.soa.mapper.common.basicmapper.methoid.IFieldNode;
028: import org.netbeans.modules.soa.mapper.common.basicmapper.tree.IMapperTreeNode;
029:
030: /**
031: *
032: * @author Alexey
033: */
034: public class XsltMapperRule extends BasicMapperRule {
035:
036: /**
037: *
038: * @param mapper
039: */
040: public XsltMapperRule(XsltMapper mapper) {
041: super (mapper);
042: }
043:
044: @Override
045: public boolean isAllowToCreate(IMapperLink link) {
046: IMapperNode startNode = link.getStartNode();
047: IMapperNode endNode = link.getEndNode();
048: //
049: // Check if the start and end nodes are specified
050: if (startNode == null || endNode == null) {
051: return false;
052: }
053: // In case of the start and end nodes are the field nodes
054: // then they should be of different types: input and output
055: if (startNode instanceof IFieldNode
056: && endNode instanceof IFieldNode) {
057: boolean isStartInput = ((IFieldNode) startNode).isInput();
058: boolean isEndInput = ((IFieldNode) endNode).isInput();
059: //
060: if (isStartInput == isEndInput) {
061: return false;
062: }
063: //
064: boolean isStartOutput = ((IFieldNode) startNode).isOutput();
065: boolean isEndOutput = ((IFieldNode) endNode).isOutput();
066: //
067: if (isStartOutput == isEndOutput) {
068: return false;
069: }
070: if (startNode.getLinkCount() > 0) {
071: return false;
072: }
073: if (endNode.getLinkCount() > 0) {
074: return false;
075: }
076: }
077: if (startNode instanceof IMapperTreeNode
078: && ((IMapperTreeNode) startNode).isDestTreeNode()
079: && startNode.getLinkCount() > 0) {
080: return false;
081: }
082: if (endNode instanceof IMapperTreeNode
083: && ((IMapperTreeNode) endNode).isDestTreeNode()
084: && endNode.getLinkCount() > 0) {
085: return false;
086: }
087: if ((startNode instanceof IMapperTreeNode)
088: && (endNode instanceof IFieldNode)
089: && (endNode.getLinkCount() > 0)) {
090: return false;
091: }
092: return !(new CheckCyclicLinks(link).isCycle());
093: }
094:
095: private class CheckCyclicLinks {
096:
097: private IMapperGroupNode stopAt;
098: private Set<IMapperNode> visited = new HashSet<IMapperNode>();
099:
100: private boolean cycleFound = false;
101:
102: public CheckCyclicLinks(IMapperLink link) {
103:
104: if (link.getStartNode() instanceof IFieldNode
105: && link.getEndNode() instanceof IFieldNode) {
106: this .stopAt = link.getStartNode().getGroupNode();
107: checkRecursive(link.getEndNode());
108: }
109: }
110:
111: public boolean isCycle() {
112: return this .cycleFound;
113: }
114:
115: private void checkRecursive(IMapperNode node) {
116:
117: if (node instanceof IFieldNode) {
118: IMapperGroupNode group = node.getGroupNode();
119: if (group == stopAt) {
120: cycleFound = true;
121: return;
122: }
123: if (group != null) {
124: IMapperNode n = group.getFirstNode();
125: while (n != null) {
126:
127: for (Object obj : n.getLinks()) {
128: IMapperLink l = (IMapperLink) obj;
129: if (l.getStartNode() == n) {
130: checkRecursive(l.getEndNode());
131: }
132: }
133: n = group.getNextNode(n);
134: }
135: }
136: }
137: }
138: }
139: }
|