package jetbrains.mps.ide.java.platform.refactorings;
/*Generated by MPS */
import jetbrains.mps.ide.platform.refactoring.RefactoringDialog;
import jetbrains.mps.project.MPSProject;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JCheckBox;
import jetbrains.mps.baseLanguage.util.plugin.refactorings.ExtractMethodRefactoringParameters;
import jetbrains.mps.openapi.editor.EditorContext;
import jetbrains.mps.baseLanguage.util.plugin.refactorings.ExtractMethodRefactoring;
import org.jetbrains.mps.openapi.model.SNode;
import org.jetbrains.mps.openapi.model.SModel;
import jetbrains.mps.baseLanguage.util.plugin.refactorings.ExtractMethodFactory;
import org.jetbrains.annotations.Nullable;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SNodeOperations;
import jetbrains.mps.smodel.adapter.structure.MetaAdapterFactory;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SPropertyOperations;
import javax.swing.JComponent;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import java.awt.Insets;
import javax.swing.event.ChangeListener;
import javax.swing.event.ChangeEvent;
import javax.swing.event.TableModelListener;
import javax.swing.event.TableModelEvent;
import javax.swing.JLabel;
import com.intellij.ui.DocumentAdapter;
import javax.swing.event.DocumentEvent;
import java.awt.event.ItemListener;
import java.awt.event.ItemEvent;
import javax.swing.border.Border;
import javax.swing.border.CompoundBorder;
import javax.swing.border.TitledBorder;
import javax.swing.border.EmptyBorder;
import java.util.Set;
import jetbrains.mps.smodel.ModelAccessHelper;
import jetbrains.mps.util.Computable;
import jetbrains.mps.internal.collections.runtime.ListSequence;
import org.jetbrains.mps.util.InstanceOfCondition;
import org.jetbrains.mps.openapi.language.SAbstractConcept;
import jetbrains.mps.internal.collections.runtime.SetSequence;
import java.util.HashSet;
import jetbrains.mps.internal.collections.runtime.Sequence;
import org.jetbrains.mps.openapi.model.SModelReference;
import jetbrains.mps.smodel.SModelOperations;
import jetbrains.mps.project.dependency.VisibilityUtil;
import org.jetbrains.annotations.NonNls;
import javax.swing.JOptionPane;
import jetbrains.mps.editor.runtime.commands.EditorCommand;
import jetbrains.mps.smodel.ModelImports;
import jetbrains.mps.baseLanguage.util.plugin.refactorings.MethodMatch;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class ExtractMethodDialog extends RefactoringDialog {
private final MPSProject myMPSProject;
private JPanel myPanel;
private boolean myCanRefactor;
private JTextArea myPreviewArea = new JTextArea();
private JTextArea myMessagesArea = new JTextArea();
private JTextField myNameField;
private JCheckBox myDeclareStaticCheckBox;
private VisibilityPanel myVisibilityPanel;
private ExtractMethodDialog.ChooseContainerPanel myChooseContainerPanel;
private ExtractMethodRefactoringParameters myParameters;
private EditorContext myContext;
private ExtractMethodRefactoring myRefactoring;
private SNode myStaticTarget;
private SModel myRefactoringModel;
private boolean myExtractIntoOuterContainer;
private boolean myStaticSelected;
private boolean myStaticSelectedByUser;
private boolean myStaticEnabled;
private String myAnalyzeErrors;
private String myErrors;
public ExtractMethodDialog(MPSProject project, EditorContext context, ExtractMethodRefactoringParameters params, ExtractMethodRefactoring refactoring) {
super(project.getProject(), true);
setTitle("Extract Method");
myMPSProject = project;
myContext = context;
myParameters = params;
myRefactoring = refactoring;
myExtractIntoOuterContainer = this.myParameters.getAnalyzer().shouldChooseOuterContainer();
myContext.getRepository().getModelAccess().runReadAction(new Runnable() {
public void run() {
myAnalyzeErrors = ExtractMethodFactory.getErrors(ExtractMethodDialog.this.myParameters.getNodesToRefactor());
init();
}
});
this.update();
}
@Nullable
@Override
protected String getHelpId() {
return "refactoring.extractMethod1";
}
private void update() {
myContext.getRepository().getModelAccess().runReadAction(new Runnable() {
public void run() {
ExtractMethodDialog.this.myErrors = ExtractMethodDialog.this.getMessagesText();
ExtractMethodDialog.this.myMessagesArea.setText(ExtractMethodDialog.this.myErrors);
ExtractMethodDialog.this.myPreviewArea.setText(ExtractMethodDialog.this.myParameters.getMethodText());
}
});
this.repaint();
}
private String getMessagesText() {
this.myCanRefactor = true;
StringBuffer buff = new StringBuffer();
String methodName = this.myParameters.getName();
if (methodName.length() == 0) {
buff.append("Method name is empty.\n");
this.myCanRefactor = false;
} else {
boolean nameIsGood = Character.isJavaIdentifierStart(methodName.charAt(0));
for (int i = 1; i < methodName.length(); i++) {
nameIsGood = nameIsGood && Character.isJavaIdentifierPart(methodName.charAt(i));
}
if (!(nameIsGood)) {
buff.append("Method name is incorrect.");
this.myCanRefactor = false;
}
}
if (this.myAnalyzeErrors != null) {
buff.append(this.myAnalyzeErrors);
this.myCanRefactor = false;
}
SNode overrides = this.myParameters.getOverridingMethodClass();
if (overrides != null && !(this.myExtractIntoOuterContainer)) {
if ((overrides == SNodeOperations.getNodeAncestor(this.myParameters.getContainerMethod(), MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x101d9d3ca30L, "jetbrains.mps.baseLanguage.structure.Classifier"), false, false))) {
buff.append("Such method already exists.\n");
} else {
buff.append("Method overrides method from class ").append(SPropertyOperations.getString(overrides, MetaAdapterFactory.getProperty(0xceab519525ea4f22L, 0x9b92103b95ca8c0cL, 0x110396eaaa4L, 0x110396ec041L, "name"))).append("\n");
}
this.myCanRefactor = false;
}
if (buff.length() == 0) {
buff.append("\n");
}
return buff.toString();
}
@Nullable
@Override
protected JComponent createCenterPanel() {
myPanel = new JPanel(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.BOTH;
c.anchor = GridBagConstraints.NORTHWEST;
c.insets = new Insets(3, 5, 3, 5);
c.gridx = 0;
c.gridy = 0;
c.weightx = 1;
c.weighty = 0;
c.gridwidth = 2;
myPanel.add(createMethodPanel(), c);
c.gridx = 0;
c.gridy = 1;
c.weightx = 1;
c.weighty = 1;
c.gridwidth = 1;
myPanel.add(createParametersPanel(), c);
c.gridx = 1;
c.gridy = 1;
c.weightx = 0;
c.weighty = 1;
c.gridwidth = 1;
myVisibilityPanel = new VisibilityPanel();
myVisibilityPanel.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
ExtractMethodDialog.this.myParameters.setVisibilityLevel(ExtractMethodDialog.this.myVisibilityPanel.getResult());
ExtractMethodDialog.this.update();
}
});
myPanel.add(myVisibilityPanel, c);
c.gridx = 0;
c.gridy = 2;
c.weightx = 1;
c.weighty = 0;
c.gridwidth = 2;
myPanel.add(createPreviewPanel(), c);
c.gridx = 0;
c.gridy = 3;
c.weightx = 1;
c.weighty = 0;
c.gridwidth = 2;
myChooseContainerPanel = new ExtractMethodDialog.ChooseContainerPanel();
myChooseContainerPanel.setBorder(this.createBorder("Choose container"));
myPanel.add(myChooseContainerPanel, c);
c.gridx = 0;
c.gridy = 4;
c.weightx = 1;
c.weighty = 0;
c.gridwidth = 2;
myPanel.add(createMessagesComponent(), c);
return myPanel;
}
private JComponent createPreviewPanel() {
this.myPreviewArea.setEditable(false);
this.myPreviewArea.setBackground(this.myPanel.getBackground());
this.myPreviewArea.setBorder(this.createBorder("Signature Preview"));
return this.myPreviewArea;
}
private JComponent createMessagesComponent() {
this.myMessagesArea.setEditable(false);
this.myMessagesArea.setBackground(this.myPanel.getBackground());
this.myMessagesArea.setBorder(this.createBorder("Messages"));
return this.myMessagesArea;
}
private JComponent createParametersPanel() {
ParametersPanel parametersPanel = new ParametersPanel(this.myParameters);
parametersPanel.setBorder(this.createBorder("Parameters"));
ParametersTableModel tableModel = parametersPanel.getTableModel();
tableModel.addTableModelListener(new TableModelListener() {
@Override
public void tableChanged(TableModelEvent p0) {
ExtractMethodDialog.this.update();
}
});
return parametersPanel;
}
private JComponent createMethodPanel() {
JPanel methodPanel = new JPanel(new GridBagLayout());
methodPanel.setBorder(this.createBorder("Method"));
GridBagConstraints c = new GridBagConstraints();
c.gridx = 0;
c.gridy = 0;
c.weightx = 0;
c.anchor = GridBagConstraints.FIRST_LINE_START;
methodPanel.add(new JLabel("Name:"), c);
c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 0;
c.gridy = 1;
c.weightx = 1;
c.weighty = 1;
c.anchor = GridBagConstraints.FIRST_LINE_START;
myNameField = new JTextField(20);
methodPanel.add(myNameField, c);
myNameField.getDocument().addDocumentListener(new DocumentAdapter() {
@Override
protected void textChanged(DocumentEvent p0) {
ExtractMethodDialog.this.myParameters.setName(myNameField.getText());
ExtractMethodDialog.this.update();
}
});
c.fill = GridBagConstraints.NONE;
c.gridx = 0;
c.gridy = 2;
c.weightx = 1;
c.weighty = 1;
c.anchor = GridBagConstraints.FIRST_LINE_START;
myDeclareStaticCheckBox = createDeclareStaticCheckBox();
methodPanel.add(this.myDeclareStaticCheckBox, c);
return methodPanel;
}
@Override
public JComponent getPreferredFocusedComponent() {
return myNameField;
}
private JCheckBox createDeclareStaticCheckBox() {
final JCheckBox result = new JCheckBox("Declare static");
boolean canBeStatic = myRefactoring.canBeStatic();
boolean shouldBeStatic = myRefactoring.shouldBeStatic();
this.myStaticSelected = shouldBeStatic;
this.myStaticEnabled = canBeStatic && !(shouldBeStatic);
setCheckBox(result, this.myStaticSelected, this.myStaticEnabled);
result.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
myStaticSelected = result.isSelected();
ExtractMethodDialog.this.myParameters.setStatic(myStaticSelected);
ExtractMethodDialog.this.update();
}
});
return result;
}
private void setCheckBox(JCheckBox checkBox, boolean selected, boolean enabled) {
checkBox.setSelected(selected);
checkBox.setEnabled(enabled);
}
private Border createBorder(String title) {
return new CompoundBorder(new TitledBorder(title), new EmptyBorder(5, 5, 5, 5));
}
private void setStaticContainer() {
myContext.getRepository().getModelAccess().runReadAction(new Runnable() {
public void run() {
ExtractMethodDialog.this.myRefactoring.setStaticContainer(ExtractMethodDialog.this.myStaticTarget);
}
});
}
public void chooseStaticContainer() {
Set<SModel> models = new ModelAccessHelper(myContext.getRepository()).runReadAction(new Computable<Set<SModel>>() {
public Set<SModel> compute() {
myRefactoringModel = SNodeOperations.getModel(ListSequence.fromList(ExtractMethodDialog.this.myParameters.getNodesToRefactor()).first());
return collectVisibleModels(myRefactoringModel);
}
});
final ChooseNodeDialog dialog = new ChooseNodeDialog(myMPSProject, new InstanceOfCondition(new SAbstractConcept[]{MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8c108ca66L, "jetbrains.mps.baseLanguage.structure.ClassConcept"), MetaAdapterFactory.getInterfaceConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x11c8f444674L, "jetbrains.mps.baseLanguage.structure.IStaticContainerForMethods")}), models, "Choose class");
dialog.show();
myContext.getRepository().getModelAccess().runReadAction(new Runnable() {
public void run() {
myStaticTarget = (dialog.getResult() != null ? dialog.getResult().resolve(myContext.getRepository()) : null);
}
});
if (myStaticTarget == null) {
myRefactoringModel = null;
}
}
private Set<SModel> collectVisibleModels(SModel model) {
Set<SModel> rv = SetSequence.fromSet(new HashSet<SModel>());
SetSequence.fromSet(rv).addElement(model);
for (SModel nextOwnModel : Sequence.fromIterable(model.getModule().getModels())) {
SetSequence.fromSet(rv).addElement(nextOwnModel);
}
for (SModelReference sm : SModelOperations.getImportedModelUIDs(model)) {
SModel m = sm.resolve(myContext.getRepository());
if (VisibilityUtil.isVisible(model.getModule(), m)) {
SetSequence.fromSet(rv).addElement(m);
}
}
return rv;
}
@Nullable
@NonNls
@Override
protected String getDimensionServiceKey() {
return getClass().getName();
}
/**
* This method will be called on pressing "Refactor" button in dialog.
*
*/
@Override
protected void doRefactoringAction() {
if (!(myCanRefactor)) {
JOptionPane.showMessageDialog(myPanel, "Can't refactor\n" + this.myErrors, "Can't perform refactoring", JOptionPane.ERROR_MESSAGE);
return;
} else {
if (myExtractIntoOuterContainer) {
if (myStaticTarget == null) {
chooseStaticContainer();
}
if (myStaticTarget != null) {
setStaticContainer();
} else {
return;
}
}
myContext.getRepository().getModelAccess().executeCommand(new EditorCommand(myContext) {
protected void doExecute() {
SNode result = myRefactoring.doRefactor();
myContext.select(result);
if ((myRefactoringModel != null) && myExtractIntoOuterContainer) {
SModelReference ref = SNodeOperations.getModel(myStaticTarget).getReference();
new ModelImports(myRefactoringModel).addModelImport(ref);
}
if ((result != null)) {
new ExtractMethodDialog.MyMethodDuplicatesProcessor(myContext, result).process(ExtractMethodDialog.this.myRefactoring.getMatches(), myProject);
}
}
});
}
super.doRefactoringAction();
}
public class MyMethodDuplicatesProcessor extends MethodDuplicatesProcessor {
private SNode myMethod;
public MyMethodDuplicatesProcessor(EditorContext context, SNode method) {
super(context);
this.myMethod = method;
}
@Override
public void substitute(MethodMatch duplicate) {
duplicate.getRefactoring().replaceMatch(duplicate, this.myMethod);
}
}
private class ChooseContainerPanel extends JPanel {
{
myOuterContainerCheckBox = new JCheckBox("Extract into outer container");
myChooseContainerButton = new JButton("Choose Container");
}
private JButton myChooseContainerButton;
private JCheckBox myOuterContainerCheckBox;
public ChooseContainerPanel() {
super(new GridBagLayout());
this.initPanel();
}
private void initPanel() {
ExtractMethodDialog.this.setCheckBox(this.myOuterContainerCheckBox, ExtractMethodDialog.this.myExtractIntoOuterContainer, !(ExtractMethodDialog.this.myExtractIntoOuterContainer));
myOuterContainerCheckBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent p0) {
ExtractMethodDialog.this.myExtractIntoOuterContainer = myOuterContainerCheckBox.isSelected();
myChooseContainerButton.setEnabled(ExtractMethodDialog.this.myExtractIntoOuterContainer);
if (ExtractMethodDialog.this.myExtractIntoOuterContainer) {
ExtractMethodDialog.this.myStaticSelectedByUser = ExtractMethodDialog.this.myStaticSelected;
}
setCheckBox(ExtractMethodDialog.this.myDeclareStaticCheckBox, ExtractMethodDialog.this.myExtractIntoOuterContainer || ExtractMethodDialog.this.myStaticSelectedByUser, !(ExtractMethodDialog.this.myExtractIntoOuterContainer) && ExtractMethodDialog.this.myStaticEnabled);
}
});
myChooseContainerButton.setEnabled(ExtractMethodDialog.this.myExtractIntoOuterContainer);
myChooseContainerButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent p0) {
chooseStaticContainer();
myContext.getRepository().getModelAccess().runReadAction(new Runnable() {
public void run() {
if (ExtractMethodDialog.this.myStaticTarget != null) {
if (SNodeOperations.isInstanceOf(ExtractMethodDialog.this.myStaticTarget, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8c108ca66L, "jetbrains.mps.baseLanguage.structure.ClassConcept"))) {
myChooseContainerButton.setIcon(IconResourceBundle_ExtractMethodIcons.getInstance().getResource("CLASS"));
} else if (SNodeOperations.isInstanceOf(ExtractMethodDialog.this.myStaticTarget, MetaAdapterFactory.getConcept(0xaf65afd8f0dd4942L, 0x87d963a55f2a9db1L, 0x11d43447b1aL, "jetbrains.mps.lang.behavior.structure.ConceptBehavior"))) {
myChooseContainerButton.setIcon(IconResourceBundle_ExtractMethodIcons.getInstance().getResource("INTERFACE"));
}
if (SNodeOperations.isInstanceOf(ExtractMethodDialog.this.myStaticTarget, MetaAdapterFactory.getInterfaceConcept(0xceab519525ea4f22L, 0x9b92103b95ca8c0cL, 0x110396eaaa4L, "jetbrains.mps.lang.core.structure.INamedConcept"))) {
myChooseContainerButton.setText(SPropertyOperations.getString((SNodeOperations.cast(ExtractMethodDialog.this.myStaticTarget, MetaAdapterFactory.getInterfaceConcept(0xceab519525ea4f22L, 0x9b92103b95ca8c0cL, 0x110396eaaa4L, "jetbrains.mps.lang.core.structure.INamedConcept"))), MetaAdapterFactory.getProperty(0xceab519525ea4f22L, 0x9b92103b95ca8c0cL, 0x110396eaaa4L, 0x110396ec041L, "name")));
}
}
ExtractMethodDialog.this.update();
}
});
}
});
GridBagConstraints c = new GridBagConstraints();
c.gridx = 0;
c.gridy = 0;
c.weightx = 3;
c.anchor = GridBagConstraints.FIRST_LINE_START;
add(myOuterContainerCheckBox, c);
c.gridx = 1;
c.gridy = 0;
c.weightx = 1;
c.anchor = GridBagConstraints.FIRST_LINE_END;
add(myChooseContainerButton, c);
}
}
}