package com.github.apigcc.core; import com.github.apigcc.core.common.helper.StringHelper; import com.github.apigcc.core.parser.ParserStrategy; import com.github.apigcc.core.parser.VisitorParser; import com.github.apigcc.core.render.ProjectRender; import com.github.apigcc.core.resolver.TypeResolvers; import com.github.apigcc.core.schema.Project; import com.github.javaparser.ParseResult; import com.github.javaparser.ParserConfiguration; import com.github.javaparser.ast.CompilationUnit; import com.github.javaparser.symbolsolver.JavaSymbolSolver; import com.github.javaparser.utils.SourceRoot; import com.google.common.collect.Iterables; import lombok.Getter; import lombok.extern.slf4j.Slf4j; import java.io.IOException; import java.nio.file.Path; import java.util.Objects; import java.util.ServiceLoader; @Slf4j public class Apigcc { private static Apigcc INSTANCE; public static Apigcc getInstance() { return INSTANCE; } @Getter private Context context; @Getter private Project project = new Project(); private VisitorParser visitorParser = new VisitorParser(); private ParserConfiguration parserConfiguration = new ParserConfiguration(); @Getter private TypeResolvers typeResolvers = new TypeResolvers(); private Apigcc() { init(new Context()); } public Apigcc(Context context) { init(context); } /** * 初始化环境配置 * * @param context */ private void init(Context context) { INSTANCE = this; this.context = context; this.project.init(this.context); ParserStrategy strategy = this.loadParserStrategy(); strategy.onLoad(); this.visitorParser.setParserStrategy(strategy); this.parserConfiguration.setSymbolResolver(new JavaSymbolSolver(this.context.buildTypeSolver())); } /** * 加载并设置解析框架 * null时,使用读取到的第一个框架解析器 * 找不到时,报错 */ private ParserStrategy loadParserStrategy() { ServiceLoader<ParserStrategy> serviceLoader = ServiceLoader.load(ParserStrategy.class); if (Iterables.isEmpty(serviceLoader)) { throw new IllegalArgumentException("no com.apigcc.core.parser.ParserStrategy implements found"); } if (StringHelper.isBlank(context.framework)) { return Iterables.get(serviceLoader, 0); } for (ParserStrategy strategy : serviceLoader) { if (Objects.equals(context.framework, strategy.name())) { return strategy; } } throw new IllegalArgumentException("no com.github.apigcc.core.parser.ParserStrategy implements found for " + context.framework); } /** * 解析源代码 * * @return */ public Project parse() { for (Path source : this.context.getSources()) { SourceRoot root = new SourceRoot(source, parserConfiguration); try { for (ParseResult<CompilationUnit> result : root.tryToParse()) { if (result.isSuccessful() && result.getResult().isPresent()) { result.getResult().get().accept(visitorParser, project); } } } catch (IOException e) { log.warn("parse root {} error {}", source, e.getMessage()); } } return project; } /** * 渲染解析结果 */ public void render() { for (ProjectRender render : this.context.getRenders()) { render.render(project); } } }