package jetbrains.mps.jps.project; import com.intellij.openapi.util.io.FileUtil; import jetbrains.mps.extapi.module.ModuleFacetBase; import jetbrains.mps.extapi.persistence.FileDataSource; import jetbrains.mps.idea.core.make.MPSMakeConstants; import jetbrains.mps.idea.core.project.JpsModelRootContributor; import jetbrains.mps.jps.build.MPSCompilerUtil; import jetbrains.mps.jps.model.JpsMPSRepositoryFacade; import jetbrains.mps.module.SDependencyImpl; import jetbrains.mps.persistence.FilePerRootDataSource; import jetbrains.mps.project.ModuleId; import jetbrains.mps.project.Solution; import jetbrains.mps.project.facets.JavaModuleFacet; import jetbrains.mps.project.facets.JavaModuleFacetImpl; import jetbrains.mps.project.structure.modules.SolutionDescriptor; import jetbrains.mps.vfs.FileSystem; import jetbrains.mps.vfs.IFile; import org.jetbrains.annotations.NotNull; import org.jetbrains.jps.incremental.CompileContext; import org.jetbrains.jps.incremental.messages.BuildMessage.Kind; import org.jetbrains.jps.incremental.messages.CompilerMessage; import org.jetbrains.jps.model.java.JpsJavaExtensionService; import org.jetbrains.jps.model.java.JpsJavaSdkType; import org.jetbrains.jps.model.library.JpsLibrary; import org.jetbrains.jps.model.module.JpsDependencyElement; import org.jetbrains.jps.model.module.JpsLibraryDependency; import org.jetbrains.jps.model.module.JpsModule; import org.jetbrains.jps.model.module.JpsModuleDependency; import org.jetbrains.jps.model.module.JpsSdkDependency; import org.jetbrains.jps.service.JpsServiceManager; import org.jetbrains.mps.openapi.model.SModel; import org.jetbrains.mps.openapi.module.SDependency; import org.jetbrains.mps.openapi.module.SDependencyScope; import org.jetbrains.mps.openapi.persistence.DataSource; import org.jetbrains.mps.openapi.persistence.Memento; import org.jetbrains.mps.openapi.persistence.ModelRoot; import java.io.File; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.atomic.AtomicReference; /** * danilla 12/10/12 */ public class JpsSolutionIdea extends Solution { private JpsModule myModule; private Set<ModelRoot> myContributedModelRoots; private CompileContext myCompileContext; private AtomicReference<Map<String, SModel>> myPathToModel = new AtomicReference<Map<String, SModel>>(); public JpsSolutionIdea(@NotNull JpsModule module, SolutionDescriptor descriptor, CompileContext compileCtx) { super(descriptor, null); myModule = module; myModule = module; myCompileContext = compileCtx; } public JpsModule getModule() { return myModule; } public SModel getModelByPath(String path) { Map<String, SModel> map = myPathToModel.get(); if (map != null) { return map.get(path); } map = new HashMap<String, SModel>(); for (SModel m : getModels()) { DataSource source = m.getSource(); if (source instanceof FileDataSource) { String p = ((FileDataSource) source).getFile().getPath(); p = FileUtil.toCanonicalPath(p); map.put(p, m); } else if(source instanceof FilePerRootDataSource) { String p = ((FilePerRootDataSource) source).getFolder().getDescendant(".model").getPath(); p = FileUtil.toCanonicalPath(p); map.put(p, m); } } myPathToModel.compareAndSet(null, map); return map.get(path); } @Override public boolean isPackaged() { return false; } @Override public Iterable<SDependency> getDeclaredDependencies() { List<SDependency> dependencies = new ArrayList<SDependency>(); MPSCompilerUtil.debug(myCompileContext, "^^^^ getDependencies for " + myModule.getName()); for (JpsDependencyElement jpsDep : myModule.getDependenciesList().getDependencies()) { Solution solution = null; if (jpsDep instanceof JpsModuleDependency) { JpsModule jpsModule = ((JpsModuleDependency) jpsDep).getModule(); solution = JpsMPSRepositoryFacade.getInstance().getSolution(jpsModule); } else if (jpsDep instanceof JpsLibraryDependency) { MPSCompilerUtil.debug(myCompileContext, "**** lib dep: " + ((JpsLibraryDependency) jpsDep).getLibraryReference().getLibraryName()); JpsLibrary lib = ((JpsLibraryDependency) jpsDep).getLibrary(); if (lib == null) { MPSCompilerUtil.debug(myCompileContext, "**** not found lib dep: " + ((JpsLibraryDependency) jpsDep).getLibraryReference().getLibraryName()); } else { String name = lib.getName(); solution = (Solution) getRepository().getModule(ModuleId.foreign(name)); } } else if (jpsDep instanceof JpsSdkDependency) { MPSCompilerUtil.debug(myCompileContext, "**** jdk dep: " + ((JpsSdkDependency) jpsDep).getSdkReference().getSdkName()); if (((JpsSdkDependency) jpsDep).getSdkType().equals(JpsJavaSdkType.INSTANCE)) { // do nothing, since we store SDK with a special module id (JDK module id, which is pulled in by use baseLanguage) // FIXME OR put JDK module id? continue; } String sdkName = ((JpsSdkDependency) jpsDep).getSdkReference().getSdkName(); solution = (Solution) getRepository().getModule(ModuleId.foreign(sdkName)); } if (solution != null) { dependencies.add(new SDependencyImpl(solution, SDependencyScope.DEFAULT, false)); } } return dependencies; } @Override protected ModuleFacetBase setupFacet(ModuleFacetBase facet, Memento memento) { if (facet instanceof JavaModuleFacet) { facet = new JavaModuleFacetImpl() { @Override public IFile getClassesGen() { IFile descriptorFile = getDescriptorFile(); if (descriptorFile != null && descriptorFile.isReadOnly()) { myCompileContext.processMessage(new CompilerMessage(MPSMakeConstants.BUILDER_ID, Kind.INFO, " super.ClassesGen " + super.getClassesGen())); return super.getClassesGen(); } // FIX hard-coded forTests=false // TODO use ProjectPaths.getModuleOutputDir(myModule, false); (using JpsJavaExtensionService directly to be compatible with IDEA 12.0.0 release) File outputDir = JpsJavaExtensionService.getInstance().getOutputDirectory(myModule, false); if (outputDir == null) return null; MPSCompilerUtil.debug(myCompileContext, " ClassesGen from module " + outputDir.getPath()); return FileSystem.getInstance().getFileByPath(outputDir.getPath()); } }; } return super.setupFacet(facet, memento); } @Override protected Iterable<ModelRoot> loadRoots() { if (myContributedModelRoots == null) { myContributedModelRoots = new HashSet<ModelRoot>(); for (JpsModelRootContributor c : JpsServiceManager.getInstance().getExtensions(JpsModelRootContributor.class)) { for (ModelRoot root : c.getModelRoots(myModule)) { myContributedModelRoots.add(root); } } } List<ModelRoot> sum = new ArrayList<ModelRoot>(); for (ModelRoot mr : super.loadRoots()) { sum.add(mr); } sum.addAll(myContributedModelRoots); return sum; } }