You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by db...@apache.org on 2021/04/30 21:54:51 UTC
[tomee-patch-plugin] branch master updated: Ability to add resource
files to a jar
This is an automated email from the ASF dual-hosted git repository.
dblevins pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tomee-patch-plugin.git
The following commit(s) were added to refs/heads/master by this push:
new 00c285d Ability to add resource files to a jar
00c285d is described below
commit 00c285d75c71b686941c60be7b15e024042eb851
Author: David Blevins <da...@gmail.com>
AuthorDate: Fri Apr 30 14:54:37 2021 -0700
Ability to add resource files to a jar
---
.../org/apache/tomee/patch/core/Additions.java | 29 ++++++++
.../apache/tomee/patch/core/Transformation.java | 86 ++++++++++++++++++++--
.../org/apache/tomee/patch/plugin/PatchMojo.java | 31 +++++++-
3 files changed, 137 insertions(+), 9 deletions(-)
diff --git a/tomee-patch-core/src/main/java/org/apache/tomee/patch/core/Additions.java b/tomee-patch-core/src/main/java/org/apache/tomee/patch/core/Additions.java
new file mode 100644
index 0000000..bcbcbf3
--- /dev/null
+++ b/tomee-patch-core/src/main/java/org/apache/tomee/patch/core/Additions.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.tomee.patch.core;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class Additions {
+
+ private Map<String, String> resources = new HashMap<>();
+
+ public Map<String, String> getResources() {
+ return resources;
+ }
+}
diff --git a/tomee-patch-core/src/main/java/org/apache/tomee/patch/core/Transformation.java b/tomee-patch-core/src/main/java/org/apache/tomee/patch/core/Transformation.java
index 982c44a..125ceef 100644
--- a/tomee-patch-core/src/main/java/org/apache/tomee/patch/core/Transformation.java
+++ b/tomee-patch-core/src/main/java/org/apache/tomee/patch/core/Transformation.java
@@ -16,6 +16,14 @@
*/
package org.apache.tomee.patch.core;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Opcodes;
+import org.tomitribe.swizzle.stream.StreamBuilder;
+import org.tomitribe.util.IO;
+import org.tomitribe.util.Mvn;
+import org.tomitribe.util.dir.Dir;
+
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
@@ -25,18 +33,12 @@ import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
+import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.ClassWriter;
-import org.objectweb.asm.Opcodes;
-import org.tomitribe.swizzle.stream.StreamBuilder;
-import org.tomitribe.util.IO;
-import org.tomitribe.util.Mvn;
-
import static org.tomitribe.jkta.util.Predicates.not;
public class Transformation {
@@ -44,19 +46,25 @@ public class Transformation {
private final List<Clazz> classes = new ArrayList<Clazz>();
private final Log log;
private final Replacements replacements;
+ private final Additions additions;
private final Boolean skipTransform;
+ private final File patchResources;
public Transformation() {
this.log = new NullLog();
this.replacements = new Replacements();
+ this.additions = new Additions();
this.skipTransform = false;
+ this.patchResources = new File("does not exist");
}
- public Transformation(final List<Clazz> classes, final Replacements replacements, final Log log, final Boolean skipTransform) {
+ public Transformation(final List<Clazz> classes, final File patchResources, final Replacements replacements, final Additions additions, final Log log, final Boolean skipTransform) {
this.classes.addAll(classes);
this.log = log;
this.replacements = replacements == null ? new Replacements() : replacements;
+ this.additions = additions == null ? new Additions() : additions;
+ this.patchResources = patchResources;
this.skipTransform = skipTransform;
}
@@ -158,6 +166,31 @@ public class Transformation {
clazz.applied();
}
}
+
+ final String jarName = new File(jar.getName()).getName();
+ if (additions.getResources().containsKey(jarName) && patchResources.exists()) {
+ final String regex = additions.getResources().get(jarName);
+ final Pattern pattern = getPattern(regex);
+
+ final Dir dir = Dir.of(Dir.class, patchResources);
+ final List<Resource> resources = dir.files()
+ .map(file -> Resource.relative(patchResources, file))
+ .filter(resource -> resource.matches(pattern))
+ .collect(Collectors.toList());
+
+ for (final Resource resource : resources) {
+ log.info("Adding " + resource.getPath());
+
+ final ZipEntry newEntry = new ZipEntry(resource.getPath());
+ zipOutputStream.putNextEntry(newEntry);
+
+ // Run any transformations on these classes as well
+ IO.copy(IO.read(resource.getFile()), zipOutputStream);
+
+ zipOutputStream.closeEntry();
+ }
+ }
+
zipOutputStream.finish();
} catch (IOException e) {
throw new IOException(jar.getPath() + e.getMessage(), e);
@@ -166,6 +199,43 @@ public class Transformation {
}
}
+ private Pattern getPattern(final String regex) {
+ try {
+ return Pattern.compile(regex);
+ } catch (Exception e) {
+ log.error(String.format("Invalid pattern: '%s'", regex));
+ return null;
+ }
+ }
+
+ public static class Resource {
+ private final File file;
+ private final String path;
+
+ public Resource(final File file, final String path) {
+ this.file = file;
+ this.path = path;
+ }
+
+ public File getFile() {
+ return file;
+ }
+
+ public String getPath() {
+ return path;
+ }
+
+ public boolean matches(final Pattern pattern) {
+ return pattern != null && pattern.matcher(path).matches();
+ }
+
+ public static Resource relative(final File parent, final File file) {
+ final int i = parent.getAbsolutePath().length() + 1;
+ final String path = file.getAbsolutePath().substring(i);
+ return new Resource(file, path);
+ }
+ }
+
/**
* Skip signed jar public key files. We most definitely
* have tampered with the jar.
diff --git a/tomee-patch-plugin/src/main/java/org/apache/tomee/patch/plugin/PatchMojo.java b/tomee-patch-plugin/src/main/java/org/apache/tomee/patch/plugin/PatchMojo.java
index 19fc142..099b662 100644
--- a/tomee-patch-plugin/src/main/java/org/apache/tomee/patch/plugin/PatchMojo.java
+++ b/tomee-patch-plugin/src/main/java/org/apache/tomee/patch/plugin/PatchMojo.java
@@ -45,6 +45,7 @@ import org.apache.maven.project.MavenProject;
import org.apache.maven.project.artifact.AttachedArtifact;
import org.apache.maven.toolchain.Toolchain;
import org.apache.maven.toolchain.ToolchainManager;
+import org.apache.tomee.patch.core.Additions;
import org.apache.tomee.patch.core.Clazz;
import org.apache.tomee.patch.core.Is;
import org.apache.tomee.patch.core.Replacements;
@@ -75,6 +76,9 @@ public class PatchMojo extends AbstractMojo {
@Parameter(defaultValue = "${project.basedir}/src/patch/java", required = true)
private List<File> patchSources;
+ @Parameter(defaultValue = "${project.basedir}/src/patch/resources", required = true)
+ private List<File> patchResources;
+
@Parameter
private List<String> sourceExcludes = new ArrayList<>();
@@ -99,6 +103,9 @@ public class PatchMojo extends AbstractMojo {
@Parameter
private Replacements replace;
+ @Parameter
+ private Additions add;
+
@Parameter(defaultValue = "false")
private Boolean createTarGz;
@@ -142,6 +149,9 @@ public class PatchMojo extends AbstractMojo {
@Parameter(defaultValue = "${project.build.directory}/patch-sources", required = true)
private File patchSourceDirectory;
+ @Parameter(defaultValue = "${project.build.directory}/patch-resources", required = true)
+ private File patchResourceDirectory;
+
/**
* The -encoding argument for the Java compiler.
*
@@ -190,6 +200,8 @@ public class PatchMojo extends AbstractMojo {
// Select the zip files and jars we'll be potentially patching
final List<Artifact> artifacts = getPatchArtifacts();
+ prepareResources();
+
// Extract any zips and return a list of jars
final List<File> jars = prepareJars(artifacts);
@@ -197,7 +209,7 @@ public class PatchMojo extends AbstractMojo {
final List<Clazz> clazzes = classes();
- final Transformation transformation = new Transformation(clazzes, replace, new MavenLog(getLog()), skipTransform);
+ final Transformation transformation = new Transformation(clazzes, patchResourceDirectory, replace, add, new MavenLog(getLog()), skipTransform);
for (final Artifact artifact : artifacts) {
final File file = artifact.getFile();
getLog().debug("Patching " + file.getAbsolutePath());
@@ -227,6 +239,23 @@ public class PatchMojo extends AbstractMojo {
}
}
+ private void prepareResources() throws MojoExecutionException {
+ Files.mkdir(patchResourceDirectory);
+ for (final File patchResource : patchResources) {
+ if (!patchResource.exists()) {
+ final String message = "Patch resource directory does not exist: " + patchResource.getAbsolutePath();
+ getLog().error(message);
+ throw new MojoExecutionException(message);
+ }
+ if (!patchResource.isDirectory()) {
+ final String message = "Patch resource directory is not a directory: " + patchResource.getAbsolutePath();
+ getLog().error(message);
+ throw new MojoExecutionException(message);
+ }
+ }
+ patchResources.forEach(file -> copy(file, file, patchResourceDirectory));
+ }
+
private List<Clazz> classes() {
return Dir.from(buildDirectory).files()
.filter(file -> file.getName().endsWith(".class"))