001: package org.objectweb.celtix.tools.common.toolspec.parser;
002:
003: import java.util.logging.Level;
004: import java.util.logging.Logger;
005:
006: import org.w3c.dom.Element;
007:
008: import org.objectweb.celtix.common.logging.LogUtils;
009: import org.objectweb.celtix.tools.common.toolspec.ToolSpec;
010:
011: public class Argument implements TokenConsumer {
012:
013: private static final Logger LOG = LogUtils
014: .getL7dLogger(Argument.class);
015:
016: protected ToolSpec toolspec;
017:
018: private final Element element;
019: private int numMatches;
020:
021: public Argument(Element el) {
022: this .element = el;
023: }
024:
025: public boolean accept(TokenInputStream args, Element result,
026: ErrorVisitor errors) {
027: if (LOG.isLoggable(Level.INFO)) {
028: LOG.info("Accepting token stream for argument: " + this );
029: }
030: int minOccurs;
031: if ("unbounded".equals(element.getAttribute("minOccurs"))) {
032: minOccurs = 0;
033: } else {
034: minOccurs = Integer.parseInt(element
035: .getAttribute("minOccurs"));
036: }
037: if (minOccurs == 0) {
038: addElement(args, result);
039: return true;
040: }
041: if (minOccurs > args.available()) {
042: return false;
043: }
044: if (args.peekPre().endsWith(",")
045: && args.peekPre().startsWith("-")) {
046: if (args.hasNext()) {
047: args.readNext();
048: } else {
049: return false;
050: }
051: }
052: for (int i = 0; i < minOccurs; i++) {
053: if (args.peek().startsWith("-")) {
054: errors.add(new ErrorVisitor.UnexpectedOption(args
055: .peek()));
056: return false;
057: }
058: addElement(args, result);
059: }
060: return true;
061: }
062:
063: private void addElement(TokenInputStream args, Element result) {
064: Element argEl = result.getOwnerDocument().createElementNS(
065: "http://www.xsume.com/Xutil/Command", "argument");
066: argEl.setAttribute("name", getName());
067: if (!args.isOutOfBound()) {
068: argEl.appendChild(result.getOwnerDocument().createTextNode(
069: args.read()));
070: }
071: result.appendChild(argEl);
072: numMatches++;
073: }
074:
075: private boolean isAtleastMinimum() {
076: boolean result = true;
077: int minOccurs = 0;
078:
079: if (!"".equals(element.getAttribute("minOccurs"))) {
080: result = numMatches >= Integer.parseInt(element
081: .getAttribute("minOccurs"));
082: } else {
083: result = numMatches >= minOccurs;
084: }
085: return result;
086: }
087:
088: private boolean isNoGreaterThanMaximum() {
089: boolean result = true;
090: // int maxOccurs = 1;
091: if ("unbounded".equals(element.getAttribute("maxOccurs"))
092: || "".equals(element.getAttribute("maxOccurs"))) {
093: return true;
094: }
095: if (!"".equals(element.getAttribute("maxOccurs"))) {
096: result = numMatches <= Integer.parseInt(element
097: .getAttribute("maxOccurs"));
098: }
099: return result;
100: }
101:
102: public boolean isSatisfied(ErrorVisitor errors) {
103: boolean result = true;
104:
105: if (errors.getErrors().size() > 0) {
106: result = false;
107: }
108: if (result && !isAtleastMinimum()) {
109: errors.add(new ErrorVisitor.MissingArgument(getName()));
110: result = false;
111: }
112: if (result && !isNoGreaterThanMaximum()) {
113: errors.add(new ErrorVisitor.DuplicateArgument(getName()));
114: result = false;
115: }
116:
117: return result;
118: }
119:
120: public void setToolSpec(ToolSpec toolSpec) {
121: this .toolspec = toolSpec;
122: }
123:
124: public String getName() {
125: return element.getAttribute("id");
126: }
127:
128: public String toString() {
129: return getName();
130: }
131: }
|