package jetbrains.mps.ide.ui.dialogs.properties;
/*Generated by MPS */
import java.util.List;
import org.jetbrains.mps.openapi.model.SModelReference;
import java.util.ArrayList;
import org.jetbrains.mps.openapi.language.SLanguage;
import org.jetbrains.mps.openapi.module.SModuleReference;
import org.jetbrains.mps.openapi.model.SModel;
import jetbrains.mps.smodel.SModelOperations;
import jetbrains.mps.smodel.SModelInternal;
import jetbrains.mps.extapi.model.GeneratableSModel;
import org.jetbrains.mps.openapi.model.EditableSModel;
import org.jetbrains.mps.openapi.persistence.NullDataSource;
import jetbrains.mps.kernel.model.MissingDependenciesFixer;
import jetbrains.mps.generator.ModelGenerationStatusManager;
import java.util.Collections;
import java.util.Set;
import java.util.HashSet;
import jetbrains.mps.project.DevKit;
import jetbrains.mps.smodel.ModuleRepositoryFacade;
public class ModelProperties {
private final List<SModelReference> myImportedModels = new ArrayList<SModelReference>();
private final List<SLanguage> myUsedLanguages = new ArrayList<SLanguage>();
private final List<SModuleReference> myUsedDevKits = new ArrayList<SModuleReference>();
private final List<SLanguage> myLanguagesEngagedOnGeneration = new ArrayList<SLanguage>();
private SModel myModelDescriptor;
private boolean myDoNotGenerate;
private boolean myGenerateIntoModelFolder;
public ModelProperties(SModel modelDescriptor) {
myModelDescriptor = modelDescriptor;
SModel model = myModelDescriptor;
myImportedModels.addAll(SModelOperations.getImportedModelUIDs(model));
myUsedLanguages.addAll(((SModelInternal) model).importedLanguageIds());
myUsedDevKits.addAll(((SModelInternal) model).importedDevkits());
myLanguagesEngagedOnGeneration.addAll(((SModelInternal) model).getLanguagesEngagedOnGeneration());
myDoNotGenerate = myModelDescriptor instanceof GeneratableSModel && ((GeneratableSModel) myModelDescriptor).isDoNotGenerate();
myGenerateIntoModelFolder = myModelDescriptor instanceof GeneratableSModel && ((GeneratableSModel) myModelDescriptor).isGenerateIntoModelFolder();
}
public SModel getModelDescriptor() {
return myModelDescriptor;
}
public List<SModelReference> getImportedModels() {
return myImportedModels;
}
public List<SLanguage> getUsedLanguages() {
// imported directly only. Languages coming from devkits are separate
return myUsedLanguages;
}
public List<SModuleReference> getUsedDevKits() {
return myUsedDevKits;
}
public List<SLanguage> getLanguagesEngagedOnGeneration() {
return myLanguagesEngagedOnGeneration;
}
public boolean isDoNotGenerate() {
return myDoNotGenerate;
}
public void setDoNotGenerate(boolean doNotGenerate) {
myDoNotGenerate = doNotGenerate;
}
public boolean isGenerateIntoModelFolder() {
return myGenerateIntoModelFolder;
}
public void setGenerateIntoModelFolder(boolean generateIntoModelFolder) {
myGenerateIntoModelFolder = generateIntoModelFolder;
}
public void saveChanges() {
if (!(myModelDescriptor instanceof EditableSModel)) {
return;
}
addNewModels();
removeUnusedModels();
updateUsedLanguages();
addNewDevKits();
removeUnusedDevKits();
saveEngagedOnGenerationLanguages();
if (myModelDescriptor instanceof GeneratableSModel) {
GeneratableSModel dmd = (GeneratableSModel) myModelDescriptor;
if (dmd.isDoNotGenerate() != myDoNotGenerate) {
dmd.setDoNotGenerate(myDoNotGenerate);
}
if (dmd.isGenerateIntoModelFolder() != myGenerateIntoModelFolder) {
dmd.setGenerateIntoModelFolder(myGenerateIntoModelFolder);
}
}
if (!(myModelDescriptor.getSource() instanceof NullDataSource)) {
((EditableSModel) myModelDescriptor).save();
}
new MissingDependenciesFixer(myModelDescriptor).fixModuleDependencies();
// change of model properties might affect generation status. This explicit call is needed
// unless model dispatch proper change events (which it does not at the moment), and project pane
// got no other means to find out it needs to update generation status
ModelGenerationStatusManager.getInstance().invalidateData(Collections.singleton(myModelDescriptor));
}
private void addNewDevKits() {
Set<SModuleReference> devKitsInModel = new HashSet<SModuleReference>(((SModelInternal) myModelDescriptor).importedDevkits());
Set<SModuleReference> devKitsInProperties = new HashSet<SModuleReference>(getUsedDevKits());
devKitsInProperties.removeAll(devKitsInModel);
for (SModuleReference dk : devKitsInProperties) {
DevKit devKit = ModuleRepositoryFacade.getInstance().getModule(dk, DevKit.class);
assert devKit != null;
SModel model = myModelDescriptor;
((SModelInternal) model).addDevKit(dk);
}
}
private void removeUnusedDevKits() {
Set<SModuleReference> propsDevKits = new HashSet<SModuleReference>(getUsedDevKits());
List<SModuleReference> imported = new ArrayList<SModuleReference>(((SModelInternal) myModelDescriptor).importedDevkits());
for (SModuleReference dk : imported) {
if (!(propsDevKits.contains(dk))) {
((SModelInternal) myModelDescriptor).deleteDevKit(dk);
}
}
}
protected String getErrorString() {
return null;
}
private void updateUsedLanguages() {
Set<SLanguage> languagesInModel = new HashSet<SLanguage>(((SModelInternal) myModelDescriptor).importedLanguageIds());
Set<SLanguage> languagesInProps = new HashSet<SLanguage>(getUsedLanguages());
languagesInProps.removeAll(languagesInModel);
for (SLanguage lang : languagesInProps) {
((SModelInternal) myModelDescriptor).addLanguage(lang);
}
languagesInModel.removeAll(getUsedLanguages());
for (SLanguage lang : languagesInModel) {
((SModelInternal) myModelDescriptor).deleteLanguageId(lang);
}
}
private void saveEngagedOnGenerationLanguages() {
final SModelInternal modelInternal = (SModelInternal) myModelDescriptor;
Set<SLanguage> languagesInModel = new HashSet<SLanguage>((modelInternal).getLanguagesEngagedOnGeneration());
Set<SLanguage> languagesInProps = new HashSet<SLanguage>(getLanguagesEngagedOnGeneration());
for (SLanguage l : languagesInModel) {
// remove if not from actual state
if (!(languagesInProps.remove(l))) {
modelInternal.removeEngagedOnGenerationLanguage(l);
}
}
// add those left
for (SLanguage l : languagesInProps) {
modelInternal.addEngagedOnGenerationLanguage(l);
}
}
private void addNewModels() {
Set<SModelReference> modelsInProps = new HashSet<SModelReference>(getImportedModels());
SModel smodel = myModelDescriptor;
modelsInProps.removeAll(SModelOperations.getImportedModelUIDs(smodel));
for (SModelReference modelReference : modelsInProps) {
((SModelInternal) smodel).addModelImport(modelReference, false);
}
}
private void removeUnusedModels() {
SModel smodel = myModelDescriptor;
Set<SModelReference> modelsInModel = new HashSet<SModelReference>(SModelOperations.getImportedModelUIDs(smodel));
modelsInModel.removeAll(getImportedModels());
for (SModelReference modelReference : modelsInModel) {
((SModelInternal) smodel).deleteModelImport(modelReference);
}
}
}