/* * Copyright 2003-2012 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jetbrains.mps.idea.core.library; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.LibraryOrderEntry; import com.intellij.openapi.roots.OrderEntry; import com.intellij.openapi.roots.OrderRootType; import com.intellij.openapi.roots.impl.libraries.ProjectLibraryTable; import com.intellij.openapi.roots.libraries.DummyLibraryProperties; import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.roots.ui.configuration.libraryEditor.NewLibraryEditor; import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesContainer; import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesContainer.LibraryLevel; import com.intellij.openapi.vfs.VirtualFile; import jetbrains.mps.ide.vfs.VirtualFileUtils; import jetbrains.mps.idea.core.project.SolutionIdea; import jetbrains.mps.project.AbstractModule; import jetbrains.mps.project.Solution; import jetbrains.mps.project.StubSolution; import jetbrains.mps.smodel.ModuleFileTracker; import jetbrains.mps.smodel.ModuleRepositoryFacade; import jetbrains.mps.vfs.IFile; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.mps.openapi.module.SModule; import org.jetbrains.mps.openapi.module.SModuleReference; import org.jetbrains.mps.openapi.module.SRepository; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Set; public class ModuleLibrariesUtil { private static final String AUTO_SUFFIX = "_auto"; public static final String LIBRARY_PREFIX = "mps."; @NotNull public static Collection<Library> getLibraries(SModuleReference reference, Project project) { Set<Library> libraries = new HashSet<Library>(); for (Library library : ProjectLibraryTable.getInstance(project).getLibraries()) { if (hasModule(library, reference)) { libraries.add(library); } } return libraries; } private static boolean hasModule(Library library, SModuleReference reference) { SModule module = ModuleRepositoryFacade.getInstance().getModule(reference); return hasModule(library, module); } private static boolean hasModule(Library library, SModule module) { if (!isSuitableModule(module) || !ModuleLibraryType.isModuleLibrary(library)) { return false; } Solution solution = (Solution) module; return Arrays.asList(library.getFiles(ModuleXmlRootDetector.MPS_MODULE_XML)).contains(VirtualFileUtils.getOrCreateVirtualFile(solution.getDescriptorFile())); } private static boolean isSuitableModule(SModule module) { return (module instanceof Solution) && !(module instanceof SolutionIdea) && !(module instanceof StubSolution); } @NotNull public static Set<SModuleReference> getModules(SRepository repository, final Library library) { if (!ModuleLibraryType.isModuleLibrary(library)) { return Collections.emptySet(); } final Set<SModuleReference> modules = new HashSet<SModuleReference>(); final Set<IFile> moduleXmls = new HashSet<IFile>(); for (VirtualFile file : library.getFiles(ModuleXmlRootDetector.MPS_MODULE_XML)) { moduleXmls.add(VirtualFileUtils.toIFile(file)); } repository.getModelAccess().runReadAction(new Runnable() { @Override public void run() { for (IFile moduleDescriptor : moduleXmls) { SModule moduleByFile = ModuleFileTracker.getInstance().getModuleByFile(moduleDescriptor); if (moduleByFile != null) { modules.add(moduleByFile.getModuleReference()); } } } }); return modules; } public static Set<SModuleReference> getModules(SRepository repository, OrderEntry... roots) { Set<SModuleReference> modules = new HashSet<SModuleReference>(); for (OrderEntry entry : roots) { if (entry instanceof LibraryOrderEntry) { modules.addAll(ModuleLibrariesUtil.getModules(repository, ((LibraryOrderEntry) entry).getLibrary())); } } return modules; } public static Library getOrCreateAutoLibrary(AbstractModule usedModule, Project project, LibrariesContainer container) { Library library = getAutoLibrary(usedModule.getModuleReference(), project); if (library != null) { return library; } Set<VirtualFile> stubFiles = ModuleLibraryType.getModuleJars(usedModule); IFile descriptorFile = usedModule.getDescriptorFile(); VirtualFile descriptorVirtualFile = null; if (descriptorFile != null) { descriptorVirtualFile = VirtualFileUtils.getOrCreateVirtualFile(descriptorFile); } return createAutoLibrary(usedModule.getModuleName(), stubFiles, descriptorVirtualFile, container); } @Nullable private static Library getAutoLibrary(SModuleReference reference, Project project) { String libraryName = LIBRARY_PREFIX + reference.getModuleName() + AUTO_SUFFIX; for (Library lib : ModuleLibrariesUtil.getLibraries(reference, project)) { if (lib.getName().equals(libraryName)) { return lib; } } return null; } private static Library createAutoLibrary(String moduleName, Collection<VirtualFile> libraryFiles, @Nullable VirtualFile moduleXml, LibrariesContainer container) { String libName = LIBRARY_PREFIX + moduleName + AUTO_SUFFIX; NewLibraryEditor editor = new NewLibraryEditor(); editor.setName(libName); for (VirtualFile classRoot : libraryFiles) { editor.addRoot(classRoot, OrderRootType.CLASSES); } if (moduleXml != null) { editor.addRoot(moduleXml, ModuleXmlRootDetector.MPS_MODULE_XML); } editor.setType(ModuleLibraryType.getInstance()); editor.setProperties(new DummyLibraryProperties()); return container.createLibrary(editor, LibraryLevel.PROJECT); } }