blob: c5eb04940b8562ecad000e61806f45daa3c2f62a [file] [log] [blame]
/*
* 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;
}
}