1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/jaxws_classes/com/sun/tools/internal/xjc/Driver.java Wed Apr 27 01:27:09 2016 +0800 1.3 @@ -0,0 +1,526 @@ 1.4 +/* 1.5 + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. Oracle designates this 1.11 + * particular file as subject to the "Classpath" exception as provided 1.12 + * by Oracle in the LICENSE file that accompanied this code. 1.13 + * 1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.17 + * version 2 for more details (a copy is included in the LICENSE file that 1.18 + * accompanied this code). 1.19 + * 1.20 + * You should have received a copy of the GNU General Public License version 1.21 + * 2 along with this work; if not, write to the Free Software Foundation, 1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.23 + * 1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.25 + * or visit www.oracle.com if you need additional information or have any 1.26 + * questions. 1.27 + */ 1.28 + 1.29 +package com.sun.tools.internal.xjc; 1.30 + 1.31 +import java.io.File; 1.32 +import java.io.FileOutputStream; 1.33 +import java.io.IOException; 1.34 +import java.io.OutputStream; 1.35 +import java.io.OutputStreamWriter; 1.36 +import java.io.PrintStream; 1.37 +import java.util.Iterator; 1.38 + 1.39 +import com.sun.codemodel.internal.CodeWriter; 1.40 +import com.sun.codemodel.internal.JCodeModel; 1.41 +import com.sun.codemodel.internal.writer.ZipCodeWriter; 1.42 +import com.sun.istack.internal.NotNull; 1.43 +import com.sun.istack.internal.Nullable; 1.44 +import com.sun.istack.internal.tools.DefaultAuthenticator; 1.45 +import com.sun.tools.internal.xjc.generator.bean.BeanGenerator; 1.46 +import com.sun.tools.internal.xjc.model.Model; 1.47 +import com.sun.tools.internal.xjc.outline.Outline; 1.48 +import com.sun.tools.internal.xjc.reader.gbind.Expression; 1.49 +import com.sun.tools.internal.xjc.reader.gbind.Graph; 1.50 +import com.sun.tools.internal.xjc.reader.internalizer.DOMForest; 1.51 +import com.sun.tools.internal.xjc.reader.xmlschema.ExpressionBuilder; 1.52 +import com.sun.tools.internal.xjc.reader.xmlschema.parser.XMLSchemaInternalizationLogic; 1.53 +import com.sun.tools.internal.xjc.util.ErrorReceiverFilter; 1.54 +import com.sun.tools.internal.xjc.util.NullStream; 1.55 +import com.sun.tools.internal.xjc.util.Util; 1.56 +import com.sun.tools.internal.xjc.writer.SignatureWriter; 1.57 +import com.sun.xml.internal.xsom.XSComplexType; 1.58 +import com.sun.xml.internal.xsom.XSParticle; 1.59 +import com.sun.xml.internal.xsom.XSSchemaSet; 1.60 + 1.61 +import org.xml.sax.SAXException; 1.62 +import org.xml.sax.SAXParseException; 1.63 + 1.64 + 1.65 +/** 1.66 + * Command Line Interface of XJC. 1.67 + */ 1.68 +public class Driver { 1.69 + 1.70 + public static void main(final String[] args) throws Exception { 1.71 + // use the platform default proxy if available. 1.72 + // see sun.net.spi.DefaultProxySelector for details. 1.73 + try { 1.74 + System.setProperty("java.net.useSystemProxies","true"); 1.75 + } catch (SecurityException e) { 1.76 + // failing to set this property isn't fatal 1.77 + } 1.78 + 1.79 + if( Util.getSystemProperty(Driver.class,"noThreadSwap")!=null ) 1.80 + _main(args); // for the ease of debugging 1.81 + 1.82 + // run all the work in another thread so that the -Xss option 1.83 + // will take effect when compiling a large schema. See 1.84 + // http://developer.java.sun.com/developer/bugParade/bugs/4362291.html 1.85 + final Throwable[] ex = new Throwable[1]; 1.86 + 1.87 + Thread th = new Thread() { 1.88 + @Override 1.89 + public void run() { 1.90 + try { 1.91 + _main(args); 1.92 + } catch( Throwable e ) { 1.93 + ex[0]=e; 1.94 + } 1.95 + } 1.96 + }; 1.97 + th.start(); 1.98 + th.join(); 1.99 + 1.100 + if(ex[0]!=null) { 1.101 + // re-throw 1.102 + if( ex[0] instanceof Exception ) 1.103 + throw (Exception)ex[0]; 1.104 + else 1.105 + throw (Error)ex[0]; 1.106 + } 1.107 + } 1.108 + 1.109 + private static void _main( String[] args ) throws Exception { 1.110 + try { 1.111 + System.exit(run( args, System.out, System.out )); 1.112 + } catch (BadCommandLineException e) { 1.113 + // there was an error in the command line. 1.114 + // print usage and abort. 1.115 + if(e.getMessage()!=null) { 1.116 + System.out.println(e.getMessage()); 1.117 + System.out.println(); 1.118 + } 1.119 + 1.120 + usage(e.getOptions(),false); 1.121 + System.exit(-1); 1.122 + } 1.123 + } 1.124 + 1.125 + 1.126 + 1.127 + /** 1.128 + * Performs schema compilation and prints the status/error into the 1.129 + * specified PrintStream. 1.130 + * 1.131 + * <p> 1.132 + * This method could be used to trigger XJC from other tools, 1.133 + * such as Ant or IDE. 1.134 + * 1.135 + * @param args 1.136 + * specified command line parameters. If there is an error 1.137 + * in the parameters, {@link BadCommandLineException} will 1.138 + * be thrown. 1.139 + * @param status 1.140 + * Status report of the compilation will be sent to this object. 1.141 + * Useful to update users so that they will know something is happening. 1.142 + * Only ignorable messages should be sent to this stream. 1.143 + * 1.144 + * This parameter can be null to suppress messages. 1.145 + * 1.146 + * @param out 1.147 + * Various non-ignorable output (error messages, etc) 1.148 + * will go to this stream. 1.149 + * 1.150 + * @return 1.151 + * If the compiler runs successfully, this method returns 0. 1.152 + * All non-zero values indicate an error. The error message 1.153 + * will be sent to the specified PrintStream. 1.154 + */ 1.155 + public static int run(String[] args, final PrintStream status, final PrintStream out) 1.156 + throws Exception { 1.157 + 1.158 + class Listener extends XJCListener { 1.159 + ConsoleErrorReporter cer = new ConsoleErrorReporter(out==null?new PrintStream(new NullStream()):out); 1.160 + 1.161 + @Override 1.162 + public void generatedFile(String fileName, int count, int total) { 1.163 + message(fileName); 1.164 + } 1.165 + @Override 1.166 + public void message(String msg) { 1.167 + if(status!=null) 1.168 + status.println(msg); 1.169 + } 1.170 + 1.171 + public void error(SAXParseException exception) { 1.172 + cer.error(exception); 1.173 + } 1.174 + 1.175 + public void fatalError(SAXParseException exception) { 1.176 + cer.fatalError(exception); 1.177 + } 1.178 + 1.179 + public void warning(SAXParseException exception) { 1.180 + cer.warning(exception); 1.181 + } 1.182 + 1.183 + public void info(SAXParseException exception) { 1.184 + cer.info(exception); 1.185 + } 1.186 + } 1.187 + 1.188 + return run(args,new Listener()); 1.189 + } 1.190 + 1.191 + /** 1.192 + * Performs schema compilation and prints the status/error into the 1.193 + * specified PrintStream. 1.194 + * 1.195 + * <p> 1.196 + * This method could be used to trigger XJC from other tools, 1.197 + * such as Ant or IDE. 1.198 + * 1.199 + * @param args 1.200 + * specified command line parameters. If there is an error 1.201 + * in the parameters, {@link BadCommandLineException} will 1.202 + * be thrown. 1.203 + * @param listener 1.204 + * Receives messages from XJC reporting progress/errors. 1.205 + * 1.206 + * @return 1.207 + * If the compiler runs successfully, this method returns 0. 1.208 + * All non-zero values indicate an error. The error message 1.209 + * will be sent to the specified PrintStream. 1.210 + */ 1.211 + public static int run(String[] args, @NotNull final XJCListener listener) throws BadCommandLineException { 1.212 + 1.213 + // recognize those special options before we start parsing options. 1.214 + for (String arg : args) { 1.215 + if (arg.equals("-version")) { 1.216 + listener.message(Messages.format(Messages.VERSION)); 1.217 + return -1; 1.218 + } 1.219 + if (arg.equals("-fullversion")) { 1.220 + listener.message(Messages.format(Messages.FULLVERSION)); 1.221 + return -1; 1.222 + } 1.223 + } 1.224 + 1.225 + final OptionsEx opt = new OptionsEx(); 1.226 + opt.setSchemaLanguage(Language.XMLSCHEMA); // disable auto-guessing 1.227 + try { 1.228 + opt.parseArguments(args); 1.229 + } catch (WeAreDone e) { 1.230 + if (opt.proxyAuth != null) { 1.231 + DefaultAuthenticator.reset(); 1.232 + } 1.233 + return -1; 1.234 + } catch(BadCommandLineException e) { 1.235 + if (opt.proxyAuth != null) { 1.236 + DefaultAuthenticator.reset(); 1.237 + } 1.238 + e.initOptions(opt); 1.239 + throw e; 1.240 + } 1.241 + 1.242 + // display a warning if the user specified the default package 1.243 + // this should work, but is generally a bad idea 1.244 + if(opt.defaultPackage != null && opt.defaultPackage.length()==0) { 1.245 + listener.message(Messages.format(Messages.WARNING_MSG, Messages.format(Messages.DEFAULT_PACKAGE_WARNING))); 1.246 + } 1.247 + 1.248 + 1.249 + // set up the context class loader so that the user-specified classes 1.250 + // can be loaded from there 1.251 + final ClassLoader contextClassLoader = SecureLoader.getContextClassLoader(); 1.252 + SecureLoader.setContextClassLoader(opt.getUserClassLoader(contextClassLoader)); 1.253 + 1.254 + // parse a grammar file 1.255 + //----------------------------------------- 1.256 + try { 1.257 + if( !opt.quiet ) { 1.258 + listener.message(Messages.format(Messages.PARSING_SCHEMA)); 1.259 + } 1.260 + 1.261 + final boolean[] hadWarning = new boolean[1]; 1.262 + 1.263 + ErrorReceiver receiver = new ErrorReceiverFilter(listener) { 1.264 + @Override 1.265 + public void info(SAXParseException exception) { 1.266 + if(opt.verbose) 1.267 + super.info(exception); 1.268 + } 1.269 + @Override 1.270 + public void warning(SAXParseException exception) { 1.271 + hadWarning[0] = true; 1.272 + if(!opt.quiet) 1.273 + super.warning(exception); 1.274 + } 1.275 + @Override 1.276 + public void pollAbort() throws AbortException { 1.277 + if(listener.isCanceled()) 1.278 + throw new AbortException(); 1.279 + } 1.280 + }; 1.281 + 1.282 + if( opt.mode==Mode.FOREST ) { 1.283 + // dump DOM forest and quit 1.284 + ModelLoader loader = new ModelLoader( opt, new JCodeModel(), receiver ); 1.285 + try { 1.286 + DOMForest forest = loader.buildDOMForest(new XMLSchemaInternalizationLogic()); 1.287 + forest.dump(System.out); 1.288 + return 0; 1.289 + } catch (SAXException e) { 1.290 + // the error should have already been reported 1.291 + } catch (IOException e) { 1.292 + receiver.error(e); 1.293 + } 1.294 + 1.295 + return -1; 1.296 + } 1.297 + 1.298 + if( opt.mode==Mode.GBIND ) { 1.299 + try { 1.300 + XSSchemaSet xss = new ModelLoader(opt, new JCodeModel(), receiver).loadXMLSchema(); 1.301 + Iterator<XSComplexType> it = xss.iterateComplexTypes(); 1.302 + while (it.hasNext()) { 1.303 + XSComplexType ct = it.next(); 1.304 + XSParticle p = ct.getContentType().asParticle(); 1.305 + if(p==null) continue; 1.306 + 1.307 + Expression tree = ExpressionBuilder.createTree(p); 1.308 + System.out.println("Graph for "+ct.getName()); 1.309 + System.out.println(tree.toString()); 1.310 + Graph g = new Graph(tree); 1.311 + System.out.println(g.toString()); 1.312 + System.out.println(); 1.313 + } 1.314 + return 0; 1.315 + } catch (SAXException e) { 1.316 + // the error should have already been reported 1.317 + } 1.318 + return -1; 1.319 + } 1.320 + 1.321 + Model model = ModelLoader.load( opt, new JCodeModel(), receiver ); 1.322 + 1.323 + if (model == null) { 1.324 + listener.message(Messages.format(Messages.PARSE_FAILED)); 1.325 + return -1; 1.326 + } 1.327 + 1.328 + if( !opt.quiet ) { 1.329 + listener.message(Messages.format(Messages.COMPILING_SCHEMA)); 1.330 + } 1.331 + 1.332 + switch (opt.mode) { 1.333 + case SIGNATURE : 1.334 + try { 1.335 + SignatureWriter.write( 1.336 + BeanGenerator.generate(model,receiver), 1.337 + new OutputStreamWriter(System.out)); 1.338 + return 0; 1.339 + } catch (IOException e) { 1.340 + receiver.error(e); 1.341 + return -1; 1.342 + } 1.343 + 1.344 + case CODE : 1.345 + case DRYRUN : 1.346 + case ZIP : 1.347 + { 1.348 + // generate actual code 1.349 + receiver.debug("generating code"); 1.350 + {// don't want to hold outline in memory for too long. 1.351 + Outline outline = model.generateCode(opt,receiver); 1.352 + if(outline==null) { 1.353 + listener.message( 1.354 + Messages.format(Messages.FAILED_TO_GENERATE_CODE)); 1.355 + return -1; 1.356 + } 1.357 + 1.358 + listener.compiled(outline); 1.359 + } 1.360 + 1.361 + if( opt.mode == Mode.DRYRUN ) 1.362 + break; // enough 1.363 + 1.364 + // then print them out 1.365 + try { 1.366 + CodeWriter cw; 1.367 + if( opt.mode==Mode.ZIP ) { 1.368 + OutputStream os; 1.369 + if(opt.targetDir.getPath().equals(".")) 1.370 + os = System.out; 1.371 + else 1.372 + os = new FileOutputStream(opt.targetDir); 1.373 + 1.374 + cw = opt.createCodeWriter(new ZipCodeWriter(os)); 1.375 + } else 1.376 + cw = opt.createCodeWriter(); 1.377 + 1.378 + if( !opt.quiet ) { 1.379 + cw = new ProgressCodeWriter(cw,listener, model.codeModel.countArtifacts()); 1.380 + } 1.381 + model.codeModel.build(cw); 1.382 + } catch (IOException e) { 1.383 + receiver.error(e); 1.384 + return -1; 1.385 + } 1.386 + 1.387 + break; 1.388 + } 1.389 + default : 1.390 + assert false; 1.391 + } 1.392 + 1.393 + if(opt.debugMode) { 1.394 + try { 1.395 + new FileOutputStream(new File(opt.targetDir,hadWarning[0]?"hadWarning":"noWarning")).close(); 1.396 + } catch (IOException e) { 1.397 + receiver.error(e); 1.398 + return -1; 1.399 + } 1.400 + } 1.401 + 1.402 + return 0; 1.403 + } catch( StackOverflowError e ) { 1.404 + if(opt.verbose) 1.405 + // in the debug mode, propagate the error so that 1.406 + // the full stack trace will be dumped to the screen. 1.407 + throw e; 1.408 + else { 1.409 + // otherwise just print a suggested workaround and 1.410 + // quit without filling the user's screen 1.411 + listener.message(Messages.format(Messages.STACK_OVERFLOW)); 1.412 + return -1; 1.413 + } 1.414 + } finally { 1.415 + if (opt.proxyAuth != null) { 1.416 + DefaultAuthenticator.reset(); 1.417 + } 1.418 + } 1.419 + } 1.420 + 1.421 + public static String getBuildID() { 1.422 + return Messages.format(Messages.BUILD_ID); 1.423 + } 1.424 + 1.425 + 1.426 + /** 1.427 + * Operation mode. 1.428 + */ 1.429 + private static enum Mode { 1.430 + // normal mode. compile the code 1.431 + CODE, 1.432 + 1.433 + // dump the signature of the generated code 1.434 + SIGNATURE, 1.435 + 1.436 + // dump DOMForest 1.437 + FOREST, 1.438 + 1.439 + // same as CODE but don't produce any Java source code 1.440 + DRYRUN, 1.441 + 1.442 + // same as CODE but pack all the outputs into a zip and dumps to stdout 1.443 + ZIP, 1.444 + 1.445 + // testing a new binding mode 1.446 + GBIND 1.447 + } 1.448 + 1.449 + 1.450 + /** 1.451 + * Command-line arguments processor. 1.452 + * 1.453 + * <p> 1.454 + * This class contains options that only make sense 1.455 + * for the command line interface. 1.456 + */ 1.457 + static class OptionsEx extends Options 1.458 + { 1.459 + /** Operation mode. */ 1.460 + protected Mode mode = Mode.CODE; 1.461 + 1.462 + /** A switch that determines the behavior in the BGM mode. */ 1.463 + public boolean noNS = false; 1.464 + 1.465 + /** Parse XJC-specific options. */ 1.466 + @Override 1.467 + public int parseArgument(String[] args, int i) throws BadCommandLineException { 1.468 + if (args[i].equals("-noNS")) { 1.469 + noNS = true; 1.470 + return 1; 1.471 + } 1.472 + if (args[i].equals("-mode")) { 1.473 + i++; 1.474 + if (i == args.length) 1.475 + throw new BadCommandLineException( 1.476 + Messages.format(Messages.MISSING_MODE_OPERAND)); 1.477 + 1.478 + String mstr = args[i].toLowerCase(); 1.479 + 1.480 + for( Mode m : Mode.values() ) { 1.481 + if(m.name().toLowerCase().startsWith(mstr) && mstr.length()>2) { 1.482 + mode = m; 1.483 + return 2; 1.484 + } 1.485 + } 1.486 + 1.487 + throw new BadCommandLineException( 1.488 + Messages.format(Messages.UNRECOGNIZED_MODE, args[i])); 1.489 + } 1.490 + if (args[i].equals("-help")) { 1.491 + usage(this,false); 1.492 + throw new WeAreDone(); 1.493 + } 1.494 + if (args[i].equals("-private")) { 1.495 + usage(this,true); 1.496 + throw new WeAreDone(); 1.497 + } 1.498 + 1.499 + return super.parseArgument(args, i); 1.500 + } 1.501 + } 1.502 + 1.503 + /** 1.504 + * Used to signal that we've finished processing. 1.505 + */ 1.506 + private static final class WeAreDone extends BadCommandLineException {} 1.507 + 1.508 + 1.509 + /** 1.510 + * Prints the usage screen and exits the process. 1.511 + * 1.512 + * @param opts 1.513 + * If the parsing of options have started, set a partly populated 1.514 + * {@link Options} object. 1.515 + */ 1.516 + public static void usage( @Nullable Options opts, boolean privateUsage ) { 1.517 + System.out.println(Messages.format(Messages.DRIVER_PUBLIC_USAGE)); 1.518 + if (privateUsage) { 1.519 + System.out.println(Messages.format(Messages.DRIVER_PRIVATE_USAGE)); 1.520 + } 1.521 + 1.522 + if( opts!=null && !opts.getAllPlugins().isEmpty()) { 1.523 + System.out.println(Messages.format(Messages.ADDON_USAGE)); 1.524 + for (Plugin p : opts.getAllPlugins()) { 1.525 + System.out.println(p.getUsage()); 1.526 + } 1.527 + } 1.528 + } 1.529 +}