001: package org.objectweb.celtix.tools.common.toolspec.parser;
002:
003: import java.util.ArrayList;
004: import java.util.List;
005: import java.util.logging.Level;
006: import java.util.logging.Logger;
007:
008: import org.w3c.dom.Element;
009: import org.w3c.dom.NodeList;
010:
011: import org.objectweb.celtix.common.logging.LogUtils;
012: import org.objectweb.celtix.tools.common.toolspec.Tool;
013:
014: public class Form implements TokenConsumer {
015:
016: private static final Logger LOG = LogUtils.getL7dLogger(Form.class);
017: private final Element element;
018:
019: private final List<Object> arguments = new ArrayList<Object>();
020: private final List<Object> optionGroups = new ArrayList<Object>();
021: private final List<Object> options = new ArrayList<Object>();
022:
023: public Form(Element el) {
024: this .element = el;
025: NodeList list = element.getElementsByTagNameNS(
026: Tool.TOOL_SPEC_PUBLIC_ID, "optionGroup");
027:
028: for (int i = 0; i < list.getLength(); i++) {
029: optionGroups.add(new OptionGroup((Element) list.item(i)));
030: }
031: list = element.getElementsByTagNameNS(Tool.TOOL_SPEC_PUBLIC_ID,
032: "argument");
033: for (int i = 0; i < list.getLength(); i++) {
034: arguments.add(new Argument((Element) list.item(i)));
035: }
036: getOptions(element);
037: }
038:
039: private void getOptions(Element el) {
040: NodeList children = el.getChildNodes();
041:
042: for (int i = 0; i < children.getLength(); i++) {
043: if ("option".equals(children.item(i).getNodeName())) {
044: options.add(new Option((Element) children.item(i)));
045: }
046: }
047: }
048:
049: /**
050: * Attempt to consume all the args in the input stream by matching them to
051: * options, optionGroups and argument specified in the usage definition.
052: */
053: public boolean accept(TokenInputStream args, Element result,
054: ErrorVisitor errors) {
055: if (LOG.isLoggable(Level.INFO)) {
056: LOG.info("Accepting token stream for form of usage: "
057: + this + ", tokens are " + args);
058: }
059: int oldpos = args.getPosition();
060: if (LOG.isLoggable(Level.INFO)) {
061: LOG.info("Position is: " + oldpos);
062: }
063: boolean hasInfo = hasInfoOption(args);
064: args.setPosition(oldpos);
065: while (args.available() > 0) {
066: if (LOG.isLoggable(Level.INFO)) {
067: LOG.info("Args is available");
068: }
069: boolean accepted = false;
070: for (int i = 0; i < optionGroups.size(); i++) {
071: OptionGroup optionGroup = (OptionGroup) optionGroups
072: .get(i);
073: if (optionGroup.accept(args, result, errors)) {
074: accepted = true;
075: break;
076: }
077: }
078:
079: if (!accepted) {
080: for (int i = 0; i < options.size(); i++) {
081: Option option = (Option) options.get(i);
082: if (option.accept(args, result, errors)) {
083: accepted = true;
084: break;
085: }
086: }
087: }
088:
089: if (!accepted) {
090: break;
091: }
092: }
093:
094: for (int i = 0; i < optionGroups.size(); i++) {
095: OptionGroup optionGroup = (OptionGroup) optionGroups.get(i);
096:
097: if (!optionGroup.isSatisfied(errors) && !hasInfo) {
098: return false;
099: }
100: }
101:
102: for (int i = 0; i < options.size(); i++) {
103: Option option = (Option) options.get(i);
104:
105: if (!option.isSatisfied(errors) && !hasInfo) {
106: return false;
107: }
108: }
109:
110: if (arguments != null) {
111: for (int i = 0; i < arguments.size(); i++) {
112: Argument argument = (Argument) arguments.get(i);
113:
114: argument.accept(args, result, errors);
115: if (!argument.isSatisfied(errors) && !hasInfo) {
116: return false;
117: }
118: }
119: }
120:
121: if (args.available() > 0) {
122: String next = args.peek();
123:
124: if (next.startsWith("-")) {
125: errors.add(new ErrorVisitor.UnexpectedOption(next));
126: } else {
127: errors.add(new ErrorVisitor.UnexpectedArgument(next));
128: }
129: if (LOG.isLoggable(Level.INFO)) {
130: LOG
131: .info(this
132: + " form is returning false as there are more args available"
133: + " that haven't been consumed");
134: }
135: args.setPosition(oldpos);
136: return false;
137: }
138: // If we have got here than we have fully consumed all the arguments.
139: if (LOG.isLoggable(Level.INFO)) {
140: LOG.info("Form " + this + " is returning true");
141: }
142: return true;
143: }
144:
145: public boolean hasInfoOption(TokenInputStream args) {
146: int pos = args.getPosition();
147: args.setPosition(0);
148: String optionValue;
149: while (args.available() > 0) {
150: optionValue = args.read();
151: if ("-?".equals(optionValue) || "-help".equals(optionValue)
152: || "-h".equals(optionValue)
153: || "-v".equals(optionValue)) {
154: return true;
155: }
156: }
157: args.setPosition(pos);
158: return false;
159: }
160:
161: public boolean isSatisfied(ErrorVisitor errors) {
162: return true;
163: }
164:
165: public String getName() {
166: if (element.hasAttribute("value")) {
167: return element.getAttribute("value");
168: } else {
169: return "default";
170: }
171:
172: }
173:
174: public String toString() {
175: return getName();
176: }
177:
178: }
|