/* * Copyright 2000-2010 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 com.intellij.packaging.impl.compiler; import com.intellij.openapi.application.ReadAction; import com.intellij.openapi.application.Result; import com.intellij.openapi.compiler.CompileContext; import com.intellij.openapi.compiler.CompilerMessageCategory; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.newvfs.ArchiveFileSystem; import com.intellij.packaging.artifacts.Artifact; import com.intellij.packaging.artifacts.ArtifactManager; import com.intellij.packaging.elements.PackagingElement; import com.intellij.packaging.elements.PackagingElementResolvingContext; import com.intellij.packaging.impl.artifacts.ArtifactUtil; import com.intellij.packaging.impl.elements.FileOrDirectoryCopyPackagingElement; import com.intellij.util.Processor; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.MultiMap; import gnu.trove.THashMap; import org.jetbrains.annotations.NotNull; import java.io.BufferedInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.*; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; /** * @author nik */ public class ArtifactCompilerUtil { private static final Logger LOG = Logger.getInstance("#com.intellij.packaging.impl.compiler.ArtifactCompilerUtil"); private ArtifactCompilerUtil() { } @NotNull public static Pair<InputStream, Long> getArchiveEntryInputStream(VirtualFile sourceFile, final CompileContext context) throws IOException { final String fullPath = sourceFile.getPath(); final int jarEnd = fullPath.indexOf(ArchiveFileSystem.ARCHIVE_SEPARATOR); LOG.assertTrue(jarEnd != -1, fullPath); String pathInJar = fullPath.substring(jarEnd + ArchiveFileSystem.ARCHIVE_SEPARATOR.length()); String jarPath = fullPath.substring(0, jarEnd); final ZipFile jarFile = new ZipFile(new File(FileUtil.toSystemDependentName(jarPath))); final ZipEntry entry = jarFile.getEntry(pathInJar); if (entry == null) { context.addMessage(CompilerMessageCategory.ERROR, "Cannot extract '" + pathInJar + "' from '" + jarFile.getName() + "': entry not found", null, -1, -1); return Pair.empty(); } BufferedInputStream bufferedInputStream = new BufferedInputStream(jarFile.getInputStream(entry)) { @Override public void close() throws IOException { super.close(); jarFile.close(); } }; return Pair.<InputStream, Long>create(bufferedInputStream, entry.getSize()); } public static File getArchiveFile(VirtualFile file) { String fullPath = file.getPath(); return new File(FileUtil.toSystemDependentName(fullPath.substring(fullPath.indexOf(ArchiveFileSystem.ARCHIVE_SEPARATOR)))); } @NotNull public static Set<VirtualFile> getArtifactOutputsContainingSourceFiles(final @NotNull Project project) { final List<VirtualFile> allOutputs = new ArrayList<VirtualFile>(); for (Artifact artifact : ArtifactManager.getInstance(project).getArtifacts()) { ContainerUtil.addIfNotNull(artifact.getOutputFile(), allOutputs); } final Set<VirtualFile> roots = new HashSet<VirtualFile>(); final PackagingElementResolvingContext context = ArtifactManager.getInstance(project).getResolvingContext(); for (Artifact artifact : ArtifactManager.getInstance(project).getArtifacts()) { Processor<PackagingElement<?>> processor = new Processor<PackagingElement<?>>() { @Override public boolean process(@NotNull PackagingElement<?> element) { if (element instanceof FileOrDirectoryCopyPackagingElement<?>) { final VirtualFile file = ((FileOrDirectoryCopyPackagingElement)element).findFile(); if (file != null) { roots.add(file); } } return true; } }; ArtifactUtil.processRecursivelySkippingIncludedArtifacts(artifact, processor, context); } final Set<VirtualFile> affectedOutputPaths = new HashSet<VirtualFile>(); for (VirtualFile output : allOutputs) { for (VirtualFile root : roots) { if (VfsUtilCore.isAncestor(output, root, false)) { affectedOutputPaths.add(output); } } } return affectedOutputPaths; } public static MultiMap<String, Artifact> createOutputToArtifactMap(final Project project) { final MultiMap<String, Artifact> result = new MultiMap<String, Artifact>() { @NotNull @Override protected Map<String, Collection<Artifact>> createMap() { return new THashMap<String, Collection<Artifact>>(FileUtil.PATH_HASHING_STRATEGY); } }; new ReadAction() { @Override protected void run(final Result r) { for (Artifact artifact : ArtifactManager.getInstance(project).getArtifacts()) { String outputPath = artifact.getOutputFilePath(); if (!StringUtil.isEmpty(outputPath)) { result.putValue(outputPath, artifact); } } } }.execute(); return result; } }