|
Java example source code file (ArgTypeCompilerFactory.java)
This example Java source code file (ArgTypeCompilerFactory.java) is included in the alvinalexander.com
"Java Source Code
Warehouse" project. The intent of this project is to help you "Learn
Java by Example" TM.
Learn more about this Java project at its project page.
The ArgTypeCompilerFactory.java Java example source code
/*
* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.io.*;
import java.util.*;
import java.util.List;
import javax.tools.*;
import com.sun.tools.javac.api.*;
import com.sun.tools.javac.api.DiagnosticFormatter.Configuration.DiagnosticPart;
import com.sun.tools.javac.api.Formattable.LocalizedString;
import com.sun.tools.javac.code.Flags.Flag;
import com.sun.tools.javac.code.Kinds.KindName;
import com.sun.tools.javac.code.*;
import com.sun.tools.javac.file.*;
import com.sun.tools.javac.main.Main;
import com.sun.tools.javac.main.JavaCompiler;
import com.sun.tools.javac.parser.Tokens.TokenKind;
import com.sun.tools.javac.util.*;
import com.sun.tools.javac.util.AbstractDiagnosticFormatter.SimpleConfiguration;
import javax.lang.model.SourceVersion;
/**
* Compiler factory for instances of Example.Compiler that use custom
* DiagnosticFormatter and Messages objects to track the types of args
* when when localizing diagnostics.
* The compiler objects only support "output" mode, not "check" mode.
*/
class ArgTypeCompilerFactory implements Example.Compiler.Factory {
// Same code as Example.Compiler.DefaultFactory, but the names resolve differently
public Example.Compiler getCompiler(List<String> opts, boolean verbose) {
String first;
String[] rest;
if (opts == null || opts.isEmpty()) {
first = null;
rest = new String[0];
} else {
first = opts.get(0);
rest = opts.subList(1, opts.size()).toArray(new String[opts.size() - 1]);
}
if (first == null || first.equals("jsr199"))
return new Jsr199Compiler(verbose, rest);
else if (first.equals("simple"))
return new SimpleCompiler(verbose);
else if (first.equals("backdoor"))
return new BackdoorCompiler(verbose);
else
throw new IllegalArgumentException(first);
}
/**
* Compile using the JSR 199 API. The diagnostics generated are
* scanned for resource keys. Not all diagnostic keys are generated
* via the JSR 199 API -- for example, rich diagnostics are not directly
* accessible, and some diagnostics generated by the file manager may
* not be generated (for example, the JSR 199 file manager does not see
* -Xlint:path).
*/
static class Jsr199Compiler extends Example.Compiler {
List<String> fmOpts;
Jsr199Compiler(boolean verbose, String... args) {
super(verbose);
for (int i = 0; i < args.length; i++) {
String arg = args[i];
if (arg.equals("-filemanager") && (i + 1 < args.length)) {
fmOpts = Arrays.asList(args[++i].split(","));
} else
throw new IllegalArgumentException(arg);
}
}
@Override
boolean run(PrintWriter out, Set<String> keys, boolean raw, List opts, List files) {
assert out != null && keys == null;
if (verbose)
System.err.println("run_jsr199: " + opts + " " + files);
JavacTool tool = JavacTool.create();
StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null);
if (fmOpts != null)
fm = new FileManager(fm, fmOpts);
Iterable<? extends JavaFileObject> fos = fm.getJavaFileObjectsFromFiles(files);
Context c = new Context();
ArgTypeMessages.preRegister(c);
ArgTypeJavaCompiler.preRegister(c);
JavacTaskImpl t = (JavacTaskImpl) tool.getTask(out, fm, null, opts, null, fos, c);
return t.call();
}
}
/**
* Run the test using the standard simple entry point.
*/
static class SimpleCompiler extends Example.Compiler {
SimpleCompiler(boolean verbose) {
super(verbose);
}
@Override
boolean run(PrintWriter out, Set<String> keys, boolean raw, List opts, List files) {
assert out != null && keys == null;
if (verbose)
System.err.println("run_simple: " + opts + " " + files);
List<String> args = new ArrayList();
args.addAll(opts);
for (File f: files)
args.add(f.getPath());
Main main = new Main("javac", out);
Context c = new Context() {
@Override public void clear() {
((JavacFileManager) get(JavaFileManager.class)).close();
super.clear();
}
};
JavacFileManager.preRegister(c); // can't create it until Log has been set up
ArgTypeJavaCompiler.preRegister(c);
ArgTypeMessages.preRegister(c);
Main.Result result = main.compile(args.toArray(new String[args.size()]), c);
return result.isOK();
}
}
static class BackdoorCompiler extends Example.Compiler {
BackdoorCompiler(boolean verbose) {
super(verbose);
}
@Override
boolean run(PrintWriter out, Set<String> keys, boolean raw, List opts, List files) {
assert out != null && keys == null;
if (verbose)
System.err.println("run_simple: " + opts + " " + files);
List<String> args = new ArrayList(opts);
for (File f: files)
args.add(f.getPath());
Context c = new Context();
JavacFileManager.preRegister(c); // can't create it until Log has been set up
ArgTypeJavaCompiler.preRegister(c);
ArgTypeMessages.preRegister(c);
Main m = new Main("javac", out);
Main.Result result = m.compile(args.toArray(new String[args.size()]), c);
return result.isOK();
}
}
// <editor-fold defaultstate="collapsed" desc="Custom Javac components">
/**
* Diagnostic formatter which reports formats a diag as a series of lines
* containing a key, and a possibly empty set of descriptive strings for the
* arg types.
*/
static class ArgTypeDiagnosticFormatter extends AbstractDiagnosticFormatter {
ArgTypeDiagnosticFormatter(Options options) {
super(null, new SimpleConfiguration(options,
EnumSet.of(DiagnosticPart.SUMMARY,
DiagnosticPart.DETAILS,
DiagnosticPart.SUBDIAGNOSTICS)));
}
@Override
protected String formatDiagnostic(JCDiagnostic d, Locale locale) {
return formatMessage(d, locale);
}
@Override
public String formatMessage(JCDiagnostic d, Locale l) {
StringBuilder buf = new StringBuilder();
formatMessage(d, buf);
return buf.toString();
}
private void formatMessage(JCDiagnostic d, StringBuilder buf) {
String key = d.getCode();
Object[] args = d.getArgs();
// report the primary arg types, without recursing into diag fragments
buf.append(getKeyArgsString(key, args));
// report details for any diagnostic fragments
for (Object arg: args) {
if (arg instanceof JCDiagnostic) {
buf.append("\n");
formatMessage((JCDiagnostic) arg, buf);
}
}
// report details for any subdiagnostics
for (String s: formatSubdiagnostics(d, null)) {
buf.append("\n");
buf.append(s);
}
}
@Override
public boolean isRaw() {
return true;
}
}
/**
* Trivial subtype of JavaCompiler to get access to the protected compilerKey field.
* The factory is used to ensure that the log is initialized with an instance of
* ArgTypeDiagnosticFormatter before we create the required JavaCompiler.
*/
static class ArgTypeJavaCompiler extends JavaCompiler {
static void preRegister(Context context) {
context.put(compilerKey, new Context.Factory<JavaCompiler>() {
public JavaCompiler make(Context c) {
Log log = Log.instance(c);
Options options = Options.instance(c);
log.setDiagnosticFormatter(new ArgTypeDiagnosticFormatter(options));
return new JavaCompiler(c);
}
});
}
// not used
private ArgTypeJavaCompiler() {
super(null);
}
}
/**
* Diagnostic formatter which "localizes" a message as a line
* containing a key, and a possibly empty set of descriptive strings for the
* arg types.
*/
static class ArgTypeMessages extends JavacMessages {
static void preRegister(Context context) {
context.put(JavacMessages.messagesKey, new Context.Factory<JavacMessages>() {
public JavacMessages make(Context c) {
return new ArgTypeMessages(c) {
@Override
public String getLocalizedString(Locale l, String key, Object... args) {
return getKeyArgsString(key, args);
}
};
}
});
}
ArgTypeMessages(Context context) {
super(context);
}
}
/**
* Utility method to generate a string for key and args
*/
static String getKeyArgsString(String key, Object... args) {
StringBuilder buf = new StringBuilder();
buf.append(key);
String sep = ": ";
for (Object o : args) {
buf.append(sep);
buf.append(getArgTypeOrStringValue(o));
sep = ", ";
}
return buf.toString();
}
static boolean showStringValues = false;
static String getArgTypeOrStringValue(Object o) {
if (showStringValues && o instanceof String)
return "\"" + o + "\"";
return getArgType(o);
}
static String getArgType(Object o) {
if (o == null)
return "null";
if (o instanceof Name)
return "name";
if (o instanceof Boolean)
return "boolean";
if (o instanceof Integer)
return "number";
if (o instanceof String)
return "string";
if (o instanceof Flag)
return "modifier";
if (o instanceof KindName)
return "symbol kind";
if (o instanceof TokenKind)
return "token";
if (o instanceof Symbol)
return "symbol";
if (o instanceof Type)
return "type";
if (o instanceof List) {
List<?> l = (List) o;
if (l.isEmpty())
return "list";
else
return "list of " + getArgType(l.get(0));
}
if (o instanceof ListBuffer)
return getArgType(((ListBuffer) o).toList());
if (o instanceof Set) {
Set<?> s = (Set) o;
if (s.isEmpty())
return "set";
else
return "set of " + getArgType(s.iterator().next());
}
if (o instanceof SourceVersion)
return "source version";
if (o instanceof FileObject || o instanceof File)
return "file name";
if (o instanceof JCDiagnostic)
return "message segment";
if (o instanceof LocalizedString)
return "message segment"; // only instance is "no arguments"
String s = o.getClass().getSimpleName();
return (s.isEmpty() ? o.getClass().getName() : s);
}
// </editor-fold>
}
Other Java examples (source code examples)
Here is a short list of links related to this Java ArgTypeCompilerFactory.java source code file:
|