diff options
Diffstat (limited to 'bundles/org.eclipse.wst.xml.core/src-contentmodel/org/eclipse/wst/xml/core/internal/contentmodel/internal/util/CMValidator.java')
-rw-r--r-- | bundles/org.eclipse.wst.xml.core/src-contentmodel/org/eclipse/wst/xml/core/internal/contentmodel/internal/util/CMValidator.java | 1244 |
1 files changed, 0 insertions, 1244 deletions
diff --git a/bundles/org.eclipse.wst.xml.core/src-contentmodel/org/eclipse/wst/xml/core/internal/contentmodel/internal/util/CMValidator.java b/bundles/org.eclipse.wst.xml.core/src-contentmodel/org/eclipse/wst/xml/core/internal/contentmodel/internal/util/CMValidator.java deleted file mode 100644 index 3ee535f6f6..0000000000 --- a/bundles/org.eclipse.wst.xml.core/src-contentmodel/org/eclipse/wst/xml/core/internal/contentmodel/internal/util/CMValidator.java +++ /dev/null @@ -1,1244 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2002, 2006 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - * Jens Lukowski/Innoopract - initial renaming/restructuring - * - *******************************************************************************/ -package org.eclipse.wst.xml.core.internal.contentmodel.internal.util; - -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Hashtable; -import java.util.Iterator; -import java.util.List; -import java.util.Vector; -import org.eclipse.wst.xml.core.internal.contentmodel.CMAnyElement; -import org.eclipse.wst.xml.core.internal.contentmodel.CMContent; -import org.eclipse.wst.xml.core.internal.contentmodel.CMDataType; -import org.eclipse.wst.xml.core.internal.contentmodel.CMDocument; -import org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration; -import org.eclipse.wst.xml.core.internal.contentmodel.CMGroup; -import org.eclipse.wst.xml.core.internal.contentmodel.CMNode; -import org.eclipse.wst.xml.core.internal.contentmodel.CMNodeList; -import org.eclipse.wst.xml.core.internal.contentmodel.util.CMVisitor; - - - -public class CMValidator -{ - protected static StringElementContentComparator stringContentComparitor = new StringElementContentComparator(); - protected Hashtable graphNodeTable = new Hashtable(); - - /** - * GraphNode - */ - protected static class GraphNode - { - public String name; - public boolean isTerminal; - public Vector arcList = new Vector(); - - public GraphNode(String name) - { - this.name = name; - } - - public void addArc(Arc arc) - { - arcList.addElement(arc); - } - - public String toString() - { - return "[GraphNode " + name + "]"; //$NON-NLS-1$ //$NON-NLS-2$ - } - } - - - /** - * Arc - */ - protected static class Arc - { - public static final int ELEMENT = 1; - public static final int REPEAT = 2; - public static final int OPTIONAL = 3; - public static final int PREV_IN = 4; - public static final int OUT_NEXT = 5; - public static final int LINK = 6; - - public int kind; - public String name; - public GraphNode node; - public CMNode cmNode; - - public Arc(int kind, GraphNode node, CMNode cmNode) - { - this(kind, "", node, cmNode); //$NON-NLS-1$ - } - - protected Arc(int kind, String name, GraphNode node, CMNode cmNode) - { - this.name = name; - this.kind = kind; - this.node = node; - this.cmNode = cmNode; - } - } - - - /** - * GraphGenerator - */ - protected static class GraphGenerator extends CMVisitor - { - public int indent; - public int count; - public GraphNode startGraphNode; - public Context context; - - protected static class Context - { - GraphNode from; - GraphNode to; - - Context(GraphNode from, GraphNode to) - { - this.from = from; - this.to = to; - } - - GraphNode getLastGraphNode() - { - return (to != null) ? to : from; - } - } - - - protected GraphGenerator() - { - startGraphNode = new GraphNode(getGraphNodeName()); - context = new Context(startGraphNode, null); - } - - - protected void generateGraph(CMElementDeclaration ed) - { - int contentType = ed.getContentType(); - - if (contentType == CMElementDeclaration.MIXED || - contentType == CMElementDeclaration.ELEMENT) - { - visitCMNode(ed.getContent()); - } - // CMElementDeclaration.PCDATA... no graph required - // CMElementDeclaration.ANY... no graph required - context.getLastGraphNode().isTerminal = true; - } - - - protected String getGraphNodeName() - { - return "n" + count++; //$NON-NLS-1$ - } - - - protected GraphNode getStartGraphNode() - { - return startGraphNode; - } - - - /** - * repeat - * +----#-----+ - * | | - * v | - * prev --#-> in --'x'-> out --#-> next - * | ^ - * | | - * +----------------#--------------+ - * optional - * - */ - protected void createArcs(GraphNode in, GraphNode out, CMContent cmContent) - { - createArcs(in, out, cmContent, false); - } - - protected void createArcs(GraphNode in, GraphNode out, CMContent cmContent, boolean isAllGroup) - { - //println("+createArcs() " + ed.getDescription() + " " + ed.getMinOccur()); - GraphNode prev = context.from; - GraphNode next = new GraphNode(getGraphNodeName()); - - prev.addArc(new Arc(Arc.PREV_IN, in, cmContent)); - out.addArc(new Arc(Arc.OUT_NEXT, next, cmContent)); - - if (context.to != null) - { - next.addArc(new Arc(Arc.LINK, context.to, cmContent)); - } - else - { - context.from = next; - } - - if (cmContent.getMinOccur() == 0) - { - // todo... should we see if an optional arc has already been added? - prev.addArc(new Arc(Arc.OPTIONAL, next, cmContent)); - } - - if (cmContent.getMaxOccur() == -1 || cmContent.getMaxOccur() > 1 || isAllGroup) - { - out.addArc(new Arc(Arc.REPEAT, in, cmContent)); - } - } - - - public void visitCMGroup(CMGroup group) - { - Context prevContext = context; - GraphNode in = new GraphNode("(" + getGraphNodeName()); //$NON-NLS-1$ - GraphNode out = new GraphNode(")" + getGraphNodeName()); //$NON-NLS-1$ - - int groupOperator = group.getOperator(); - if (groupOperator == CMGroup.SEQUENCE) - { - context = new Context(in, null); - super.visitCMGroup(group); - context.from.addArc(new Arc(Arc.LINK, out, group)); - } - else if (groupOperator == CMGroup.CHOICE || - groupOperator == CMGroup.ALL) - { - context = new Context(in, out); - super.visitCMGroup(group); - } - - context = prevContext; - createArcs(in, out, group, groupOperator == CMGroup.ALL); - } - - - public void visitCMElementDeclaration(CMElementDeclaration ed) - { - GraphNode in = new GraphNode(getGraphNodeName()); - GraphNode out = new GraphNode(getGraphNodeName()); - createArcs(in, out, ed); - in.addArc(new Arc(Arc.ELEMENT, ed.getElementName(), out, ed)); - } - - - public void visitCMAnyElement(CMAnyElement anyElement) - { - GraphNode in = new GraphNode(getGraphNodeName()); - GraphNode out = new GraphNode(getGraphNodeName()); - createArcs(in, out, anyElement); - in.addArc(new Arc(Arc.ELEMENT, "any", out, anyElement)); //$NON-NLS-1$ - } - } - - // todo.. implement cache strategy hook, handle name spaces, locals etc. - // - public GraphNode lookupOrCreateGraph(CMElementDeclaration element) - { - Object key = element; - GraphNode node = (GraphNode)graphNodeTable.get(key); - if (node == null) - { - node = createGraph(element); - graphNodeTable.put(key, node); - } - return node; - } - - public GraphNode createGraph(CMElementDeclaration element) - { - GraphGenerator generator = new GraphGenerator(); - generator.generateGraph(element); - return generator.getStartGraphNode(); - } - - - public void printGraph(GraphNode node, Vector namedArcList, Vector unamedArcList, int indent) - { - //String decoration = node.isTerminal ? " *" : ""; - //printlnIndented(indent, "GraphNode:" + node.name + decoration); - - indent += 2; - for (Enumeration e = node.arcList.elements() ; e.hasMoreElements() ;) - { - Arc arc = (Arc)e.nextElement(); - //boolean visit = false; - //printlnIndented(indent, "Arc:" + arc.name + " (" + arc.kind + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - if (arc.kind == Arc.ELEMENT) - { - //table.add(currentGrammarObject, arc.grammarObject); - if (!namedArcList.contains(arc)) - { - namedArcList.add(arc); - unamedArcList = new Vector(); - printGraph(arc.node, namedArcList, unamedArcList, indent + 2); - } - } - else - { - if (!unamedArcList.contains(arc)) - { - unamedArcList.add(arc); - printGraph(arc.node, namedArcList, unamedArcList, indent + 2); - } - } - } - } - - public void printGraph(GraphNode node) - { - printGraph(node, new Vector(), new Vector(), 0); - } - - - public void validateElementList(ElementList list, GraphNode node, ElementContentComparator comparator, Result result, boolean loopFlag) - { - //println("+validateElementList " + node + " " + list); - if (list == null && node.isTerminal) - { - result.isValid = true; - } - else - { - for (Iterator i = node.arcList.iterator(); i.hasNext();) - { - Arc arc = (Arc)i.next(); - boolean traverseArc = false; - if (arc.kind == Arc.ELEMENT) - { - if (list != null && comparator.matches(list.head, arc.cmNode)) - { - loopFlag = false; - traverseArc = true; - list = list.tail; // increment our position in the list - } - } - else if (arc.kind == Arc.REPEAT) - { - if (!loopFlag) - { - traverseArc = true; - } - loopFlag = true; - } - else - { - traverseArc = true; - } - - if (traverseArc) - { - // test to see if we can push this arc due to facet constraints - // - if (result.canPush(arc)) - { - // see if this arc leads to a correct solution - result.push(arc); - validateElementList(list, arc.node, comparator, result, loopFlag); - if (result.isValid) - { - break; - } - result.pop(arc); - } - } - } - } - } - - - /** - * - */ - protected static ElementList createElementList(int contentType, List v, ElementContentComparator comparator, Result result) - { - ElementList first = null; - ElementList prev = null; - - int size = v.size(); - for (int i = 0; i < size; i++) - { - Object o = v.get(i); - if (o != null && !comparator.isIgnorable(o)) - { - if (comparator.isElement(o)) - { - ElementList list = new ElementList(); - list.head = o; - - if (prev != null) - { - prev.tail = list; - } - else - { - first = list; - } - prev = list; - } - else if (contentType == CMElementDeclaration.ELEMENT) - { - result.isValid = false; - result.errorIndex = i; - result.errorMessage = "Element can not include PCDATA content"; //$NON-NLS-1$ - } - } - } - return first; - } - - /** - * - */ - public void validate(CMElementDeclaration ed, List elementContent, ElementContentComparator comparator, Result result) - { - int contentType = ed.getContentType(); - - if (contentType == CMElementDeclaration.MIXED || - contentType == CMElementDeclaration.ELEMENT) - { - ElementList elementList = createElementList(contentType, elementContent, comparator, result); - if (result.isValid == true) - { - // defect 226213 ... elements with a large number of children will cause the recursion based validation - // algorithm to stack overflow ... as a quick fix assume any element with a large number of children is valid - if (elementContent.size() < 500) - { - boolean isGraphValidationNeeded = !(elementList == null && contentType == CMElementDeclaration.MIXED); - - // exlicity handle 'All' groups - // - CMContent content = ed.getContent(); - if (content.getNodeType() == CMNode.GROUP) - { - CMGroup group = (CMGroup)content; - if (group.getOperator() == CMGroup.ALL) - { - isGraphValidationNeeded = false; - validatAllGroupContent(elementContent, comparator, group, result); - } - } - - if (isGraphValidationNeeded) - { - // validate the elementList using a graph - // - result.isValid = false; - GraphNode node = lookupOrCreateGraph(ed); - validateElementList(elementList, node, comparator, result, false); - } - } - } - } - else if (contentType == CMElementDeclaration.PCDATA) - { - int size = elementContent.size(); - for (int i = 0; i < size; i++) - { - Object o = elementContent.get(i); - if (comparator.isElement(o)) - { - result.isValid = false; - result.errorIndex = i; - result.errorMessage = "Element may only include PCDATA content"; //$NON-NLS-1$ - break; - } - } - } - else if (contentType == CMElementDeclaration.EMPTY) - { - int size = elementContent.size(); - for (int i = 0; i < size; i++) - { - Object o = elementContent.get(i); - if (!comparator.isIgnorable(o)) - { - result.isValid = false; - result.errorIndex = i; - result.errorMessage = "Element may not contain PCDATA or Element content"; //$NON-NLS-1$ - break; - } - } - } - //else if (contentType == CMElementDeclaration.ANY) - // { - // assume elementContent will always be valid for this content type - // } - } - - static class ItemCount - { - int count = 0; - } - - private void validatAllGroupContent(List elementContent, ElementContentComparator comparator, CMGroup allGroup, Result result) - { - boolean isValid = true; - boolean isPartiallyValid = true; - HashMap map = new HashMap(); - CMNodeList list = allGroup.getChildNodes(); - for (int j = list.getLength() - 1; j >= 0; j--) - { - CMNode node = list.item(j); - if (map.get(node) == null) - { - map.put(node, new ItemCount()); - } - } - int validitionCount = 0; - for (Iterator i = elementContent.iterator(); i.hasNext(); validitionCount++) - { - Object o = i.next(); - if (comparator.isElement(o)) - { - // test to see if the element is listed in the all group - // - CMNode matchingCMNode = null; - for (int j = list.getLength() - 1; j >= 0; j--) - { - CMNode node = list.item(j); - if (comparator.matches(o, node)) - { - matchingCMNode = node; - break; - } - } - if (matchingCMNode == null) - { - isPartiallyValid = false; - isValid = false; - break; - } - else - { - // test to see that the element occurs only once - // - ItemCount itemCount = (ItemCount)map.get(matchingCMNode); - if (itemCount != null) - { - if (itemCount.count > 0) - { - // we don't want to allow too many elements! - // we consider 'not enough' to be partially valid... but not 'too many' - isPartiallyValid = false; - break; - } - else - { - itemCount.count++; - } - } - } - } - } - if (isValid) - { - for (int j = list.getLength() - 1; j >= 0; j--) - { - CMNode node = list.item(j); - if (node.getNodeType() == CMNode.ELEMENT_DECLARATION) - { - CMContent content = (CMContent)node; - ItemCount itemCount = (ItemCount)map.get(node); -// System.out.print("content " + content.getNodeName() + " " + content.getMinOccur()); - if (itemCount.count < content.getMinOccur()) - { - isValid = false; - break; - } - } - } - } - if (result instanceof ElementPathRecordingResult && isPartiallyValid) - { - ((ElementPathRecordingResult)result).setPartialValidationCount(validitionCount); - } - result.isValid = isValid; - } - - - public void getOriginArray(CMElementDeclaration ed, List elementContent, ElementContentComparator comparator, ElementPathRecordingResult result) - { - CMNode[] cmNodeArray = null; - validate(ed, elementContent, comparator, result); - if (result.isValid) - { - CMDataType dataType = ed.getDataType(); - int size = elementContent.size(); - cmNodeArray = new CMNode[size]; - Vector originList = result.getElementOriginList(); - int originListSize = originList.size(); - int originListIndex = 0; - for (int i = 0; i < size; i++) - { - Object o = elementContent.get(i); - if (comparator.isElement(o)) - { - if (originListIndex < originListSize) - { - cmNodeArray[i] = (CMNode)originList.get(originListIndex); - originListIndex++; - } - } - else if (comparator.isPCData(o)) - { - cmNodeArray[i] = dataType; - } - // else the CMNode at this index is null - } - result.setOriginArray(cmNodeArray); - } - } - - private void collectNamedArcs(GraphNode node, List namedArcList, int indent) - { - //printlnIndented(indent, "GraphNode:" + node.name + decoration); - indent += 2; - for (Iterator i = node.arcList.iterator(); i.hasNext() ;) - { - Arc arc = (Arc)i.next(); - //printlnIndented(indent, "Arc:" + arc.name + " (" + arc.kind + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - if (arc.kind == Arc.ELEMENT) - { - if (!namedArcList.contains(arc)) - { - namedArcList.add(arc); - collectNamedArcs(arc.node, namedArcList, indent + 2); - } - } - else if (arc.kind != Arc.REPEAT && arc.kind != Arc.OPTIONAL) - { - collectNamedArcs(arc.node, namedArcList, indent + 2); - } - } - } - - - private List getMatchingArcs(CMElementDeclaration ed, String elementName) - { - List arcList = new ArrayList(); - GraphNode graphNode = lookupOrCreateGraph(ed); - if (elementName == null) - { - // here we add the 'root' arc - for (Iterator i = graphNode.arcList.iterator(); i.hasNext() ;) - { - Arc arc = (Arc)i.next(); - if (arc.kind == Arc.PREV_IN) - { - arcList.add(arc); - break; - } - } - } - else - { - List namedArcs = new ArrayList(); - collectNamedArcs(graphNode, namedArcs, 0); - for (Iterator i = namedArcs.iterator(); i.hasNext(); ) - { - Arc arc = (Arc)i.next(); - if (arc.cmNode != null && elementName.equals(arc.cmNode.getNodeName())) - { - arcList.add(arc); - } - } - } - return arcList; - } - - - private void collectNextSiblings(GraphNode node, List nextSiblingList, List namedArcList, List unamedArcList, int indent) - { - //printlnIndented(indent, "GraphNode:" + node.name + decoration); - indent += 2; - for (Iterator i = node.arcList.iterator(); i.hasNext(); ) - { - Arc arc = (Arc)i.next(); - if (arc.kind == Arc.ELEMENT) - { - if (!namedArcList.contains(arc)) - { - if (arc.cmNode != null) - { - nextSiblingList.add(arc.cmNode); - if (arc.cmNode.getNodeType() == CMNode.ELEMENT_DECLARATION || - arc.cmNode.getNodeType() == CMNode.ANY_ELEMENT) - { - namedArcList.add(arc); - CMContent cmNode = (CMContent)arc.cmNode; - if (cmNode.getMinOccur() == 0) - { - unamedArcList = new ArrayList(); - collectNextSiblings(arc.node, nextSiblingList, namedArcList, unamedArcList, indent + 2); - } - } - } - } - } - else - { - if (!unamedArcList.contains(arc)) - { - unamedArcList.add(arc); - collectNextSiblings(arc.node, nextSiblingList, namedArcList, unamedArcList, indent + 2); - } - } - } - } - - public CMNode[] getNextSiblings(CMElementDeclaration ed, String elementName) - { - List arcList = getMatchingArcs(ed, elementName); - List nextSiblingList = new ArrayList(); - for (Iterator i = arcList.iterator(); i.hasNext(); ) - { - Arc arc = (Arc)i.next(); - collectNextSiblings(arc.node, nextSiblingList, new ArrayList(), new ArrayList(), 0); - } - CMNode[] result = new CMNode[nextSiblingList.size()]; - nextSiblingList.toArray(result); - //System.out.print("getNextSibling(" +elementName + ")"); - //for (int i = 0; i < result.length; i++) - //{ - // System.out.print("[" + result[i].getNodeName() + "]"); - //} - //System.out.println(); - return result; - } - - /** - * - */ - public static class Result - { - public boolean isValid = true; - public int errorIndex = -1; - public String errorMessage; - public boolean isRepeatTraversed; // detects if a repeat has been traversed - - public boolean canPush(Arc arc) - { - return true; - } - - public void push(Arc arc) - { - // overide this method to record traversed nodes - } - public void pop(Arc arc) - { - // overide this method to record traversed nodes - } - public CMNode[] getOriginArray() - { - return null; - } - } - - /** - * - */ - public static class ElementPathRecordingResult extends Result - { - protected List activeItemCountList = new ArrayList(); - protected List inactiveItemCountList = new ArrayList(); - protected Vector elementOriginStack = new Vector(); - protected CMNode[] originArray = null; - protected int partialValidationCount = 0; - - - // this method is used to support facet counts - // - public boolean canPush(Arc arc) - { - boolean result = true; - try - { - if (arc.kind == Arc.REPEAT) - { - if (arc.cmNode instanceof CMContent) - { - CMContent content = (CMContent)arc.cmNode; - - // we only need to do 'special' facet checking if the maxOccurs is > 1 - // values of '0' and '-1' (unbounded) work 'for free' without any special checking - // - if (content.getMaxOccur() > 1) - { - ItemCount itemCount = (ItemCount)activeItemCountList.get(activeItemCountList.size() - 1); - - // here we need to compute if we can do another repeat - // if we increase the repeat count by '1' will this violate the maxOccurs - // - if (itemCount.count + 1 >= content.getMaxOccur()) - { - result = false; - } - } - //System.out.println("canPush REPEAT (" + itemCount.count + ")" + content.getNodeName() + " result= " + result); - } - } - } - catch (Exception e) - { - e.printStackTrace(); - } - //System.out.flush(); - return result; - } - - public void push(Arc arc) - { - if (arc.kind == Arc.ELEMENT) - { - //System.out.println("[X]push(" + arc.kind + ")" + arc.cmNode.getNodeName()); - elementOriginStack.add(arc.cmNode); - partialValidationCount = Math.max(elementOriginStack.size(), partialValidationCount); - } - else if (arc.kind == Arc.PREV_IN) - { - //System.out.println("[X]push(" + arc.kind + ")" + arc.cmNode.getNodeName()); - activeItemCountList.add(new ItemCount()); - } - else if (arc.kind == Arc.OUT_NEXT) - { - //System.out.println("[X]push(" + arc.kind + ")" + arc.cmNode.getNodeName() + "[" + arc + "]"); - int size = activeItemCountList.size(); - ItemCount itemCount = (ItemCount)activeItemCountList.get(size - 1); - activeItemCountList.remove(size - 1); - inactiveItemCountList.add(itemCount); - } - else if (arc.kind == Arc.REPEAT) - { - //System.out.println("[X]push(" + arc.kind + ")" + arc.cmNode.getNodeName()); - ItemCount itemCount = (ItemCount)activeItemCountList.get(activeItemCountList.size() - 1); - itemCount.count++; - //System.out.println("repeat(" + itemCount.count + ")" + arc.cmNode.getNodeName()); - } - } - - public void pop(Arc arc) - { - if (arc.kind == Arc.ELEMENT) - { - //System.out.println("[X]pop(" + arc.kind + ")" + arc.cmNode.getNodeName()); - int size = elementOriginStack.size(); - elementOriginStack.remove(size - 1); - } - else if (arc.kind == Arc.PREV_IN) - { - //System.out.println("[X]pop(" + arc.kind + ")" + arc.cmNode.getNodeName()); - activeItemCountList.remove(activeItemCountList.size() - 1); - } - else if (arc.kind == Arc.OUT_NEXT) - { - //System.out.println("[X]pop(" + arc.kind + ")" + arc.cmNode.getNodeName()); - int size = inactiveItemCountList.size(); - ItemCount itemCount = (ItemCount)inactiveItemCountList.get(size - 1); - inactiveItemCountList.remove(size - 1); - activeItemCountList.add(itemCount); - } - else if (arc.kind == Arc.REPEAT) - { - //System.out.println("[X]pop(" + arc.kind + ")" + arc.cmNode.getNodeName()); - ItemCount itemCount = (ItemCount)activeItemCountList.get(activeItemCountList.size() - 1); - itemCount.count--; - } - } - - public Vector getElementOriginList() - { - return elementOriginStack; - } - - public CMNode[] getOriginArray() - { - return originArray; - } - - public void setOriginArray(CMNode[] originArray) - { - this.originArray = originArray; - } - - public int getPartialValidationCount() - { - return partialValidationCount; - } - - public void setPartialValidationCount(int partialValidationCount) - { - this.partialValidationCount = partialValidationCount; - } - } - - /** - * - */ - public static class PathRecordingResult extends Result - { - protected Vector arcList = new Vector(); - - public void push(Arc arc) - { - arcList.add(arc); - } - - public void pop(Arc arc) - { - int size = arcList.size(); - arcList.remove(size - 1); - } - - public List getArcList() - { - List list = new Vector(); - for (Iterator iterator = arcList.iterator(); iterator.hasNext(); ) - { - Arc arc = (Arc)iterator.next(); - if (arc.kind == Arc.ELEMENT) - { - list.add(arc); - } - } - return list; - } - - public MatchModelNode getMatchModel() - { - MatchModelNodeBuilder builder = new MatchModelNodeBuilder(arcList); - builder.buildMatchModel(); - return builder.getRoot(); - } - } - - /** - * - */ - public static class MatchModelNode - { - public CMNode cmNode; - public List children = new Vector(); - public Object data; - - public MatchModelNode(MatchModelNode parent, CMNode cmNode) - { - this.cmNode = cmNode; - } - - public void printModel(int indent) - { - //String cmNodeName = cmNode != null ? cmNode.getNodeName() : "null"; - //printlnIndented(indent, "MatchModelNode : " + cmNodeName); - for (Iterator iterator = children.iterator(); iterator.hasNext(); ) - { - MatchModelNode child = (MatchModelNode)iterator.next(); - child.printModel(indent + 2); - } - } - } - - public static class MatchModelNodeBuilder - { - protected List arcList; - protected List stack = new Vector(); - protected MatchModelNode root; - protected MatchModelNode current; - - public MatchModelNodeBuilder(List arcList) - { - this.arcList = arcList; - root = new MatchModelNode(null, null); - push(root); - } - - protected void push(MatchModelNode node) - { - current = node; - stack.add(node); - } - - protected void pop() - { - int size = stack.size(); - stack.remove(size - 1); - current = (MatchModelNode)stack.get(size - 2); - } - - public boolean isCMGroup(CMNode cmNode) - { - return cmNode != null && cmNode.getNodeType() == CMNode.GROUP; - } - - public void buildMatchModel() - { - for (Iterator iterator = arcList.iterator(); iterator.hasNext(); ) - { - Arc arc = (Arc)iterator.next(); - - if (arc.kind == Arc.ELEMENT) - { - current.children.add(new MatchModelNode(current, arc.cmNode)); - } - else if (arc.kind == Arc.PREV_IN) - { - if (isCMGroup(arc.cmNode)) - { - MatchModelNode newModelNode = new MatchModelNode(current, arc.cmNode); - current.children.add(newModelNode); - push(newModelNode); - } - } - else if (arc.kind == Arc.OUT_NEXT) - { - if (isCMGroup(arc.cmNode)) - { - pop(); - } - } - else if (arc.kind == Arc.REPEAT) - { - if (isCMGroup(arc.cmNode)) - { - pop(); - MatchModelNode newModelNode = new MatchModelNode(current, arc.cmNode); - current.children.add(newModelNode); - push(newModelNode); - } - } - } - } - - public MatchModelNode getRoot() - { - return root; - } - } - - - /** - * - */ - public interface ElementContentComparator - { - public boolean isIgnorable(Object o); - public boolean isPCData(Object o); - public boolean isElement(Object o); - public boolean matches(Object o, CMNode cmNode); - } - - /** - * A linked list - */ - public static class ElementList - { - protected Object head; - protected ElementList tail; - - public static ElementList create(List v) - { - ElementList first = null; - ElementList prev = null; - - for (Iterator iterator = v.iterator(); iterator.hasNext(); ) - { - Object o = iterator.next(); - if (o != null) - { - ElementList list = new ElementList(); - list.head = o; - - if (prev != null) - { - prev.tail = list; - } - else - { - first = list; - } - prev = list; - } - } - return first; - } - - - public String toString() - { - String string = "[" + head + "],"; //$NON-NLS-1$ //$NON-NLS-2$ - - if (tail != null) - { - string += tail.toString(); - } - - return string; - } - } - - /** - * StringElementContentComparator - */ - public static class StringElementContentComparator implements ElementContentComparator - { - public boolean isIgnorable(Object o) - { - String string = o.toString(); - return string.startsWith("!") || string.startsWith("?"); //$NON-NLS-1$ //$NON-NLS-2$ - } - - public boolean isPCData(Object o) - { - String string = o.toString(); - return string.startsWith("'") || string.startsWith("\""); //$NON-NLS-1$ //$NON-NLS-2$ - } - - public boolean isElement(Object o) - { - return !isIgnorable(o) && !isPCData(o); - } - - public boolean matches(Object o, CMNode cmNode) - { - boolean result = false; - if (cmNode.getNodeType() == CMNode.ELEMENT_DECLARATION) - { - CMElementDeclaration element = (CMElementDeclaration)cmNode; - String name = o.toString(); - int index = name.indexOf("]"); //$NON-NLS-1$ - if (index != -1) - { - name = name.substring(index + 1); - } - result = name.equalsIgnoreCase(element.getElementName()); - - // TODO... here's we consider substitution groups... revisit to see if this should be moved into validator code - if (!result) - { - CMNodeList cmNodeList = (CMNodeList)element.getProperty("SubstitutionGroup"); //$NON-NLS-1$ - if (cmNodeList != null) - { - int cmNodeListLength = cmNodeList.getLength(); - if (cmNodeListLength > 1) - { - for (int i = 0; i < cmNodeListLength; i++) - { - CMElementDeclaration alternativeCMElementDeclaration = (CMElementDeclaration)cmNodeList.item(i); - String altName = alternativeCMElementDeclaration.getElementName(); - result = name.equalsIgnoreCase(altName); - if (result) - { - break; - } - } - } - } - } - } - else if (cmNode.getNodeType() == CMNode.ANY_ELEMENT) - { - String string = o.toString(); - if (string.equals("*")) //$NON-NLS-1$ - { - result = true; - } - else - { - CMAnyElement anyElement = (CMAnyElement)cmNode; - String anyElementURI = anyElement.getNamespaceURI(); - if (anyElementURI != null) - { - if (anyElementURI.equals("##any")) //$NON-NLS-1$ - { - result = true; - } - else if (anyElementURI.equals("##other")) //$NON-NLS-1$ - { - result = true; - CMDocument cmDocument = (CMDocument)anyElement.getProperty("CMDocument"); //$NON-NLS-1$ - if (cmDocument != null) - { - String excludedURI = (String)cmDocument.getProperty("http://org.eclipse.wst/cm/properties/targetNamespaceURI"); //$NON-NLS-1$ - if (excludedURI != null) - { - String specifiedURI = getURIForContentSpecification(string); - if (specifiedURI != null && excludedURI.equals(specifiedURI)) - { - result = false; - } - } - } - } - else if (anyElementURI.equals("##targetNamespace")) //$NON-NLS-1$ - { - result = true; - CMDocument cmDocument = (CMDocument)anyElement.getProperty("CMDocument"); //$NON-NLS-1$ - if (cmDocument != null) - { - String targetNamespaceURI = (String)cmDocument.getProperty("http://org.eclipse.wst/cm/properties/targetNamespaceURI"); //$NON-NLS-1$ - String specifiedURI = getURIForContentSpecification(string); - if (specifiedURI != null && !targetNamespaceURI.equals(specifiedURI)) - { - result = false; - } - } - } - else - { - result = true; - String specifiedURI = getURIForContentSpecification(string); - if (specifiedURI != null && !anyElementURI.equals(specifiedURI)) - { - result = false; - } - } - } - else - { - result = true; - } - } - } - return result; - } - - - protected String getURIForContentSpecification(String specification) - { - String result = null; - int index = specification.indexOf("]"); //$NON-NLS-1$ - if (index != -1) - { - result = specification.substring(1, index); - } - return result; - } - } - - public static List createStringList(String arg[], int startIndex) - { - Vector v = new Vector(); - for (int i = startIndex; i < arg.length; i++) - { - v.add(arg[i]); - } - return v; - } -} |