Sat, 07 Nov 2020 10:30:02 +0800
Added tag mips-jdk8u275-b01 for changeset fdbe50121f48
1 /*
2 * Copyright (c) 1997, 2013, 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.xml.internal.bind.util.Which;
32 import javax.lang.model.SourceVersion;
33 import javax.tools.Diagnostic;
34 import javax.tools.DiagnosticCollector;
35 import javax.tools.JavaCompiler;
36 import javax.tools.JavaFileObject;
37 import javax.tools.OptionChecker;
38 import javax.tools.StandardJavaFileManager;
39 import javax.tools.ToolProvider;
40 import javax.xml.bind.JAXBContext;
41 import java.io.File;
42 import java.lang.reflect.InvocationTargetException;
43 import java.lang.reflect.Method;
44 import java.net.MalformedURLException;
45 import java.net.URISyntaxException;
46 import java.net.URL;
47 import java.net.URLClassLoader;
48 import java.util.ArrayList;
49 import java.util.Collection;
50 import java.util.Collections;
51 import java.util.List;
52 import java.util.logging.Level;
53 import java.util.logging.Logger;
55 /**
56 * CLI entry-point to the schema generator.
57 *
58 * @author Bhakti Mehta
59 */
60 public class SchemaGenerator {
61 /**
62 * Runs the schema generator.
63 */
64 public static void main(String[] args) throws Exception {
65 System.exit(run(args));
66 }
68 public static int run(String[] args) throws Exception {
69 try {
70 ClassLoader cl = SecureLoader.getClassClassLoader(SchemaGenerator.class);
71 if (cl==null) {
72 cl = SecureLoader.getSystemClassLoader();
73 }
74 return run(args, cl);
75 } catch(Exception e) {
76 System.err.println(e.getMessage());
77 return -1;
78 }
79 }
81 /**
82 * Runs the schema generator.
83 *
84 * @param classLoader
85 * the schema generator will run in this classLoader.
86 * It needs to be able to load annotation processing and JAXB RI classes. Note that
87 * JAXB RI classes refer to annotation processing classes. Must not be null.
88 *
89 * @return
90 * exit code. 0 if success.
91 *
92 */
93 public static int run(String[] args, ClassLoader classLoader) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {
94 final Options options = new Options();
95 if (args.length ==0) {
96 usage();
97 return -1;
98 }
99 for (String arg : args) {
100 if (arg.equals("-help")) {
101 usage();
102 return -1;
103 }
105 if (arg.equals("-version")) {
106 System.out.println(Messages.VERSION.format());
107 return -1;
108 }
110 if (arg.equals("-fullversion")) {
111 System.out.println(Messages.FULLVERSION.format());
112 return -1;
113 }
115 }
117 try {
118 options.parseArguments(args);
119 } catch (BadCommandLineException e) {
120 // there was an error in the command line.
121 // print usage and abort.
122 System.out.println(e.getMessage());
123 System.out.println();
124 usage();
125 return -1;
126 }
128 Class schemagenRunner = classLoader.loadClass(Runner.class.getName());
129 Method compileMethod = schemagenRunner.getDeclaredMethod("compile",String[].class,File.class);
131 List<String> aptargs = new ArrayList<String>();
133 if (options.encoding != null) {
134 aptargs.add("-encoding");
135 aptargs.add(options.encoding);
136 }
138 aptargs.add("-cp");
139 aptargs.add(setClasspath(options.classpath)); // set original classpath + jaxb-api to be visible to annotation processor
141 if(options.targetDir!=null) {
142 aptargs.add("-d");
143 aptargs.add(options.targetDir.getPath());
144 }
146 aptargs.addAll(options.arguments);
148 String[] argsarray = aptargs.toArray(new String[aptargs.size()]);
149 return ((Boolean) compileMethod.invoke(null, argsarray, options.episodeFile)) ? 0 : 1;
150 }
152 private static String setClasspath(String givenClasspath) {
153 StringBuilder cp = new StringBuilder();
154 appendPath(cp, givenClasspath);
155 ClassLoader cl = Thread.currentThread().getContextClassLoader();
156 while (cl != null) {
157 if (cl instanceof URLClassLoader) {
158 for (URL url : ((URLClassLoader) cl).getURLs()) {
159 appendPath(cp, url.getPath());
160 }
161 }
162 cl = cl.getParent();
163 }
165 appendPath(cp, findJaxbApiJar());
166 return cp.toString();
167 }
169 private static void appendPath(StringBuilder cp, String url) {
170 if (url == null || url.trim().isEmpty())
171 return;
172 if (cp.length() != 0)
173 cp.append(File.pathSeparatorChar);
174 cp.append(url);
175 }
177 /**
178 * Computes the file system path of <tt>jaxb-api.jar</tt> so that
179 * Annotation Processing will see them in the <tt>-cp</tt> option.
180 *
181 * <p>
182 * In Java, you can't do this reliably (for that matter there's no guarantee
183 * that such a jar file exists, such as in Glassfish), so we do the best we can.
184 *
185 * @return
186 * null if failed to locate it.
187 */
188 private static String findJaxbApiJar() {
189 String url = Which.which(JAXBContext.class);
190 if(url==null) return null; // impossible, but hey, let's be defensive
192 if(!url.startsWith("jar:") || url.lastIndexOf('!')==-1)
193 // no jar file
194 return null;
196 String jarFileUrl = url.substring(4,url.lastIndexOf('!'));
197 if(!jarFileUrl.startsWith("file:"))
198 return null; // not from file system
200 try {
201 File f = new File(new URL(jarFileUrl).toURI());
202 if (f.exists() && f.getName().endsWith(".jar")) { // see 6510966
203 return f.getPath();
204 }
205 f = new File(new URL(jarFileUrl).getFile());
206 if (f.exists() && f.getName().endsWith(".jar")) { // this is here for potential backw. compatibility issues
207 return f.getPath();
208 }
209 } catch (URISyntaxException ex) {
210 Logger.getLogger(SchemaGenerator.class.getName()).log(Level.SEVERE, null, ex);
211 } catch (MalformedURLException ex) {
212 Logger.getLogger(SchemaGenerator.class.getName()).log(Level.SEVERE, null, ex);
213 }
214 return null;
215 }
217 private static void usage( ) {
218 System.out.println(Messages.USAGE.format());
219 }
221 public static final class Runner {
222 public static boolean compile(String[] args, File episode) throws Exception {
224 JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
225 DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
226 StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null);
227 JavacOptions options = JavacOptions.parse(compiler, fileManager, args);
228 List<String> unrecognizedOptions = options.getUnrecognizedOptions();
229 if (!unrecognizedOptions.isEmpty())
230 Logger.getLogger(SchemaGenerator.class.getName()).log(Level.WARNING, "Unrecognized options found: {0}", unrecognizedOptions);
231 Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjectsFromFiles(options.getFiles());
232 JavaCompiler.CompilationTask task = compiler.getTask(
233 null,
234 fileManager,
235 diagnostics,
236 options.getRecognizedOptions(),
237 options.getClassNames(),
238 compilationUnits);
239 com.sun.tools.internal.jxc.ap.SchemaGenerator r = new com.sun.tools.internal.jxc.ap.SchemaGenerator();
240 if (episode != null)
241 r.setEpisodeFile(episode);
242 task.setProcessors(Collections.singleton(r));
243 boolean res = task.call();
244 //Print messages generated by compiler
245 for (Diagnostic<? extends JavaFileObject> d : diagnostics.getDiagnostics()) {
246 System.err.println(d.toString());
247 }
248 return res;
249 }
250 }
252 /**
253 * @author Peter von der Ahe
254 */
255 private static final class JavacOptions {
256 private final List<String> recognizedOptions;
257 private final List<String> classNames;
258 private final List<File> files;
259 private final List<String> unrecognizedOptions;
261 private JavacOptions(List<String> recognizedOptions, List<String> classNames, List<File> files,
262 List<String> unrecognizedOptions) {
263 this.recognizedOptions = recognizedOptions;
264 this.classNames = classNames;
265 this.files = files;
266 this.unrecognizedOptions = unrecognizedOptions;
267 }
269 public static JavacOptions parse(OptionChecker primary, OptionChecker secondary, String... arguments) {
270 List<String> recognizedOptions = new ArrayList<String>();
271 List<String> unrecognizedOptions = new ArrayList<String>();
272 List<String> classNames = new ArrayList<String>();
273 List<File> files = new ArrayList<File>();
274 for (int i = 0; i < arguments.length; i++) {
275 String argument = arguments[i];
276 int optionCount = primary.isSupportedOption(argument);
277 if (optionCount < 0) {
278 optionCount = secondary.isSupportedOption(argument);
279 }
280 if (optionCount < 0) {
281 File file = new File(argument);
282 if (file.exists())
283 files.add(file);
284 else if (SourceVersion.isName(argument))
285 classNames.add(argument);
286 else
287 unrecognizedOptions.add(argument);
288 } else {
289 for (int j = 0; j < optionCount + 1; j++) {
290 int index = i + j;
291 if (index == arguments.length) throw new IllegalArgumentException(argument);
292 recognizedOptions.add(arguments[index]);
293 }
294 i += optionCount;
295 }
296 }
297 return new JavacOptions(recognizedOptions, classNames, files, unrecognizedOptions);
298 }
300 /**
301 * Returns the list of recognized options and their arguments.
302 *
303 * @return a list of options
304 */
305 public List<String> getRecognizedOptions() {
306 return Collections.unmodifiableList(recognizedOptions);
307 }
309 /**
310 * Returns the list of file names.
311 *
312 * @return a list of file names
313 */
314 public List<File> getFiles() {
315 return Collections.unmodifiableList(files);
316 }
318 /**
319 * Returns the list of class names.
320 *
321 * @return a list of class names
322 */
323 public List<String> getClassNames() {
324 return Collections.unmodifiableList(classNames);
325 }
327 /**
328 * Returns the list of unrecognized options.
329 *
330 * @return a list of unrecognized options
331 */
332 public List<String> getUnrecognizedOptions() {
333 return Collections.unmodifiableList(unrecognizedOptions);
334 }
336 @Override
337 public String toString() {
338 return String.format("recognizedOptions = %s; classNames = %s; " + "files = %s; unrecognizedOptions = %s", recognizedOptions, classNames, files, unrecognizedOptions);
339 }
340 }
341 }