package com.github.setial.intellijjavadocs.generator.impl; import com.github.setial.intellijjavadocs.configuration.JavaDocConfiguration; import com.github.setial.intellijjavadocs.generator.JavaDocGenerator; import com.github.setial.intellijjavadocs.model.JavaDoc; import com.github.setial.intellijjavadocs.model.settings.JavaDocSettings; import com.github.setial.intellijjavadocs.model.settings.Mode; import com.github.setial.intellijjavadocs.model.settings.Visibility; import com.github.setial.intellijjavadocs.template.DocTemplateManager; import com.github.setial.intellijjavadocs.template.DocTemplateProcessor; import com.github.setial.intellijjavadocs.utils.JavaDocUtils; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.project.Project; import com.intellij.pom.PomNamedTarget; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElementFactory; import com.intellij.psi.PsiModifier; import com.intellij.psi.PsiModifierList; import com.intellij.psi.javadoc.PsiDocComment; import org.apache.commons.lang3.StringUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.HashMap; import java.util.Map; /** * The type Abstract java doc generator. * * @param <T> the type parameter * @author Sergey Timofiychuk */ public abstract class AbstractJavaDocGenerator<T extends PsiElement> implements JavaDocGenerator<T> { private DocTemplateManager docTemplateManager; private DocTemplateProcessor docTemplateProcessor; private PsiElementFactory psiElementFactory; private JavaDocConfiguration settings; /** * Instantiates a new Abstract java doc generator. * * @param project the Project */ public AbstractJavaDocGenerator(@NotNull Project project) { docTemplateManager = ServiceManager.getService(project, DocTemplateManager.class); docTemplateProcessor = ServiceManager.getService(project, DocTemplateProcessor.class); psiElementFactory = PsiElementFactory.SERVICE.getInstance(project); settings = ServiceManager.getService(project, JavaDocConfiguration.class); } @Nullable @Override public final PsiDocComment generate(@NotNull T element) { PsiDocComment result = null; PsiDocComment oldDocComment = null; PsiElement firstElement = element.getFirstChild(); if (firstElement instanceof PsiDocComment) { oldDocComment = (PsiDocComment) firstElement; } JavaDocSettings configuration = settings.getConfiguration(); if (configuration != null) { Mode mode = configuration.getGeneralSettings().getMode(); switch (mode) { case KEEP: if (oldDocComment != null) { break; } case REPLACE: result = replaceJavaDocAction(element); break; case UPDATE: default: if (oldDocComment != null) { result = updateJavaDocAction(element, oldDocComment); } else { result = replaceJavaDocAction(element); } break; } } return result; } /** * Gets the doc template manager. * * @return the Doc template manager */ @NotNull protected DocTemplateManager getDocTemplateManager() { return docTemplateManager; } /** * Gets the doc template processor. * * @return the Doc template processor */ @NotNull protected DocTemplateProcessor getDocTemplateProcessor() { return docTemplateProcessor; } /** * Gets the psi element factory. * * @return the Psi element factory */ @NotNull protected PsiElementFactory getPsiElementFactory() { return psiElementFactory; } /** * Gets settings. * * @return the settings */ @NotNull protected JavaDocConfiguration getSettings() { return settings; } /** * Check whether javadoc should be generated. * * @param modifiers the modifiers * @return the boolean */ protected boolean shouldGenerate(PsiModifierList modifiers) { return checkModifiers(modifiers, PsiModifier.PUBLIC, Visibility.PUBLIC) || checkModifiers(modifiers, PsiModifier.PROTECTED, Visibility.PROTECTED) || checkModifiers(modifiers, PsiModifier.PACKAGE_LOCAL, Visibility.DEFAULT) || checkModifiers(modifiers, PsiModifier.PRIVATE, Visibility.PRIVATE); } /** * Gets default parameters used to build template. * * @param element the element * @return the default parameters */ protected Map<String, Object> getDefaultParameters(PomNamedTarget element) { Map<String, Object> params = new HashMap<String, Object>(); params.put("element", element); params.put("name", getDocTemplateProcessor().buildDescription(element.getName(), true)); params.put("partName", getDocTemplateProcessor().buildPartialDescription(element.getName())); params.put("splitNames", StringUtils.splitByCharacterTypeCamelCase(element.getName())); return params; } private PsiDocComment updateJavaDocAction(T element, PsiDocComment oldDocComment) { PsiDocComment result = null; JavaDoc newJavaDoc = generateJavaDoc(element); JavaDoc oldJavaDoc = JavaDocUtils.createJavaDoc(oldDocComment); if (newJavaDoc != null) { newJavaDoc = JavaDocUtils.mergeJavaDocs(oldJavaDoc, newJavaDoc); String javaDoc = newJavaDoc.toJavaDoc(); result = psiElementFactory.createDocCommentFromText(javaDoc); } return result; } private PsiDocComment replaceJavaDocAction(T element) { PsiDocComment result = null; JavaDoc newJavaDoc = generateJavaDoc(element); if (newJavaDoc != null) { String javaDoc = newJavaDoc.toJavaDoc(); result = psiElementFactory.createDocCommentFromText(javaDoc); } return result; } private boolean checkModifiers(PsiModifierList modifiers, String modifier, Visibility visibility) { JavaDocSettings configuration = getSettings().getConfiguration(); return modifiers != null && modifiers.hasModifierProperty(modifier) && configuration != null && configuration.getGeneralSettings().getVisibilities().contains(visibility); } /** * Generate java doc. * * @param element the Element * @return the Java doc */ @Nullable protected abstract JavaDoc generateJavaDoc(@NotNull T element); }