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.

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

mercurial