aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/tools/android/java/com/google/devtools/build/android/ziputils
diff options
context:
space:
mode:
authorGravatar Googler <noreply@google.com>2016-06-02 18:20:24 +0000
committerGravatar Dmitry Lomov <dslomov@google.com>2016-06-03 12:53:37 +0000
commit1bfa4017954f723e31c10c21b7510dae2ac3c8e6 (patch)
tree747ab0adbd3bca1ac778593d150e8db8a20bd1e8 /src/tools/android/java/com/google/devtools/build/android/ziputils
parentd9f3e89326b4f6e3d19968fa5034b02b0568fc6c (diff)
Add support for an "inclusion filter" to DexMapper tool
-- MOS_MIGRATED_REVID=123887669
Diffstat (limited to 'src/tools/android/java/com/google/devtools/build/android/ziputils')
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/ziputils/BUILD14
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/ziputils/DexMapper.java13
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/ziputils/SplitZip.java28
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/ziputils/SplitZipFilters.java44
4 files changed, 88 insertions, 11 deletions
diff --git a/src/tools/android/java/com/google/devtools/build/android/ziputils/BUILD b/src/tools/android/java/com/google/devtools/build/android/ziputils/BUILD
index cc578b7397..4f88bf774e 100644
--- a/src/tools/android/java/com/google/devtools/build/android/ziputils/BUILD
+++ b/src/tools/android/java/com/google/devtools/build/android/ziputils/BUILD
@@ -25,6 +25,7 @@ java_library(
"DexMapper.java",
"DexReducer.java",
"SplitZip.java",
+ "SplitZipFilters.java",
"Splitter.java",
],
),
@@ -37,12 +38,11 @@ java_library(
java_library(
name = "splitter_lib",
- srcs = glob(
- [
- "SplitZip.java",
- "Splitter.java",
- ],
- ),
+ srcs = [
+ "SplitZip.java",
+ "SplitZipFilters.java",
+ "Splitter.java",
+ ],
visibility = ["//visibility:public"],
deps = [
":ziputils_lib",
@@ -61,6 +61,7 @@ java_binary(
deps = [
":splitter_lib",
"//src/main/java/com/google/devtools/common/options",
+ "//third_party:guava",
],
)
@@ -88,5 +89,6 @@ java_binary(
":splitter_lib",
":ziputils_lib",
"//src/main/java/com/google/devtools/common/options",
+ "//third_party:guava",
],
)
diff --git a/src/tools/android/java/com/google/devtools/build/android/ziputils/DexMapper.java b/src/tools/android/java/com/google/devtools/build/android/ziputils/DexMapper.java
index 1e788678a6..694a00156a 100644
--- a/src/tools/android/java/com/google/devtools/build/android/ziputils/DexMapper.java
+++ b/src/tools/android/java/com/google/devtools/build/android/ziputils/DexMapper.java
@@ -14,6 +14,8 @@
package com.google.devtools.build.android.ziputils;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
import com.google.devtools.common.options.Option;
import com.google.devtools.common.options.OptionsBase;
import com.google.devtools.common.options.OptionsParser;
@@ -42,12 +44,17 @@ public class DexMapper {
String resourceFile = options.outputResources;
try {
+ Predicate<String> inputFilter = Predicates.alwaysTrue();
+ if (options.inclusionFilterJar != null) {
+ inputFilter = SplitZipFilters.entriesIn(options.inclusionFilterJar);
+ }
new SplitZip()
.setVerbose(false)
.useDefaultEntryDate()
.setSplitDexedClasses(options.splitDexedClasses)
.addInputs(inputs)
.addOutputs(outputs)
+ .setInputFilter(inputFilter)
.setMainClassListFile(filterFile)
.setResourceFile(resourceFile)
.run()
@@ -99,5 +106,11 @@ public class DexMapper {
defaultValue = "false",
help = "Split X.class.dex like X.class if true. Treated as resources if false.")
public boolean splitDexedClasses;
+
+ @Option(name = "inclusion_filter_jar",
+ defaultValue = "null",
+ help = "Only copy entries that are listed in the given Jar file. By default, all entries "
+ + "are copied over.")
+ public String inclusionFilterJar;
}
}
diff --git a/src/tools/android/java/com/google/devtools/build/android/ziputils/SplitZip.java b/src/tools/android/java/com/google/devtools/build/android/ziputils/SplitZip.java
index 4fd1f154b3..dabe4dd34b 100644
--- a/src/tools/android/java/com/google/devtools/build/android/ziputils/SplitZip.java
+++ b/src/tools/android/java/com/google/devtools/build/android/ziputils/SplitZip.java
@@ -25,6 +25,9 @@ import static com.google.devtools.build.android.ziputils.LocalFileHeader.LOCTIM;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.google.common.base.Preconditions;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.collect.Sets;
import java.io.BufferedReader;
import java.io.File;
@@ -67,6 +70,7 @@ public class SplitZip implements EntryHandler {
private final Map<String, ZipOut> assignments = new HashMap<>();
private final Map<String, CentralDirectory> centralDirectories;
private final Set<String> classes = new TreeSet<>();
+ private Predicate<String> inputFilter = Predicates.alwaysTrue();
/**
* Creates an un-configured {@code SplitZip} instance.
@@ -257,6 +261,16 @@ public class SplitZip implements EntryHandler {
}
/**
+ * Set a predicate to only include files with matching filenames in any of the outputs. <b>Other
+ * zip entries are dropped</b>, regardless of whether they're classes or resources and regardless
+ * of whether they're listed in {@link #setMainClassListFile}.
+ */
+ public SplitZip setInputFilter(Predicate<String> inputFilter) {
+ this.inputFilter = Preconditions.checkNotNull(inputFilter);
+ return this;
+ }
+
+ /**
* Executes this {@code SplitZip}, reading content from the configured input locations, creating
* the specified number of archives, in the configured output directory.
*
@@ -305,7 +319,8 @@ public class SplitZip implements EntryHandler {
ZipOut out = assignments.remove(normalizedFilename(header.getFilename()));
if (out == null) {
// Skip unassigned file; includes a file with the same name as a previously processed one.
- // This in particular picks the first .class or .dex file encountered for a given class name.
+ // This in particular picks the first .class or .dex file encountered for a given class name
+ // and drops any file not matched by inputFilter.
return;
}
if (dirEntry == null) {
@@ -391,6 +406,9 @@ public class SplitZip implements EntryHandler {
CentralDirectory cdir = centralDirectories.get(in.getFilename());
for (DirectoryEntry entry : cdir.list()) {
String filename = normalizedFilename(entry.getFilename());
+ if (!inputFilter.apply(filename)) {
+ continue;
+ }
if (filename.endsWith(".class")) {
// Only pass classes to the splitter, so that it can do the best job
// possible distributing them across output files.
@@ -402,15 +420,15 @@ public class SplitZip implements EntryHandler {
}
}
}
- Splitter entryFilter = new Splitter(outputs.size(), classes.size());
+ Splitter splitter = new Splitter(outputs.size(), classes.size());
if (filter != null) {
// Assign files in the filter to the first output file.
- entryFilter.assign(filter);
- entryFilter.nextShard(); // minimal initial shard
+ splitter.assign(Sets.filter(filter, inputFilter));
+ splitter.nextShard(); // minimal initial shard
}
for (String path : classes) {
// Use normalized filename so the filter file doesn't have to change
- int assignment = entryFilter.assign(path);
+ int assignment = splitter.assign(path);
Preconditions.checkState(assignment >= 0 && assignment < zipOuts.length);
assignments.put(path, zipOuts[assignment]);
}
diff --git a/src/tools/android/java/com/google/devtools/build/android/ziputils/SplitZipFilters.java b/src/tools/android/java/com/google/devtools/build/android/ziputils/SplitZipFilters.java
new file mode 100644
index 0000000000..07c38e8889
--- /dev/null
+++ b/src/tools/android/java/com/google/devtools/build/android/ziputils/SplitZipFilters.java
@@ -0,0 +1,44 @@
+// Copyright 2015 The Bazel Authors. All rights reserved.
+//
+// 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.google.devtools.build.android.ziputils;
+
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.collect.ImmutableSet;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+
+/**
+ * Custom filters intended for {@link SplitZip#setInputFilter}.
+ */
+public class SplitZipFilters {
+
+ /**
+ * Returns a predicate that returns true for filenames contained in the given zip file.
+ */
+ public static Predicate<String> entriesIn(String filterZip) throws IOException {
+ // Aggregate filenames into a set so Predicates.in is efficient
+ ImmutableSet.Builder<String> filenames = ImmutableSet.builder();
+ @SuppressWarnings("resource") // ZipIn takes ownership but isn't Closable
+ ZipIn zip = new ZipIn(new FileInputStream(filterZip).getChannel(), filterZip);
+ for (DirectoryEntry entry : zip.centralDirectory().list()) {
+ filenames.add(entry.getFilename());
+ }
+ return Predicates.in(filenames.build());
+ }
+
+ private SplitZipFilters() {
+ }
+}