blob: 141afccdfdaac2b82cd201cda9d4d3d2ee2bebae [file] [log] [blame]
/*
* Copyright (c) 2002 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
* Jens Lukowski/Innoopract - initial renaming/restructuring
*
*/
package org.eclipse.wst.xml.core.internal.contentmodel.internal.test;
import org.eclipse.wst.xml.core.internal.contentmodel.CMContent;
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.util.CMVisitor;
public class CMUtility
{
/**
* return true if the child or any of its ancestor group nodes are repeatable
*/
public static boolean isNodeOrAncestorGroupRepeatable(CMContent content, CMNode child)
{
// since we can't walk up the CMNode tree (why you ask? ... its a long story)
// we walk down the tree to consider the child's parent node's
//
boolean result = isRepeatable(child);
if (!result)
{
CanRepeatVisitor visitor = new CanRepeatVisitor(content, child);
visitor.visitCMNode(content);
result = visitor.getResult();
}
return result;
}
/**
* return true if the child is repeatable
*/
public static boolean isNodeRepeatable(CMContent content, CMNode child)
{
// since we can't walk up the CMNode tree (why you ask? ... its a long story)
// we walk down the tree to consider the child's parent node's
//
boolean result = isRepeatable(child);
if (!result)
{
IsRepeatableVisitor visitor = new IsRepeatableVisitor(content, child);
visitor.visitCMNode(content);
result = visitor.getResult();
}
return result;
}
public static boolean isRepeatable(CMNode child)
{
boolean result = false;
if (child instanceof CMContent)
{
CMContent content = (CMContent)child;
result = content.getMaxOccur() > 1 || content.getMaxOccur() == -1;
}
return result;
}
protected static class CanRepeatVisitor extends CMVisitor
{
public boolean result;
protected boolean isWithinRepeatableGroup;
protected CMNode root;
protected CMNode target;
public CanRepeatVisitor(CMNode root, CMNode target)
{
this.root = root;
this.target = target;
}
public void visitCMGroup(CMGroup group)
{
boolean oldIsWithinRepeatableGroup = isWithinRepeatableGroup;
isWithinRepeatableGroup = isRepeatable(group);
super.visitCMGroup(group);
isWithinRepeatableGroup = oldIsWithinRepeatableGroup;
}
public void visitCMElementDeclaration(CMElementDeclaration cmelement)
{
if (cmelement == target)
{
result = isWithinRepeatableGroup;
}
}
public boolean getResult()
{
return result;
}
}
protected static class IsRepeatableVisitor extends CMVisitor
{
public boolean result = false;;
protected CMGroup currentGroup;
protected CMNode root;
protected CMNode target;
public IsRepeatableVisitor(CMNode root, CMNode target)
{
this.root = root;
this.target = target;
}
public void visitCMGroup(CMGroup group)
{
CMGroup previousGroup = currentGroup;
currentGroup = group;
super.visitCMGroup(group);
currentGroup = previousGroup;
}
public void visitCMElementDeclaration(CMElementDeclaration cmelement)
{
if (cmelement == target)
{
if (currentGroup != null)
{
result = ((currentGroup.getOperator() == CMGroup.CHOICE) &&
(isRepeatable(currentGroup)));
}
}
}
public boolean getResult()
{
return result;
}
}
}