package com.wingsofts.mvphelper.biz.file.generator.impl; import com.intellij.ide.fileTemplates.JavaTemplateUtil; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.PsiShortNamesCache; import com.wingsofts.mvphelper.biz.config.MvpConfigurable; import com.wingsofts.mvphelper.biz.config.impl.MvpConfig; import com.wingsofts.mvphelper.biz.file.generator.FileGenerator; import static com.wingsofts.mvphelper.biz.EventLogger.log; /** * The base file generator, provide basic functions for child-class. * * @author Administrator * @since 2017/4/24. */ @SuppressWarnings({"ConstantConditions", "WeakerAccess"}) abstract class BaseFileGenerator implements FileGenerator { // private final org.apache.log4j.Logger logger; protected Project myProject;//current java project protected PsiDirectory myContractDir;//the contract package dir protected PsiDirectory myModelDir;//the model package dir protected PsiDirectory myPresenterDir;//the presenter package dir protected String myPrefix;//the prefix used to identify each other protected PsiElementFactory myFactory;//the factory used to generate interface/class/innerClass/classReference protected JavaDirectoryService myDirectoryService;//the dirService used to generate files under particular dir(package) protected PsiShortNamesCache myShortNamesCache;//used to search a class in particular scope protected GlobalSearchScope myProjectScope;//just this project is enough private MvpConfigurable myConfig; BaseFileGenerator(Project project, PsiDirectory contractDir, PsiDirectory modelDir, PsiDirectory presenterDir, String prefix) { this.myProject = project; this.myContractDir = contractDir; this.myModelDir = modelDir; this.myPresenterDir = presenterDir; this.myPrefix = prefix; myShortNamesCache = PsiShortNamesCache.getInstance(project); myFactory = JavaPsiFacade.getElementFactory(project); myDirectoryService = JavaDirectoryService.getInstance(); myProjectScope = GlobalSearchScope.projectScope(project); myConfig = new MvpConfig(project); } /** * Generate a java file * * @param directory the directory to place the file * @param fileName the name of the file tobe generate * @param type the type of the file * @param listener when the file has been generated, then the listener will be called. * @see JavaTemplateUtil#INTERNAL_CLASS_TEMPLATES */ protected void generateFile(final PsiDirectory directory, final String fileName, final String type, final onFileGeneratedListener listener) { WriteCommandAction.runWriteCommandAction(myProject, () -> { String fixedFileName = fileName; if (myConfig.hasSuffix() && type.equals(JavaTemplateUtil.INTERNAL_CLASS_TEMPLATE_NAME)) { //only sub-class need to fix name fixedFileName += myConfig.getSuffix(); } PsiClass[] psiClasses = myShortNamesCache.getClassesByName(fixedFileName, myProjectScope);//NotNull PsiClass psiClass; PsiJavaFile javaFile; if (psiClasses.length != 0) {//if the class already exist. psiClass = psiClasses[0]; javaFile = (PsiJavaFile) psiClass.getContainingFile(); javaFile.delete();//then delete the old one log("BaseFileGenerator: " + fixedFileName + " old file deleted"); }//and re-generate one psiClass = myDirectoryService.createClass(directory, fixedFileName, type); javaFile = (PsiJavaFile) psiClass.getContainingFile(); PsiPackage psiPackage = myDirectoryService.getPackage(directory); javaFile.setPackageName(psiPackage.getQualifiedName()); log("BaseFileGenerator: " + fixedFileName + " generated"); listener.onJavaFileGenerated(javaFile, psiClass); }); } @FunctionalInterface protected interface onFileGeneratedListener { /** * When the file has been generated, then the listener will be called. * * @param javaFile the PsiJavaFile generated just now * @param psiClass the corresponding PsiClass */ void onJavaFileGenerated(PsiJavaFile javaFile, PsiClass psiClass); } }