package jetbrains.mps.ide.dialogs.project.creation;
/*Generated by MPS */
import com.intellij.openapi.ui.DialogWrapper;
import jetbrains.mps.project.MPSProject;
import jetbrains.mps.project.AbstractModule;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import javax.swing.JTextField;
import javax.swing.JComboBox;
import org.jetbrains.mps.openapi.persistence.ModelRoot;
import org.jetbrains.mps.openapi.persistence.ModelFactoryType;
import org.jetbrains.mps.openapi.model.SModel;
import org.jetbrains.mps.openapi.model.EditableSModel;
import jetbrains.mps.project.Project;
import java.awt.HeadlessException;
import jetbrains.mps.ide.project.ProjectHelper;
import org.jetbrains.mps.openapi.model.SModelName;
import org.jetbrains.mps.openapi.module.SModule;
import jetbrains.mps.smodel.Generator;
import com.intellij.uiDesigner.core.GridLayoutManager;
import java.awt.Dimension;
import com.intellij.uiDesigner.core.GridConstraints;
import javax.swing.JLabel;
import javax.swing.DefaultComboBoxModel;
import jetbrains.mps.smodel.Language;
import jetbrains.mps.extapi.persistence.FileBasedModelRoot;
import javax.swing.DefaultListCellRenderer;
import java.awt.event.ItemListener;
import java.awt.event.ItemEvent;
import jetbrains.mps.persistence.DefaultModelRoot;
import java.awt.Insets;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.List;
import java.util.LinkedList;
import java.util.Arrays;
import jetbrains.mps.smodel.SModelStereotype;
import com.intellij.ui.ColoredListCellRenderer;
import javax.swing.JList;
import jetbrains.mps.extapi.persistence.ModelFactoryService;
import org.jetbrains.mps.openapi.persistence.Memento;
import jetbrains.mps.persistence.MementoImpl;
import jetbrains.mps.project.structure.model.ModelRootDescriptor;
import org.jetbrains.mps.openapi.persistence.PersistenceFacade;
import java.io.File;
import jetbrains.mps.project.structure.modules.LanguageDescriptor;
import java.util.Iterator;
import java.util.Objects;
import jetbrains.mps.util.Reference;
import jetbrains.mps.persistence.ModelCannotBeCreatedException;
import jetbrains.mps.smodel.ModelAccessHelper;
import jetbrains.mps.util.Computable;
import org.jetbrains.annotations.NotNull;
import jetbrains.mps.project.SModuleOperations;
import jetbrains.mps.smodel.ModelImports;
import jetbrains.mps.smodel.CopyUtil;
import com.intellij.openapi.ui.Messages;
import jetbrains.mps.ide.ui.dialogs.properties.MPSPropertiesConfigurable;
import jetbrains.mps.ide.ui.dialogs.properties.ModelPropertiesConfigurable;
import com.intellij.openapi.options.ex.SingleConfigurableEditor;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import jetbrains.mps.smodel.language.LanguageAspectSupport;
import javax.lang.model.SourceVersion;
import org.jetbrains.annotations.Nullable;
import javax.swing.JComponent;
public class NewModelDialog extends DialogWrapper {
private final MPSProject myProject;
private final AbstractModule myModule;
private final JPanel myContentPane = new JPanel(new BorderLayout());
private final JTextField myModelName = new JTextField();
private final JComboBox<String> myModelStereotype = new JComboBox<String>();
private final JComboBox<ModelRoot> myModelRoots = new JComboBox<ModelRoot>();
private final JComboBox<ModelFactoryType> myModelStorageFormat = new JComboBox<ModelFactoryType>();
private SModel myClone;
private boolean myPreserveIds;
private EditableSModel myResult;
private String myNamespace;
public NewModelDialog(Project project, AbstractModule module, String namespace, String stereotype, boolean strict) throws HeadlessException {
super(ProjectHelper.toIdeaProject(project));
setTitle("New Model");
myProject = (MPSProject) project;
myModule = module;
myNamespace = (namespace == null ? "" : namespace);
project.getRepository().getModelAccess().runReadAction(new Runnable() {
public void run() {
assert myModule.getModelRoots().iterator().hasNext() : "Can't create a model in solution with no model roots";
initContentPane();
}
});
if (stereotype != null) {
myModelStereotype.setSelectedItem(stereotype);
myModelStereotype.setEnabled(!(strict));
}
init();
}
public NewModelDialog(Project project, SModel cloneModel) {
this(project, (AbstractModule) cloneModel.getModule(), null, cloneModel.getName().getStereotype(), false);
myClone = cloneModel;
myPreserveIds = false;
SModelName originalName = myClone.getName();
setTitle(String.format("Clone Model %s", originalName.getValue()));
myModelName.setText(new SModelName(originalName.getLongName() + "_clone").getValue());
check();
}
public NewModelDialog(Project project, AbstractModule module, SModel cloneModel) {
this(project, module, null, cloneModel.getName().getStereotype(), false);
myClone = cloneModel;
myPreserveIds = true;
SModelName originalName = myClone.getName();
setTitle(String.format("Move Model %s", originalName.getValue()));
myModelName.setText(originalName.getValue());
check();
}
public static String getNamespace(SModel model) {
SModule module = model.getModule();
if (module instanceof Generator) {
Generator gen = (Generator) module;
String name = gen.getModuleName();
String genNamespace = gen.getSourceLanguage().getModuleName() + ".generator";
if ((name == null || name.length() == 0)) {
return genNamespace;
}
return genNamespace + "." + name;
}
return module.getModuleName();
}
public EditableSModel getResult() {
return myResult;
}
private void initContentPane() {
JPanel mainPanel = new JPanel(new GridLayoutManager(6, 1));
mainPanel.setPreferredSize(new Dimension(200, 50));
GridConstraints constraints = new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_NORTHWEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null);
mainPanel.add(new JLabel("Model root:"), constraints);
constraints.setRow(constraints.getRow() + 1);
mainPanel.add(myModelRoots, constraints);
DefaultComboBoxModel<ModelRoot> model = new DefaultComboBoxModel<ModelRoot>();
for (ModelRoot root : myModule.getModelRoots()) {
if (root.canCreateModels()) {
model.addElement(root);
} else if (myModule instanceof Language && root instanceof FileBasedModelRoot) {
// Can fix only FileBased model root (default for language)
model.addElement(root);
}
}
if (model.getSize() == 0) {
model.addElement(null);
}
myModelRoots.setRenderer(new DefaultListCellRenderer());
myModelRoots.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
check();
myModelStorageFormat.setVisible(myModelRoots.getSelectedItem() instanceof DefaultModelRoot);
}
});
myModelRoots.setModel(model);
myModelName.setText((myNamespace.length() == 0 ? myNamespace : myNamespace + "."));
constraints.setRow(constraints.getRow() + 1);
mainPanel.add(new JLabel("Model name:"), constraints);
JPanel nameAndStereotype = new JPanel(new GridLayoutManager(1, 3, new Insets(0, 0, 0, 0), -1, -1));
GridConstraints nameConstraints = new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_NORTHWEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null);
nameAndStereotype.add(myModelName, nameConstraints);
myModelName.addKeyListener(new KeyAdapter() {
@Override
public void keyReleased(KeyEvent event) {
check();
}
});
final JLabel atSign = new JLabel();
nameConstraints.setColumn(nameConstraints.getColumn() + 1);
nameConstraints.setHSizePolicy(GridConstraints.SIZEPOLICY_FIXED);
nameAndStereotype.add(atSign, nameConstraints);
List<String> stereotypes = new LinkedList<String>(Arrays.asList(SModelStereotype.values));
if (!(myModule instanceof Generator)) {
stereotypes.remove(SModelStereotype.GENERATOR);
}
myModelStereotype.setEditable(true);
myModelStereotype.setModel(new DefaultComboBoxModel<String>(stereotypes.toArray(new String[stereotypes.size()])));
myModelStereotype.addKeyListener(new KeyAdapter() {
@Override
public void keyReleased(KeyEvent event) {
check();
}
});
myModelStereotype.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent p0) {
check();
atSign.setText((myModelStereotype.getSelectedItem().equals(SModelStereotype.NONE) ? "" : "@"));
}
});
nameConstraints.setColumn(nameConstraints.getColumn() + 1);
nameAndStereotype.add(myModelStereotype, nameConstraints);
constraints.setRow(constraints.getRow() + 1);
mainPanel.add(nameAndStereotype, constraints);
constraints.setRow(constraints.getRow() + 1);
mainPanel.add(new JLabel("Storage format:"), constraints);
constraints.setRow(constraints.getRow() + 1);
myModelStorageFormat.setModel(new DefaultComboBoxModel<ModelFactoryType>(getStorageFormats()));
myModelStorageFormat.setRenderer(new ColoredListCellRenderer<ModelFactoryType>() {
protected void customizeCellRenderer(JList<? extends ModelFactoryType> p0, ModelFactoryType factoryType, int p2, boolean p3, boolean p4) {
append(factoryType.getFormatTitle());
}
});
myModelStorageFormat.setSelectedItem(ModelFactoryService.getInstance().getFactoryTypes().get(0));
mainPanel.add(myModelStorageFormat, constraints);
myContentPane.add(mainPanel, BorderLayout.CENTER);
}
private ModelFactoryType[] getStorageFormats() {
List<ModelFactoryType> result = ModelFactoryService.getInstance().getFactoryTypes();
return result.toArray(new ModelFactoryType[result.size()]);
}
@Override
protected void doOKAction() {
if (!(check())) {
return;
}
if (!(((ModelRoot) myModelRoots.getSelectedItem()).canCreateModel(getFqName())) && myModule instanceof Language && myModelRoots.getSelectedItem() instanceof FileBasedModelRoot) {
final FileBasedModelRoot selectedModelRoot = (FileBasedModelRoot) myModelRoots.getSelectedItem();
Memento memento = new MementoImpl();
selectedModelRoot.save(memento);
final ModelRootDescriptor oldModelRootDescriptor = new ModelRootDescriptor(selectedModelRoot.getType(), memento);
final FileBasedModelRoot newModelRoot = (FileBasedModelRoot) PersistenceFacade.getInstance().getModelRootFactory(selectedModelRoot.getType()).create();
newModelRoot.load(memento);
newModelRoot.addFile(FileBasedModelRoot.SOURCE_ROOTS, newModelRoot.getContentRoot() + File.separator + "languageAccessories");
memento = new MementoImpl();
newModelRoot.save(memento);
final ModelRootDescriptor newModelRootDescriptor = new ModelRootDescriptor(newModelRoot.getType(), memento);
myProject.getRepository().getModelAccess().runWriteAction(new Runnable() {
public void run() {
final LanguageDescriptor languageDescriptor = ((Language) myModule).getModuleDescriptor();
Iterator<ModelRootDescriptor> iterator = languageDescriptor.getModelRootDescriptors().iterator();
while (iterator.hasNext()) {
ModelRootDescriptor descriptor = iterator.next();
if (descriptor.getType().equals(oldModelRootDescriptor.getType()) && descriptor.getMemento().equals(oldModelRootDescriptor.getMemento())) {
iterator.remove();
break;
}
}
languageDescriptor.getModelRootDescriptors().add(newModelRootDescriptor);
// see MPS-18743
myProject.getRepository().saveAll();
myModule.setModuleDescriptor(languageDescriptor);
myModule.save();
}
});
myProject.getRepository().getModelAccess().runReadAction(new Runnable() {
public void run() {
for (ModelRoot modelRoot : myModule.getModelRoots()) {
if (modelRoot instanceof FileBasedModelRoot && Objects.equals(((FileBasedModelRoot) modelRoot).getContentRoot(), selectedModelRoot.getContentRoot())) {
myModelRoots.addItem(modelRoot);
myModelRoots.setSelectedItem(modelRoot);
}
}
}
});
}
final Reference<ModelCannotBeCreatedException> refException = new Reference<ModelCannotBeCreatedException>();
myResult = new ModelAccessHelper(myProject.getModelAccess()).executeCommand(new Computable<EditableSModel>() {
@Override
public EditableSModel compute() {
String fqName = getFqName();
ModelRoot mr = (ModelRoot) myModelRoots.getSelectedItem();
@NotNull EditableSModel result;
try {
if (mr instanceof DefaultModelRoot) {
result = SModuleOperations.createModelWithAdjustments(fqName, mr, (ModelFactoryType) myModelStorageFormat.getSelectedItem());
} else {
result = SModuleOperations.createModelWithAdjustments(fqName, mr, null);
}
} catch (ModelCannotBeCreatedException e) {
refException.set(e);
return null;
}
if (myClone == null) {
return result;
}
ModelImports imports = new ModelImports(result);
imports.copyImportedModelsFrom(myClone);
imports.copyUsedLanguagesFrom(myClone);
imports.copyEmployedDevKitsFrom(myClone);
imports.copyLanguageEngagedOnGeneration(myClone);
if (myPreserveIds) {
CopyUtil.copyModelContentAndPreserveIds(myClone, result);
} else {
CopyUtil.copyModelContent(myClone, result);
}
result.setChanged(true);
result.save();
return result;
}
});
if (!(refException.isNull())) {
Messages.showErrorDialog(myProject.getProject(), "Could not create a new model because '" + refException.get().getMessage() + "'", "Error");
}
super.doOKAction();
if (myResult != null) {
MPSPropertiesConfigurable configurable = new ModelPropertiesConfigurable(myResult, myProject);
final SingleConfigurableEditor configurableEditor = new SingleConfigurableEditor(ProjectHelper.toIdeaProject(myProject), configurable, "#MPSPropertiesConfigurable");
ApplicationManager.getApplication().invokeLater(new Runnable() {
public void run() {
configurableEditor.show();
}
}, ModalityState.current());
}
}
private String getFqName() {
String stereo = myModelStereotype.getSelectedItem().toString().trim();
return myModelName.getText() + ((stereo.length() > 0 ? "@" + stereo : ""));
}
private boolean check() {
Object selected = myModelRoots.getSelectedItem();
if (!((selected instanceof ModelRoot))) {
setErrorText("Model root is not selected");
return false;
}
ModelRoot mr = ((ModelRoot) selected);
String modelName = myModelName.getText();
if (modelName.length() == 0) {
setErrorText("Empty model name isn't allowed");
return false;
}
if (modelName.lastIndexOf(".") == modelName.length()) {
setErrorText("Empty model short name isn't allowed");
return false;
}
if (myModule instanceof Language) {
if (LanguageAspectSupport.isLanguageModelNameForbidden(modelName)) {
String shortName = modelName.substring(modelName.lastIndexOf(".") + 1);
setErrorText("This name isn't allowed because '" + shortName + "' is language aspect name");
return false;
}
}
if (!(SourceVersion.isName(modelName))) {
setErrorText("Model name should be valid Java package");
return false;
}
if (!(mr.canCreateModel(getFqName()))) {
boolean isLang = myModule instanceof Language;
if (!(isLang) || !((mr instanceof FileBasedModelRoot))) {
setErrorText("Can't create a model with this name under this model root");
return false;
}
}
setErrorText(null);
return true;
}
@Nullable
@Override
protected JComponent createCenterPanel() {
return myContentPane;
}
@Nullable
@Override
public JComponent getPreferredFocusedComponent() {
return myModelName;
}
}