You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by rm...@apache.org on 2020/03/05 13:21:37 UTC

[maven-shade-plugin] 01/01: MSHADE-353 adding a generic relocation friendly transformer delegating to other transformers the actual processing

This is an automated email from the ASF dual-hosted git repository.

rmannibucau pushed a commit to branch rmannibucau/MSHADE-353-ensure-relocations-can-be-applied-to-any-transformer
in repository https://gitbox.apache.org/repos/asf/maven-shade-plugin.git

commit 1840449b2cb73de77843fa5277ffec6f4d686b2f
Author: Romain Manni-Bucau <rm...@apache.org>
AuthorDate: Thu Mar 5 14:21:19 2020 +0100

    MSHADE-353 adding a generic relocation friendly transformer delegating to other transformers the actual processing
---
 .../shade/resource/BaseRelocatingTransformer.java  |  46 +++++++++
 .../resource/ManifestResourceTransformer.java      |  18 +---
 .../shade/resource/RelocationTransformer.java      | 106 +++++++++++++++++++++
 src/site/apt/examples/resource-transformers.apt.vm |  43 ++++++++-
 .../shade/resource/RelocationTransformerTest.java  |  75 +++++++++++++++
 5 files changed, 270 insertions(+), 18 deletions(-)

diff --git a/src/main/java/org/apache/maven/plugins/shade/resource/BaseRelocatingTransformer.java b/src/main/java/org/apache/maven/plugins/shade/resource/BaseRelocatingTransformer.java
new file mode 100644
index 0000000..4e57aee
--- /dev/null
+++ b/src/main/java/org/apache/maven/plugins/shade/resource/BaseRelocatingTransformer.java
@@ -0,0 +1,46 @@
+package org.apache.maven.plugins.shade.resource;
+
+/*
+ * 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.
+ */
+
+import java.util.List;
+
+import org.apache.maven.plugins.shade.relocation.Relocator;
+
+/**
+ * Abstract class providing the needed logic to relocate any content.
+ */
+public abstract class BaseRelocatingTransformer implements ResourceTransformer
+{
+    protected String relocate( String originalValue, List<Relocator> relocators )
+    {
+        String newValue = originalValue;
+        for ( Relocator relocator : relocators )
+        {
+            String value;
+            do
+            {
+                value = newValue;
+                newValue = relocator.relocateClass( value );
+            }
+            while ( !value.equals( newValue ) );
+        }
+        return newValue;
+    }
+}
diff --git a/src/main/java/org/apache/maven/plugins/shade/resource/ManifestResourceTransformer.java b/src/main/java/org/apache/maven/plugins/shade/resource/ManifestResourceTransformer.java
index 688078c..82b98e7 100644
--- a/src/main/java/org/apache/maven/plugins/shade/resource/ManifestResourceTransformer.java
+++ b/src/main/java/org/apache/maven/plugins/shade/resource/ManifestResourceTransformer.java
@@ -41,7 +41,7 @@ import org.apache.maven.plugins.shade.relocation.Relocator;
  * @since 1.2
  */
 public class ManifestResourceTransformer
-    implements ResourceTransformer
+    extends BaseRelocatingTransformer
 {
     private final List<String> defaultAttributes = Arrays.asList( "Export-Package",
                                                                   "Import-Package",
@@ -163,20 +163,4 @@ public class ManifestResourceTransformer
         jos.putNextEntry( new JarEntry( JarFile.MANIFEST_NAME ) );
         manifest.write( jos );
     }
-    
-    private String relocate( String originalValue, List<Relocator> relocators )
-    {
-        String newValue = originalValue;
-        for ( Relocator relocator : relocators )
-        {
-            String value;
-            do
-            {
-                value = newValue;
-                newValue = relocator.relocateClass( value );
-            }
-            while ( !value.equals( newValue ) );
-        }
-        return newValue;
-    }
 }
diff --git a/src/main/java/org/apache/maven/plugins/shade/resource/RelocationTransformer.java b/src/main/java/org/apache/maven/plugins/shade/resource/RelocationTransformer.java
new file mode 100644
index 0000000..40acb9d
--- /dev/null
+++ b/src/main/java/org/apache/maven/plugins/shade/resource/RelocationTransformer.java
@@ -0,0 +1,106 @@
+package org.apache.maven.plugins.shade.resource;
+
+/*
+ * 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.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.Collection;
+import java.util.List;
+import java.util.jar.JarOutputStream;
+
+import org.apache.maven.plugins.shade.relocation.Relocator;
+import org.codehaus.plexus.util.IOUtil;
+
+/**
+ * Trivial transformer applying relocators on resources content.
+ */
+public class RelocationTransformer extends BaseRelocatingTransformer
+{
+    private Collection<ResourceTransformer> delegates;
+    private boolean transformed;
+
+    @Override
+    public boolean canTransformResource( String resource )
+    {
+        if ( delegates == null )
+        {
+            return false;
+        }
+        for ( ResourceTransformer transformer : delegates )
+        {
+            if ( transformer.canTransformResource( resource ) )
+            {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public void processResource( String resource, InputStream is, List<Relocator> relocators ) throws IOException
+    {
+        byte[] relocated = null;
+        for ( ResourceTransformer transformer : delegates )
+        {
+            if ( transformer.canTransformResource( resource ) )
+            {
+                transformed = true;
+                if ( relocated == null )
+                {
+                    relocated = relocate( IOUtil.toString( is ), relocators )
+                            .getBytes( StandardCharsets.UTF_8 );
+                }
+                transformer.processResource(
+                        resource,
+                        new ByteArrayInputStream( relocated ),
+                        relocators );
+            }
+        }
+    }
+
+    @Override
+    public boolean hasTransformedResource()
+    {
+        return transformed;
+    }
+
+    @Override
+    public void modifyOutputStream( JarOutputStream os ) throws IOException
+    {
+        if ( !transformed )
+        {
+            return;
+        }
+        for ( ResourceTransformer transformer : delegates )
+        {
+            if ( transformer.hasTransformedResource() )
+            {
+                transformer.modifyOutputStream( os );
+            }
+        }
+    }
+
+    public void setDelegates( Collection<ResourceTransformer> delegates )
+    {
+        this.delegates = delegates;
+    }
+}
diff --git a/src/site/apt/examples/resource-transformers.apt.vm b/src/site/apt/examples/resource-transformers.apt.vm
index 1482baa..1a20fdc 100644
--- a/src/site/apt/examples/resource-transformers.apt.vm
+++ b/src/site/apt/examples/resource-transformers.apt.vm
@@ -55,7 +55,9 @@ Resource Transformers
 *-----------------------------------------+------------------------------------------+
 | {{PropertiesTransformer}}               | Merges properties files owning an ordinal to solve conflicts |
 *-----------------------------------------+------------------------------------------+
-| {{ResourceBundleAppendingTransformer}}  | Merges ResourceBundles                  | 
+| {{RelocationTransformer}}               | Delegates the processing to other transformers but relocating the resource contents |
+*-----------------------------------------+------------------------------------------+
+| {{ResourceBundleAppendingTransformer}}  | Merges ResourceBundles                  |
 *-----------------------------------------+------------------------------------------+
 | {{ServicesResourceTransformer}}         | Relocated class names in <<<META-INF/services>>> resources and merges them. |
 *-----------------------------------------+------------------------------------------+
@@ -601,6 +603,45 @@ Transformers in <<<org.apache.maven.plugins.shade.resource>>>
 </project>
 +-----
 
+* Relocating file content with {RelocationTransformer}
+
+  The <<<RelocationTransformer>>> allows to apply relocators before delegating the processing to other transformers.
+
++-----
+<project>
+  ...
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-shade-plugin</artifactId>
+        <version>${project.version}</version>
+        <executions>
+          <execution>
+            <goals>
+              <goal>shade</goal>
+            </goals>
+            <configuration>
+              <transformers>
+                <transformer implementation="org.apache.maven.plugins.shade.resource.RelocationTransformer">
+                  <delegates>
+                    <transformer implementation="org.apache.maven.plugins.shade.resource.properties.PropertiesTransformer">
+                      <resource>configuration/application.properties</resource>
+                      <ordinalKey>ordinal</ordinalKey>
+                    </transformer>
+                  </delegates>
+                </transformer>
+              </transformers>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+  ...
+</project>
++-----
+
 * Merging Apache OpenWebBeans configuration with {OpenWebBeansPropertiesTransformer}
 
   <<<OpenWebBeansPropertiesTransformer>>> preconfigure a <<<PropertiesTransformer>>>
diff --git a/src/test/java/org/apache/maven/plugins/shade/resource/RelocationTransformerTest.java b/src/test/java/org/apache/maven/plugins/shade/resource/RelocationTransformerTest.java
new file mode 100644
index 0000000..b860bd3
--- /dev/null
+++ b/src/test/java/org/apache/maven/plugins/shade/resource/RelocationTransformerTest.java
@@ -0,0 +1,75 @@
+package org.apache.maven.plugins.shade.resource;
+
+/*
+ * 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.
+ */
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.Collections;
+import java.util.jar.JarEntry;
+import java.util.jar.JarInputStream;
+import java.util.jar.JarOutputStream;
+
+import org.apache.maven.plugins.shade.relocation.Relocator;
+import org.apache.maven.plugins.shade.relocation.SimpleRelocator;
+import org.codehaus.plexus.util.IOUtil;
+import org.junit.Test;
+
+/**
+ * Ensure the relation transformer uses relocators.
+ */
+public class RelocationTransformerTest
+{
+    @Test
+    public void relocate() throws IOException
+    {
+        AppendingTransformer delegate = new AppendingTransformer();
+        delegate.resource = "foo/bar.txt";
+
+        RelocationTransformer resourceTransformer = new RelocationTransformer();
+        resourceTransformer.setDelegates( Collections.<ResourceTransformer>singletonList( delegate ) );
+
+        assertTrue( resourceTransformer.canTransformResource( "foo/bar.txt" ) );
+        resourceTransformer.processResource(
+                "foo/bar.txt",
+                new ByteArrayInputStream("a=javax.foo.bar".getBytes( StandardCharsets.UTF_8 )),
+                Collections.<Relocator>singletonList( new SimpleRelocator(
+                        "javax", "jakarta", null, null ) ));
+        final ByteArrayOutputStream out = new ByteArrayOutputStream();
+        try ( JarOutputStream jarOutputStream = new JarOutputStream(out) )
+        {
+            resourceTransformer.modifyOutputStream(jarOutputStream);
+        }
+        try ( JarInputStream jarInputStream = new JarInputStream( new ByteArrayInputStream( out.toByteArray() ) ))
+        {
+            final JarEntry entry = jarInputStream.getNextJarEntry();
+            assertNotNull( entry );
+            assertEquals( "foo/bar.txt", entry.getName() );
+            assertEquals( "a=jakarta.foo.bar", IOUtil.toString( jarInputStream ).trim() );
+            assertNull( jarInputStream.getNextJarEntry() );
+        }
+    }
+}