All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.tools.jxc.SchemaGenerator Maven / Gradle / Ivy

There is a newer version: 4.0.5
Show newest version
/*
 * Copyright (c) 1997, 2022 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Distribution License v. 1.0, which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

package com.sun.tools.jxc;

import com.sun.tools.jxc.ap.Options;
import com.sun.tools.xjc.BadCommandLineException;
import org.glassfish.jaxb.core.util.Which;

import javax.lang.model.SourceVersion;
import javax.tools.Diagnostic;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.OptionChecker;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import jakarta.xml.bind.JAXBContext;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * CLI entry-point to the schema generator.
 *
 * @author Bhakti Mehta
 */
public final class SchemaGenerator {

    private static final Logger LOGGER = Logger.getLogger(SchemaGenerator.class.getName());

    private SchemaGenerator() {}

    /**
     * Runs the schema generator.
     * @param args command line arguments
     * @throws java.lang.Exception for error
     */
    public static void main(String[] args) throws Exception {
        System.exit(run(args));
    }

    /**
     * Runs the schema generator.
     * @param args command line arguments
     * @return
     *      exit code. 0 if success.
     * @throws java.lang.Exception for error
     */
    public static int run(String[] args) throws Exception {
        try {
            ClassLoader cl = SecureLoader.getClassClassLoader(SchemaGenerator.class);
            if (cl==null) {
                cl = SecureLoader.getSystemClassLoader();
            }
            return run(args, cl);
        } catch(Exception e) {
            LOGGER.log(Level.SEVERE, e.getMessage(), e);
            return -1;
        }
    }

    /**
     * Runs the schema generator.
     *
     * @param args arguments for the schema generator
     * @param classLoader
     *      the schema generator will run in this classLoader.
     *      It needs to be able to load annotation processing and JAXB RI classes. Note that
     *      JAXB RI classes refer to annotation processing classes. Must not be null.
     *
     * @return
     *      exit code. 0 if success.
     * @throws java.lang.ClassNotFoundException if {@link Runner} cannot be found
     * @throws java.lang.NoSuchMethodException if {@link Runner#compile(java.lang.String[], java.io.File) } cannot be found
     * @throws java.lang.IllegalAccessException if {@link Runner#compile(java.lang.String[], java.io.File) } cannot be accessed
     * @throws java.lang.reflect.InvocationTargetException if {@link Runner#compile(java.lang.String[], java.io.File) } cannot be invoked
     *
     */
    public static int run(String[] args, ClassLoader classLoader) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {
        final Options options = new Options();
        if (args.length ==0) {
            usage();
            return -1;
        }
        for (String arg : args) {
            if (arg.equals("-help")) {
                usage();
                return -1;
            }

            if (arg.equals("-version")) {
                System.out.println(Messages.VERSION.format());
                return -1;
            }

            if (arg.equals("-fullversion")) {
                System.out.println(Messages.FULLVERSION.format());
                return -1;
            }

        }

        try {
            options.parseArguments(args);
        } catch (BadCommandLineException e) {
            // there was an error in the command line.
            // print usage and abort.
            System.out.println(e.getMessage());
            System.out.println();
            usage();
            return -1;
        }

        Class schemagenRunner = classLoader.loadClass(Runner.class.getName());
        Method compileMethod = schemagenRunner.getDeclaredMethod("compile",String[].class,File.class);

        List aptargs = new ArrayList<>();

        if (options.encoding != null) {
            aptargs.add("-encoding");
            aptargs.add(options.encoding);
        }

        aptargs.add("-cp");
        aptargs.add(setClasspath(options.classpath)); // set original classpath + jaxb-api to be visible to annotation processor

        if(options.targetDir!=null) {
            aptargs.add("-d");
            aptargs.add(options.targetDir.getPath());
        }

        aptargs.addAll(options.arguments);

        String[] argsarray = aptargs.toArray(new String[0]);
        return ((Boolean) compileMethod.invoke(null, argsarray, options.episodeFile)) ? 0 : 1;
    }

    private static String setClasspath(String givenClasspath) {
        StringBuilder cp = new StringBuilder();
        appendPath(cp, givenClasspath);
        ClassLoader cl = Thread.currentThread().getContextClassLoader();
        while (cl != null) {
            if (cl instanceof URLClassLoader) {
                for (URL url : ((URLClassLoader) cl).getURLs()) {
                    try {
                        appendPath(cp,new File(url.toURI()).getPath());
                    } catch(URISyntaxException ex) {
                        /*If the URL is not properly formated - skip it*/
                        LOGGER.log(Level.SEVERE, ex.getMessage(), ex);
                    }
                }
            }
            cl = cl.getParent();
        }

        appendPath(cp, findJaxbApiJar());
        return cp.toString();
    }

    private static void appendPath(StringBuilder cp, String url) {
        if (url == null || url.trim().isEmpty())
            return;
        if (cp.length() != 0)
            cp.append(File.pathSeparatorChar);
        cp.append(url);
    }

    /**
     * Computes the file system path of {@code jakarta.xml.bind-api.jar} so that
     * Annotation Processing will see them in the {@code -cp} option.
     *
     * 

* In Java, you can't do this reliably (for that matter there's no guarantee * that such a jar file exists, such as in Glassfish), so we do the best we can. * * @return * null if failed to locate it. */ private static String findJaxbApiJar() { String url = Which.which(JAXBContext.class); if(url==null) return null; // impossible, but hey, let's be defensive if(!url.startsWith("jar:") || url.lastIndexOf('!')==-1) // no jar file return null; String jarFileUrl = url.substring(4,url.lastIndexOf('!')); if(!jarFileUrl.startsWith("file:")) return null; // not from file system try { File f = new File(new URL(jarFileUrl).toURI()); if (f.exists() && f.getName().endsWith(".jar")) { // see 6510966 return f.getPath(); } f = new File(new URL(jarFileUrl).getFile()); if (f.exists() && f.getName().endsWith(".jar")) { // this is here for potential backw. compatibility issues return f.getPath(); } } catch (URISyntaxException | MalformedURLException ex) { LOGGER.log(Level.SEVERE, ex.getMessage(), ex); } return null; } private static void usage( ) { System.out.println(Messages.USAGE.format()); } public static final class Runner { private Runner() {} public static boolean compile(String[] args, File episode) throws Exception { JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); DiagnosticCollector diagnostics = new DiagnosticCollector<>(); StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null); JavacOptions options = JavacOptions.parse(compiler, fileManager, args); List unrecognizedOptions = options.getUnrecognizedOptions(); if (!unrecognizedOptions.isEmpty()) { LOGGER.log(Level.WARNING, "Unrecognized options found: {0}", unrecognizedOptions); } Iterable compilationUnits = fileManager.getJavaFileObjectsFromFiles(options.getFiles()); JavaCompiler.CompilationTask task = compiler.getTask( null, fileManager, diagnostics, options.getRecognizedOptions(), options.getClassNames(), compilationUnits); com.sun.tools.jxc.ap.SchemaGenerator r = new com.sun.tools.jxc.ap.SchemaGenerator(); if (episode != null) r.setEpisodeFile(episode); task.setProcessors(Collections.singleton(r)); boolean res = task.call(); //Print compiler generated messages for( Diagnostic d : diagnostics.getDiagnostics() ) { System.err.println(d.toString()); } return res; } } /** * @author Peter von der Ahe */ private static final class JavacOptions { private final List recognizedOptions; private final List classNames; private final List files; private final List unrecognizedOptions; private JavacOptions(List recognizedOptions, List classNames, List files, List unrecognizedOptions) { this.recognizedOptions = recognizedOptions; this.classNames = classNames; this.files = files; this.unrecognizedOptions = unrecognizedOptions; } public static JavacOptions parse(OptionChecker primary, OptionChecker secondary, String... arguments) { List recognizedOptions = new ArrayList<>(); List unrecognizedOptions = new ArrayList<>(); List classNames = new ArrayList<>(); List files = new ArrayList<>(); for (int i = 0; i < arguments.length; i++) { String argument = arguments[i]; int optionCount = primary.isSupportedOption(argument); if (optionCount < 0) { optionCount = secondary.isSupportedOption(argument); } if (optionCount < 0) { File file = new File(argument); if (file.exists()) files.add(file); else if (SourceVersion.isName(argument)) classNames.add(argument); else unrecognizedOptions.add(argument); } else { for (int j = 0; j < optionCount + 1; j++) { int index = i + j; if (index == arguments.length) throw new IllegalArgumentException(argument); recognizedOptions.add(arguments[index]); } i += optionCount; } } return new JavacOptions(recognizedOptions, classNames, files, unrecognizedOptions); } /** * Returns the list of recognized options and their arguments. * * @return a list of options */ public List getRecognizedOptions() { return Collections.unmodifiableList(recognizedOptions); } /** * Returns the list of file names. * * @return a list of file names */ public List getFiles() { return Collections.unmodifiableList(files); } /** * Returns the list of class names. * * @return a list of class names */ public List getClassNames() { return Collections.unmodifiableList(classNames); } /** * Returns the list of unrecognized options. * * @return a list of unrecognized options */ public List getUnrecognizedOptions() { return Collections.unmodifiableList(unrecognizedOptions); } @Override public String toString() { return String.format("recognizedOptions = %s; classNames = %s; " + "files = %s; unrecognizedOptions = %s", recognizedOptions, classNames, files, unrecognizedOptions); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy