generate equals/hashCode: ui to configure additional templates

This commit is contained in:
Anna Kozlova
2015-01-12 17:05:03 +01:00
parent 8ad2ec468a
commit b6f4a751cc
3 changed files with 278 additions and 14 deletions
@@ -19,6 +19,7 @@ import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.components.State;
import com.intellij.openapi.components.Storage;
import com.intellij.openapi.components.StoragePathMacros;
import com.intellij.openapi.util.Couple;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.containers.ContainerUtil;
@@ -28,8 +29,7 @@ import org.jetbrains.java.generate.template.TemplateResource;
import org.jetbrains.java.generate.template.TemplatesManager;
import java.io.IOException;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.*;
@State(
name = "EqualsHashCodeTemplates",
@@ -83,11 +83,19 @@ public class EqualsHashCodeTemplatesManager extends TemplatesManager {
}
public TemplateResource getDefaultEqualsTemplate() {
return getDefaultTemplate(EQUALS_SUFFIX, HASH_CODE_SUFFIX);
return getEqualsTemplate(getDefaultTemplate());
}
public TemplateResource getDefaultHashcodeTemplate() {
return getDefaultTemplate(HASH_CODE_SUFFIX, EQUALS_SUFFIX);
return getHashcodeTemplate(getDefaultTemplate());
}
public TemplateResource getEqualsTemplate(TemplateResource template) {
return getDefaultTemplate(EQUALS_SUFFIX, HASH_CODE_SUFFIX, template);
}
public TemplateResource getHashcodeTemplate(TemplateResource template) {
return getDefaultTemplate(HASH_CODE_SUFFIX, EQUALS_SUFFIX, template);
}
public String[] getTemplateNames() {
@@ -99,12 +107,11 @@ public class EqualsHashCodeTemplatesManager extends TemplatesManager {
}
@NotNull
private String getTemplateBaseName(TemplateResource resource) {
public static String getTemplateBaseName(TemplateResource resource) {
return StringUtil.trimEnd(StringUtil.trimEnd(resource.getFileName(), EQUALS_SUFFIX), HASH_CODE_SUFFIX).trim();
}
private TemplateResource getDefaultTemplate(String selfSuffix, String oppositeSuffix) {
final TemplateResource defaultTemplate = getDefaultTemplate();
private TemplateResource getDefaultTemplate(String selfSuffix, String oppositeSuffix, TemplateResource defaultTemplate) {
final String fileName = defaultTemplate.getFileName();
if (fileName.endsWith(selfSuffix)) {
return defaultTemplate;
@@ -132,4 +139,30 @@ public class EqualsHashCodeTemplatesManager extends TemplatesManager {
public String getDefaultTemplateBaseName() {
return getTemplateBaseName(getDefaultTemplate());
}
public static String toEqualsName(String name) {
return name + " " + EQUALS_SUFFIX;
}
public static String toHashCodeName(String name) {
return name + " " + HASH_CODE_SUFFIX;
}
public Collection<Couple<TemplateResource>> getTemplateCouples() {
final LinkedHashMap<String, Couple<TemplateResource>> resources = new LinkedHashMap<String, Couple<TemplateResource>>();
for (TemplateResource resource : getAllTemplates()) {
final String baseName = getTemplateBaseName(resource);
TemplateResource eq = toEqualsName(baseName).equals(resource.getFileName()) ? resource : null;
TemplateResource hc = toHashCodeName(baseName).equals(resource.getFileName()) ? resource : null;
final Couple<TemplateResource> couple = resources.get(baseName);
if (couple != null) {
resources.put(baseName, Couple.of(couple.first != null ? couple.first : eq,
couple.second != null ? couple.second : hc));
}
else {
resources.put(baseName, Couple.of(eq, hc));
}
}
return resources.values();
}
}
@@ -0,0 +1,204 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.codeInsight.generation.ui;
import com.intellij.codeInsight.generation.EqualsHashCodeTemplatesManager;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.UnnamedConfigurable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.NamedItemsListEditor;
import com.intellij.openapi.ui.Namer;
import com.intellij.openapi.ui.Splitter;
import com.intellij.openapi.util.Cloner;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Couple;
import com.intellij.openapi.util.Factory;
import com.intellij.ui.TitledSeparator;
import gnu.trove.Equality;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.java.generate.template.TemplateResource;
import org.jetbrains.java.generate.view.GenerateTemplateConfigurable;
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
public class EqualsHashCodeTemplatesPanel extends NamedItemsListEditor<Couple<TemplateResource>> {
private static final Namer<Couple<TemplateResource>> NAMER = new Namer<Couple<TemplateResource>>() {
@Override
public String getName(Couple<TemplateResource> couple) {
return EqualsHashCodeTemplatesManager.getTemplateBaseName(couple.first);
}
@Override
public boolean canRename(Couple<TemplateResource> item) {
return !item.first.isDefault();
}
@Override
public void setName(Couple<TemplateResource> couple, String name) {
couple.first.setFileName(EqualsHashCodeTemplatesManager.toEqualsName(name));
couple.second.setFileName(EqualsHashCodeTemplatesManager.toHashCodeName(name));
}
};
private static final Factory<Couple<TemplateResource>> FACTORY = new Factory<Couple<TemplateResource>>() {
@Override
public Couple<TemplateResource> create() {
return Couple.of(new TemplateResource(), new TemplateResource());
}
};
private static final Cloner<Couple<TemplateResource>> CLONER = new Cloner<Couple<TemplateResource>>() {
@Override
public Couple<TemplateResource> cloneOf(Couple<TemplateResource> couple) {
if (couple.first.isDefault()) return couple;
return copyOf(couple);
}
@Override
public Couple<TemplateResource> copyOf(Couple<TemplateResource> couple) {
return Couple.of(copyOf(couple.first), copyOf(couple.second));
}
@NotNull
private TemplateResource copyOf(TemplateResource resource) {
TemplateResource result = new TemplateResource();
result.setFileName(resource.getFileName());
result.setTemplate(resource.getTemplate());
return result;
}
};
private static final Equality<Couple<TemplateResource>> COMPARER = new Equality<Couple<TemplateResource>>() {
@Override
public boolean equals(Couple<TemplateResource> o1, Couple<TemplateResource> o2) {
return equals(o1.first, o2.first) && equals(o1.second, o2.second);
}
private boolean equals(TemplateResource r1, TemplateResource r2) {
return Comparing.equal(r1.getTemplate(), r2.getTemplate()) && Comparing.equal(r1.getFileName(), r2.getFileName());
}
};
private final Project myProject;
private final EqualsHashCodeTemplatesManager myManager;
public EqualsHashCodeTemplatesPanel(Project project, EqualsHashCodeTemplatesManager manager) {
super(NAMER, FACTORY, CLONER, COMPARER, new ArrayList<Couple<TemplateResource>>(manager.getTemplateCouples()));
myProject = project;
myManager = manager;
}
@Nls
public String getDisplayName() {
return "Templates";
}
@Override
protected String subjDisplayName() {
return "template";
}
@Nullable
@NonNls
public String getHelpTopic() {
return null;
}
@Override
public boolean isModified() {
return super.isModified() || !Comparing.equal(myManager.getDefaultTemplate(), getSelectedItem().first);
}
@Override
protected boolean canDelete(Couple<TemplateResource> item) {
return !item.first.isDefault();
}
@Override
protected UnnamedConfigurable createConfigurable(Couple<TemplateResource> item) {
final GenerateTemplateConfigurable equalsConfigurable = new GenerateTemplateConfigurable(item.first, myProject);
final GenerateTemplateConfigurable hashCodeConfigurable = new GenerateTemplateConfigurable(item.second, myProject);
return new UnnamedConfigurable() {
@Nullable
@Override
public JComponent createComponent() {
final Splitter splitter = new Splitter(true);
final JPanel eqPanel = new JPanel(new BorderLayout());
eqPanel.add(new TitledSeparator("Equals Template:"), BorderLayout.NORTH);
final JComponent eqPane = equalsConfigurable.createComponent();
eqPane.setPreferredSize(new Dimension(300, 200));
eqPanel.add(eqPane, BorderLayout.CENTER);
splitter.setFirstComponent(eqPanel);
final JPanel hcPanel = new JPanel(new BorderLayout());
hcPanel.add(new TitledSeparator("HashCode Template:"), BorderLayout.NORTH);
final JComponent hcPane = hashCodeConfigurable.createComponent();
hcPane.setPreferredSize(new Dimension(300, 200));
hcPanel.add(hcPane, BorderLayout.CENTER);
splitter.setSecondComponent(hcPanel);
return splitter;
}
@Override
public boolean isModified() {
return equalsConfigurable.isModified() || hashCodeConfigurable.isModified();
}
@Override
public void apply() throws ConfigurationException {
equalsConfigurable.apply();
hashCodeConfigurable.apply();
}
@Override
public void reset() {
equalsConfigurable.reset();
hashCodeConfigurable.reset();
}
@Override
public void disposeUIResources() {
equalsConfigurable.disposeUIResources();
hashCodeConfigurable.disposeUIResources();
}
};
}
@Override
public void apply() throws ConfigurationException {
super.apply();
List<TemplateResource> resources = new ArrayList<TemplateResource>();
for (Couple<TemplateResource> resource : getItems()) {
resources.add(resource.first);
resources.add(resource.second);
}
myManager.setTemplates(resources);
final Couple<TemplateResource> selection = getSelectedItem();
if (selection != null) {
myManager.setDefaultTemplate(selection.first);
}
}
}
@@ -22,10 +22,12 @@ import com.intellij.codeInsight.generation.EqualsHashCodeTemplatesManager;
import com.intellij.codeInsight.generation.GenerateEqualsHelper;
import com.intellij.ide.wizard.StepAdapter;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.options.ShowSettingsUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.JavaSdkVersion;
import com.intellij.openapi.projectRoots.JavaVersionService;
import com.intellij.openapi.ui.ComboBox;
import com.intellij.openapi.ui.ComponentWithBrowseButton;
import com.intellij.openapi.ui.VerticalFlowLayout;
import com.intellij.psi.*;
import com.intellij.refactoring.classMembers.AbstractMemberInfoModel;
@@ -251,7 +253,7 @@ public class GenerateEqualsWizard extends AbstractGenerateEqualsWizard<PsiClass,
@Override
protected void addSteps() {
if (myEqualsPanel != null) {
addStep(new TemplateChooserStep(myClass.hasModifierProperty(PsiModifier.FINAL)));
addStep(new TemplateChooserStep(myClass.hasModifierProperty(PsiModifier.FINAL), myClass.getProject()));
}
super.addSteps();
}
@@ -338,7 +340,7 @@ public class GenerateEqualsWizard extends AbstractGenerateEqualsWizard<PsiClass,
private static class TemplateChooserStep extends StepAdapter {
private final JComponent myPanel;
private TemplateChooserStep(boolean isFinal) {
private TemplateChooserStep(boolean isFinal, Project project) {
final JCheckBox checkbox = new NonFocusableCheckBox(CodeInsightBundle.message("generate.equals.hashcode.accept.sublcasses"));
checkbox.setSelected(!isFinal && CodeInsightSettings.getInstance().USE_INSTANCEOF_ON_EQUALS_PARAMETER);
checkbox.setEnabled(!isFinal);
@@ -348,7 +350,14 @@ public class GenerateEqualsWizard extends AbstractGenerateEqualsWizard<PsiClass,
}
});
myPanel = new JPanel(new VerticalFlowLayout());
final JPanel templateChooserPanel = new JPanel(new BorderLayout());
final JLabel templateChooserLabel = new JLabel("Template:");
templateChooserPanel.add(templateChooserLabel, BorderLayout.WEST);
final ComboBox comboBox = new ComboBox();
final ComponentWithBrowseButton<ComboBox> comboBoxWithBrowseButton = new ComponentWithBrowseButton<ComboBox>(comboBox,
new MyEditTemplatesListener(project, myPanel, comboBox));
final EqualsHashCodeTemplatesManager manager = EqualsHashCodeTemplatesManager.getInstance();
comboBox.setModel(new DefaultComboBoxModel(manager.getTemplateNames()));
comboBox.setSelectedItem(manager.getDefaultTemplateBaseName());
@@ -358,11 +367,7 @@ public class GenerateEqualsWizard extends AbstractGenerateEqualsWizard<PsiClass,
}
});
myPanel = new JPanel(new VerticalFlowLayout());
final JPanel templateChooserPanel = new JPanel(new BorderLayout());
final JLabel templateChooserLabel = new JLabel("Template:");
templateChooserPanel.add(templateChooserLabel, BorderLayout.WEST);
templateChooserPanel.add(comboBox, BorderLayout.CENTER);
templateChooserPanel.add(comboBoxWithBrowseButton, BorderLayout.CENTER);
myPanel.add(templateChooserPanel);
myPanel.add(checkbox);
myPanel.add(new JLabel(CodeInsightBundle.message("generate.equals.hashcode.accept.sublcasses.explanation")));
@@ -372,5 +377,27 @@ public class GenerateEqualsWizard extends AbstractGenerateEqualsWizard<PsiClass,
public JComponent getComponent() {
return myPanel;
}
private static class MyEditTemplatesListener implements ActionListener {
private final Project myProject;
private final JComponent myParent;
private final ComboBox myComboBox;
public MyEditTemplatesListener(Project project, JComponent panel, ComboBox comboBox) {
myProject = project;
myParent = panel;
myComboBox = comboBox;
}
@Override
public void actionPerformed(ActionEvent e) {
final EqualsHashCodeTemplatesManager templatesManager = EqualsHashCodeTemplatesManager.getInstance();
final EqualsHashCodeTemplatesPanel ui = new EqualsHashCodeTemplatesPanel(myProject, EqualsHashCodeTemplatesManager.getInstance());
ui.selectNodeInTree(templatesManager.getDefaultTemplateBaseName());
ShowSettingsUtil.getInstance().editConfigurable(myParent, ui);
myComboBox.setModel(new DefaultComboBoxModel(templatesManager.getTemplateNames()));
myComboBox.setSelectedItem(templatesManager.getDefaultTemplateBaseName());
}
}
}
}