Archive for July, 2013

greenDAO: keep annotations

I am using greenDAO, an “Android ORM for SQLite”, for my last android project.
It seems to be very nice, but I faced a problem. Every time I regenerate the code, the annotations that I put to some methods disappear. I know that there is a pull request to add support for annotations at, but it requires a lot of modifications in greenDAO’s code.

Here is my approach. greenDAO allows you to enable “keep sections” which is a mechanism to avoid your code to be overwritten by the DAO generator tool. These sections are based on regular expressions inside the generated classes. To enable the annotations, I followed the same principle and created a regular expression for annotations based on names given to such annotations. To incorporate this feature, follow the instructions below.

First, add a property to the class:

private Pattern patternKeepAnnotations;

Then, inside the constructor of the class, add the initialization of such property:

// add the following below the line that goes by patternKeepMethods = compilePattern("METHODS");
patternKeepAnnotations = compileNamedPattern("ANNOTATIONS");

Next, define the compileNamedPattern method:

private Pattern compileNamedPattern(String sectionName) {
int flags = Pattern.DOTALL | Pattern.MULTILINE;
return Pattern.compile("//\\s*?KEEP\\s+(\\S*)\\s*" + sectionName + ".*?\n(.*?)^\\s*// KEEP " + sectionName + " END.*?\n", flags);

Finally, in the checkKeepSections method, add the following just before the catch(IOException e) instruction:

matcher = patternKeepAnnotations.matcher(contents);
Map allMatches = new HashMap();
while (matcher.find()) {
root.put("keepAnnotations", allMatches);

That’s all. If you read through the code you would have realized that the annotations are different from the common keep sections in the sense that they need a name. That name is defined in the template.
For example, if you want to have a “keep annotations section” for every property in your class, then modify the entity.ftl file as follows.

Locate the line containing <#list as property>.
After this line the loop of the class’s properties begin.
Now, look for the line that reads public ${property.javaType} get${property.propertyName?cap_first}() {, and add the following code before that line:

<#if entity.hasKeepSections>
// KEEP ${property.propertyName} ANNOTATIONS - put your custom annotations here
${(keepAnnotations[property.propertyName])!} // KEEP ANNOTATIONS END

This code first checks if the keep sections property is enabled.
If so, we will add a keep annotations section, named as the property name (${property.propertyName}), to each property.

I hope this helps you!

You can download the modified files below, in case you want to just add them :)