From f0f0264e6db15f68f3781c9315714da799b659ea Mon Sep 17 00:00:00 2001 From: nik Date: Mon, 6 Feb 2012 16:59:18 +0400 Subject: [PATCH] support for 'extracted directory' elements in artifacts on compile server --- .../artifacts/IncArtifactBuilder.java | 24 +------ .../artifacts/impl/JarsBuilder.java | 38 ++++++---- .../ArtifactInstructionsBuilderImpl.java | 14 ++-- .../instructions/ArtifactSourceRoot.java | 4 ++ .../FileBasedArtifactSourceRoot.java | 23 ++++++ .../JarBasedArtifactSourceRoot.java | 71 ++++++++++++++++++- 6 files changed, 128 insertions(+), 46 deletions(-) diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/IncArtifactBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/IncArtifactBuilder.java index 6ca0a195981d..971eec712f40 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/IncArtifactBuilder.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/IncArtifactBuilder.java @@ -6,7 +6,6 @@ import com.intellij.util.ArrayUtil; import com.intellij.util.SmartList; import com.intellij.util.containers.ContainerUtil; import gnu.trove.THashSet; -import org.jetbrains.jps.PathUtil; import org.jetbrains.jps.artifacts.Artifact; import org.jetbrains.jps.incremental.CompileContext; import org.jetbrains.jps.incremental.ProjectBuildException; @@ -21,7 +20,6 @@ import org.jetbrains.jps.incremental.messages.UptoDateFilesSavedEvent; import org.jetbrains.jps.incremental.storage.BuildDataManager; import java.io.File; -import java.io.IOException; import java.util.*; /** @@ -97,7 +95,7 @@ public class IncArtifactBuilder extends ProjectLevelBuilder { public void process(ArtifactSourceRoot root, Collection destinations) throws Exception { for (DestinationInfo destination : destinations) { if (destination instanceof ExplodedDestinationInfo) { - copyFromRoot(root, filePath, destination.getOutputPath(), outputs); + root.copyFromRoot(filePath, destination.getOutputPath(), outputs); } else { outputs.add(destination.getOutputFilePath()); @@ -126,26 +124,6 @@ public class IncArtifactBuilder extends ProjectLevelBuilder { } } - private static void copyFromRoot(ArtifactSourceRoot root, String path, String outputPath, List outputs) throws IOException { - if (root instanceof FileBasedArtifactSourceRoot) { - final File file = new File(FileUtil.toSystemDependentName(path)); - String targetPath; - if (!file.equals(root.getRootFile())) { - final String relativePath = FileUtil.getRelativePath(FileUtil.toSystemIndependentName(root.getRootFile().getPath()), path, '/'); - targetPath = PathUtil.appendToPath(outputPath, relativePath); - } - else { - targetPath = outputPath; - } - final File targetFile = new File(FileUtil.toSystemDependentName(targetPath)); - FileUtil.copyContent(file, targetFile); - outputs.add(outputPath); - } - else { - //todo[nik] - } - } - private static Set deleteOutdatedFiles(Set deletedFiles, CompileContext context, ArtifactSourceToOutputMapping mapping) throws Exception { if (deletedFiles.isEmpty()) return Collections.emptySet(); diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/impl/JarsBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/impl/JarsBuilder.java index 4b570e9717c6..1aa7c878c77c 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/impl/JarsBuilder.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/impl/JarsBuilder.java @@ -29,6 +29,7 @@ import gnu.trove.THashSet; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.jps.PathUtil; import org.jetbrains.jps.incremental.CompileContext; import org.jetbrains.jps.incremental.artifacts.IncArtifactBuilder; import org.jetbrains.jps.incremental.artifacts.instructions.*; @@ -182,22 +183,29 @@ public class JarsBuilder { } } - private void extractFileAndAddToJar(JarOutputStream jarOutputStream, JarBasedArtifactSourceRoot root, String relativePath, THashSet writtenPaths) + private static void extractFileAndAddToJar(final JarOutputStream jarOutputStream, final JarBasedArtifactSourceRoot root, + final String relativeOutputPath, final THashSet writtenPaths) throws IOException { - //todo[nik] - /* - relativePath = addParentDirectories(jarOutputStream, writtenPaths, relativePath); - if (!writtenPaths.add(relativePath)) return; + final long timestamp = root.getRootFile().lastModified(); + root.processEntries(new JarBasedArtifactSourceRoot.EntryProcessor() { + @Override + public void process(@Nullable InputStream inputStream, @NotNull String relativePath) throws IOException { + String pathInJar = addParentDirectories(jarOutputStream, writtenPaths, PathUtil.appendToPath(relativeOutputPath, relativePath)); + if (!writtenPaths.add(pathInJar)) return; - final BufferedInputStream input = ArtifactCompilerUtil.getJarEntryInputStream(root, myContext); - if (input == null) return; + if (inputStream != null) { + ZipEntry entry = new ZipEntry(pathInJar); + entry.setTime(timestamp); + jarOutputStream.putNextEntry(entry); + FileUtil.copy(inputStream, jarOutputStream); + jarOutputStream.closeEntry(); + } + else { + addDirectoryEntry(jarOutputStream, pathInJar + "/"); + } + } + }); - ZipEntry entry = new ZipEntry(relativePath); - entry.setTime(root.getRootFile().lastModified()); - jarOutputStream.putNextEntry(entry); - FileUtil.copy(input, jarOutputStream); - jarOutputStream.closeEntry(); - */ } private void addFileToJar(final @NotNull JarOutputStream jarOutputStream, final @NotNull File jarFile, @NotNull File file, @@ -218,7 +226,7 @@ public class JarsBuilder { while (i != -1) { String prefix = relativePath.substring(0, i+1); if (!writtenPaths.contains(prefix) && prefix.length() > 1) { - addEntry(jarOutputStream, prefix); + addDirectoryEntry(jarOutputStream, prefix); writtenPaths.add(prefix); } i = relativePath.indexOf('/', i + 1); @@ -226,7 +234,7 @@ public class JarsBuilder { return relativePath; } - private static void addEntry(final ZipOutputStream output, @NonNls final String relativePath) throws IOException { + private static void addDirectoryEntry(final ZipOutputStream output, @NonNls final String relativePath) throws IOException { ZipEntry e = new ZipEntry(relativePath); e.setMethod(ZipEntry.STORED); e.setSize(0); diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/ArtifactInstructionsBuilderImpl.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/ArtifactInstructionsBuilderImpl.java index 32aa1ffe4568..564c5a5c0056 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/ArtifactInstructionsBuilderImpl.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/ArtifactInstructionsBuilderImpl.java @@ -46,17 +46,17 @@ public class ArtifactInstructionsBuilderImpl implements ArtifactInstructionsBuil public boolean checkOutputPath(final String outputPath, final ArtifactSourceRoot sourceFile) { //todo[nik] combine intersecting roots - ArtifactSourceRoot old = mySourceByOutput.get(outputPath); - if (old == null) { - mySourceByOutput.put(outputPath, sourceFile); - return true; - } + //ArtifactSourceRoot old = mySourceByOutput.get(outputPath); + //if (old == null) { + // mySourceByOutput.put(outputPath, sourceFile); + // return true; + //} //todo[nik] show warning? - return false; + return true; } public boolean registerJarFile(@NotNull JarInfo jarInfo, @NotNull String outputPath) { - if (mySourceByOutput.containsKey(outputPath) || myJarByPath.containsKey(outputPath)) { + if (myJarByPath.containsKey(outputPath)) { return false; } myJarByPath.put(outputPath, jarInfo); diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/ArtifactSourceRoot.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/ArtifactSourceRoot.java index b0bbf9e79d51..5f57da302b7d 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/ArtifactSourceRoot.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/ArtifactSourceRoot.java @@ -3,6 +3,8 @@ package org.jetbrains.jps.incremental.artifacts.instructions; import org.jetbrains.annotations.NotNull; import java.io.File; +import java.io.IOException; +import java.util.List; /** * @author nik @@ -19,6 +21,8 @@ public abstract class ArtifactSourceRoot { public abstract boolean containsFile(String filePath); + public abstract void copyFromRoot(String filePath, String outputPath, List outputs) throws IOException; + public SourceFileFilter getFilter() { return myFilter; } diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/FileBasedArtifactSourceRoot.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/FileBasedArtifactSourceRoot.java index 51df48f08dd8..e07e0305c3e9 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/FileBasedArtifactSourceRoot.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/FileBasedArtifactSourceRoot.java @@ -2,8 +2,11 @@ package org.jetbrains.jps.incremental.artifacts.instructions; import com.intellij.openapi.util.io.FileUtil; import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.PathUtil; import java.io.File; +import java.io.IOException; +import java.util.List; /** * @author nik @@ -36,8 +39,28 @@ public class FileBasedArtifactSourceRoot extends ArtifactSourceRoot { return myFile.equals(((FileBasedArtifactSourceRoot)o).myFile); } + @Override + public String toString() { + return myFile.getPath(); + } + @Override public int hashCode() { return 31 * super.hashCode() + myFile.hashCode(); } + + public void copyFromRoot(String filePath, String outputPath, List outputs) throws IOException { + final File file = new File(FileUtil.toSystemDependentName(filePath)); + String targetPath; + if (!file.equals(getRootFile())) { + final String relativePath = FileUtil.getRelativePath(FileUtil.toSystemIndependentName(getRootFile().getPath()), filePath, '/'); + targetPath = PathUtil.appendToPath(outputPath, relativePath); + } + else { + targetPath = outputPath; + } + final File targetFile = new File(FileUtil.toSystemDependentName(targetPath)); + FileUtil.copyContent(file, targetFile); + outputs.add(outputPath); + } } diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/JarBasedArtifactSourceRoot.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/JarBasedArtifactSourceRoot.java index 7e8784b1774f..5505f62c7758 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/JarBasedArtifactSourceRoot.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/JarBasedArtifactSourceRoot.java @@ -1,9 +1,17 @@ package org.jetbrains.jps.incremental.artifacts.instructions; 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.PathUtil; +import org.jetbrains.jps.incremental.artifacts.JarPathUtil; -import java.io.File; +import java.io.*; +import java.util.Enumeration; +import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; /** * @author nik @@ -43,4 +51,65 @@ public class JarBasedArtifactSourceRoot extends ArtifactSourceRoot { public int hashCode() { return 31 * (31 * super.hashCode() + myJarFile.hashCode()) + myPathInJar.hashCode(); } + + @Override + public String toString() { + return myJarFile.getPath() + JarPathUtil.JAR_SEPARATOR + myPathInJar; + } + + public void processEntries(EntryProcessor processor) throws IOException { + String prefix = StringUtil.trimStart(myPathInJar, "/"); + if (!StringUtil.endsWithChar(prefix, '/')) prefix += "/"; + if (prefix.equals("/")) { + prefix = ""; + } + + ZipFile zipFile = new ZipFile(myJarFile); + try { + final Enumeration 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()); + processor.process(entry.isDirectory() ? null : zipFile.getInputStream(entry), relativePath); + } + } + } + finally { + zipFile.close(); + } + } + + public void copyFromRoot(String filePath, final String outputPath, final List outputs) throws IOException { + processEntries(new EntryProcessor() { + @Override + public void process(@Nullable InputStream inputStream, @NotNull String relativePath) throws IOException { + final String fullOutputPath = FileUtil.toSystemDependentName(PathUtil.appendToPath(outputPath, relativePath)); + final File outputFile = new File(fullOutputPath); + + FileUtil.createParentDirs(outputFile); + if (inputStream == null) { + outputFile.mkdir(); + } + else { + final BufferedInputStream from = new BufferedInputStream(inputStream); + final BufferedOutputStream to = new BufferedOutputStream(new FileOutputStream(outputFile)); + try { + FileUtil.copy(from, to); + } + finally { + from.close(); + to.close(); + } + } + outputs.add(fullOutputPath); + } + }); + } + + public interface EntryProcessor { + void process(@Nullable InputStream inputStream, @NotNull String relativePath) throws IOException; + } }