package jetbrains.mps.ide.newModuleDialogs;
/*Generated by MPS */
import org.jetbrains.annotations.NotNull;
import jetbrains.mps.project.AbstractModule;
import jetbrains.mps.util.ModulePathConverter;
import jetbrains.mps.vfs.IFile;
import jetbrains.mps.util.PathConverters;
import org.jetbrains.annotations.Nullable;
import jetbrains.mps.project.structure.modules.ModuleDescriptor;
import jetbrains.mps.project.structure.modules.LanguageDescriptor;
import java.util.function.Consumer;
import jetbrains.mps.project.structure.modules.GeneratorDescriptor;
import jetbrains.mps.smodel.SModel;
import jetbrains.mps.project.structure.modules.SolutionDescriptor;
import jetbrains.mps.project.ModuleId;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
import jetbrains.mps.project.structure.modules.DeploymentDescriptor;
/**
* Incorporates the descriptor copying ('cloning') logic,
* also involving several hacks which are going to be removed after
* certain fixes in the <code>AbstractModule</code> subsystem.
*
* Created by apyshkin on 12/6/16.
*/
/*package*/ final class DescriptorCopyOrganizer {
@NotNull
private final AbstractModule myModuleToCopy;
@NotNull
private final String myNewName;
private final ModulePathConverter myModulePathConverter;
public DescriptorCopyOrganizer(@NotNull AbstractModule moduleToCopy, @NotNull String newName, @NotNull IFile newFile) {
myModuleToCopy = moduleToCopy;
myNewName = newName;
if (moduleToCopy.getDescriptorFile() != null) {
myModulePathConverter = PathConverters.forDescriptorFiles(moduleToCopy.getDescriptorFile(), newFile);
} else {
myModulePathConverter = null;
}
if (moduleToCopy.getModuleDescriptor() == null) {
throw new UnsupportedOperationException("Cannot copy without descriptor so far");
}
}
/**
* here we copy descriptor but remove the model roots and module facets descriptors since
* we need to copy them in an abstract way afterwards
*/
@Nullable
public ModuleDescriptor copyDescriptor() {
ModuleDescriptor moduleDescriptor = myModuleToCopy.getModuleDescriptor();
if (moduleDescriptor == null) {
return null;
}
final ModuleDescriptor copyDescriptor = moduleDescriptor.copy();
setNewIdAndTimestamp(copyDescriptor);
copyDescriptor.setNamespace(myNewName);
if (copyDescriptor instanceof LanguageDescriptor) {
((LanguageDescriptor) copyDescriptor).getGenerators().forEach(new Consumer<GeneratorDescriptor>() {
public void accept(GeneratorDescriptor gd) {
gd.setSourceLanguage(copyDescriptor.getModuleReference());
setNewIdAndTimestamp(gd);
// copied from Generator.generateGeneratorUID(Language sourceLanguage), I got no language instance here
gd.setNamespace(myNewName + '#' + SModel.generateUniqueId());
}
});
}
if (myModulePathConverter != null) {
hackModuleDescriptor(copyDescriptor);
if (copyDescriptor instanceof SolutionDescriptor) {
hackSolutionDescriptor((SolutionDescriptor) copyDescriptor);
} else
if (copyDescriptor instanceof LanguageDescriptor) {
hackLanguageDescriptor((LanguageDescriptor) copyDescriptor);
((LanguageDescriptor) copyDescriptor).getGenerators().forEach(new Consumer<GeneratorDescriptor>() {
@Override
public void accept(GeneratorDescriptor genDescriptor) {
DescriptorCopyOrganizer.this.hackGeneratorDescriptor(genDescriptor);
hackModuleDescriptor(genDescriptor);
}
});
}
}
return copyDescriptor;
}
private void hackModuleDescriptor(final ModuleDescriptor copyDescriptor) {
hackJavaFacetProperties(copyDescriptor);
hackDeploymentDescriptor(copyDescriptor);
resetModelRootsAndFacets(copyDescriptor);
}
private void resetModelRootsAndFacets(final ModuleDescriptor copyDescriptor) {
// these are descriptors not the model roots themselves and thus we have a problem
copyDescriptor.getModuleFacetDescriptors().clear();
// same problem with facets
copyDescriptor.getModelRootDescriptors().clear();
}
private static void setNewIdAndTimestamp(final ModuleDescriptor descriptor) {
descriptor.setId(ModuleId.regular());
descriptor.setTimestamp(Long.toString(System.currentTimeMillis()));
}
/**
* will go away when these paths are restrained to be relative [from the module file] or absolute without regard to the module file
* moreover these paths will move to the java module facet implementation
*/
private void hackJavaFacetProperties(@NotNull ModuleDescriptor copyDescriptor) {
List<String> newStubPaths = copyDescriptor.getAdditionalJavaStubPaths().stream().map(new Function<String, String>() {
@Override
public String apply(String path) {
return myModulePathConverter.source2Target(path);
}
}).collect(Collectors.<String>toList());
copyDescriptor.getAdditionalJavaStubPaths().clear();
copyDescriptor.getAdditionalJavaStubPaths().addAll(newStubPaths);
List<String> newSourcePaths = copyDescriptor.getSourcePaths().stream().map(new Function<String, String>() {
@Override
public String apply(String path) {
return myModulePathConverter.source2Target(path);
}
}).collect(Collectors.<String>toList());
copyDescriptor.getSourcePaths().clear();
copyDescriptor.getSourcePaths().addAll(newSourcePaths);
}
/**
* will go away when these paths are restrained to be relative [from the module file] or absolute without regard to the module file
* or if these locations are not needed right in the module, just are vital for its initialization
*/
private void hackDeploymentDescriptor(@NotNull ModuleDescriptor copyDescriptor) {
DeploymentDescriptor deploymentDescriptor = copyDescriptor.getDeploymentDescriptor();
if (deploymentDescriptor != null) {
deploymentDescriptor.setSourcesJar(myModulePathConverter.source2Target(deploymentDescriptor.getSourcesJar()));
deploymentDescriptor.setDescriptorFile(myModulePathConverter.source2Target(deploymentDescriptor.getDescriptorFile()));
}
}
/**
* will go away when these paths are restrained to be relative [from the module file] or absolute without regard to the module file
*/
private void hackSolutionDescriptor(@NotNull SolutionDescriptor copyDescriptor) {
final String outputPath = copyDescriptor.getOutputPath();
if (outputPath != null) {
copyDescriptor.setOutputPath(myModulePathConverter.source2Target(outputPath));
}
}
/**
* will go away when these paths are restrained to be relative [from the module file] or absolute without regard to the module file
*/
private void hackLanguageDescriptor(@NotNull LanguageDescriptor copyDescriptor) {
final String genPath = copyDescriptor.getGenPath();
if (genPath != null) {
copyDescriptor.setGenPath(myModulePathConverter.source2Target(genPath));
}
}
private void hackGeneratorDescriptor(@NotNull GeneratorDescriptor genDescriptor) {
String outputPath = genDescriptor.getOutputPath();
if (outputPath != null) {
genDescriptor.setOutputPath(myModulePathConverter.source2Target(outputPath));
}
}
}