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.io.ByteArrayOutputStream;
021: import java.io.InputStream;
022: import java.io.PrintStream;
023: import java.util.ArrayList;
024: import java.util.List;
025: import java.util.StringTokenizer;
026: import java.util.logging.Level;
027: import java.util.logging.Logger;
028: import javax.xml.parsers.DocumentBuilderFactory;
029: import javax.xml.transform.Transformer;
030: import javax.xml.transform.TransformerException;
031: import javax.xml.transform.TransformerFactory;
032: import javax.xml.transform.dom.DOMSource;
033: import javax.xml.transform.stream.StreamResult;
034: import javax.xml.transform.stream.StreamSource;
035:
036: import org.w3c.dom.Document;
037: import org.w3c.dom.Element;
038: import org.w3c.dom.NodeList;
039:
040: import org.apache.cxf.common.logging.LogUtils;
041: import org.apache.cxf.tools.common.toolspec.Tool;
042: import org.apache.cxf.tools.common.toolspec.ToolSpec;
043:
044: public class CommandLineParser {
045:
046: private static final Logger LOG = LogUtils
047: .getL7dLogger(CommandLineParser.class);
048: private ToolSpec toolspec;
049:
050: public CommandLineParser(ToolSpec ts) {
051: this .toolspec = ts;
052: }
053:
054: public void setToolSpec(ToolSpec ts) {
055: this .toolspec = ts;
056: }
057:
058: public static String[] getArgsFromString(String s) {
059: StringTokenizer toker = new StringTokenizer(s);
060: List<Object> res = new ArrayList<Object>();
061:
062: while (toker.hasMoreTokens()) {
063: res.add(toker.nextToken());
064: }
065: return res.toArray(new String[res.size()]);
066: }
067:
068: public CommandDocument parseArguments(String args)
069: throws BadUsageException {
070: return parseArguments(getArgsFromString(args));
071: }
072:
073: public CommandDocument parseArguments(String[] args)
074: throws BadUsageException {
075:
076: if (LOG.isLoggable(Level.FINE)) {
077: StringBuffer debugMsg = new StringBuffer(
078: "Parsing arguments: ");
079:
080: for (int i = 0; i < args.length; i++) {
081: debugMsg.append(args[i]).append(" ");
082: }
083: LOG.fine(debugMsg.toString());
084: }
085:
086: if (toolspec == null) {
087: throw new IllegalStateException(
088: "No schema known- call to acceptSc"
089: + "hema() must be made and must succeed");
090: }
091:
092: // Create a result document
093:
094: Document resultDoc = null;
095:
096: try {
097: DocumentBuilderFactory factory = DocumentBuilderFactory
098: .newInstance();
099: factory.setNamespaceAware(true);
100: resultDoc = factory.newDocumentBuilder().newDocument();
101: } catch (Exception ex) {
102: LOG.log(Level.SEVERE, "FAIL_CREATE_DOM_MSG");
103: }
104: Element commandEl = resultDoc.createElementNS(
105: "http://cxf.apache.org/Xutil/Command", "command");
106:
107: // resultDoc.createAttributeNS("http://www.w3.org/2001/XMLSchema-instance","schemaLocation");
108: commandEl.setAttributeNS(
109: "http://www.w3.org/2001/XMLSchema-instance",
110: "xsi:schemaLocation",
111: "http://cxf.apache.org/Xutil/Command http://cxf.apache.org/schema/xutil/c"
112: + "ommand.xsd");
113: commandEl.setAttribute("xmlns",
114: "http://cxf.apache.org/Xutil/Command");
115: commandEl.setAttribute("xmlns:xsi",
116: "http://www.w3.org/2001/XMLSchema-instance");
117: resultDoc.appendChild(commandEl);
118:
119: TokenInputStream tokens = new TokenInputStream(args);
120:
121: // for all form elements...
122: Element usage = toolspec.getUsage();
123:
124: NodeList usageForms = toolspec.getUsageForms();
125: if (LOG.isLoggable(Level.FINE)) {
126: LOG
127: .fine("Found "
128: + usageForms.getLength()
129: + " alternative forms of usage, will use default form");
130: }
131: if (usageForms.getLength() > 0) {
132: ErrorVisitor errors = new ErrorVisitor();
133:
134: for (int i = 0; i < usageForms.getLength(); i++) {
135: Form form = new Form((Element) usageForms.item(i));
136:
137: int pos = tokens.getPosition();
138:
139: if (form.accept(tokens, commandEl, errors)) {
140: commandEl.setAttribute("form", form.getName());
141: break;
142: } else {
143: // if no more left then return null;
144: tokens.setPosition(pos);
145: if (i == usageForms.getLength() - 1) {
146: if (LOG.isLoggable(Level.INFO)) {
147: LOG
148: .info("No more forms left to try, returning null");
149: }
150: throwUsage(errors);
151: }
152: }
153: }
154: } else {
155: ErrorVisitor errors = new ErrorVisitor();
156: Form form = new Form(usage);
157:
158: if (!form.accept(tokens, commandEl, errors)) {
159: throwUsage(errors);
160: }
161: }
162:
163: // output the result document
164: if (LOG.isLoggable(Level.FINE)) {
165: try {
166: Transformer serializer = TransformerFactory
167: .newInstance()
168: .newTransformer(
169: new StreamSource(
170: Tool.class
171: .getResourceAsStream("indent-no-xml-declaration.xsl")));
172:
173: serializer.transform(new DOMSource(resultDoc),
174: new StreamResult(new PrintStream(System.out)));
175: } catch (Exception ex) {
176: LOG
177: .log(Level.SEVERE,
178: "ERROR_SERIALIZE_COMMAND_MSG", ex);
179: }
180: }
181:
182: return new CommandDocument(toolspec, resultDoc);
183: }
184:
185: public void throwUsage(ErrorVisitor errors)
186: throws BadUsageException {
187: try {
188: throw new BadUsageException(getUsage(), errors);
189: } catch (TransformerException ex) {
190: LOG.log(Level.SEVERE, "CANNOT_GET_USAGE_MSG", ex);
191: throw new BadUsageException(errors);
192: }
193: }
194:
195: public String getUsage() throws TransformerException {
196: // REVISIT: style usage document into a form more readily output as a
197: // usage message
198: ByteArrayOutputStream baos = new ByteArrayOutputStream();
199: InputStream in = getClass().getResourceAsStream("usage.xsl");
200:
201: toolspec.transform(in, baos);
202: return baos.toString();
203: }
204:
205: public String getDetailedUsage() throws TransformerException {
206: // REVISIT: style usage document into a form more readily output as a
207: // usage message
208: ByteArrayOutputStream baos = new ByteArrayOutputStream();
209:
210: toolspec.transform(getClass().getResourceAsStream(
211: "detailedUsage.xsl"), baos);
212: return baos.toString();
213: }
214:
215: public String getDetailedUsage(String id) {
216: String result = null;
217: Element element = toolspec.getElementById(id);
218: NodeList annotations = element.getElementsByTagNameNS(
219: Tool.TOOL_SPEC_PUBLIC_ID, "annotation");
220: if ((annotations != null) && (annotations.getLength() > 0)) {
221: result = annotations.item(0).getFirstChild().getNodeValue();
222: }
223: return result;
224: }
225:
226: public String getToolUsage() {
227: return toolspec.getAnnotation();
228: }
229:
230: }
|