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

Tue, 06 Mar 2012 16:09:35 -0800

author
ohair
date
Tue, 06 Mar 2012 16:09:35 -0800
changeset 286
f50545b5e2f1
child 368
0989ad8c0860
permissions
-rw-r--r--

7150322: Stop using drop source bundles in jaxws
Reviewed-by: darcy, ohrstrom

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

mercurial