/Mezzanine

An annotation processor that reads files at compile time

Primary LanguageKotlinApache License 2.0Apache-2.0

Mezzanine

An annotation processor that allows you to read static UTF-8 files synchronously.

Build Status Download codecov

What does this do?

Android apps often need to read in a default configuration file on startup and change functionality based on the contents of the configuration file. A convenient, frequently used way to store this configuration file is in assets, and then to read out of this file on startup. This can mean doing expensive disk I/O on the main thread, which increases startup times. You can get around the additional I/O by pasting the contents of the file into a String constant, but this can make code review difficult.

Mezzanine solves this problem by generating a class at compile time which stores the file contents in a String constant. This is loaded by the class loader, along with your code, when the application is started, rather than requiring additional disk I/O after startup. It acts as an intermediary between files and your running Java code. Instead of needing to paste the contents of the file into the constant yourself, you can store it in its own file and maintain proper separation. For instance, if you are executing JavaScript using a WebView or some library like duktape, you can store the files in .js files without the additional annoyance of needing to perform disk I/O.

Note: There is a hard limit set by the javac compiler where String constants cannot exceed 65535 bytes in size.

Usage

allprojects {
    repositories {
        bintray()
    }
}
Android/Java
def mezzanineVersion = '1.0.0'
compile "com.anthonycr.mezzanine:mezzanine:$mezzanineVersion"
annotationProcessor "com.anthonycr.mezzanine:mezzanine-compiler:$mezzanineVersion"
Kotlin
apply plugin: 'kotlin-kapt'

def mezzanineVersion = '1.0.0'
compile "com.anthonycr.mezzanine:mezzanine:$mezzanineVersion"
kapt "com.anthonycr.mezzanine:mezzanine-compiler:$mezzanineVersion"
Java
plugins {
    id 'net.ltgt.apt' version '0.10'
}

dependencies {
    def mezzanineVersion = '1.0.0'
    compile "com.anthonycr.mezzanine:mezzanine:$mezzanineVersion"
    apt "com.anthonycr.mezzanine:mezzanine-compiler:$mezzanineVersion"
}

API

  • @FileStream(String path): the path to the file relative to the project root.
  • Create an interface with one method with no parameters and a return type of String.
  • Annotate the interface with @FileStream and pass the path to the file as the value in the annotation.
  • Consume the generated implementation of the interface to get the file as a string.
  • Files are assumed to be encoded as UTF-8.
  • Files must be less than 65kB, otherwise compilation will fail.

Sample

Kotlin

@FileStream("path/from/root/to/file.json")
interface MyFileReader {

    fun readMyFile(): String

}
...

val fileReader = MezzanineGenerator.MyFileReader()

val fileContents = fileReader.readMyFile()

println("File contents: $fileContents")

Java

@FileStream("path/from/root/to/file.json")
public interface MyFileReader {

    String readMyFile();

}
...

MyFileReader fileReader = new MezzanineGenerator.MyFileReader();

String fileContents = fileReader.readMyFile();

System.out.println("File contents: " + fileContents);

License

Copyright 2017 Anthony Restaino

Licensed under the Apache License, Version 2.0 (the "License"); you may 
not use this file except in compliance with the License. You may obtain 
a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software 
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 
License for the specific language governing permissions and limitations 
under the License.