001/**
002 * Copyright (c) 2015-2022, Michael Yang 杨福海 (fuhai999@gmail.com).
003 * <p>
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 * <p>
008 * http://www.apache.org/licenses/LICENSE-2.0
009 * <p>
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package io.jboot.codegen.service;
017
018import com.jfinal.core.JFinal;
019import com.jfinal.kit.JavaKeyword;
020import com.jfinal.kit.Kv;
021import com.jfinal.kit.StrKit;
022import com.jfinal.plugin.activerecord.generator.MetaBuilder;
023import com.jfinal.plugin.activerecord.generator.TableMeta;
024import com.jfinal.template.Engine;
025import com.jfinal.template.source.ClassPathSourceFactory;
026import io.jboot.codegen.CodeGenHelpler;
027
028import java.io.File;
029import java.io.FileOutputStream;
030import java.io.IOException;
031import java.io.OutputStreamWriter;
032import java.util.HashMap;
033import java.util.List;
034import java.util.Map;
035
036public class JbootServiceImplGenerator {
037
038    private String basePackage;
039    private String implPackage;
040    private String modelPackage;
041
042    private MetaBuilder metaBuilder;
043
044    private String template;
045    private String implName = "impl";
046    private String outputDir;
047
048
049    public JbootServiceImplGenerator(String basePackage, String modelPackage) {
050
051        this.basePackage = basePackage;
052        this.modelPackage = modelPackage;
053        this.template = "io/jboot/codegen/service/service_impl_template.tp";
054        this.metaBuilder = CodeGenHelpler.createMetaBuilder();
055        this.outputDir = buildOutPutDir();
056
057    }
058    public JbootServiceImplGenerator(String basePackage,String implPackage,String outputDir ,String modelPackage) {
059
060        this.basePackage = basePackage;
061        this.implPackage = implPackage;
062        this.modelPackage = modelPackage;
063        this.template = "io/jboot/codegen/service/service_impl_template.tp";
064        this.metaBuilder = CodeGenHelpler.createMetaBuilder();
065        this.outputDir = outputDir;
066
067    }
068
069    private String buildOutPutDir() {
070        return CodeGenHelpler.getUserDir() + "/src/main/java/" + (basePackage + "." + implName).replace(".", "/");
071    }
072
073
074    public void generate() {
075        generate(metaBuilder.build());
076    }
077
078    /**
079     * 设置需要被移除的表名前缀
080     * 例如表名  "tb_account",移除前缀 "tb_" 后变为 "account"
081     */
082    public JbootServiceImplGenerator setRemovedTableNamePrefixes(String... prefixes) {
083        metaBuilder.setRemovedTableNamePrefixes(prefixes);
084        return this;
085    }
086
087    public JbootServiceImplGenerator addExcludedTable(String... excludedTables) {
088        metaBuilder.addExcludedTable(excludedTables);
089        return this;
090    }
091
092    public JbootServiceImplGenerator addWhitelist(String... tableNames) {
093        if (tableNames != null) {
094            this.metaBuilder.addWhitelist(tableNames);
095        }
096        return this;
097    }
098    
099    public JbootServiceImplGenerator setGenerateRemarks(boolean generateRemarks) {
100        metaBuilder.setGenerateRemarks(generateRemarks);
101        return this;
102    }
103
104    public JbootServiceImplGenerator setImplName(String implName) {
105        this.implName = implName;
106        return this;
107    }
108
109    public void generate(List<TableMeta> tableMetas) {
110        System.out.println("Generate Service Impl ...");
111        System.out.println("Service Impl Output Dir: " + outputDir);
112
113        Engine engine = Engine.create("forServiceImpl");
114        engine.setSourceFactory(new ClassPathSourceFactory());
115        engine.addSharedMethod(new StrKit());
116        engine.addSharedObject("getterTypeMap", getterTypeMap);
117        engine.addSharedObject("javaKeyword", JavaKeyword.me);
118
119        for (TableMeta tableMeta : tableMetas) {
120            genBaseModelContent(tableMeta);
121        }
122        writeToFile(tableMetas);
123    }
124
125
126    protected void genBaseModelContent(TableMeta tableMeta) {
127        Kv data = Kv.by("serviceImplPackageName", implPackage == null ? (basePackage + "." + implName) : implPackage);
128//        data.set("generateChainSetter", generateChainSetter);
129        data.set("tableMeta", tableMeta);
130        data.set("basePackage", basePackage);
131        data.set("modelPackage", modelPackage);
132        data.set("implName", implName);
133
134        Engine engine = Engine.use("forServiceImpl");
135        tableMeta.baseModelContent = engine.getTemplate(template).renderToString(data);
136    }
137
138
139    protected void writeToFile(List<TableMeta> tableMetas) {
140        try {
141            for (TableMeta tableMeta : tableMetas) {
142                writeToFile(tableMeta);
143            }
144        } catch (IOException e) {
145            throw new RuntimeException(e);
146        }
147    }
148
149    /**
150     * base model 覆盖写入
151     */
152    protected void writeToFile(TableMeta tableMeta) throws IOException {
153        File dir = new File(outputDir);
154        if (!dir.exists()) {
155            dir.mkdirs();
156        }
157
158        String target =outputDir + File.separator + tableMeta.modelName + "Service" + StrKit.firstCharToUpperCase(implName) + ".java";
159
160        File targetFile = new File(target);
161        if (targetFile.exists()) {
162            return;
163        }
164
165        try (OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(target), JFinal.me().getConstants().getEncoding())) {
166            osw.write(tableMeta.baseModelContent);
167        }
168
169    }
170
171
172    protected Map<String, String> getterTypeMap = new HashMap<String, String>() {{
173        put("java.lang.String", "getStr");
174        put("java.lang.Integer", "getInt");
175        put("java.lang.Long", "getLong");
176        put("java.lang.Double", "getDouble");
177        put("java.lang.Float", "getFloat");
178        put("java.lang.Short", "getShort");
179        put("java.lang.Byte", "getByte");
180    }};
181}