com.tsc9526.monalisa.orm.generator.DBGeneratorProcessing.java Source code

Java tutorial

Introduction

Here is the source code for com.tsc9526.monalisa.orm.generator.DBGeneratorProcessing.java

Source

/*******************************************************************************************
 *   Copyright (c) 2016, zzg.zhou(11039850@qq.com)
 * 
 *  Monalisa is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Lesser General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
    
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Lesser General Public License for more details.
    
 *   You should have received a copy of the GNU Lesser General Public License
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *******************************************************************************************/
package com.tsc9526.monalisa.orm.generator;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Writer;

import javax.annotation.processing.Filer;
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.MirroredTypeException;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.Types;
import javax.tools.FileObject;
import javax.tools.JavaFileManager.Location;
import javax.tools.JavaFileObject;
import javax.tools.StandardLocation;

import com.tsc9526.monalisa.orm.Version;
import com.tsc9526.monalisa.orm.annotation.DB;
import com.tsc9526.monalisa.orm.datasource.ConfigClass;
import com.tsc9526.monalisa.orm.datasource.DataSourceManager;
import com.tsc9526.monalisa.orm.datasource.DbProp;
import com.tsc9526.monalisa.orm.meta.MetaTable;
import com.tsc9526.monalisa.orm.model.Model;
import com.tsc9526.monalisa.tools.clazz.MelpClass;
import com.tsc9526.monalisa.tools.io.JavaWriter;
import com.tsc9526.monalisa.tools.misc.MelpEclipse;

/**
 * 
 * @author zzg.zhou(11039850@qq.com)
 */
public class DBGeneratorProcessing extends DBGenerator {
    private ProcessingEnvironment processingEnv;
    private TypeElement typeElement;

    DBGeneratorProcessing() {

    }

    public DBGeneratorProcessing(ProcessingEnvironment processingEnv, TypeElement typeElement) {
        super();

        this.processingEnv = processingEnv;
        this.typeElement = typeElement;

        DB db = typeElement.getAnnotation(DB.class);
        if (db == null) {
            throw new RuntimeException("TypeElement without @DB: " + typeElement.toString());
        }
        String dbKey = db.key();
        if (dbKey == null || dbKey.length() < 1) {
            dbKey = typeElement.toString();
        }

        boolean inEclipseIDE = false;
        String projectPath = DbProp.CFG_ROOT_PATH;
        if (MelpEclipse.inEclipseIDE()) {
            if (processingEnv instanceof org.eclipse.jdt.internal.apt.pluggable.core.dispatch.IdeBuildProcessingEnvImpl) {
                org.eclipse.jdt.core.IJavaProject project = ((org.eclipse.jdt.internal.apt.pluggable.core.dispatch.IdeBuildProcessingEnvImpl) processingEnv)
                        .getJavaProject();
                projectPath = project.getProject().getLocation().toString();

                inEclipseIDE = true;

                DbProp.SET_CFG_ROOT_PATH(projectPath);

                plogger.info("Generate(" + Version.getVersion() + ") files from eclipse project: " + projectPath
                        + " ...");
                plogger.info("Database " + dbKey + ", "
                        + (db.configFile().length() > 0 ? ("Config-file: " + db.configFile()) : (db.url())));
            }
        }

        if (!inEclipseIDE) {
            plogger.info("Generate(" + Version.getVersion() + ") files from dbkey: " + dbKey + "("
                    + (db.configFile().length() > 0 ? db.configFile() : db.url()) + "): "
                    + new File(DbProp.CFG_ROOT_PATH).getAbsolutePath() + " ...");
        }

        System.setProperty("DB@" + dbKey, projectPath);

        String name = typeElement.getQualifiedName().toString();
        setJavaResourcePackage(name);

        initDbcfg(dbKey, db);

        this.dbmetadata = new DBMetadata(projectPath, javaPackage, dbcfg);
    }

    protected void initDbcfg(String dbKey, DB db) {
        DataSourceManager dsm = DataSourceManager.getInstance();
        this.dbcfg = dsm.getDBConfig(dbKey, db);

        String cff = db.configFile();
        if (cff != null && cff.startsWith("classpath:")) {
            String resource = cff.substring("classpath:".length());
            if (resource.startsWith("/")) {
                resource = resource.substring(1);
            }

            String pkg = "";
            String relativeName = resource;
            int p = resource.lastIndexOf("/");
            if (p > 0) {
                pkg = resource.substring(0, p).replace('/', '.');
                relativeName = resource.substring(p + 1);
            }

            try {
                File f = tryGetResourceFile(pkg, relativeName);

                String basepath = f.getAbsolutePath().replace('\\', '/');
                basepath = basepath.substring(0, basepath.length() - resource.length());
                dsm.getDBConfig(dbKey, db, basepath);
                dsm.getDBConfig(dbKey, db, true);
            } catch (IOException e) {
                throw new RuntimeException("Failed to read classpath resource: " + resource, e);
            }
        }
    }

    protected File tryGetResourceFile(String pkg, String relativeName) throws IOException {
        Filer filer = processingEnv.getFiler();

        Location[] ls = new Location[] { StandardLocation.CLASS_OUTPUT, StandardLocation.SOURCE_PATH };
        for (Location l : ls) {
            FileObject fo = filer.getResource(l, pkg, relativeName);
            File f = new File(fo.toUri());
            if (f.exists()) {
                return f;
            }
        }

        return null;
    }

    protected OutputStream getResourceOutputStream(String pkg, String filename) {
        try {
            FileObject res = processingEnv.getFiler().createResource(StandardLocation.SOURCE_OUTPUT, pkg, filename,
                    typeElement);
            OutputStream out = res.openOutputStream();

            return out;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    protected Writer getJavaWriter(MetaTable table) {
        try {
            String className = table.getJavaName();
            JavaFileObject java = processingEnv.getFiler().createSourceFile(javaPackage + "." + className,
                    typeElement);
            Writer os = java.openWriter();
            return new JavaWriter(os);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    protected String getModelClassValue(MetaTable table) {
        String modelClass = null;
        try {
            modelClass = super.getModelClassValue(table);

        } catch (MirroredTypeException mte) {
            TypeMirror typeMirror = mte.getTypeMirror();
            Types TypeUtils = processingEnv.getTypeUtils();
            TypeElement te = (TypeElement) TypeUtils.asElement(typeMirror);
            modelClass = te.getQualifiedName().toString();
        }

        if (modelClass == null || modelClass.trim().length() == 0) {
            modelClass = Model.class.getName();
        }

        return modelClass;
    }

    @SuppressWarnings("unchecked")
    public static Class<? extends ConfigClass> getDBConfigClass(DB db) {
        Class<? extends ConfigClass> clazz = null;
        try {
            clazz = db.configClass();
        } catch (MirroredTypeException mte) {
            MirroredTypeException x = (MirroredTypeException) mte;
            DeclaredType classTypeMirror = (DeclaredType) x.getTypeMirror();
            TypeElement classTypeElement = (TypeElement) classTypeMirror.asElement();

            String className = classTypeElement.getQualifiedName().toString();
            try {
                clazz = (Class<? extends ConfigClass>) MelpClass.forName(className);
                plogger.info("Loaded db config from class: " + className);
            } catch (ClassNotFoundException e) {
                plogger.info("Class not found, try load class  from project path: " + className);

                return loadClassFromProject(className);
            }
        }

        return clazz;
    }

    private static Class<? extends ConfigClass> loadClassFromProject(String className) {
        throw new RuntimeException("Class not found: " + className);
    }
}