package org.infernus.idea.checkstyle.util; import com.intellij.openapi.module.Module; import com.intellij.openapi.roots.CompilerModuleExtension; import com.intellij.openapi.roots.libraries.LibraryUtil; import com.intellij.openapi.vfs.JarFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.impl.jar.JarFileSystemImpl; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.jetbrains.annotations.NotNull; import java.io.File; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.List; import java.util.Optional; import static java.util.Collections.emptyList; import static java.util.Optional.empty; public final class ModulePaths { private static final Log LOG = LogFactory.getLog(ModulePaths.class); private ModulePaths() { // utility class } public static List<URL> libraryPathsFor(final Module moduleInScope) { return pathsOf(libraryRootsFor(moduleInScope)); } private static VirtualFile[] libraryRootsFor(final Module module) { return LibraryUtil.getLibraryRoots(new Module[]{module}, false, false); } public static List<URL> compilerOutputPathsFor(final Module module) { final CompilerModuleExtension compilerModule = CompilerModuleExtension.getInstance(module); if (compilerModule != null) { return pathsOf(compilerModule.getOutputRoots(true)); } return emptyList(); } private static List<URL> pathsOf(final VirtualFile[] files) { final List<URL> outputPaths = new ArrayList<>(); for (final VirtualFile file : files) { try { outputPaths.add(urlFor(pathOf(file))); } catch (MalformedURLException e) { LOG.error("Malformed virtual file URL: " + file, e); } } return outputPaths; } @NotNull private static URL urlFor(final String filePath) throws MalformedURLException { // toURI().toURL() escapes, whereas toURL() doesn't. return new File(filePath).toURI().toURL(); } @NotNull private static String pathOf(final VirtualFile file) { String filePath = stripJarFileSuffix(file); if (filePath.endsWith(".jar")) { return mirrorPathOf(file).orElse(filePath); } return filePath; } @NotNull private static Optional<String> mirrorPathOf(final VirtualFile file) { final JarFileSystem jarFileSystem = JarFileSystem.getInstance(); if (jarFileSystem instanceof JarFileSystemImpl) { final File mirroredFile = ((JarFileSystemImpl) jarFileSystem).getMirroredFile(file); if (mirroredFile != null) { return Optional.of(mirroredFile.getPath()); } } return empty(); } @NotNull private static String stripJarFileSuffix(final VirtualFile file) { final String filePath = file.getPath(); if (filePath.endsWith("!/")) { // filter JAR suffix return filePath.substring(0, filePath.length() - 2); } return filePath; } }