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 <rmannibu...@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() ); + } + } +}