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)); } } }