src/share/jaxws_classes/com/sun/tools/internal/jxc/SchemaGenerator.java

Thu, 24 May 2018 16:44:14 +0800

author
aoqi
date
Thu, 24 May 2018 16:44:14 +0800
changeset 1288
f4ace6971570
parent 1011
70d4d5435eb4
parent 637
9c07ef4934dd
permissions
-rw-r--r--

Merge

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation. Oracle designates this
aoqi@0 8 * particular file as subject to the "Classpath" exception as provided
aoqi@0 9 * by Oracle in the LICENSE file that accompanied this code.
aoqi@0 10 *
aoqi@0 11 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 14 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 15 * accompanied this code).
aoqi@0 16 *
aoqi@0 17 * You should have received a copy of the GNU General Public License version
aoqi@0 18 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 20 *
aoqi@0 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 22 * or visit www.oracle.com if you need additional information or have any
aoqi@0 23 * questions.
aoqi@0 24 */
aoqi@0 25
aoqi@0 26 package com.sun.tools.internal.jxc;
aoqi@0 27
aoqi@0 28 import com.sun.tools.internal.jxc.ap.Options;
aoqi@0 29 import com.sun.tools.internal.xjc.BadCommandLineException;
aoqi@0 30 import com.sun.xml.internal.bind.util.Which;
aoqi@0 31
aoqi@0 32 import javax.lang.model.SourceVersion;
aefimov@1011 33 import javax.tools.Diagnostic;
aoqi@0 34 import javax.tools.DiagnosticCollector;
aoqi@0 35 import javax.tools.JavaCompiler;
aoqi@0 36 import javax.tools.JavaFileObject;
aoqi@0 37 import javax.tools.OptionChecker;
aoqi@0 38 import javax.tools.StandardJavaFileManager;
aoqi@0 39 import javax.tools.ToolProvider;
aoqi@0 40 import javax.xml.bind.JAXBContext;
aoqi@0 41 import java.io.File;
aoqi@0 42 import java.lang.reflect.InvocationTargetException;
aoqi@0 43 import java.lang.reflect.Method;
aoqi@0 44 import java.net.MalformedURLException;
aoqi@0 45 import java.net.URISyntaxException;
aoqi@0 46 import java.net.URL;
aoqi@0 47 import java.net.URLClassLoader;
aoqi@0 48 import java.util.ArrayList;
aoqi@0 49 import java.util.Collection;
aoqi@0 50 import java.util.Collections;
aoqi@0 51 import java.util.List;
aoqi@0 52 import java.util.logging.Level;
aoqi@0 53 import java.util.logging.Logger;
aoqi@0 54
aoqi@0 55 /**
aoqi@0 56 * CLI entry-point to the schema generator.
aoqi@0 57 *
aoqi@0 58 * @author Bhakti Mehta
aoqi@0 59 */
aoqi@0 60 public class SchemaGenerator {
aoqi@0 61 /**
aoqi@0 62 * Runs the schema generator.
aoqi@0 63 */
aoqi@0 64 public static void main(String[] args) throws Exception {
aoqi@0 65 System.exit(run(args));
aoqi@0 66 }
aoqi@0 67
aoqi@0 68 public static int run(String[] args) throws Exception {
aoqi@0 69 try {
aoqi@0 70 ClassLoader cl = SecureLoader.getClassClassLoader(SchemaGenerator.class);
aoqi@0 71 if (cl==null) {
aoqi@0 72 cl = SecureLoader.getSystemClassLoader();
aoqi@0 73 }
aoqi@0 74 return run(args, cl);
aoqi@0 75 } catch(Exception e) {
aoqi@0 76 System.err.println(e.getMessage());
aoqi@0 77 return -1;
aoqi@0 78 }
aoqi@0 79 }
aoqi@0 80
aoqi@0 81 /**
aoqi@0 82 * Runs the schema generator.
aoqi@0 83 *
aoqi@0 84 * @param classLoader
aoqi@0 85 * the schema generator will run in this classLoader.
aoqi@0 86 * It needs to be able to load annotation processing and JAXB RI classes. Note that
aoqi@0 87 * JAXB RI classes refer to annotation processing classes. Must not be null.
aoqi@0 88 *
aoqi@0 89 * @return
aoqi@0 90 * exit code. 0 if success.
aoqi@0 91 *
aoqi@0 92 */
aoqi@0 93 public static int run(String[] args, ClassLoader classLoader) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {
aoqi@0 94 final Options options = new Options();
aoqi@0 95 if (args.length ==0) {
aoqi@0 96 usage();
aoqi@0 97 return -1;
aoqi@0 98 }
aoqi@0 99 for (String arg : args) {
aoqi@0 100 if (arg.equals("-help")) {
aoqi@0 101 usage();
aoqi@0 102 return -1;
aoqi@0 103 }
aoqi@0 104
aoqi@0 105 if (arg.equals("-version")) {
aoqi@0 106 System.out.println(Messages.VERSION.format());
aoqi@0 107 return -1;
aoqi@0 108 }
aoqi@0 109
aoqi@0 110 if (arg.equals("-fullversion")) {
aoqi@0 111 System.out.println(Messages.FULLVERSION.format());
aoqi@0 112 return -1;
aoqi@0 113 }
aoqi@0 114
aoqi@0 115 }
aoqi@0 116
aoqi@0 117 try {
aoqi@0 118 options.parseArguments(args);
aoqi@0 119 } catch (BadCommandLineException e) {
aoqi@0 120 // there was an error in the command line.
aoqi@0 121 // print usage and abort.
aoqi@0 122 System.out.println(e.getMessage());
aoqi@0 123 System.out.println();
aoqi@0 124 usage();
aoqi@0 125 return -1;
aoqi@0 126 }
aoqi@0 127
aoqi@0 128 Class schemagenRunner = classLoader.loadClass(Runner.class.getName());
aoqi@0 129 Method compileMethod = schemagenRunner.getDeclaredMethod("compile",String[].class,File.class);
aoqi@0 130
aoqi@0 131 List<String> aptargs = new ArrayList<String>();
aoqi@0 132
aoqi@0 133 if (options.encoding != null) {
aoqi@0 134 aptargs.add("-encoding");
aoqi@0 135 aptargs.add(options.encoding);
aoqi@0 136 }
aoqi@0 137
aoqi@0 138 aptargs.add("-cp");
aoqi@0 139 aptargs.add(setClasspath(options.classpath)); // set original classpath + jaxb-api to be visible to annotation processor
aoqi@0 140
aoqi@0 141 if(options.targetDir!=null) {
aoqi@0 142 aptargs.add("-d");
aoqi@0 143 aptargs.add(options.targetDir.getPath());
aoqi@0 144 }
aoqi@0 145
aoqi@0 146 aptargs.addAll(options.arguments);
aoqi@0 147
aoqi@0 148 String[] argsarray = aptargs.toArray(new String[aptargs.size()]);
aoqi@0 149 return ((Boolean) compileMethod.invoke(null, argsarray, options.episodeFile)) ? 0 : 1;
aoqi@0 150 }
aoqi@0 151
aoqi@0 152 private static String setClasspath(String givenClasspath) {
aoqi@0 153 StringBuilder cp = new StringBuilder();
aoqi@0 154 appendPath(cp, givenClasspath);
aoqi@0 155 ClassLoader cl = Thread.currentThread().getContextClassLoader();
aoqi@0 156 while (cl != null) {
aoqi@0 157 if (cl instanceof URLClassLoader) {
aoqi@0 158 for (URL url : ((URLClassLoader) cl).getURLs()) {
aoqi@0 159 appendPath(cp, url.getPath());
aoqi@0 160 }
aoqi@0 161 }
aoqi@0 162 cl = cl.getParent();
aoqi@0 163 }
aoqi@0 164
aoqi@0 165 appendPath(cp, findJaxbApiJar());
aoqi@0 166 return cp.toString();
aoqi@0 167 }
aoqi@0 168
aoqi@0 169 private static void appendPath(StringBuilder cp, String url) {
aoqi@0 170 if (url == null || url.trim().isEmpty())
aoqi@0 171 return;
aoqi@0 172 if (cp.length() != 0)
aoqi@0 173 cp.append(File.pathSeparatorChar);
aoqi@0 174 cp.append(url);
aoqi@0 175 }
aoqi@0 176
aoqi@0 177 /**
aoqi@0 178 * Computes the file system path of <tt>jaxb-api.jar</tt> so that
aoqi@0 179 * Annotation Processing will see them in the <tt>-cp</tt> option.
aoqi@0 180 *
aoqi@0 181 * <p>
aoqi@0 182 * In Java, you can't do this reliably (for that matter there's no guarantee
aoqi@0 183 * that such a jar file exists, such as in Glassfish), so we do the best we can.
aoqi@0 184 *
aoqi@0 185 * @return
aoqi@0 186 * null if failed to locate it.
aoqi@0 187 */
aoqi@0 188 private static String findJaxbApiJar() {
aoqi@0 189 String url = Which.which(JAXBContext.class);
aoqi@0 190 if(url==null) return null; // impossible, but hey, let's be defensive
aoqi@0 191
aoqi@0 192 if(!url.startsWith("jar:") || url.lastIndexOf('!')==-1)
aoqi@0 193 // no jar file
aoqi@0 194 return null;
aoqi@0 195
aoqi@0 196 String jarFileUrl = url.substring(4,url.lastIndexOf('!'));
aoqi@0 197 if(!jarFileUrl.startsWith("file:"))
aoqi@0 198 return null; // not from file system
aoqi@0 199
aoqi@0 200 try {
aoqi@0 201 File f = new File(new URL(jarFileUrl).toURI());
aoqi@0 202 if (f.exists() && f.getName().endsWith(".jar")) { // see 6510966
aoqi@0 203 return f.getPath();
aoqi@0 204 }
aoqi@0 205 f = new File(new URL(jarFileUrl).getFile());
aoqi@0 206 if (f.exists() && f.getName().endsWith(".jar")) { // this is here for potential backw. compatibility issues
aoqi@0 207 return f.getPath();
aoqi@0 208 }
aoqi@0 209 } catch (URISyntaxException ex) {
aoqi@0 210 Logger.getLogger(SchemaGenerator.class.getName()).log(Level.SEVERE, null, ex);
aoqi@0 211 } catch (MalformedURLException ex) {
aoqi@0 212 Logger.getLogger(SchemaGenerator.class.getName()).log(Level.SEVERE, null, ex);
aoqi@0 213 }
aoqi@0 214 return null;
aoqi@0 215 }
aoqi@0 216
aoqi@0 217 private static void usage( ) {
aoqi@0 218 System.out.println(Messages.USAGE.format());
aoqi@0 219 }
aoqi@0 220
aoqi@0 221 public static final class Runner {
aoqi@0 222 public static boolean compile(String[] args, File episode) throws Exception {
aoqi@0 223
aoqi@0 224 JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
aoqi@0 225 DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
aoqi@0 226 StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null);
aoqi@0 227 JavacOptions options = JavacOptions.parse(compiler, fileManager, args);
aoqi@0 228 List<String> unrecognizedOptions = options.getUnrecognizedOptions();
aoqi@0 229 if (!unrecognizedOptions.isEmpty())
aoqi@0 230 Logger.getLogger(SchemaGenerator.class.getName()).log(Level.WARNING, "Unrecognized options found: {0}", unrecognizedOptions);
aoqi@0 231 Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjectsFromFiles(options.getFiles());
aoqi@0 232 JavaCompiler.CompilationTask task = compiler.getTask(
aoqi@0 233 null,
aoqi@0 234 fileManager,
aoqi@0 235 diagnostics,
aoqi@0 236 options.getRecognizedOptions(),
aoqi@0 237 options.getClassNames(),
aoqi@0 238 compilationUnits);
aoqi@0 239 com.sun.tools.internal.jxc.ap.SchemaGenerator r = new com.sun.tools.internal.jxc.ap.SchemaGenerator();
aoqi@0 240 if (episode != null)
aoqi@0 241 r.setEpisodeFile(episode);
aoqi@0 242 task.setProcessors(Collections.singleton(r));
aefimov@1011 243 boolean res = task.call();
aefimov@1011 244 //Print messages generated by compiler
aefimov@1011 245 for (Diagnostic<? extends JavaFileObject> d : diagnostics.getDiagnostics()) {
aefimov@1011 246 System.err.println(d.toString());
aefimov@1011 247 }
aefimov@1011 248 return res;
aoqi@0 249 }
aoqi@0 250 }
aoqi@0 251
aoqi@0 252 /**
aoqi@0 253 * @author Peter von der Ahe
aoqi@0 254 */
aoqi@0 255 private static final class JavacOptions {
aoqi@0 256 private final List<String> recognizedOptions;
aoqi@0 257 private final List<String> classNames;
aoqi@0 258 private final List<File> files;
aoqi@0 259 private final List<String> unrecognizedOptions;
aoqi@0 260
aoqi@0 261 private JavacOptions(List<String> recognizedOptions, List<String> classNames, List<File> files,
aoqi@0 262 List<String> unrecognizedOptions) {
aoqi@0 263 this.recognizedOptions = recognizedOptions;
aoqi@0 264 this.classNames = classNames;
aoqi@0 265 this.files = files;
aoqi@0 266 this.unrecognizedOptions = unrecognizedOptions;
aoqi@0 267 }
aoqi@0 268
aoqi@0 269 public static JavacOptions parse(OptionChecker primary, OptionChecker secondary, String... arguments) {
aoqi@0 270 List<String> recognizedOptions = new ArrayList<String>();
aoqi@0 271 List<String> unrecognizedOptions = new ArrayList<String>();
aoqi@0 272 List<String> classNames = new ArrayList<String>();
aoqi@0 273 List<File> files = new ArrayList<File>();
aoqi@0 274 for (int i = 0; i < arguments.length; i++) {
aoqi@0 275 String argument = arguments[i];
aoqi@0 276 int optionCount = primary.isSupportedOption(argument);
aoqi@0 277 if (optionCount < 0) {
aoqi@0 278 optionCount = secondary.isSupportedOption(argument);
aoqi@0 279 }
aoqi@0 280 if (optionCount < 0) {
aoqi@0 281 File file = new File(argument);
aoqi@0 282 if (file.exists())
aoqi@0 283 files.add(file);
aoqi@0 284 else if (SourceVersion.isName(argument))
aoqi@0 285 classNames.add(argument);
aoqi@0 286 else
aoqi@0 287 unrecognizedOptions.add(argument);
aoqi@0 288 } else {
aoqi@0 289 for (int j = 0; j < optionCount + 1; j++) {
aoqi@0 290 int index = i + j;
aoqi@0 291 if (index == arguments.length) throw new IllegalArgumentException(argument);
aoqi@0 292 recognizedOptions.add(arguments[index]);
aoqi@0 293 }
aoqi@0 294 i += optionCount;
aoqi@0 295 }
aoqi@0 296 }
aoqi@0 297 return new JavacOptions(recognizedOptions, classNames, files, unrecognizedOptions);
aoqi@0 298 }
aoqi@0 299
aoqi@0 300 /**
aoqi@0 301 * Returns the list of recognized options and their arguments.
aoqi@0 302 *
aoqi@0 303 * @return a list of options
aoqi@0 304 */
aoqi@0 305 public List<String> getRecognizedOptions() {
aoqi@0 306 return Collections.unmodifiableList(recognizedOptions);
aoqi@0 307 }
aoqi@0 308
aoqi@0 309 /**
aoqi@0 310 * Returns the list of file names.
aoqi@0 311 *
aoqi@0 312 * @return a list of file names
aoqi@0 313 */
aoqi@0 314 public List<File> getFiles() {
aoqi@0 315 return Collections.unmodifiableList(files);
aoqi@0 316 }
aoqi@0 317
aoqi@0 318 /**
aoqi@0 319 * Returns the list of class names.
aoqi@0 320 *
aoqi@0 321 * @return a list of class names
aoqi@0 322 */
aoqi@0 323 public List<String> getClassNames() {
aoqi@0 324 return Collections.unmodifiableList(classNames);
aoqi@0 325 }
aoqi@0 326
aoqi@0 327 /**
aoqi@0 328 * Returns the list of unrecognized options.
aoqi@0 329 *
aoqi@0 330 * @return a list of unrecognized options
aoqi@0 331 */
aoqi@0 332 public List<String> getUnrecognizedOptions() {
aoqi@0 333 return Collections.unmodifiableList(unrecognizedOptions);
aoqi@0 334 }
aoqi@0 335
aoqi@0 336 @Override
aoqi@0 337 public String toString() {
aoqi@0 338 return String.format("recognizedOptions = %s; classNames = %s; " + "files = %s; unrecognizedOptions = %s", recognizedOptions, classNames, files, unrecognizedOptions);
aoqi@0 339 }
aoqi@0 340 }
aoqi@0 341 }

mercurial