Android Open Source - storm-gen Entity Processor






From Project

Back to project page storm-gen.

License

The source code is released under:

Apache License

If you think the Android project storm-gen 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

/*******************************************************************************
 * Copyright 2012 Google, Inc./*from ww w  .  j  av a2 s .c o  m*/
 *
 * 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.
 ******************************************************************************/
package com.turbomanage.storm.apt.entity;

import java.util.List;
import java.util.Set;

import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.MirroredTypeException;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;

import com.turbomanage.storm.SQLiteDao;
import com.turbomanage.storm.api.Entity;
import com.turbomanage.storm.api.Id;
import com.turbomanage.storm.apt.BaseDaoModel;
import com.turbomanage.storm.apt.ClassProcessor;
import com.turbomanage.storm.apt.SqlUtil;
import com.turbomanage.storm.apt.StormEnvironment;
import com.turbomanage.storm.apt.converter.ConverterModel;
import com.turbomanage.storm.apt.database.DatabaseModel;
import com.turbomanage.storm.exception.TypeNotSupportedException;

public class EntityProcessor extends ClassProcessor {

    private static final String TAG = EntityProcessor.class.getName();
    private EntityModel entityModel;

    public EntityProcessor(Element el, StormEnvironment stormEnv) {
        super(el, stormEnv);
    }

    @Override
    public EntityModel getModel() {
        return this.entityModel;
    }

    @Override
    public void populateModel() {
        // TODO make more elegant
        Entity entity = this.typeElement.getAnnotation(Entity.class);
        if (entity != null) {
            this.entityModel = new EntityModel(entity);
        } else {
            javax.persistence.Entity jpaEntity = this.typeElement.getAnnotation(javax.persistence.Entity.class);
            if (jpaEntity != null) {
                this.entityModel = new EntityModel(jpaEntity);
            }
        }
        super.populateModel();
        this.entityModel.addImport(getQualifiedClassName());
        validateTableName(entityModel.getTableName());
        chooseDatabase(entityModel.getDbName());
        chooseBaseDao(entity);
        readFields(typeElement);
        inspectId();
        // TODO Verify >1 column. If only ID col, insert() will fail
    }

    private void validateTableName(String tableName) {
        if (tableName != null && tableName.length() > 0) {
            this.entityModel.setTableName(tableName);
        } else {
            this.entityModel.setTableName(getClassName());
        }
        if (!SqlUtil.isValidIdentifier(this.entityModel.getTableName())) {
            abort(tableName + " is not a valid identifier. Enclose SQL keywords with [].");
        }
    }

    protected void chooseBaseDao(Entity entity) {
        BaseDaoModel baseDao = getBaseDaoClass(entity);
        this.entityModel.setBaseDaoClass(baseDao);
    }

    protected void chooseDatabase(String dbName) {
        DatabaseModel defaultDb = stormEnv.getDefaultDb();
        if (dbName != null && dbName.length() > 0) {
            // Add db to entity model and vice versa
            DatabaseModel db = stormEnv.getDbByName(dbName);
            if (db != null) {
                this.entityModel.setDatabase(db);
            } else {
                abort("There is no @Database named " + dbName);
            }
        } else if (defaultDb != null) {
            this.entityModel.setDatabase(defaultDb);
        } else {
            abort("You must define at least one @Database");
        }
    }

    @Override
    protected void inspectField(VariableElement field) {
        Set<Modifier> modifiers = field.getModifiers();
        boolean hasId = (field.getAnnotation(Id.class) != null);
        String fieldName = field.getSimpleName().toString();
        if (!SqlUtil.isValidIdentifier(field.getSimpleName().toString())) {
            abort(fieldName + " is not a valid SQL column name.");
        }
        if (!modifiers.contains(Modifier.TRANSIENT) && !modifiers.contains(Modifier.STATIC)) {
            String javaType = getFieldType(field);
            if (TypeKind.DECLARED.equals(field.asType().getKind())) {
                DeclaredType type = (DeclaredType) field.asType();
                TypeElement typeElement = (TypeElement) type.asElement();
                TypeMirror superclass = typeElement.getSuperclass();
                if (ElementKind.ENUM.equals(typeElement.getKind())) {
                    if (hasId) {
                        abort("@Id invalid on enums", field);
                    } else {
                        FieldModel fm = new FieldModel(field.getSimpleName().toString(), javaType, true, stormEnv.getConverterForType("java.lang.Enum"));
                        entityModel.addField(fm);
                    }
                    return;
                }
            }
            // Verify supported type
            try {
                ConverterModel converter = stormEnv.getConverterForType(javaType);
                FieldModel f = new FieldModel(field.getSimpleName().toString(), javaType, false, converter);
                if (hasId) {
                    if (entityModel.getIdField() == null) {
                        if ("long".equals(f.getJavaType())) {
                            entityModel.setIdField(f);
                        } else {
                            abort("@Id field must be of type long", field);
                        }
                    } else {
                        abort("Duplicate @Id", field);
                    }
                }
                entityModel.addField(f);
            } catch (TypeNotSupportedException e) {
                stormEnv.getLogger().error(TAG + "inspectField", e, field);
            } catch (Exception e) {
                stormEnv.getLogger().error(TAG, e, field);
            }
            // TODO verify getter + setter
        } else if (hasId) {
            abort("@Id fields cannot be transient", field);
        }
    }

    /**
     * Verifies that the entity has exactly one id field of type long.
     */
    private void inspectId() {
        if (entityModel.getIdField() == null) {
            // Default to field named "id"
            List<FieldModel> fields = entityModel.getFields();
            for (FieldModel f : fields) {
                if (EntityModel.DEFAULT_ID_FIELD.equals(f.getFieldName())) {
                    entityModel.setIdField(f);
                }
            }
        }
        FieldModel idField = entityModel.getIdField();
        if (idField != null && "long".equals(idField.getJavaType())) {
            return;
        } else {
            abort("Entity must contain a field named id or annotated with @Id of type long");
        }
    }

    /**
     * Trying to get Class<?> from an annotation raises an exception
     * see http://stackoverflow.com/questions/7687829/java-6-annotation-processing-getting-a-class-from-an-annotation
     */
    private static TypeMirror getBaseDaoTypeMirror(Entity entity) {
        if(entity != null) {
            try {
                entity.baseDaoClass();
            } catch (MirroredTypeException mte) {
                return mte.getTypeMirror();
            }
        }
        return null;
    }

    /**
     * Builds a BaseDaoModel from the class passed as attribute baseDaoClass of the annotation Entity
     * @param entity
     * @return BaseDaoModel containing the package name + Class name
     */
    private static BaseDaoModel getBaseDaoClass(Entity entity) {
        String qualifiedName = SQLiteDao.class.getName();
        TypeMirror typeMirror = getBaseDaoTypeMirror(entity);
        if(typeMirror != null) qualifiedName = typeMirror.toString();
        return new BaseDaoModel(qualifiedName);
    }
}




Java Source Code List

com.turbomanage.storm.DatabaseHelper.java
com.turbomanage.storm.ModelBase.java
com.turbomanage.storm.SQLiteDao.java
com.turbomanage.storm.TableHelper.java
com.turbomanage.storm.api.Converter.java
com.turbomanage.storm.api.DatabaseFactory.java
com.turbomanage.storm.api.Database.java
com.turbomanage.storm.api.Entity.java
com.turbomanage.storm.api.Id.java
com.turbomanage.storm.api.Syncable.java
com.turbomanage.storm.api.package-info.java
com.turbomanage.storm.apt.BaseDaoModel.java
com.turbomanage.storm.apt.ClassModel.java
com.turbomanage.storm.apt.ClassProcessor.java
com.turbomanage.storm.apt.ClassTemplate.java
com.turbomanage.storm.apt.MainProcessor.java
com.turbomanage.storm.apt.ProcessorLogger.java
com.turbomanage.storm.apt.SqlUtil.java
com.turbomanage.storm.apt.StormAnnotationException.java
com.turbomanage.storm.apt.StormEnvironment.java
com.turbomanage.storm.apt.converter.ConverterModel.java
com.turbomanage.storm.apt.converter.ConverterProcessor.java
com.turbomanage.storm.apt.converter.ConverterTypeAnnotationValueVisitor.java
com.turbomanage.storm.apt.converter.ConverterTypeAnnotationValuesVisitor.java
com.turbomanage.storm.apt.converter.package-info.java
com.turbomanage.storm.apt.database.DatabaseFactoryTemplate.java
com.turbomanage.storm.apt.database.DatabaseModel.java
com.turbomanage.storm.apt.database.DatabaseProcessor.java
com.turbomanage.storm.apt.database.package-info.java
com.turbomanage.storm.apt.entity.EntityDaoTemplate.java
com.turbomanage.storm.apt.entity.EntityModel.java
com.turbomanage.storm.apt.entity.EntityProcessor.java
com.turbomanage.storm.apt.entity.FieldModel.java
com.turbomanage.storm.apt.entity.TableHelperTemplate.java
com.turbomanage.storm.apt.entity.package-info.java
com.turbomanage.storm.csv.CsvTableReader.java
com.turbomanage.storm.csv.CsvTableWriter.java
com.turbomanage.storm.csv.CsvUtils.java
com.turbomanage.storm.csv.package-info.java
com.turbomanage.storm.exception.TooManyResultsException.java
com.turbomanage.storm.exception.TypeNotSupportedException.java
com.turbomanage.storm.exception.package-info.java
com.turbomanage.storm.query.Query.java
com.turbomanage.storm.query.package-info.java
com.turbomanage.storm.sample.activity.ContactActivity.java
com.turbomanage.storm.sample.activity.NewContactActivity.java
com.turbomanage.storm.sample.adapter.ContactAdapter.java
com.turbomanage.storm.sample.database.SampleDatabaseHelper.java
com.turbomanage.storm.sample.loader.AbstractAsyncTaskLoader.java
com.turbomanage.storm.sample.loader.ContactLoader.java
com.turbomanage.storm.sample.model.Contact.java
com.turbomanage.storm.types.BlobConverter.java
com.turbomanage.storm.types.BooleanConverter.java
com.turbomanage.storm.types.ByteConverter.java
com.turbomanage.storm.types.CharConverter.java
com.turbomanage.storm.types.DateConverter.java
com.turbomanage.storm.types.DoubleConverter.java
com.turbomanage.storm.types.EnumConverter.java
com.turbomanage.storm.types.FloatConverter.java
com.turbomanage.storm.types.IntegerConverter.java
com.turbomanage.storm.types.LongConverter.java
com.turbomanage.storm.types.PrimitiveConverter.java
com.turbomanage.storm.types.ShortConverter.java
com.turbomanage.storm.types.StringConverter.java
com.turbomanage.storm.types.TypeConverter.java
com.turbomanage.storm.types.package-info.java
com.turbomanage.storm.package-info.java