| /* |
| * Copyright 2000-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 org.jetbrains.jps.incremental.artifacts.instructions; |
| |
| import com.intellij.openapi.util.Condition; |
| import com.intellij.openapi.util.io.FileUtil; |
| import com.intellij.openapi.util.text.StringUtil; |
| import org.jetbrains.annotations.NotNull; |
| import org.jetbrains.annotations.Nullable; |
| import org.jetbrains.jps.builders.BuildOutputConsumer; |
| import org.jetbrains.jps.builders.logging.ProjectBuilderLogger; |
| import org.jetbrains.jps.incremental.CompileContext; |
| import org.jetbrains.jps.incremental.artifacts.ArtifactBuildTarget; |
| import org.jetbrains.jps.incremental.artifacts.ArtifactOutputToSourceMapping; |
| import org.jetbrains.jps.incremental.artifacts.IncArtifactBuilder; |
| import org.jetbrains.jps.incremental.artifacts.JarPathUtil; |
| import org.jetbrains.jps.incremental.artifacts.impl.JpsArtifactPathUtil; |
| |
| import java.io.*; |
| import java.util.Collections; |
| import java.util.Enumeration; |
| import java.util.zip.ZipEntry; |
| import java.util.zip.ZipFile; |
| |
| /** |
| * @author nik |
| */ |
| public class JarBasedArtifactRootDescriptor extends ArtifactRootDescriptor { |
| private final String myPathInJar; |
| private final Condition<String> myPathInJarFilter; |
| |
| public JarBasedArtifactRootDescriptor(@NotNull File jarFile, |
| @NotNull String pathInJar, |
| @NotNull SourceFileFilter filter, |
| int index, |
| @NotNull ArtifactBuildTarget target, |
| @NotNull DestinationInfo destinationInfo, |
| @NotNull Condition<String> pathInJarFilter) { |
| super(jarFile, filter, index, target, destinationInfo); |
| myPathInJar = pathInJar; |
| myPathInJarFilter = pathInJarFilter; |
| } |
| |
| public void processEntries(EntryProcessor processor) throws IOException { |
| if (!myRoot.isFile()) return; |
| |
| String prefix = StringUtil.trimStart(myPathInJar, "/"); |
| if (!StringUtil.endsWithChar(prefix, '/')) prefix += "/"; |
| if (prefix.equals("/")) { |
| prefix = ""; |
| } |
| |
| try { |
| ZipFile zipFile = new ZipFile(myRoot); |
| try { |
| final Enumeration<? extends ZipEntry> entries = zipFile.entries(); |
| |
| while (entries.hasMoreElements()) { |
| ZipEntry entry = entries.nextElement(); |
| final String name = entry.getName(); |
| if (name.startsWith(prefix)) { |
| String relativePath = name.substring(prefix.length()); |
| if (myPathInJarFilter.value(relativePath)) { |
| processor.process(entry.isDirectory() ? null : zipFile.getInputStream(entry), relativePath, entry); |
| } |
| } |
| } |
| } |
| finally { |
| zipFile.close(); |
| } |
| } |
| catch (IOException e) { |
| throw new IOException("Error occurred during processing zip file " + myRoot + ": " + e.getMessage(), e); |
| } |
| } |
| |
| @Override |
| protected String getFullPath() { |
| return myRoot.getPath() + JarPathUtil.JAR_SEPARATOR + myPathInJar; |
| } |
| |
| public void copyFromRoot(final String filePath, |
| final int rootIndex, final String outputPath, |
| CompileContext context, final BuildOutputConsumer outputConsumer, |
| final ArtifactOutputToSourceMapping outSrcMapping) throws IOException { |
| if (!myRoot.isFile()) return; |
| ProjectBuilderLogger logger = context.getLoggingManager().getProjectBuilderLogger(); |
| if (logger.isEnabled()) { |
| logger.logCompiledPaths(Collections.singletonList(filePath), IncArtifactBuilder.BUILDER_NAME, "Extracting archive:"); |
| } |
| processEntries(new EntryProcessor() { |
| @Override |
| public void process(@Nullable InputStream inputStream, @NotNull String relativePath, ZipEntry entry) throws IOException { |
| final String fullOutputPath = JpsArtifactPathUtil.appendToPath(outputPath, relativePath); |
| final File outputFile = new File(fullOutputPath); |
| |
| FileUtil.createParentDirs(outputFile); |
| if (inputStream == null) { |
| outputFile.mkdir(); |
| } |
| else { |
| if (outSrcMapping.getState(fullOutputPath) == null) { |
| final BufferedInputStream from = new BufferedInputStream(inputStream); |
| final BufferedOutputStream to = new BufferedOutputStream(new FileOutputStream(outputFile)); |
| try { |
| FileUtil.copy(from, to); |
| } |
| finally { |
| from.close(); |
| to.close(); |
| } |
| outputConsumer.registerOutputFile(outputFile, Collections.singletonList(filePath)); |
| } |
| outSrcMapping.appendData(fullOutputPath, rootIndex, filePath); |
| } |
| } |
| }); |
| } |
| |
| public interface EntryProcessor { |
| void process(@Nullable InputStream inputStream, @NotNull String relativePath, ZipEntry entry) throws IOException; |
| } |
| } |