325N/A/*
325N/A * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
325N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
325N/A *
325N/A * This code is free software; you can redistribute it and/or modify it
325N/A * under the terms of the GNU General Public License version 2 only, as
325N/A * published by the Free Software Foundation. Oracle designates this
325N/A * particular file as subject to the "Classpath" exception as provided
325N/A * by Oracle in the LICENSE file that accompanied this code.
325N/A *
325N/A * This code is distributed in the hope that it will be useful, but WITHOUT
325N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
325N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
325N/A * version 2 for more details (a copy is included in the LICENSE file that
325N/A * accompanied this code).
325N/A *
325N/A * You should have received a copy of the GNU General Public License version
325N/A * 2 along with this work; if not, write to the Free Software Foundation,
325N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
325N/A *
325N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
325N/A * or visit www.oracle.com if you need additional information or have any
325N/A * questions.
325N/A */
325N/A
325N/Apackage com.sun.tools.internal.jxc;
325N/A
325N/Aimport java.io.File;
325N/Aimport java.lang.reflect.InvocationTargetException;
325N/Aimport java.lang.reflect.Method;
325N/Aimport java.net.MalformedURLException;
325N/Aimport java.net.URISyntaxException;
325N/Aimport java.net.URL;
325N/Aimport java.util.ArrayList;
325N/Aimport java.util.List;
325N/Aimport java.util.logging.Level;
325N/Aimport java.util.logging.Logger;
325N/A
325N/Aimport javax.xml.bind.JAXBContext;
325N/A
325N/Aimport com.sun.mirror.apt.AnnotationProcessorFactory;
325N/Aimport com.sun.tools.internal.jxc.apt.Options;
325N/Aimport com.sun.tools.internal.xjc.BadCommandLineException;
325N/Aimport com.sun.tools.internal.xjc.api.util.APTClassLoader;
325N/Aimport com.sun.tools.internal.xjc.api.util.ToolsJarNotFoundException;
325N/Aimport com.sun.xml.internal.bind.util.Which;
325N/A
325N/A/**
325N/A * CLI entry-point to the schema generator.
325N/A *
325N/A * @author Bhakti Mehta
325N/A */
325N/Apublic class SchemaGenerator {
325N/A /**
325N/A * Runs the schema generator.
325N/A */
325N/A public static void main(String[] args) throws Exception {
325N/A System.exit(run(args));
325N/A }
325N/A
325N/A public static int run(String[] args) throws Exception {
325N/A try {
325N/A ClassLoader cl = SchemaGenerator.class.getClassLoader();
325N/A if(cl==null) cl = ClassLoader.getSystemClassLoader();
325N/A ClassLoader classLoader = new APTClassLoader(cl,packagePrefixes);
325N/A return run(args, classLoader);
325N/A } catch( ToolsJarNotFoundException e) {
325N/A System.err.println(e.getMessage());
325N/A return -1;
325N/A }
325N/A }
325N/A
325N/A /**
325N/A * List of package prefixes we want to load in the same package
325N/A */
325N/A private static final String[] packagePrefixes = {
325N/A "com.sun.tools.internal.jxc.",
325N/A "com.sun.tools.internal.xjc.",
325N/A "com.sun.istack.internal.tools.",
325N/A "com.sun.tools.apt.",
325N/A "com.sun.tools.javac.",
325N/A "com.sun.tools.javadoc.",
325N/A "com.sun.mirror."
325N/A };
325N/A
325N/A /**
325N/A * Runs the schema generator.
325N/A *
325N/A * @param classLoader
325N/A * the schema generator will run in this classLoader.
325N/A * It needs to be able to load APT and JAXB RI classes. Note that
325N/A * JAXB RI classes refer to APT classes. Must not be null.
325N/A *
325N/A * @return
325N/A * exit code. 0 if success.
325N/A *
325N/A */
325N/A public static int run(String[] args, ClassLoader classLoader) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {
325N/A final Options options = new Options();
325N/A if (args.length ==0) {
325N/A usage();
325N/A return -1;
325N/A }
325N/A for (String arg : args) {
325N/A if (arg.equals("-help")) {
325N/A usage();
325N/A return -1;
325N/A }
325N/A
325N/A if (arg.equals("-version")) {
325N/A System.out.println(Messages.VERSION.format());
325N/A return -1;
325N/A }
325N/A
325N/A if (arg.equals("-fullversion")) {
325N/A System.out.println(Messages.FULLVERSION.format());
325N/A return -1;
325N/A }
325N/A
325N/A }
325N/A
325N/A try {
325N/A options.parseArguments(args);
325N/A } catch (BadCommandLineException e) {
325N/A // there was an error in the command line.
325N/A // print usage and abort.
325N/A System.out.println(e.getMessage());
325N/A System.out.println();
325N/A usage();
325N/A return -1;
325N/A }
325N/A
325N/A Class schemagenRunner = classLoader.loadClass(Runner.class.getName());
325N/A Method mainMethod = schemagenRunner.getDeclaredMethod("main",String[].class,File.class);
325N/A
325N/A List<String> aptargs = new ArrayList<String>();
325N/A
325N/A if(hasClass(options.arguments)) {
325N/A aptargs.add("-XclassesAsDecls");
325N/A }
325N/A
325N/A if (options.encoding != null) {
325N/A aptargs.add("-encoding");
325N/A aptargs.add(options.encoding);
325N/A }
325N/A
325N/A // make jaxb-api.jar visible to classpath
325N/A File jaxbApi = findJaxbApiJar();
325N/A if(jaxbApi!=null) {
325N/A if(options.classpath!=null) {
325N/A options.classpath = options.classpath+File.pathSeparatorChar+jaxbApi;
325N/A } else {
325N/A options.classpath = jaxbApi.getPath();
325N/A }
325N/A }
325N/A
325N/A aptargs.add("-cp");
325N/A aptargs.add(options.classpath);
325N/A
325N/A if(options.targetDir!=null) {
325N/A aptargs.add("-d");
325N/A aptargs.add(options.targetDir.getPath());
325N/A }
325N/A
325N/A aptargs.addAll(options.arguments);
325N/A
325N/A String[] argsarray = aptargs.toArray(new String[aptargs.size()]);
325N/A return (Integer)mainMethod.invoke(null,new Object[]{argsarray,options.episodeFile});
325N/A }
325N/A
325N/A /**
325N/A * Computes the file system path of <tt>jaxb-api.jar</tt> so that
325N/A * APT will see them in the <tt>-cp</tt> option.
325N/A *
325N/A * <p>
325N/A * In Java, you can't do this reliably (for that matter there's no guarantee
325N/A * that such a jar file exists, such as in Glassfish), so we do the best we can.
325N/A *
325N/A * @return
325N/A * null if failed to locate it.
325N/A */
325N/A private static File findJaxbApiJar() {
325N/A String url = Which.which(JAXBContext.class);
325N/A if(url==null) return null; // impossible, but hey, let's be defensive
325N/A
325N/A if(!url.startsWith("jar:") || url.lastIndexOf('!')==-1)
325N/A // no jar file
325N/A return null;
325N/A
325N/A String jarFileUrl = url.substring(4,url.lastIndexOf('!'));
325N/A if(!jarFileUrl.startsWith("file:"))
325N/A return null; // not from file system
325N/A
325N/A try {
325N/A File f = new File(new URL(jarFileUrl).toURI());
325N/A if (f.exists() && f.getName().endsWith(".jar")) { // see 6510966
325N/A return f;
325N/A }
325N/A f = new File(new URL(jarFileUrl).getFile());
325N/A if (f.exists() && f.getName().endsWith(".jar")) { // this is here for potential backw. compatibility issues
325N/A return f;
325N/A }
325N/A } catch (URISyntaxException ex) {
325N/A Logger.getLogger(SchemaGenerator.class.getName()).log(Level.SEVERE, null, ex);
325N/A } catch (MalformedURLException ex) {
325N/A Logger.getLogger(SchemaGenerator.class.getName()).log(Level.SEVERE, null, ex);
325N/A }
325N/A return null;
325N/A }
325N/A
325N/A /**
325N/A * Returns true if the list of arguments have an argument
325N/A * that looks like a class name.
325N/A */
325N/A private static boolean hasClass(List<String> args) {
325N/A for (String arg : args) {
325N/A if(!arg.endsWith(".java"))
325N/A return true;
325N/A }
325N/A return false;
325N/A }
325N/A
325N/A private static void usage( ) {
325N/A System.out.println(Messages.USAGE.format());
325N/A }
325N/A
325N/A public static final class Runner {
325N/A public static int main(String[] args, File episode) throws Exception {
325N/A ClassLoader cl = Runner.class.getClassLoader();
325N/A Class apt = cl.loadClass("com.sun.tools.apt.Main");
325N/A Method processMethod = apt.getMethod("process",AnnotationProcessorFactory.class, String[].class);
325N/A
325N/A com.sun.tools.internal.jxc.apt.SchemaGenerator r = new com.sun.tools.internal.jxc.apt.SchemaGenerator();
325N/A if(episode!=null)
325N/A r.setEpisodeFile(episode);
325N/A return (Integer) processMethod.invoke(null, r, args);
325N/A }
325N/A }
325N/A}