001: /*
002: * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package com.sun.tools.javac.sym;
027:
028: import com.sun.tools.javac.api.JavacTaskImpl;
029: import com.sun.tools.javac.code.Kinds;
030: import com.sun.tools.javac.code.Scope;
031: import com.sun.tools.javac.code.Symbol.*;
032: import com.sun.tools.javac.code.Symbol;
033: import com.sun.tools.javac.code.Attribute;
034: import com.sun.tools.javac.code.Symtab;
035: import com.sun.tools.javac.code.Type;
036: import com.sun.tools.javac.jvm.ClassReader;
037: import com.sun.tools.javac.jvm.ClassWriter;
038: import com.sun.tools.javac.jvm.Pool;
039: import com.sun.tools.javac.processing.JavacProcessingEnvironment;
040: import com.sun.tools.javac.util.List;
041: import com.sun.tools.javac.util.Pair;
042: import com.sun.tools.javac.util.Name;
043:
044: import java.io.File;
045: import java.io.IOException;
046: import java.util.ArrayList;
047: import java.util.EnumSet;
048: import java.util.Enumeration;
049: import java.util.HashSet;
050: import java.util.Properties;
051: import java.util.ResourceBundle;
052: import java.util.Set;
053:
054: import javax.annotation.processing.AbstractProcessor;
055: import javax.annotation.processing.RoundEnvironment;
056: import javax.annotation.processing.SupportedAnnotationTypes;
057: import javax.annotation.processing.SupportedOptions;
058: import javax.lang.model.SourceVersion;
059: import javax.lang.model.element.ElementKind;
060: import javax.lang.model.element.TypeElement;
061: import javax.tools.Diagnostic;
062: import javax.tools.JavaCompiler;
063: import javax.tools.JavaFileManager.Location;
064: import javax.tools.JavaFileObject;
065: import static javax.tools.JavaFileObject.Kind.CLASS;
066: import javax.tools.StandardJavaFileManager;
067: import javax.tools.StandardLocation;
068: import javax.tools.ToolProvider;
069:
070: /**
071: * Used to generate a "symbol file" representing rt.jar that only
072: * includes supported or legacy proprietary API. Valid annotation
073: * processor options:
074: *
075: * <dl>
076: * <dt>com.sun.tools.javac.sym.Jar</dt>
077: * <dd>Specifies the location of rt.jar.</dd>
078: * <dt>com.sun.tools.javac.sym.Dest</dt>
079: * <dd>Specifies the destination directory.</dd>
080: * </dl>
081: *
082: * <p><b>This is NOT part of any API supported by Sun Microsystems.
083: * If you write code that depends on this, you do so at your own
084: * risk. This code and its internal interfaces are subject to change
085: * or deletion without notice.</b></p>
086: *
087: * @author Peter von der Ah\u00e9
088: */
089: @SupportedOptions({"com.sun.tools.javac.sym.Jar","com.sun.tools.javac.sym.Dest"})
090: @SupportedAnnotationTypes("*")
091: public class CreateSymbols extends AbstractProcessor {
092:
093: static Set<String> getLegacyPackages() {
094: ResourceBundle legacyBundle = ResourceBundle
095: .getBundle("com.sun.tools.javac.resources.legacy");
096: Set<String> keys = new HashSet<String>();
097: for (Enumeration<String> e = legacyBundle.getKeys(); e
098: .hasMoreElements();)
099: keys.add(e.nextElement());
100: return keys;
101: }
102:
103: public boolean process(Set<? extends TypeElement> tes,
104: RoundEnvironment renv) {
105: try {
106: if (renv.processingOver())
107: createSymbols();
108: } catch (IOException e) {
109: processingEnv.getMessager().printMessage(
110: Diagnostic.Kind.ERROR, e.getLocalizedMessage());
111: } catch (Throwable t) {
112: Throwable cause = t.getCause();
113: if (cause == null)
114: cause = t;
115: processingEnv.getMessager().printMessage(
116: Diagnostic.Kind.ERROR, cause.getLocalizedMessage());
117: }
118: return true;
119: }
120:
121: void createSymbols() throws IOException {
122: Set<String> legacy = getLegacyPackages();
123: Set<String> legacyProprietary = getLegacyPackages();
124: Set<String> documented = new HashSet<String>();
125: Set<PackageSymbol> packages = ((JavacProcessingEnvironment) processingEnv)
126: .getSpecifiedPackages();
127: String jarName = processingEnv.getOptions().get(
128: "com.sun.tools.javac.sym.Jar");
129: if (jarName == null)
130: throw new RuntimeException(
131: "Must use -Acom.sun.tools.javac.sym.Jar=LOCATION_OF_JAR");
132: String destName = processingEnv.getOptions().get(
133: "com.sun.tools.javac.sym.Dest");
134: if (destName == null)
135: throw new RuntimeException(
136: "Must use -Acom.sun.tools.javac.sym.Dest=LOCATION_OF_JAR");
137:
138: for (PackageSymbol psym : packages) {
139: String name = psym.getQualifiedName().toString();
140: legacyProprietary.remove(name);
141: documented.add(name);
142: }
143:
144: JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
145: StandardJavaFileManager fm = tool.getStandardFileManager(null,
146: null, null);
147: Location jarLocation = StandardLocation.locationFor(jarName);
148: File jarFile = new File(jarName);
149: fm.setLocation(jarLocation, List.of(jarFile));
150: fm.setLocation(StandardLocation.CLASS_PATH, List.<File> nil());
151: fm.setLocation(StandardLocation.SOURCE_PATH, List.<File> nil());
152: {
153: ArrayList<File> bootClassPath = new ArrayList<File>();
154: bootClassPath.add(jarFile);
155: for (File path : fm
156: .getLocation(StandardLocation.PLATFORM_CLASS_PATH)) {
157: if (!new File(path.getName())
158: .equals(new File("rt.jar")))
159: bootClassPath.add(path);
160: }
161: System.err.println("Using boot class path = "
162: + bootClassPath);
163: fm.setLocation(StandardLocation.PLATFORM_CLASS_PATH,
164: bootClassPath);
165: }
166: // System.out.println(fm.getLocation(StandardLocation.PLATFORM_CLASS_PATH));
167: File destDir = new File(destName);
168: if (!destDir.exists())
169: if (!destDir.mkdirs())
170: throw new RuntimeException("Could not create "
171: + destDir);
172: fm.setLocation(StandardLocation.CLASS_OUTPUT, List.of(destDir));
173: Set<String> hiddenPackages = new HashSet<String>();
174: Set<String> crisp = new HashSet<String>();
175: List<String> options = List.of("-XDdev");
176: // options = options.prepend("-doe");
177: // options = options.prepend("-verbose");
178: JavacTaskImpl task = (JavacTaskImpl) tool.getTask(null, fm,
179: null, options, null, null);
180: com.sun.tools.javac.main.JavaCompiler compiler = com.sun.tools.javac.main.JavaCompiler
181: .instance(task.getContext());
182: ClassReader reader = ClassReader.instance(task.getContext());
183: ClassWriter writer = ClassWriter.instance(task.getContext());
184: Symtab syms = Symtab.instance(task.getContext());
185: Attribute.Compound proprietary = new Attribute.Compound(
186: syms.proprietaryType, List
187: .<Pair<Symbol.MethodSymbol, Attribute>> nil());
188:
189: Type.moreInfo = true;
190: Pool pool = new Pool();
191: for (JavaFileObject file : fm.list(jarLocation, "", EnumSet
192: .of(CLASS), true)) {
193: String className = fm.inferBinaryName(jarLocation, file);
194: int index = className.lastIndexOf('.');
195: String pckName = index == -1 ? "" : className.substring(0,
196: index);
197: boolean addLegacyAnnotation = false;
198: if (documented.contains(pckName)) {
199: if (!legacy.contains(pckName))
200: crisp.add(pckName);
201: // System.out.println("Documented: " + className);
202: } else if (legacyProprietary.contains(pckName)) {
203: addLegacyAnnotation = true;
204: // System.out.println("Legacy proprietary: " + className);
205: } else {
206: // System.out.println("Hidden " + className);
207: hiddenPackages.add(pckName);
208: continue;
209: }
210: TypeSymbol sym = (TypeSymbol) compiler
211: .resolveIdent(className);
212: if (sym.kind != Kinds.TYP) {
213: if (className.indexOf('$') < 0) {
214: System.err.println("Ignoring (other) " + className
215: + " : " + sym);
216: System.err.println(" "
217: + sym.getClass().getSimpleName() + " "
218: + sym.type);
219: }
220: continue;
221: }
222: sym.complete();
223: if (sym.getEnclosingElement().getKind() != ElementKind.PACKAGE) {
224: System.err.println("Ignoring (bad) "
225: + sym.getQualifiedName());
226: continue;
227: }
228: ClassSymbol cs = (ClassSymbol) sym;
229: if (addLegacyAnnotation) {
230: cs.attributes_field = (cs.attributes_field == null) ? List
231: .of(proprietary)
232: : cs.attributes_field.prepend(proprietary);
233: }
234: writeClass(pool, cs, writer);
235: }
236:
237: if (false) {
238: for (String pckName : crisp)
239: System.out.println("Crisp: " + pckName);
240: for (String pckName : hiddenPackages)
241: System.out.println("Hidden: " + pckName);
242: for (String pckName : legacyProprietary)
243: System.out.println("Legacy proprietary: " + pckName);
244: for (String pckName : documented)
245: System.out.println("Documented: " + pckName);
246: }
247: }
248:
249: void writeClass(final Pool pool, final ClassSymbol cs,
250: final ClassWriter writer) throws IOException {
251: try {
252: pool.reset();
253: cs.pool = pool;
254: writer.writeClass(cs);
255: for (Scope.Entry e = cs.members().elems; e != null; e = e.sibling) {
256: if (e.sym.kind == Kinds.TYP) {
257: ClassSymbol nestedClass = (ClassSymbol) e.sym;
258: nestedClass.complete();
259: writeClass(pool, nestedClass, writer);
260: }
261: }
262: } catch (ClassWriter.StringOverflow ex) {
263: throw new RuntimeException(ex);
264: } catch (ClassWriter.PoolOverflow ex) {
265: throw new RuntimeException(ex);
266: }
267: }
268:
269: public SourceVersion getSupportedSourceVersion() {
270: return SourceVersion.latest();
271: }
272:
273: // used for debugging
274: public static void main(String... args) {
275: String rt_jar = args[0];
276: String dest = args[1];
277: args = new String[] {
278: "-Xbootclasspath:" + rt_jar,
279: "-XDprocess.packages",
280: "-proc:only",
281: "-processor",
282: "com.sun.tools.javac.sym.CreateSymbols",
283: "-Acom.sun.tools.javac.sym.Jar=" + rt_jar,
284: "-Acom.sun.tools.javac.sym.Dest=" + dest,
285: // <editor-fold defaultstate="collapsed">
286: "java.applet", "java.awt", "java.awt.color",
287: "java.awt.datatransfer", "java.awt.dnd",
288: "java.awt.event", "java.awt.font", "java.awt.geom",
289: "java.awt.im", "java.awt.im.spi", "java.awt.image",
290: "java.awt.image.renderable", "java.awt.print",
291: "java.beans", "java.beans.beancontext", "java.io",
292: "java.lang", "java.lang.annotation",
293: "java.lang.instrument", "java.lang.management",
294: "java.lang.ref", "java.lang.reflect", "java.math",
295: "java.net", "java.nio", "java.nio.channels",
296: "java.nio.channels.spi", "java.nio.charset",
297: "java.nio.charset.spi", "java.rmi",
298: "java.rmi.activation", "java.rmi.dgc",
299: "java.rmi.registry", "java.rmi.server",
300: "java.security", "java.security.acl",
301: "java.security.cert", "java.security.interfaces",
302: "java.security.spec", "java.sql", "java.text",
303: "java.text.spi", "java.util", "java.util.concurrent",
304: "java.util.concurrent.atomic",
305: "java.util.concurrent.locks", "java.util.jar",
306: "java.util.logging", "java.util.prefs",
307: "java.util.regex", "java.util.spi", "java.util.zip",
308: "javax.accessibility", "javax.activation",
309: "javax.activity", "javax.annotation",
310: "javax.annotation.processing", "javax.crypto",
311: "javax.crypto.interfaces", "javax.crypto.spec",
312: "javax.imageio", "javax.imageio.event",
313: "javax.imageio.metadata", "javax.imageio.plugins.jpeg",
314: "javax.imageio.plugins.bmp", "javax.imageio.spi",
315: "javax.imageio.stream", "javax.jws", "javax.jws.soap",
316: "javax.lang.model", "javax.lang.model.element",
317: "javax.lang.model.type", "javax.lang.model.util",
318: "javax.management", "javax.management.loading",
319: "javax.management.monitor",
320: "javax.management.relation",
321: "javax.management.openmbean", "javax.management.timer",
322: "javax.management.modelmbean",
323: "javax.management.remote",
324: "javax.management.remote.rmi", "javax.naming",
325: "javax.naming.directory", "javax.naming.event",
326: "javax.naming.ldap", "javax.naming.spi", "javax.net",
327: "javax.net.ssl", "javax.print",
328: "javax.print.attribute",
329: "javax.print.attribute.standard", "javax.print.event",
330: "javax.rmi", "javax.rmi.CORBA", "javax.rmi.ssl",
331: "javax.script", "javax.security.auth",
332: "javax.security.auth.callback",
333: "javax.security.auth.kerberos",
334: "javax.security.auth.login", "javax.security.auth.spi",
335: "javax.security.auth.x500", "javax.security.cert",
336: "javax.security.sasl", "javax.sound.sampled",
337: "javax.sound.sampled.spi", "javax.sound.midi",
338: "javax.sound.midi.spi", "javax.sql",
339: "javax.sql.rowset", "javax.sql.rowset.serial",
340: "javax.sql.rowset.spi", "javax.swing",
341: "javax.swing.border", "javax.swing.colorchooser",
342: "javax.swing.filechooser", "javax.swing.event",
343: "javax.swing.table", "javax.swing.text",
344: "javax.swing.text.html",
345: "javax.swing.text.html.parser", "javax.swing.text.rtf",
346: "javax.swing.tree", "javax.swing.undo",
347: "javax.swing.plaf", "javax.swing.plaf.basic",
348: "javax.swing.plaf.metal", "javax.swing.plaf.multi",
349: "javax.swing.plaf.synth", "javax.tools",
350: "javax.transaction", "javax.transaction.xa",
351: "javax.xml.parsers", "javax.xml.bind",
352: "javax.xml.bind.annotation",
353: "javax.xml.bind.annotation.adapters",
354: "javax.xml.bind.attachment", "javax.xml.bind.helpers",
355: "javax.xml.bind.util", "javax.xml.soap",
356: "javax.xml.ws", "javax.xml.ws.handler",
357: "javax.xml.ws.handler.soap", "javax.xml.ws.http",
358: "javax.xml.ws.soap", "javax.xml.ws.spi",
359: "javax.xml.transform", "javax.xml.transform.sax",
360: "javax.xml.transform.dom", "javax.xml.transform.stax",
361: "javax.xml.transform.stream", "javax.xml",
362: "javax.xml.crypto", "javax.xml.crypto.dom",
363: "javax.xml.crypto.dsig", "javax.xml.crypto.dsig.dom",
364: "javax.xml.crypto.dsig.keyinfo",
365: "javax.xml.crypto.dsig.spec", "javax.xml.datatype",
366: "javax.xml.validation", "javax.xml.namespace",
367: "javax.xml.xpath", "javax.xml.stream",
368: "javax.xml.stream.events", "javax.xml.stream.util",
369: "org.ietf.jgss", "org.omg.CORBA",
370: "org.omg.CORBA.DynAnyPackage",
371: "org.omg.CORBA.ORBPackage",
372: "org.omg.CORBA.TypeCodePackage",
373: "org.omg.stub.java.rmi", "org.omg.CORBA.portable",
374: "org.omg.CORBA_2_3", "org.omg.CORBA_2_3.portable",
375: "org.omg.CosNaming",
376: "org.omg.CosNaming.NamingContextExtPackage",
377: "org.omg.CosNaming.NamingContextPackage",
378: "org.omg.SendingContext", "org.omg.PortableServer",
379: "org.omg.PortableServer.CurrentPackage",
380: "org.omg.PortableServer.POAPackage",
381: "org.omg.PortableServer.POAManagerPackage",
382: "org.omg.PortableServer.ServantLocatorPackage",
383: "org.omg.PortableServer.portable",
384: "org.omg.PortableInterceptor",
385: "org.omg.PortableInterceptor.ORBInitInfoPackage",
386: "org.omg.Messaging", "org.omg.IOP",
387: "org.omg.IOP.CodecFactoryPackage",
388: "org.omg.IOP.CodecPackage", "org.omg.Dynamic",
389: "org.omg.DynamicAny",
390: "org.omg.DynamicAny.DynAnyPackage",
391: "org.omg.DynamicAny.DynAnyFactoryPackage",
392: "org.w3c.dom", "org.w3c.dom.events",
393: "org.w3c.dom.bootstrap", "org.w3c.dom.ls",
394: "org.xml.sax", "org.xml.sax.ext",
395: "org.xml.sax.helpers", "com.sun.java.browser.dom",
396: "org.w3c.dom", "org.w3c.dom.bootstrap",
397: "org.w3c.dom.ls", "org.w3c.dom.ranges",
398: "org.w3c.dom.traversal", "org.w3c.dom.html",
399: "org.w3c.dom.stylesheets", "org.w3c.dom.css",
400: "org.w3c.dom.events", "org.w3c.dom.views",
401: "com.sun.management", "com.sun.security.auth",
402: "com.sun.security.auth.callback",
403: "com.sun.security.auth.login",
404: "com.sun.security.auth.module",
405: "com.sun.security.jgss", "com.sun.net.httpserver",
406: "com.sun.net.httpserver.spi", "javax.smartcardio"
407: // </editor-fold>
408: };
409: com.sun.tools.javac.Main.compile(args);
410: }
411:
412: }
|