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"))