001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */package org.apache.cxf.tools.common.toolspec.parser;
019:
020: import java.util.ArrayList;
021: import java.util.List;
022: import java.util.logging.Level;
023: import java.util.logging.Logger;
024:
025: import org.w3c.dom.Element;
026: import org.w3c.dom.NodeList;
027:
028: import org.apache.cxf.common.logging.LogUtils;
029: import org.apache.cxf.tools.common.toolspec.Tool;
030:
031: public class Form implements TokenConsumer {
032:
033: private static final Logger LOG = LogUtils.getL7dLogger(Form.class);
034: private final Element element;
035:
036: private final List<Object> arguments = new ArrayList<Object>();
037: private final List<Object> optionGroups = new ArrayList<Object>();
038: private final List<Object> options = new ArrayList<Object>();
039:
040: public Form(Element el) {
041: this .element = el;
042: NodeList list = element.getElementsByTagNameNS(
043: Tool.TOOL_SPEC_PUBLIC_ID, "optionGroup");
044:
045: for (int i = 0; i < list.getLength(); i++) {
046: optionGroups.add(new OptionGroup((Element) list.item(i)));
047: }
048: list = element.getElementsByTagNameNS(Tool.TOOL_SPEC_PUBLIC_ID,
049: "argument");
050: for (int i = 0; i < list.getLength(); i++) {
051: arguments.add(new Argument((Element) list.item(i)));
052: }
053: getOptions(element);
054: }
055:
056: private void getOptions(Element el) {
057: NodeList children = el.getChildNodes();
058:
059: for (int i = 0; i < children.getLength(); i++) {
060: if ("option".equals(children.item(i).getNodeName())) {
061: options.add(new Option((Element) children.item(i)));
062: }
063: }
064: }
065:
066: /**
067: * Attempt to consume all the args in the input stream by matching them to
068: * options, optionGroups and argument specified in the usage definition.
069: */
070: public boolean accept(TokenInputStream args, Element result,
071: ErrorVisitor errors) {
072: if (LOG.isLoggable(Level.FINE)) {
073: LOG.fine("Accepting token stream for form of usage: "
074: + this + ", tokens are " + args);
075: }
076: int oldpos = args.getPosition();
077: if (LOG.isLoggable(Level.FINE)) {
078: LOG.fine("Position is: " + oldpos);
079: }
080: boolean hasInfo = hasInfoOption(args);
081: args.setPosition(oldpos);
082: while (args.available() > 0) {
083: if (LOG.isLoggable(Level.FINE)) {
084: LOG.fine("Args is available");
085: }
086: boolean accepted = false;
087: for (int i = 0; i < optionGroups.size(); i++) {
088: OptionGroup optionGroup = (OptionGroup) optionGroups
089: .get(i);
090: if (optionGroup.accept(args, result, errors)) {
091: accepted = true;
092: break;
093: }
094: }
095:
096: if (!accepted) {
097: for (int i = 0; i < options.size(); i++) {
098: Option option = (Option) options.get(i);
099: if (option.accept(args, result, errors)) {
100: accepted = true;
101: break;
102: }
103: }
104: }
105:
106: if (!accepted) {
107: break;
108: }
109: }
110:
111: for (int i = 0; i < optionGroups.size(); i++) {
112: OptionGroup optionGroup = (OptionGroup) optionGroups.get(i);
113:
114: if (!optionGroup.isSatisfied(errors) && !hasInfo) {
115: return false;
116: }
117: }
118:
119: for (int i = 0; i < options.size(); i++) {
120: Option option = (Option) options.get(i);
121:
122: if (!option.isSatisfied(errors) && !hasInfo) {
123: return false;
124: }
125: }
126:
127: if (arguments != null) {
128: for (int i = 0; i < arguments.size(); i++) {
129: Argument argument = (Argument) arguments.get(i);
130:
131: argument.accept(args, result, errors);
132: if (!argument.isSatisfied(errors) && !hasInfo) {
133: return false;
134: }
135: }
136: }
137:
138: if (args.available() > 0) {
139: String next = args.peek();
140:
141: if (next.startsWith("-")) {
142: errors.add(new ErrorVisitor.UnexpectedOption(next));
143: } else {
144: errors.add(new ErrorVisitor.UnexpectedArgument(next));
145: }
146: if (LOG.isLoggable(Level.FINE)) {
147: LOG
148: .fine(this
149: + " form is returning false as there are more args available"
150: + " that haven't been consumed");
151: }
152: args.setPosition(oldpos);
153: return false;
154: }
155: // If we have got here than we have fully consumed all the arguments.
156: if (LOG.isLoggable(Level.FINE)) {
157: LOG.fine("Form " + this + " is returning true");
158: }
159: return true;
160: }
161:
162: public boolean hasInfoOption(TokenInputStream args) {
163: int pos = args.getPosition();
164: args.setPosition(0);
165: String optionValue;
166: while (args.available() > 0) {
167: optionValue = args.read();
168: if ("-?".equals(optionValue) || "-help".equals(optionValue)
169: || "-h".equals(optionValue)
170: || "-v".equals(optionValue)) {
171: return true;
172: }
173: }
174: args.setPosition(pos);
175: return false;
176: }
177:
178: public boolean isSatisfied(ErrorVisitor errors) {
179: return true;
180: }
181:
182: public String getName() {
183: if (element.hasAttribute("value")) {
184: return element.getAttribute("value");
185: } else {
186: return "default";
187: }
188:
189: }
190:
191: public String toString() {
192: return getName();
193: }
194:
195: }
|