1 package org.objectweb.celtix.tools.common.toolspec.parser; 2 3 import java.io.ByteArrayOutputStream ; 4 import java.io.InputStream ; 5 import java.io.PrintStream ; 6 import java.util.ArrayList ; 7 import java.util.List ; 8 import java.util.StringTokenizer ; 9 import java.util.logging.Level ; 10 import java.util.logging.Logger ; 11 12 import javax.xml.parsers.DocumentBuilderFactory ; 13 import javax.xml.transform.Transformer ; 14 import javax.xml.transform.TransformerException ; 15 import javax.xml.transform.TransformerFactory ; 16 import javax.xml.transform.dom.DOMSource ; 17 import javax.xml.transform.stream.StreamResult ; 18 import javax.xml.transform.stream.StreamSource ; 19 20 import org.w3c.dom.Document ; 21 import org.w3c.dom.Element ; 22 import org.w3c.dom.NodeList ; 23 24 import org.objectweb.celtix.common.logging.LogUtils; 25 import org.objectweb.celtix.tools.common.toolspec.Tool; 26 import org.objectweb.celtix.tools.common.toolspec.ToolSpec; 27 28 29 public class CommandLineParser { 30 31 private static final Logger LOG = LogUtils.getL7dLogger(CommandLineParser.class); 32 private ToolSpec toolspec; 33 34 public CommandLineParser(ToolSpec ts) { 35 this.toolspec = ts; 36 } 37 38 public void setToolSpec(ToolSpec ts) { 39 this.toolspec = ts; 40 } 41 42 public static String [] getArgsFromString(String s) { 43 StringTokenizer toker = new StringTokenizer (s); 44 List <Object > res = new ArrayList <Object >(); 45 46 while (toker.hasMoreTokens()) { 47 res.add(toker.nextToken()); 48 } 49 return res.toArray(new String [res.size()]); 50 } 51 52 public CommandDocument parseArguments(String args) throws BadUsageException { 53 return parseArguments(getArgsFromString(args)); 54 } 55 56 public CommandDocument parseArguments(String [] args) throws BadUsageException { 57 58 if (LOG.isLoggable(Level.INFO)) { 59 StringBuffer debugMsg = new StringBuffer ("Parsing arguments: "); 60 61 for (int i = 0; i < args.length; i++) { 62 debugMsg.append(args[i]).append(" "); 63 } 64 LOG.info(debugMsg.toString()); 65 } 66 67 if (toolspec == null) { 68 throw new IllegalStateException ("No schema known- call to acceptSc" 69 + "hema() must be made and must succeed"); 70 } 71 72 74 Document resultDoc = null; 75 76 try { 77 resultDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); 78 } catch (Exception ex) { 79 LOG.log(Level.SEVERE, "FAIL_CREATE_DOM_MSG"); 80 } 81 Element commandEl = resultDoc.createElementNS("http://www.xsume.com/Xutil/Command", "command"); 82 83 commandEl.setAttributeNS("http://www.w3.org/2001/XMLSchema-instance", "xsi:schemaLocation", 85 "http://www.xsume.com/Xutil/Command http://www.xsume.com/schema/xutil/c" 86 + "ommand.xsd"); 87 commandEl.setAttribute("xmlns", "http://www.xsume.com/Xutil/Command"); 88 commandEl.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); 89 resultDoc.appendChild(commandEl); 90 91 TokenInputStream tokens = new TokenInputStream(args); 92 93 Element usage = toolspec.getUsage(); 95 96 NodeList usageForms = toolspec.getUsageForms(); 97 if (LOG.isLoggable(Level.INFO)) { 98 LOG 99 .info("Found " + usageForms.getLength() 100 + " alternative forms of usage, will use default form"); 101 } 102 if (usageForms.getLength() > 0) { 103 ErrorVisitor errors = new ErrorVisitor(); 104 105 for (int i = 0; i < usageForms.getLength(); i++) { 106 Form form = new Form((Element )usageForms.item(i)); 107 108 int pos = tokens.getPosition(); 109 110 if (form.accept(tokens, commandEl, errors)) { 111 commandEl.setAttribute("form", form.getName()); 112 break; 113 } else { 114 tokens.setPosition(pos); 116 if (i == usageForms.getLength() - 1) { 117 if (LOG.isLoggable(Level.INFO)) { 118 LOG.info("No more forms left to try, returning null"); 119 } 120 throwUsage(errors); 121 } 122 } 123 } 124 } else { 125 ErrorVisitor errors = new ErrorVisitor(); 126 Form form = new Form(usage); 127 128 if (!form.accept(tokens, commandEl, errors)) { 129 throwUsage(errors); 130 } 131 } 132 133 if (LOG.isLoggable(Level.FINE)) { 135 try { 136 Transformer serializer = TransformerFactory.newInstance() 137 .newTransformer( 138 new StreamSource (Tool.class 139 .getResourceAsStream("indent-no-xml-declaration.xsl"))); 140 141 serializer.transform(new DOMSource (resultDoc), new StreamResult (new PrintStream (System.out))); 142 } catch (Exception ex) { 143 LOG.log(Level.SEVERE, "ERROR_SERIALIZE_COMMAND_MSG", ex); 144 } 145 } 146 147 return new CommandDocument(toolspec, resultDoc); 148 } 149 150 public void throwUsage(ErrorVisitor errors) throws BadUsageException { 151 try { 152 throw new BadUsageException(getUsage(), errors); 153 } catch (TransformerException ex) { 154 LOG.log(Level.SEVERE, "CANNOT_GET_USAGE_MSG", ex); 155 throw new BadUsageException(errors); 156 } 157 } 158 159 public String getUsage() throws TransformerException { 160 ByteArrayOutputStream baos = new ByteArrayOutputStream (); 163 InputStream in = getClass().getResourceAsStream("usage.xsl"); 164 165 toolspec.transform(in, baos); 166 return baos.toString(); 167 } 168 169 public String getDetailedUsage() throws TransformerException { 170 ByteArrayOutputStream baos = new ByteArrayOutputStream (); 173 174 toolspec.transform(getClass().getResourceAsStream("detailedUsage.xsl"), baos); 175 return baos.toString(); 176 } 177 178 public String getDetailedUsage(String id) { 179 String result = null; 180 Element element = toolspec.getElementById(id); 181 NodeList annotations = element.getElementsByTagNameNS(Tool.TOOL_SPEC_PUBLIC_ID, "annotation"); 182 if ((annotations != null) && (annotations.getLength() > 0)) { 183 result = annotations.item(0).getFirstChild().getNodeValue(); 184 } 185 return result; 186 } 187 188 public String getToolUsage() { 189 return toolspec.getAnnotation(); 190 } 191 192 } 193 | Popular Tags |