build/annotationProcessors/AnnotationProcessor.java

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 package org.mozilla.gecko.annotationProcessors;
michael@0 6
michael@0 7 import org.mozilla.gecko.annotationProcessors.classloader.AnnotatableEntity;
michael@0 8 import org.mozilla.gecko.annotationProcessors.classloader.ClassWithOptions;
michael@0 9 import org.mozilla.gecko.annotationProcessors.classloader.IterableJarLoadingURLClassLoader;
michael@0 10 import org.mozilla.gecko.annotationProcessors.utils.GeneratableElementIterator;
michael@0 11
michael@0 12 import java.io.FileOutputStream;
michael@0 13 import java.io.IOException;
michael@0 14 import java.util.Arrays;
michael@0 15 import java.util.Iterator;
michael@0 16
michael@0 17 public class AnnotationProcessor {
michael@0 18 public static final String OUTFILE = "GeneratedJNIWrappers.cpp";
michael@0 19 public static final String HEADERFILE = "GeneratedJNIWrappers.h";
michael@0 20
michael@0 21 public static final String GENERATED_COMMENT =
michael@0 22 "// GENERATED CODE\n" +
michael@0 23 "// Generated by the Java program at /build/annotationProcessors at compile time from\n" +
michael@0 24 "// annotations on Java methods. To update, change the annotations on the corresponding Java\n" +
michael@0 25 "// methods and rerun the build. Manually updating this file will cause your build to fail.\n\n";
michael@0 26
michael@0 27 public static void main(String[] args) {
michael@0 28 // We expect a list of jars on the commandline. If missing, whinge about it.
michael@0 29 if (args.length <= 1) {
michael@0 30 System.err.println("Usage: java AnnotationProcessor jarfiles ...");
michael@0 31 System.exit(1);
michael@0 32 }
michael@0 33
michael@0 34 System.out.println("Processing annotations...");
michael@0 35
michael@0 36 // We want to produce the same output as last time as often as possible. Ordering of
michael@0 37 // generated statements, therefore, needs to be consistent.
michael@0 38 Arrays.sort(args);
michael@0 39
michael@0 40 // Start the clock!
michael@0 41 long s = System.currentTimeMillis();
michael@0 42
michael@0 43 // Get an iterator over the classes in the jar files given...
michael@0 44 Iterator<ClassWithOptions> jarClassIterator = IterableJarLoadingURLClassLoader.getIteratorOverJars(args);
michael@0 45
michael@0 46 StringBuilder headerFile = new StringBuilder(GENERATED_COMMENT);
michael@0 47 headerFile.append("#ifndef GeneratedJNIWrappers_h__\n" +
michael@0 48 "#define GeneratedJNIWrappers_h__\n\n" +
michael@0 49 "#include \"nsXPCOMStrings.h\"\n" +
michael@0 50 "#include \"AndroidJavaWrappers.h\"\n" +
michael@0 51 "\n" +
michael@0 52 "namespace mozilla {\n" +
michael@0 53 "namespace widget {\n" +
michael@0 54 "namespace android {\n" +
michael@0 55 "void InitStubs(JNIEnv *jEnv);\n\n");
michael@0 56
michael@0 57 StringBuilder implementationFile = new StringBuilder(GENERATED_COMMENT);
michael@0 58 implementationFile.append("#include \"GeneratedJNIWrappers.h\"\n" +
michael@0 59 "#include \"AndroidBridgeUtilities.h\"\n" +
michael@0 60 "#include \"nsXPCOMStrings.h\"\n" +
michael@0 61 "#include \"AndroidBridge.h\"\n" +
michael@0 62 "\n" +
michael@0 63 "namespace mozilla {\n" +
michael@0 64 "namespace widget {\n" +
michael@0 65 "namespace android {\n");
michael@0 66
michael@0 67 // Used to track the calls to the various class-specific initialisation functions.
michael@0 68 StringBuilder stubInitialiser = new StringBuilder();
michael@0 69 stubInitialiser.append("void InitStubs(JNIEnv *jEnv) {\n");
michael@0 70
michael@0 71 while (jarClassIterator.hasNext()) {
michael@0 72 ClassWithOptions aClassTuple = jarClassIterator.next();
michael@0 73
michael@0 74 CodeGenerator generatorInstance;
michael@0 75
michael@0 76 // Get an iterator over the appropriately generated methods of this class
michael@0 77 Iterator<AnnotatableEntity> methodIterator = new GeneratableElementIterator(aClassTuple.wrappedClass);
michael@0 78
michael@0 79 if (!methodIterator.hasNext()) {
michael@0 80 continue;
michael@0 81 }
michael@0 82 generatorInstance = new CodeGenerator(aClassTuple.wrappedClass, aClassTuple.generatedName);
michael@0 83
michael@0 84 stubInitialiser.append(" ").append(aClassTuple.generatedName).append("::InitStubs(jEnv);\n");
michael@0 85
michael@0 86 // Iterate all annotated members in this class..
michael@0 87 while (methodIterator.hasNext()) {
michael@0 88 AnnotatableEntity aElementTuple = methodIterator.next();
michael@0 89 switch (aElementTuple.mEntityType) {
michael@0 90 case METHOD:
michael@0 91 generatorInstance.generateMethod(aElementTuple);
michael@0 92 break;
michael@0 93 case FIELD:
michael@0 94 generatorInstance.generateField(aElementTuple);
michael@0 95 break;
michael@0 96 case CONSTRUCTOR:
michael@0 97 generatorInstance.generateConstructor(aElementTuple);
michael@0 98 break;
michael@0 99 }
michael@0 100 }
michael@0 101
michael@0 102 headerFile.append(generatorInstance.getHeaderFileContents());
michael@0 103 implementationFile.append(generatorInstance.getWrapperFileContents());
michael@0 104 }
michael@0 105
michael@0 106 implementationFile.append('\n');
michael@0 107 stubInitialiser.append("}");
michael@0 108 implementationFile.append(stubInitialiser);
michael@0 109
michael@0 110 implementationFile.append("\n} /* android */\n" +
michael@0 111 "} /* widget */\n" +
michael@0 112 "} /* mozilla */\n");
michael@0 113
michael@0 114 headerFile.append("\n} /* android */\n" +
michael@0 115 "} /* widget */\n" +
michael@0 116 "} /* mozilla */\n" +
michael@0 117 "#endif\n");
michael@0 118
michael@0 119 writeOutputFiles(headerFile, implementationFile);
michael@0 120 long e = System.currentTimeMillis();
michael@0 121 System.out.println("Annotation processing complete in " + (e - s) + "ms");
michael@0 122 }
michael@0 123
michael@0 124 private static void writeOutputFiles(StringBuilder aHeaderFile, StringBuilder aImplementationFile) {
michael@0 125 FileOutputStream headerStream = null;
michael@0 126 try {
michael@0 127 headerStream = new FileOutputStream(OUTFILE);
michael@0 128 headerStream.write(aImplementationFile.toString().getBytes());
michael@0 129 } catch (IOException e) {
michael@0 130 System.err.println("Unable to write " + OUTFILE + ". Perhaps a permissions issue?");
michael@0 131 e.printStackTrace(System.err);
michael@0 132 } finally {
michael@0 133 if (headerStream != null) {
michael@0 134 try {
michael@0 135 headerStream.close();
michael@0 136 } catch (IOException e) {
michael@0 137 System.err.println("Unable to close headerStream due to "+e);
michael@0 138 e.printStackTrace(System.err);
michael@0 139 }
michael@0 140 }
michael@0 141 }
michael@0 142
michael@0 143 FileOutputStream outStream = null;
michael@0 144 try {
michael@0 145 outStream = new FileOutputStream(HEADERFILE);
michael@0 146 outStream.write(aHeaderFile.toString().getBytes());
michael@0 147 } catch (IOException e) {
michael@0 148 System.err.println("Unable to write " + HEADERFILE + ". Perhaps a permissions issue?");
michael@0 149 e.printStackTrace(System.err);
michael@0 150 } finally {
michael@0 151 if (outStream != null) {
michael@0 152 try {
michael@0 153 outStream.close();
michael@0 154 } catch (IOException e) {
michael@0 155 System.err.println("Unable to close outStream due to "+e);
michael@0 156 e.printStackTrace(System.err);
michael@0 157 }
michael@0 158 }
michael@0 159 }
michael@0 160 }
michael@0 161 }

mercurial