package de.jigp.plugin.actions.builder.generator; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiField; import com.intellij.psi.PsiMethod; import de.jigp.plugin.GeneratorPluginContext; import de.jigp.plugin.actions.builder.PsiFieldFilterDialog; import de.jigp.plugin.actions.generator.AbstractGenerator; import de.jigp.plugin.actions.generator.CancelActionException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; public class BuilderGenerator extends AbstractGenerator { private boolean isWithAssertions; private List<String> attributeAssertionTexts = new ArrayList<String>(); private Collection<PsiField> assertionPsiFields; public BuilderGenerator(DataContext dataContext, PsiClass targetClassSuffix, String annotatedClass) { super(dataContext, annotatedClass, targetClassSuffix, false, true); } @Override protected void beforeHandlingHook() { createBuilderConstructor(); } private void createBuilderConstructor() { String sourceQualifiedName = sourceClassForGeneration.getQualifiedName(); String builderConstructorMethodText = "public " + targetClassName() + "(){" + "instance = new " + sourceQualifiedName + "();" + "}"; addOrReplaceMethod(builderConstructorMethodText); } @Override protected void handleMethod(PsiMethod psiMethod) { } @Override protected void handleField(PsiField psiField) { String setMethodText = "public " + sourceClassForGeneration.getQualifiedName() + "." + targetClassName() + " " + psiField.getName() + "(" + psiField.getTypeElement().getType().getCanonicalText() + " " + psiField.getName() + "){" + "instance." + psiField.getName() + "=" + psiField.getName() + ";" + "return this;" + "}"; this.addOrReplaceMethod(setMethodText); if (isAssertionForFieldEnabled(psiField)) { String assertionText = GeneratorPluginContext.getConfiguration().builderAssertionExpression + "(instance." + psiField.getName() + ", \"Attribute: " + psiField.getName() + "\");"; attributeAssertionTexts.add(assertionText); } } private boolean isAssertionForFieldEnabled(PsiField psiField) { return isWithAssertions && (assertionPsiFields == null || assertionPsiFields.contains(psiField)); } @Override protected void afterHandlingHook() { StringBuilder buildMethodText = new StringBuilder("public "); buildMethodText.append(sourceClassForGeneration.getQualifiedName()).append(" build(){"); if (isWithAssertions) { for (String attributeAssertionText : attributeAssertionTexts) { buildMethodText.append(attributeAssertionText); } } buildMethodText.append("return instance;}"); this.addOrReplaceMethod(buildMethodText.toString()); } @Override protected void addNewFields() { PsiField instanceField = psiElementFactory.createFieldFromText("private " + sourceClassForGeneration.getQualifiedName() + " instance;", null); addField(instanceField); } protected Collection<PsiMethod> filterMethodsToHandle(PsiMethod[] psiMethods) { return null; } protected Collection<PsiField> filterFieldsToHandle(PsiField[] psiFields) throws CancelActionException { if (psiFields == null) { return Collections.emptySet(); } PsiFieldFilterDialog psiFieldFilterDialog = new PsiFieldFilterDialog(psiFields); psiFieldFilterDialog.show(); isWithAssertions = true; Collection<PsiField> selectedPsiFields = psiFieldFilterDialog.getSelectedPsiFields(); if (psiFieldFilterDialog.getExitCode() == PsiFieldFilterDialog.CANCEL_EXIT_CODE) { throw new CancelActionException(); } assertionPsiFields = psiFieldFilterDialog.getAssertionPsiFields(); return selectedPsiFields; } }