/** * Copyright (c) 2011-2017, James Zhan 詹波 (jfinal@126.com). * * 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.jfinal.plugin.activerecord.generator; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.util.List; import com.jfinal.kit.JavaKeyword; import com.jfinal.kit.StrKit; /** * Base model 生成器 */ public class BaseModelGenerator { protected String packageTemplate = "package %s;%n%n"; protected String importTemplate = "import com.jfinal.plugin.activerecord.Model;%n" + "import com.jfinal.plugin.activerecord.IBean;%n%n"; protected String classDefineTemplate = "/**%n" + " * Generated by JFinal, do not modify this file.%n" + " */%n" + "@SuppressWarnings(\"serial\")%n" + "public abstract class %s<M extends %s<M>> extends Model<M> implements IBean {%n%n"; protected String classDefineForSetterChainTemplate = "/**%n" + " * Generated by JFinal, do not modify this file.%n" + " */%n" + "@SuppressWarnings({\"serial\", \"unchecked\"})%n" + "public abstract class %s<M extends %s<M>> extends Model<M> implements IBean {%n%n"; protected String setterTemplate = "\tpublic void %s(%s %s) {%n" + "\t\tset(\"%s\", %s);%n" + "\t}%n%n"; protected String setterChainTemplate = "\tpublic M %s(%s %s) {%n" + "\t\tset(\"%s\", %s);%n" + "\t\treturn (M)this;%n" + "\t}%n%n"; protected String getterTemplate = "\tpublic %s %s() {%n" + "\t\treturn get(\"%s\");%n" + "\t}%n%n"; protected String baseModelPackageName; protected String baseModelOutputDir; protected boolean generateChainSetter = false; protected JavaKeyword javaKeyword = JavaKeyword.me; public BaseModelGenerator(String baseModelPackageName, String baseModelOutputDir) { if (StrKit.isBlank(baseModelPackageName)) { throw new IllegalArgumentException("baseModelPackageName can not be blank."); } if (baseModelPackageName.contains("/") || baseModelPackageName.contains("\\")) { throw new IllegalArgumentException("baseModelPackageName error : " + baseModelPackageName); } if (StrKit.isBlank(baseModelOutputDir)) { throw new IllegalArgumentException("baseModelOutputDir can not be blank."); } this.baseModelPackageName = baseModelPackageName; this.baseModelOutputDir = baseModelOutputDir; } public void setGenerateChainSetter(boolean generateChainSetter) { this.generateChainSetter = generateChainSetter; } public void generate(List<TableMeta> tableMetas) { System.out.println("Generate base model ..."); System.out.println("Base Model Output Dir: " + baseModelOutputDir); for (TableMeta tableMeta : tableMetas) { genBaseModelContent(tableMeta); } writeToFile(tableMetas); } protected void genBaseModelContent(TableMeta tableMeta) { StringBuilder ret = new StringBuilder(); genPackage(ret); genImport(ret); genClassDefine(tableMeta, ret); for (ColumnMeta columnMeta : tableMeta.columnMetas) { genSetMethodName(columnMeta, ret); genGetMethodName(columnMeta, ret); } ret.append(String.format("}%n")); tableMeta.baseModelContent = ret.toString(); } protected void genPackage(StringBuilder ret) { ret.append(String.format(packageTemplate, baseModelPackageName)); } protected void genImport(StringBuilder ret) { ret.append(String.format(importTemplate)); } protected void genClassDefine(TableMeta tableMeta, StringBuilder ret) { String template = generateChainSetter ? classDefineForSetterChainTemplate : classDefineTemplate; ret.append(String.format(template, tableMeta.baseModelName, tableMeta.baseModelName)); } protected void genSetMethodName(ColumnMeta columnMeta, StringBuilder ret) { String setterMethodName = "set" + StrKit.firstCharToUpperCase(columnMeta.attrName); // 如果 setter 参数名为 java 语言关键字,则添加下划线前缀 "_" String argName = javaKeyword.contains(columnMeta.attrName) ? "_" + columnMeta.attrName : columnMeta.attrName; String template = generateChainSetter ? setterChainTemplate : setterTemplate; String setter = String.format(template, setterMethodName, columnMeta.javaType, argName, columnMeta.name, argName); ret.append(setter); } protected void genGetMethodName(ColumnMeta columnMeta, StringBuilder ret) { String getterMethodName = "get" + StrKit.firstCharToUpperCase(columnMeta.attrName); String getter = String.format(getterTemplate, columnMeta.javaType, getterMethodName, columnMeta.name); ret.append(getter); } protected void writeToFile(List<TableMeta> tableMetas) { try { for (TableMeta tableMeta : tableMetas) { writeToFile(tableMeta); } } catch (IOException e) { throw new RuntimeException(e); } } /** * base model 覆盖写入 */ protected void writeToFile(TableMeta tableMeta) throws IOException { File dir = new File(baseModelOutputDir); if (!dir.exists()) { dir.mkdirs(); } String target = baseModelOutputDir + File.separator + tableMeta.baseModelName + ".java"; FileWriter fw = new FileWriter(target); try { fw.write(tableMeta.baseModelContent); } finally { fw.close(); } } }