Android Open Source - GenDbHandler Gen Db Handler Annotation Processor






From Project

Back to project page GenDbHandler.

License

The source code is released under:

Open Data Commons ? Public Domain Dedication & Licence (PDDL) Preamble The Open Data Commons ? Public Domain Dedication & Licence is a document intended to allow you to freely share, modify, an...

If you think the Android project GenDbHandler listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package net.cattaka.util.gendbhandler.apt;
// w  w  w  .  j  ava2  s.  c  om
import static javax.lang.model.util.ElementFilter.typesIn;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Filer;
import javax.annotation.processing.Messager;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.ArrayType;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.MirroredTypeException;
import javax.lang.model.type.PrimitiveType;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.ElementFilter;
import javax.lang.model.util.SimpleTypeVisitor6;
import javax.tools.Diagnostic.Kind;
import javax.tools.JavaFileObject;

import net.cattaka.util.gendbhandler.Attribute;
import net.cattaka.util.gendbhandler.Attribute.FieldType;
import net.cattaka.util.gendbhandler.GenDbHandler;
import net.cattaka.util.gendbhandler.GenDbHandler.NamingConventions;

@SupportedSourceVersion(SourceVersion.RELEASE_6)
@SupportedAnnotationTypes("net.cattaka.util.gendbhandler.*")
public class GenDbHandlerAnnotationProcessor extends AbstractProcessor {
    static enum Target {
        DB, PARCEL, CONTENT_RESOLVER
    }

    static class EnvironmentBundle {
        GenDbHandler genDbHandler;

        Map<String, FieldEntry> fieldEntryMap;

        List<FieldEntry> fieldEntries;

        List<FindEntry> findList;

        List<UniqueEntry> uniqueList;
    }

    static class FindEntriesPerVersion implements Comparable<FindEntriesPerVersion> {
        long version;

        List<FieldEntry> fieldEntries;

        @Override
        public int compareTo(FindEntriesPerVersion o) {
            return (int)(this.version - o.version);
        }
    }

    static class FieldEntry {
        EnumSet<Target> targets = EnumSet.noneOf(Target.class);

        boolean primaryKey = false;

        String name = null;

        String columnName = null;

        String constantsColumnName = null;

        InnerFieldType fieldType = InnerFieldType.STRING;

        String fieldClass;

        String nullValue;

        String customParser;

        FieldType customDataType = FieldType.STRING;

        long version = 1;
    }

    static class OrderByEntry extends FieldEntry {
        boolean desc;

        public OrderByEntry(FieldEntry fe, boolean desc) {
            super();
            this.targets = fe.targets;
            this.primaryKey = fe.primaryKey;
            this.name = fe.name;
            this.columnName = fe.columnName;
            this.fieldType = fe.fieldType;
            this.fieldClass = fe.fieldClass;
            this.customParser = fe.customParser;
            this.customDataType = fe.customDataType;
            this.version = fe.version;
            this.desc = desc;
        }
    }

    static class FindEntry {
        List<FieldEntry> columns;

        List<OrderByEntry> orderBy;
    }

    static class UniqueEntry {
        List<FieldEntry> columns;
    }

    static class MyTypeVisitor extends SimpleTypeVisitor6<Void, Void> {
        private DeclaredType declaredType;

        private DeclaredType enumType;

        private ArrayType arrayType;

        private PrimitiveType primitiveType;

        @Override
        public Void visitDeclared(DeclaredType t, Void p) {
            TypeElement element = (TypeElement)t.asElement();

            TypeMirror tm = element.getSuperclass();
            if (Enum.class.getName().equals(pickQualifiedName(tm))) {
                enumType = t;
                return super.visitDeclared(t, p);
            }
            declaredType = t;
            return super.visitDeclared(t, p);
        }

        @Override
        public Void visitArray(ArrayType t, Void p) {
            arrayType = t;
            return super.visitArray(t, p);
        }

        @Override
        public Void visitPrimitive(PrimitiveType t, Void p) {
            primitiveType = t;
            return super.visitPrimitive(t, p);
        }

        public String getQualifiedName() {
            if (primitiveType != null) {
                return pickQualifiedName(primitiveType);
            } else if (arrayType != null) {
                return pickQualifiedName(arrayType);
            } else if (enumType != null) {
                return pickQualifiedName(enumType);
            } else if (declaredType != null) {
                return pickQualifiedName(declaredType);
            } else {
                return null;
            }
        }
    }

    @Override
    public synchronized void init(ProcessingEnvironment processingEnv) {
        super.init(processingEnv);
    }

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        for (TypeElement element : typesIn(roundEnv.getElementsAnnotatedWith(GenDbHandler.class))) {
            processElement(element);
        }
        return true;
    }

    public void processElement(TypeElement srcElement) {
        Messager messager = processingEnv.getMessager();
        GenDbHandler genDbHandler = srcElement.getAnnotation(GenDbHandler.class);

        String className = srcElement.getSimpleName().toString();
        String qualifiedName = srcElement.getQualifiedName().toString();
        String packageName = qualifiedName.substring(0, qualifiedName.length() - className.length()
                - 1);
        String cprPackageName = packageName + ".handler";
        String cprClassName = className + "Handler";

        EnvironmentBundle bundle = new EnvironmentBundle();
        {
            bundle.genDbHandler = genDbHandler;
            bundle.fieldEntries = pickFieldDeclaration(srcElement, messager, genDbHandler);
            { // fieldEntryMap:name->fieldEntyr???????
                Map<String, FieldEntry> feMap = new HashMap<String, FieldEntry>();
                for (FieldEntry fe : bundle.fieldEntries) {
                    feMap.put(fe.name, fe);
                }
                bundle.fieldEntryMap = feMap;
            }
            bundle.findList = createFindEntries(srcElement, genDbHandler.find(), bundle, messager);
            bundle.uniqueList = createUniqueEntries(srcElement, genDbHandler.unique(), bundle,
                    messager);
        }

        try {
            Filer filer = processingEnv.getFiler();
            JavaFileObject fileObject = filer.createSourceFile(cprPackageName + "." + cprClassName,
                    srcElement);
            PrintWriter pw = new PrintWriter(fileObject.openWriter());
            pw.println("package " + cprPackageName + ";");
            pw.println("import net.cattaka.util.gendbhandler.Accessor;");
            if (genDbHandler.genDbFunc() || genDbHandler.genContentResolverFunc()) {
                pw.println("import android.content.ContentValues;");
                pw.println("import android.database.Cursor;");
            }
            if (genDbHandler.genDbFunc()) {
                pw.println("import android.database.sqlite.SQLiteDatabase;");
            }
            if (genDbHandler.genContentResolverFunc()) {
                pw.println("import android.content.ContentResolver;");
                pw.println("import android.net.Uri;");
            }
            if (genDbHandler.genParcelFunc()) {
                pw.println("import android.os.Parcel;");
                pw.println("import android.os.Parcelable;");
            }
            pw.println("import " + packageName + "." + className + ";");
            pw.println();
            pw.println("public class " + cprClassName + " {");

            if (genDbHandler.genDbFunc() || genDbHandler.genContentResolverFunc()) {
                writeCursorFunc(messager, pw, bundle, srcElement, genDbHandler, className);
            }
            if (genDbHandler.genDbFunc()) {
                writeDbFunc(messager, pw, bundle, srcElement, genDbHandler, className);
            }
            if (genDbHandler.genContentResolverFunc()) {
                writeContentResolverFunc(messager, pw, bundle, srcElement, genDbHandler, className);
            }
            if (genDbHandler.genParcelFunc()) {
                writeParcelFunc(messager, pw, bundle, srcElement, genDbHandler, className);
            }

            pw.println("}");
            pw.close();
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }

    public void writeCursorFunc(Messager messager, PrintWriter pw, EnvironmentBundle bundle,
            TypeElement td, GenDbHandler genDbHandler, String className) throws IOException {
        String tableName = convertName(genDbHandler.tableNamingConventions(), className);

        List<FieldEntry> targetFieldEntries = new ArrayList<GenDbHandlerAnnotationProcessor.FieldEntry>();
        for (FieldEntry fe : bundle.fieldEntries) {
            if (fe.targets.contains(Target.DB)) {
                targetFieldEntries.add(fe);
            }
        }

        List<FindEntriesPerVersion> findEntriesPerVersions;
        {
            Map<Long, FindEntriesPerVersion> findEntriesPerVersionMap = new TreeMap<Long, FindEntriesPerVersion>();
            for (FieldEntry fe : targetFieldEntries) {
                FindEntriesPerVersion item = findEntriesPerVersionMap.get(fe.version);
                if (item == null) {
                    item = new FindEntriesPerVersion();
                    item.version = fe.version;
                    item.fieldEntries = new ArrayList<FieldEntry>();
                    findEntriesPerVersionMap.put(fe.version, item);
                }
                item.fieldEntries.add(fe);
            }
            findEntriesPerVersions = new ArrayList<FindEntriesPerVersion>(
                    findEntriesPerVersionMap.values());
        }
        pw.println("    public static final String SQL_CREATE_TABLE = \""
                + createCreateStatement(tableName, bundle) + "\";");
        if (findEntriesPerVersions.size() > 1) {
            FindEntriesPerVersion lastItem = findEntriesPerVersions.get(0);
            for (int i = 1; i < findEntriesPerVersions.size(); i++) {
                FindEntriesPerVersion nextItem = findEntriesPerVersions.get(i);
                List<String> sqls = createAlterTableStatements(tableName, nextItem);
                pw.println("    public static final String[] SQL_ALTER_TABLE_" + lastItem.version
                        + "_TO_" + nextItem.version + " = new String[] {");
                for (String sql : sqls) {
                    pw.println("        \"" + sql + "\",");
                }
                pw.println("    };");
                lastItem = nextItem;
            }
        }
        pw.println("    public static final String TABLE_NAME = \"" + tableName + "\";");
        pw.println("    public static final String COLUMNS = \"" + createColumns(bundle, Target.DB)
                + "\";");
        pw.println("    public static final String[] COLUMNS_ARRAY = new String[] {"
                + createColumnsArray(bundle, Target.DB) + "};");

        if (genDbHandler.columnIndexConstants()) {
            int index = 0;
            for (FieldEntry fe : targetFieldEntries) {
                pw.println("    public static final int COL_INDEX_" + fe.constantsColumnName
                        + " = " + index + ";");
                index++;
            }
        }
        if (genDbHandler.columnNameConstants()) {
            for (FieldEntry fe : targetFieldEntries) {
                pw.println("    public static final String COL_NAME_" + fe.constantsColumnName
                        + " = \"" + fe.columnName + "\";");
            }
        }
        {
            pw.println("    public static void readCursorByIndex(Cursor cursor, " + className
                    + " dest) {");
            {
                int index = 0;
                for (FieldEntry fe : targetFieldEntries) {
                    String readFromCursor = String.format(fe.fieldType.readFromCursor, "cursor",
                            String.valueOf(index), fe.nullValue, fe.fieldClass);
                    pw.println("        "
                            + String.format(fe.fieldType.setterBlock, "dest",
                                    convertCap(fe.name, true), readFromCursor) + ";");
                    index++;
                }
            }
            pw.println("    }");
        }
        {
            pw.println("    public static " + className + " readCursorByIndex(Cursor cursor) {");
            pw.println("        " + className + " result = new " + className + "();");
            pw.println("        readCursorByIndex(cursor, result);");
            pw.println("        return result;");
            pw.println("    }");
        }
        {
            pw.println("    public static void readCursorByName(Cursor cursor, " + className
                    + " dest) {");
            pw.println("        int idx;");
            {
                // int index = 0;
                for (FieldEntry fe : targetFieldEntries) {
                    pw.println("        idx = cursor.getColumnIndex(\"" + fe.columnName + "\");");
                    String readFromCursor = String.format(fe.fieldType.readFromCursor, "cursor",
                            "idx", fe.nullValue, fe.fieldClass);
                    pw.println("        "
                            + String.format(fe.fieldType.setterBlock, "dest",
                                    convertCap(fe.name, true), readFromCursor) + ";");

                    // index++;
                }
            }
            pw.println("    }");
        }
        {
            pw.println("    public static " + className + " readCursorByName(Cursor cursor) {");
            pw.println("        " + className + " result = new " + className + "();");
            pw.println("        readCursorByName(cursor, result);");
            pw.println("        return result;");
            pw.println("    }");
            pw.println("    public static String toStringValue(Object arg) {");
            pw.println("        return (arg != null) ? arg.toString() : null;");
            pw.println("    }");
        }
    }

    public void writeDbFunc(Messager messager, PrintWriter pw, EnvironmentBundle bundle,
            TypeElement td, GenDbHandler genDbHandler, String className) throws IOException {
        List<FieldEntry> targetFieldEntries = new ArrayList<GenDbHandlerAnnotationProcessor.FieldEntry>();
        for (FieldEntry fe : bundle.fieldEntries) {
            if (fe.targets.contains(Target.DB)) {
                targetFieldEntries.add(fe);
            }
        }

        FieldEntry keyFieldEntry = null;
        { // Check existence of PRIMARY KEY (Only 1 key is supported.)
            int primaryKeyCount = 0;
            for (FieldEntry fe : targetFieldEntries) {
                if (fe.primaryKey) {
                    primaryKeyCount++;
                    keyFieldEntry = fe;
                }
            }
            if (primaryKeyCount == 0) {
                messager.printMessage(
                        Kind.ERROR,
                        "At least one primary key is required. put @Attribute(primaryKey=true) to field of key",
                        td);
            } else if (primaryKeyCount > 1) {
                messager.printMessage(Kind.ERROR, "Only single primary key is supported.", td);
            }
        }

        {// Insert
            pw.println("    public static long insert(SQLiteDatabase db, " + className
                    + " model) {");
            pw.println("        ContentValues values = new ContentValues();");
            for (FieldEntry fe : targetFieldEntries) {
                if (genDbHandler.autoinclement() && fe.primaryKey) {
                    continue;
                }
                String getterBlock = String.format(fe.fieldType.getterBlock, "model",
                        convertCap(fe.name, true));
                pw.println("        "
                        + String.format(fe.fieldType.putToContentValue, "values", "\""
                                + fe.columnName + "\"", getterBlock) + ";");
            }
            pw.println("        long key = db.insert(TABLE_NAME, null, values);");
            String cast = (!"long".equals(keyFieldEntry.fieldClass)) ? ("("
                    + keyFieldEntry.fieldClass + ")") : "";
            if (genDbHandler.autoinclement()) {
                pw.println("        "
                        + String.format(keyFieldEntry.fieldType.setterBlock, "model",
                                convertCap(keyFieldEntry.name, true), cast + "key") + ";");
            }
            pw.println("        return key;");
            pw.println("    }");
        }
        {// Update
            pw.println("    public static int update(SQLiteDatabase db, " + className + " model) {");
            pw.println("        ContentValues values = new ContentValues();");
            pw.println("        String whereClause = \"" + keyFieldEntry.columnName + "=?\";");
            pw.println("        String[] whereArgs = new String[]{String.valueOf("
                    + String.format(keyFieldEntry.fieldType.getterBlock, "model",
                            convertCap(keyFieldEntry.name, true)) + ")};");
            for (FieldEntry fe : targetFieldEntries) {
                if (!fe.primaryKey) {
                    String getterBlock = String.format(fe.fieldType.getterBlock, "model",
                            convertCap(fe.name, true));
                    pw.println("        "
                            + String.format(fe.fieldType.putToContentValue, "values", "\""
                                    + fe.columnName + "\"", getterBlock) + ";");
                }
            }
            pw.println("        return db.update(TABLE_NAME, values, whereClause, whereArgs);");
            pw.println("    }");
        }
        {// Delete
            pw.println("    public static int delete(SQLiteDatabase db, "
                    + keyFieldEntry.fieldClass + " key) {");
            pw.println("        String whereClause = \"" + keyFieldEntry.columnName + "=?\";");
            pw.println("        String[] whereArgs = new String[]{String.valueOf(key)};");
            pw.println("        return db.delete(TABLE_NAME, whereClause, whereArgs);");
            pw.println("    }");
        }
        {// Find
            for (FindEntry findEntry : bundle.findList) {
                if (checkUnique(findEntry, bundle.uniqueList)) {
                    pw.println("    public static " + className + " "
                            + createMethodName(findEntry, false) + "(SQLiteDatabase db"
                            + createMethodArg(findEntry, true) + ") {");
                    pw.println("        Cursor cursor = " + createMethodName(findEntry, true)
                            + "(db" + createMethodArg(findEntry, false) + ");");
                    pw.println("        " + className
                            + " model = (cursor.moveToNext()) ? readCursorByIndex(cursor) : null;");
                    pw.println("        cursor.close();");
                    pw.println("        return model;");
                    pw.println("    }");
                } else {
                    pw.println("    public static java.util.List<" + className + "> "
                            + createMethodName(findEntry, false) + "(SQLiteDatabase db, int limit"
                            + createMethodArg(findEntry, true) + ") {");
                    pw.println("        Cursor cursor = " + createMethodName(findEntry, true)
                            + "(db, limit" + createMethodArg(findEntry, false) + ");");
                    pw.println("        java.util.List<" + className
                            + "> result = new java.util.ArrayList<" + className + ">();");
                    pw.println("        while (cursor.moveToNext()) {");
                    pw.println("            result.add(readCursorByIndex(cursor));");
                    pw.println("        }");
                    pw.println("        cursor.close();");
                    pw.println("        return result;");
                    pw.println("    }");
                }
            }
            for (FindEntry findEntry : bundle.findList) {
                if (checkUnique(findEntry, bundle.uniqueList)) {
                    pw.println("    public static Cursor " + createMethodName(findEntry, true)
                            + "(SQLiteDatabase db" + createMethodArg(findEntry, true) + ") {");
                    pw.println("        String selection = \"" + createSelection(findEntry) + "\";");
                    pw.println("        String[] selectionArgs = new String[]{"
                            + createSelectionArgs(findEntry) + "};");
                    pw.println("        return db.query(TABLE_NAME, COLUMNS_ARRAY, selection, selectionArgs, null, null, null);");
                    pw.println("    }");
                } else {
                    String orderBy = createOrderBy(findEntry);
                    pw.println("    public static Cursor " + createMethodName(findEntry, true)
                            + "(SQLiteDatabase db, int limit" + createMethodArg(findEntry, true)
                            + ") {");
                    pw.println("        String selection = \"" + createSelection(findEntry) + "\";");
                    pw.println("        String[] selectionArgs = new String[]{"
                            + createSelectionArgs(findEntry) + "};");
                    pw.println("        String limitStr = (limit > 0) ? String.valueOf(limit) : null;");
                    if (orderBy.length() > 0) {
                        pw.println("        String orderBy = \"" + createOrderBy(findEntry) + "\";");
                        pw.println("        return db.query(TABLE_NAME, COLUMNS_ARRAY, selection, selectionArgs, null, null, orderBy, limitStr);");
                    } else {
                        pw.println("        return db.query(TABLE_NAME, COLUMNS_ARRAY, selection, selectionArgs, null, null, null, limitStr);");
                    }
                    pw.println("    }");
                }
            }
        }
    }

    public void writeContentResolverFunc(Messager messager, PrintWriter pw,
            EnvironmentBundle bundle, TypeElement td, GenDbHandler genDbHandler, String className)
            throws IOException {
        List<FieldEntry> targetFieldEntries = new ArrayList<GenDbHandlerAnnotationProcessor.FieldEntry>();
        for (FieldEntry fe : bundle.fieldEntries) {
            if (fe.targets.contains(Target.CONTENT_RESOLVER)) {
                targetFieldEntries.add(fe);
            }
        }

        FieldEntry keyFieldEntry = null;
        { // Check existence of PRIMARY KEY (Only 1 key is supported.)
            int primaryKeyCount = 0;
            for (FieldEntry fe : targetFieldEntries) {
                if (fe.primaryKey) {
                    primaryKeyCount++;
                    keyFieldEntry = fe;
                }
            }
            if (primaryKeyCount == 0) {
                messager.printMessage(
                        Kind.ERROR,
                        "At least one primary key is required. put @Attribute(primaryKey=true) to field of key",
                        td);
            } else if (primaryKeyCount > 1) {
                messager.printMessage(Kind.ERROR, "Only single primary key is supported.", td);
            }
        }

        {// Insert
            pw.println("    public static Uri insert(ContentResolver resolver, Uri uri, "
                    + className + " model) {");
            pw.println("        ContentValues values = new ContentValues();");
            for (FieldEntry fe : targetFieldEntries) {
                if (genDbHandler.autoinclement() && fe.primaryKey) {
                    continue;
                }
                String getterBlock = String.format(fe.fieldType.getterBlock, "model",
                        convertCap(fe.name, true));
                pw.println("        "
                        + String.format(fe.fieldType.putToContentValue, "values", "\""
                                + fe.columnName + "\"", getterBlock) + ";");
            }
            pw.println("        return resolver.insert(uri, values);");
            pw.println("    }");
        }
        {// Update
            pw.println("    public static int update(ContentResolver resolver, Uri uri, "
                    + className + " model) {");
            pw.println("        ContentValues values = new ContentValues();");
            pw.println("        String whereClause = \"" + keyFieldEntry.columnName + "=?\";");
            pw.println("        String[] whereArgs = new String[]{String.valueOf("
                    + String.format(keyFieldEntry.fieldType.getterBlock, "model",
                            convertCap(keyFieldEntry.name, true)) + ")};");
            for (FieldEntry fe : targetFieldEntries) {
                if (!fe.primaryKey) {
                    String getterBlock = String.format(fe.fieldType.getterBlock, "model",
                            convertCap(fe.name, true));
                    pw.println("        "
                            + String.format(fe.fieldType.putToContentValue, "values", "\""
                                    + fe.columnName + "\"", getterBlock) + ";");
                }
            }
            pw.println("        return resolver.update(uri, values, whereClause, whereArgs);");
            pw.println("    }");
        }
        {// Delete
            pw.println("    public static int delete(ContentResolver resolver, Uri uri, "
                    + keyFieldEntry.fieldClass + " key) {");
            pw.println("        String whereClause = \"" + keyFieldEntry.columnName + "=?\";");
            pw.println("        String[] whereArgs = new String[]{String.valueOf(key)};");
            pw.println("        return resolver.delete(uri, whereClause, whereArgs);");
            pw.println("    }");
        }
        {// Find
            for (FindEntry findEntry : bundle.findList) {
                if (checkUnique(findEntry, bundle.uniqueList)) {
                    pw.println("    public static " + className + " "
                            + createMethodName(findEntry, false)
                            + "(ContentResolver resolver, Uri uri"
                            + createMethodArg(findEntry, true) + ") {");
                    pw.println("        Cursor cursor = " + createMethodName(findEntry, true)
                            + "(resolver, uri" + createMethodArg(findEntry, false) + ");");
                    pw.println("        " + className
                            + " model = (cursor.moveToNext()) ? readCursorByIndex(cursor) : null;");
                    pw.println("        cursor.close();");
                    pw.println("        return model;");
                    pw.println("    }");
                } else {
                    pw.println("    public static java.util.List<" + className + "> "
                            + createMethodName(findEntry, false)
                            + "(ContentResolver resolver, Uri uri"
                            + createMethodArg(findEntry, true) + ") {");
                    pw.println("        Cursor cursor = " + createMethodName(findEntry, true)
                            + "(resolver, uri" + createMethodArg(findEntry, false) + ");");
                    pw.println("        java.util.List<" + className
                            + "> result = new java.util.ArrayList<" + className + ">();");
                    pw.println("        while (cursor.moveToNext()) {");
                    pw.println("            result.add(readCursorByIndex(cursor));");
                    pw.println("        }");
                    pw.println("        cursor.close();");
                    pw.println("        return result;");
                    pw.println("    }");
                }
            }
            for (FindEntry findEntry : bundle.findList) {
                if (checkUnique(findEntry, bundle.uniqueList)) {
                    pw.println("    public static Cursor " + createMethodName(findEntry, true)
                            + "(ContentResolver resolver, Uri uri"
                            + createMethodArg(findEntry, true) + ") {");
                    pw.println("        String selection = \"" + createSelection(findEntry) + "\";");
                    pw.println("        String[] selectionArgs = new String[]{"
                            + createSelectionArgs(findEntry) + "};");
                    pw.println("        return resolver.query(uri, COLUMNS_ARRAY, selection, selectionArgs, null);");
                    pw.println("    }");
                } else {
                    String orderBy = createOrderBy(findEntry);
                    pw.println("    public static Cursor " + createMethodName(findEntry, true)
                            + "(ContentResolver resolver, Uri uri"
                            + createMethodArg(findEntry, true) + ") {");
                    pw.println("        String selection = \"" + createSelection(findEntry) + "\";");
                    pw.println("        String[] selectionArgs = new String[]{"
                            + createSelectionArgs(findEntry) + "};");
                    if (orderBy.length() > 0) {
                        pw.println("        String orderBy = \"" + createOrderBy(findEntry) + "\";");
                        pw.println("        return resolver.query(uri, COLUMNS_ARRAY, selection, selectionArgs, orderBy);");
                    } else {
                        pw.println("        return resolver.query(uri, COLUMNS_ARRAY, selection, selectionArgs, null);");
                    }
                    pw.println("    }");
                }
            }
        }
    }

    public void writeParcelFunc(Messager messager, PrintWriter pw, EnvironmentBundle bundle,
            TypeElement td, GenDbHandler genDbHandler, String className) {
        List<FieldEntry> targetFieldEntries = new ArrayList<GenDbHandlerAnnotationProcessor.FieldEntry>();
        for (FieldEntry fe : bundle.fieldEntries) {
            if (fe.targets.contains(Target.PARCEL)) {
                targetFieldEntries.add(fe);
            }
        }

        pw.println("    public static final Parcelable.Creator<" + className
                + "> CREATOR = new Parcelable.Creator<" + className + ">() {");
        pw.println("        @Override");
        pw.println("        public " + className + " createFromParcel(Parcel in) {");
        pw.println("            " + className + " dest = new " + className + "();");
        pw.println("            readFromParcel(dest, in);");
        pw.println("            return dest;");
        pw.println("        }");
        pw.println("        @Override");
        pw.println("        public " + className + "[] newArray(int size) {");
        pw.println("            return new " + className + "[size];");
        pw.println("        }");
        pw.println("    };");

        pw.println("    public static void readFromParcel(" + className + " dest, Parcel in) {");
        for (FieldEntry fe : targetFieldEntries) {
            String readFromParcel = String.format(Locale.ROOT, fe.fieldType.readFromParcel, "in",
                    fe.fieldClass);
            pw.print("        ");
            pw.println("        "
                    + String.format(fe.fieldType.setterBlock, "dest", convertCap(fe.name, true),
                            readFromParcel) + ";");

        }
        pw.println("    }");

        pw.println("    public static void writeToParcel(" + className
                + " src, Parcel out, int flags) {");
        for (FieldEntry fe : targetFieldEntries) {
            String getterBlock = String.format(fe.fieldType.getterBlock, "src",
                    convertCap(fe.name, true));
            pw.println("        " + String.format(fe.fieldType.writeToParcel, "out", getterBlock)
                    + ";");
        }
        pw.println("    }");
    }

    public String createCreateStatement(String tableName, EnvironmentBundle bundle) {
        StringBuilder sb = new StringBuilder();
        sb.append("CREATE TABLE ");
        sb.append(tableName);
        sb.append("(");
        boolean firstFlag = true;
        for (FieldEntry fe : bundle.fieldEntries) {
            if (!fe.targets.contains(Target.DB)) {
                continue;
            }
            if (firstFlag) {
                firstFlag = false;
            } else {
                sb.append(",");
            }
            sb.append(fe.columnName);
            sb.append(" ");
            sb.append(fe.fieldType.dbType);
            if (fe.primaryKey) {
                sb.append(" PRIMARY KEY");
                if (bundle.genDbHandler.autoinclement()) {
                    sb.append(" AUTOINCREMENT");
                }
            }
        }
        for (UniqueEntry entries : bundle.uniqueList) {
            sb.append(",UNIQUE(");
            boolean firstFlag2 = true;
            for (FieldEntry entry : entries.columns) {
                if (firstFlag2) {
                    firstFlag2 = false;
                } else {
                    sb.append(",");
                }
                sb.append(entry.columnName);
            }
            sb.append(")");
        }
        sb.append(")");
        return sb.toString();
    }

    public List<String> createAlterTableStatements(String tableName,
            FindEntriesPerVersion findEntriesPerVersion) {
        List<String> result = new ArrayList<String>();
        for (FieldEntry fe : findEntriesPerVersion.fieldEntries) {
            StringBuilder sb = new StringBuilder();
            sb.append("ALTER TABLE ");
            sb.append(tableName);
            sb.append(" ADD COLUMN ");
            sb.append(fe.columnName);
            sb.append(" ");
            sb.append(fe.fieldType.dbType);
            result.add(sb.toString());
        }
        return result;
    }

    private static String createMethodName(FindEntry findEntry, boolean cursor) {
        StringBuilder sb = new StringBuilder();
        if (cursor) {
            sb.append("findCursor");
        } else {
            sb.append("find");
        }
        {
            boolean firstFlag = true;
            for (FieldEntry fe : findEntry.columns) {
                if (firstFlag) {
                    sb.append("By");
                    firstFlag = false;
                } else {
                    sb.append("And");
                }
                sb.append(convertCap(fe.name, true));
            }
        }
        if (findEntry.orderBy.size() > 0) {
            boolean firstFlag = true;
            for (OrderByEntry fe : findEntry.orderBy) {
                if (firstFlag) {
                    sb.append("OrderBy");
                    firstFlag = false;
                } else {
                    sb.append("And");
                }
                sb.append(convertCap(fe.name, true));
                sb.append((fe.desc) ? "Desc" : "Asc");
            }
        }
        return sb.toString();
    }

    private static String createMethodArg(FindEntry findEntry, boolean withType) {
        StringBuilder sb = new StringBuilder();
        for (FieldEntry fe : findEntry.columns) {
            sb.append(", ");
            if (withType) {
                sb.append(fe.fieldClass);
                sb.append(" ");
            }
            sb.append(fe.name);
        }
        return sb.toString();
    }

    private static String createColumns(EnvironmentBundle bundle, Target target) {
        StringBuilder sb = new StringBuilder();
        for (FieldEntry fe : bundle.fieldEntries) {
            if (!fe.targets.contains(target)) {
                continue;
            }
            if (sb.length() > 0) {
                sb.append(",");
            }
            sb.append(fe.columnName);
        }
        return sb.toString();
    }

    private static String createColumnsArray(EnvironmentBundle bundle, Target target) {
        StringBuilder sb = new StringBuilder();
        for (FieldEntry fe : bundle.fieldEntries) {
            if (!fe.targets.contains(target)) {
                continue;
            }
            if (sb.length() > 0) {
                sb.append(", ");
            }
            sb.append('"' + fe.columnName + '"');
        }
        return sb.toString();
    }

    private static String createSelection(FindEntry findEntry) {
        StringBuilder sb = new StringBuilder();
        for (FieldEntry fe : findEntry.columns) {
            if (sb.length() > 0) {
                sb.append(" AND ");
            }
            sb.append(fe.columnName);
            sb.append("=?");
        }
        return sb.toString();
    }

    private static String createSelectionArgs(FindEntry findEntry) {
        StringBuilder sb = new StringBuilder();
        for (FieldEntry fe : findEntry.columns) {
            if (sb.length() > 0) {
                sb.append(", ");
            }
            sb.append(String.format(fe.fieldType.toStringBlock, fe.name));
        }
        return sb.toString();
    }

    private static String createOrderBy(FindEntry findEntry) {
        StringBuilder sb = new StringBuilder();
        for (OrderByEntry fe : findEntry.orderBy) {
            if (sb.length() > 0) {
                sb.append(", ");
            }
            sb.append(fe.columnName);
            sb.append((fe.desc) ? " desc" : " asc");
        }
        return sb.toString();
    }

    private static boolean checkUnique(FindEntry findEntry, List<UniqueEntry> uniqueEntries) {
        if (findEntry.columns.size() == 0) {
            return false;
        }
        String targetStr = toSortedString(findEntry.columns);
        for (UniqueEntry uniqueEntry : uniqueEntries) {
            String uniqueStr = toSortedString(uniqueEntry.columns);
            if (targetStr.equals(uniqueStr)) {
                return true;
            }
        }
        {
            for (FieldEntry fe : findEntry.columns) {
                if (!fe.primaryKey) {
                    return false;
                }
            }
            return true;
        }
    }

    private static String toSortedString(List<FieldEntry> src) {
        ArrayList<String> tmp = new ArrayList<String>();
        for (FieldEntry fe : src) {
            tmp.add(fe.name);
        }
        Collections.sort(tmp);
        StringBuilder sb = new StringBuilder();
        for (String str : tmp) {
            sb.append(str);
            sb.append(',');
        }
        return sb.toString();
    }

    private static List<UniqueEntry> createUniqueEntries(Element element, String[] srcs,
            EnvironmentBundle bundle, Messager messager) {
        List<UniqueEntry> uniqueEntries = new ArrayList<UniqueEntry>();
        for (String src : srcs) {
            UniqueEntry entry = new UniqueEntry();
            entry.columns = createFieldList(element, src, bundle, messager);
            uniqueEntries.add(entry);
        }
        return uniqueEntries;
    }

    private static List<FindEntry> createFindEntries(Element element, String[] srcs,
            EnvironmentBundle bundle, Messager messager) {
        List<FindEntry> findEntries = new ArrayList<FindEntry>();
        for (String src : srcs) {
            String[] src2 = src.split(":");
            FindEntry entry = new FindEntry();
            entry.columns = createFieldList(element, src2[0], bundle, messager);
            entry.orderBy = (src2.length > 1) ? createOrderByList(element, src2[1], bundle,
                    messager) : new ArrayList<OrderByEntry>();
            findEntries.add(entry);
        }
        return findEntries;
    }

    private static List<FieldEntry> createFieldList(Element element, String src,
            EnvironmentBundle bundle, Messager messager) {
        List<FieldEntry> fieldEntries = new ArrayList<FieldEntry>();
        if (src != null && src.length() > 0) {
            String[] names = src.split(",");
            for (String name : names) {
                name = name.trim();
                FieldEntry fe = bundle.fieldEntryMap.get(name);
                if (fe != null) {
                    fieldEntries.add(fe);
                } else {
                    messager.printMessage(Kind.ERROR, "Field '" + name
                            + "' in fields is not found.", element);
                }
            }
        }
        return fieldEntries;
    }

    private static List<OrderByEntry> createOrderByList(Element element, String src,
            EnvironmentBundle bundle, Messager messager) {
        String[] names = src.split(",");
        List<OrderByEntry> orderByEntries = new ArrayList<OrderByEntry>();
        for (String name : names) {
            name = name.trim();
            boolean desc = false;
            {
                char ch = name.charAt(name.length() - 1);
                if (ch == '+' || ch == '-') {
                    name = name.substring(0, name.length() - 1);
                    desc = (ch == '-');
                }
            }
            FieldEntry fe = bundle.fieldEntryMap.get(name);
            if (fe != null) {
                orderByEntries.add(new OrderByEntry(fe, desc));
            } else {
                messager.printMessage(Kind.ERROR, "Field '" + name + "' in fields is not found.",
                        element);
            }
        }
        return orderByEntries;
    }

    private static List<FieldEntry> pickFieldDeclaration(TypeElement td, Messager messager,
            GenDbHandler genDbHandler) {
        List<FieldEntry> fes = new ArrayList<FieldEntry>();
        List<Element> fds = new ArrayList<Element>(ElementFilter.fieldsIn(Bug300408.getEnclosedElementsDeclarationOrder(td)));
        // Collections.sort(fds, new Comparator<Element>() {
        // @Override
        // public int compare(Element o1, Element o2) {
        //
        // int r = o1.getPosition().line() - o2.getPosition().line();
        // return (r != 0) ? r : (o1.getPosition().column() -
        // o2.getPosition().column());
        // }
        // });

        for (Element fd : fds) {
            FieldEntry fe = new FieldEntry();
            if (fd.getModifiers().contains(Modifier.STATIC)) {
                continue;
            }
            {
                Attribute attribute = fd.getAnnotation(Attribute.class);
                if (attribute != null) {
                    if (attribute.persistent()) {
                        if (attribute.forDb()) {
                            fe.targets.add(Target.DB);
                        }
                        if (attribute.forParcel()) {
                            fe.targets.add(Target.PARCEL);
                        }
                        if (attribute.forContentResolver()) {
                            fe.targets.add(Target.CONTENT_RESOLVER);
                        }
                    } else {
                        // none
                    }
                } else {
                    fe.targets.add(Target.DB);
                    fe.targets.add(Target.PARCEL);
                    fe.targets.add(Target.CONTENT_RESOLVER);
                }
                if (attribute != null) {
                    fe.primaryKey = attribute.primaryKey();
                    fe.customDataType = attribute.customDataType();
                    fe.version = attribute.version();
                    fe.nullValue = attribute.nullValue();
                    try {
                        fe.customParser = attribute.customCoder().toString();
                    } catch (MirroredTypeException expected) {
                        TypeMirror type = expected.getTypeMirror();
                        fe.customParser = type.toString();
                    }
                    if (!attribute.persistent()
                            && !(attribute.forDb() && attribute.forParcel() && attribute
                                    .forContentResolver())
                            && (attribute.forDb() || attribute.forParcel() || attribute
                                    .forContentResolver())) {
                        messager.printMessage(
                                Kind.ERROR,
                                "persistent=false will overwrite forDb, forParcel, forContentResolver as false.",
                                fd);
                    }
                }
            }
            {
                MyTypeVisitor myTypeVisitor = new MyTypeVisitor();
                TypeMirror typeMirror = fd.asType();
                typeMirror.accept(myTypeVisitor, null);
                fe.fieldClass = myTypeVisitor.getQualifiedName();
                if (fe.targets.size() > 0) {
                    findFieldEntry(myTypeVisitor, fe);
                    if (fe.fieldType == null) {
                        messager.printMessage(
                                Kind.ERROR,
                                "Data type is not supported. set persistent=false, or use @customCoder and @customDataType",
                                fd);
                    }
                }
            }
            {
                if (fe.primaryKey && genDbHandler.autoinclement() && !fe.fieldType.isInteger) {
                    messager.printMessage(Kind.ERROR,
                            "use autoinclement=false, or use number type.", fd);
                }
                if (fe.fieldType.isPrimitive
                        && (fe.nullValue == null || fe.nullValue.length() == 0)) {
                    fe.nullValue = fe.fieldType.defaultNullValue;
                } else if (!fe.fieldType.isPrimitive && fe.nullValue != null
                        && fe.nullValue.length() > 0) {
                    messager.printMessage(Kind.ERROR, "nullValue is only for primitive type.", fd);
                }
            }
            {
                fe.name = fd.getSimpleName().toString();
                fe.columnName = convertName(genDbHandler.fieldNamingConventions(), fe.name);
                fe.constantsColumnName = convertName(NamingConventions.UPPER_COMPOSITE, fe.name);
            }
            if (fe.targets.size() > 0) {
                fes.add(fe);
            } else {
                // ignored
            }
        }
        return fes;
    }

    private static String convertName(NamingConventions namingConventions, String src) {
        if (src == null) {
            return null;
        }
        switch (namingConventions) {
            case LOWER_CAMEL_CASE:
                return convertCap(src, false);
            case UPPER_CAMEL_CASE:
                return convertCap(src, true);
            case LOWER_COMPOSITE:
                return camelToComposite(src, false);
            case UPPER_COMPOSITE:
                return camelToComposite(src, true);
        }
        return src;
    }

    private static String camelToComposite(String camel, boolean upperCase) {
        if (camel == null) {
            return null;
        }
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < camel.length(); i++) {
            char ch = camel.charAt(i);
            if (i > 0 && Character.isUpperCase(ch)) {
                sb.append('_');
                sb.append(ch);
            } else {
                sb.append(Character.toUpperCase(ch));
            }
        }
        if (upperCase) {
            return sb.toString().toUpperCase();
        } else {
            return sb.toString().toLowerCase();
        }
    }

    private static String convertCap(String name, boolean upperCase) {
        if (name == null) {
            return null;
        }
        if (name.length() == 0) {
            return name;
        }
        if (upperCase) {
            return name.substring(0, 1).toUpperCase() + name.substring(1);
        } else {
            return name.substring(0, 1).toLowerCase() + name.substring(1);
        }
    }

    private static void findFieldEntry(MyTypeVisitor myTypeVisitor, FieldEntry fe) {
        if (fe.customParser != null && !Object.class.getCanonicalName().equals(fe.customParser)) {
            if (fe.customDataType == FieldType.BLOB) {
                fe.fieldType = InnerFieldType.BLOB;
            } else if (fe.customDataType == FieldType.BOOLEAN) {
                fe.fieldType = InnerFieldType.BOOLEAN;
            } else if (fe.customDataType == FieldType.BYTE) {
                fe.fieldType = InnerFieldType.BYTE;
            } else if (fe.customDataType == FieldType.CHAR) {
                fe.fieldType = InnerFieldType.BLOB;
            } else if (fe.customDataType == FieldType.DOUBLE) {
                fe.fieldType = InnerFieldType.DOUBLE;
            } else if (fe.customDataType == FieldType.FLOAT) {
                fe.fieldType = InnerFieldType.FLOAT;
            } else if (fe.customDataType == FieldType.INTEGER) {
                fe.fieldType = InnerFieldType.INTEGER;
            } else if (fe.customDataType == FieldType.LONG) {
                fe.fieldType = InnerFieldType.LONG;
            } else if (fe.customDataType == FieldType.P_BOOLEAN) {
                fe.fieldType = InnerFieldType.P_BOOLEAN;
            } else if (fe.customDataType == FieldType.P_BYTE) {
                fe.fieldType = InnerFieldType.P_BYTE;
            } else if (fe.customDataType == FieldType.P_CHAR) {
                fe.fieldType = InnerFieldType.P_CHAR;
            } else if (fe.customDataType == FieldType.P_DOUBLE) {
                fe.fieldType = InnerFieldType.P_DOUBLE;
            } else if (fe.customDataType == FieldType.P_FLOAT) {
                fe.fieldType = InnerFieldType.P_FLOAT;
            } else if (fe.customDataType == FieldType.P_INT) {
                fe.fieldType = InnerFieldType.P_INT;
            } else if (fe.customDataType == FieldType.P_LONG) {
                fe.fieldType = InnerFieldType.P_LONG;
            } else if (fe.customDataType == FieldType.P_SHORT) {
                fe.fieldType = InnerFieldType.P_SHORT;
            } else if (fe.customDataType == FieldType.PARCELABLE) {
                fe.fieldType = InnerFieldType.PARCELABLE;
            } else if (fe.customDataType == FieldType.SERIALIZABLE) {
                fe.fieldType = InnerFieldType.SERIALIZABLE;
            } else if (fe.customDataType == FieldType.SHORT) {
                fe.fieldType = InnerFieldType.SHORT;
            } else if (fe.customDataType == FieldType.STRING) {
                fe.fieldType = InnerFieldType.STRING;
            }
            fe.fieldType = new InnerFieldType(fe.fieldType.isInteger, //
                    false, //
                    fe.fieldType.dbType, //
                    fe.fieldType.defaultNullValue, //
                    fe.fieldType.readFromParcel, //
                    fe.fieldType.writeToParcel, //
                    fe.fieldType.readFromCursor, //
                    fe.fieldType.putToContentValue, //
                    String.format(fe.fieldType.toStringBlock, fe.customParser + ".encode(%1$s)"), //
                    fe.customParser + ".encode(%1$s.get%2$s())", "%1$s.set%2$s(" + fe.customParser
                            + ".decode(%3$s))" //
            );
        } else if (myTypeVisitor.arrayType != null) {
            if (myTypeVisitor.arrayType.getComponentType() instanceof PrimitiveType) {
                PrimitiveType pt = (PrimitiveType)myTypeVisitor.arrayType.getComponentType();
                if (pt.getKind() == TypeKind.BYTE) {
                    fe.fieldType = InnerFieldType.BLOB;
                } else {
                    // TODO
                }
            }
        } else if (myTypeVisitor.primitiveType != null) {

            if (myTypeVisitor.primitiveType.getKind() == TypeKind.BOOLEAN) {
                fe.fieldType = InnerFieldType.P_BOOLEAN;
            } else if (myTypeVisitor.primitiveType.getKind() == TypeKind.BYTE) {
                fe.fieldType = InnerFieldType.P_BYTE;
            } else if (myTypeVisitor.primitiveType.getKind() == TypeKind.CHAR) {
                fe.fieldType = InnerFieldType.P_CHAR;
            } else if (myTypeVisitor.primitiveType.getKind() == TypeKind.INT) {
                fe.fieldType = InnerFieldType.P_INT;
            } else if (myTypeVisitor.primitiveType.getKind() == TypeKind.SHORT) {
                fe.fieldType = InnerFieldType.P_SHORT;
            } else if (myTypeVisitor.primitiveType.getKind() == TypeKind.LONG) {
                fe.fieldType = InnerFieldType.P_LONG;
            } else if (myTypeVisitor.primitiveType.getKind() == TypeKind.FLOAT) {
                fe.fieldType = InnerFieldType.P_FLOAT;
            } else if (myTypeVisitor.primitiveType.getKind() == TypeKind.DOUBLE) {
                fe.fieldType = InnerFieldType.P_DOUBLE;
            }
        } else if (myTypeVisitor.enumType != null) {
            fe.fieldType = InnerFieldType.ENUM_NAME;
        } else if (myTypeVisitor.declaredType != null) {
            String qualifiedName = pickQualifiedName(myTypeVisitor.declaredType);
            if (Boolean.class.getName().equals(qualifiedName)) {
                fe.fieldType = InnerFieldType.BOOLEAN;
            } else if (Byte.class.getName().equals(qualifiedName)) {
                fe.fieldType = InnerFieldType.BYTE;
            } else if (Character.class.getName().equals(qualifiedName)) {
                fe.fieldType = InnerFieldType.CHAR;
            } else if (Integer.class.getName().equals(qualifiedName)) {
                fe.fieldType = InnerFieldType.INTEGER;
            } else if (Short.class.getName().equals(qualifiedName)) {
                fe.fieldType = InnerFieldType.SHORT;
            } else if (Long.class.getName().equals(qualifiedName)) {
                fe.fieldType = InnerFieldType.LONG;
            } else if (Float.class.getName().equals(qualifiedName)) {
                fe.fieldType = InnerFieldType.FLOAT;
            } else if (Double.class.getName().equals(qualifiedName)) {
                fe.fieldType = InnerFieldType.DOUBLE;
            } else if (String.class.getName().equals(qualifiedName)) {
                fe.fieldType = InnerFieldType.STRING;
            } else if (byte[].class.getName().equals(qualifiedName)) {
                fe.fieldType = InnerFieldType.BLOB;
            } else if (Date.class.getName().equals(qualifiedName)) {
                fe.fieldType = InnerFieldType.DATE;
            } else {
                TypeElement element = (TypeElement)myTypeVisitor.declaredType.asElement();
                for (TypeMirror tm : element.getInterfaces()) {
                    InnerFieldType origFt = null;
                    if (Serializable.class.getCanonicalName().equals(pickQualifiedName(tm))) {
                        origFt = InnerFieldType.SERIALIZABLE;
                    } else if ("android.os.Parcelable".equals(pickQualifiedName(tm))) {
                        origFt = InnerFieldType.PARCELABLE;
                    }
                    if (origFt != null) {
                        fe.fieldType = new InnerFieldType(origFt.isInteger, false, //
                                origFt.dbType, //
                                origFt.defaultNullValue, //
                                "((" + qualifiedName + ")" + origFt.readFromParcel + ")", //
                                origFt.writeToParcel, //
                                "((" + qualifiedName + ")" + origFt.readFromCursor + ")", //
                                origFt.putToContentValue, //
                                origFt.toStringBlock, //
                                origFt.getterBlock, origFt.setterBlock);
                        break;
                    }
                }
            }
        }
    }

    private static String pickQualifiedName(TypeMirror src) {
        if (src instanceof PrimitiveType) {
            return ((PrimitiveType)src).getKind().name().toLowerCase();
        } else if (src instanceof ArrayType) {
            return pickQualifiedName(((ArrayType)src).getComponentType()) + "[]";
        } else if (src instanceof DeclaredType) {
            TypeElement typeElement = (TypeElement)((DeclaredType)src).asElement();
            return typeElement.getQualifiedName().toString();
        }
        return null;
    }
}




Java Source Code List

net.cattaka.util.genasyncif.AsyncIfAttr.java
net.cattaka.util.genasyncif.AsyncInterfaceException.java
net.cattaka.util.genasyncif.GenAsyncInterface.java
net.cattaka.util.genasyncif.apt.GenAsycInterfaceAnnotationProcessor.java
net.cattaka.util.gendbhandler.Accessor.java
net.cattaka.util.gendbhandler.Attribute.java
net.cattaka.util.gendbhandler.GenDbHandler.java
net.cattaka.util.gendbhandler.apt.Bug300408.java
net.cattaka.util.gendbhandler.apt.Converter.java
net.cattaka.util.gendbhandler.apt.GenDbHandlerAnnotationProcessor.java
net.cattaka.util.gendbhandler.apt.InnerFieldType.java
net.cattaka.util.genparcelfunc.GenParcelFuncAnnotationProcessorFactory.java
net.cattaka.util.genparcelfunc.GenParcelFuncAnnotationProcessor.java
net.cattaka.util.genparcelfunc.GenParcelFuncPlugin.java
net.cattaka.util.genparcelfunc.GenParcelFunc.java
net.cattaka.util.genparcelfunc.ParcelFuncAttr.java