Author: olamy Date: Sat Nov 26 11:03:21 2016 New Revision: 1771458 URL: http://svn.apache.org/viewvc?rev=1771458&view=rev Log: Groovy transformer for Maven Shade Plugin
Added: maven/plugins/trunk/maven-shade-plugin/src/main/java/org/apache/maven/plugins/shade/resource/GroovyResourceTransformer.java (with props) maven/plugins/trunk/maven-shade-plugin/src/test/java/org/apache/maven/plugins/shade/resource/GroovyResourceTransformerTest.java (with props) Modified: maven/plugins/trunk/maven-shade-plugin/src/site/apt/examples/resource-transformers.apt.vm Added: maven/plugins/trunk/maven-shade-plugin/src/main/java/org/apache/maven/plugins/shade/resource/GroovyResourceTransformer.java URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-shade-plugin/src/main/java/org/apache/maven/plugins/shade/resource/GroovyResourceTransformer.java?rev=1771458&view=auto ============================================================================== --- maven/plugins/trunk/maven-shade-plugin/src/main/java/org/apache/maven/plugins/shade/resource/GroovyResourceTransformer.java (added) +++ maven/plugins/trunk/maven-shade-plugin/src/main/java/org/apache/maven/plugins/shade/resource/GroovyResourceTransformer.java Sat Nov 26 11:03:21 2016 @@ -0,0 +1,130 @@ +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 org.apache.maven.plugins.shade.relocation.Relocator; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Properties; +import java.util.jar.JarEntry; +import java.util.jar.JarOutputStream; + +/** + * @author <a href="mailto:jul...@julienviet.com">Julien Viet</a> + */ +public class GroovyResourceTransformer implements ResourceTransformer +{ + + static final String EXT_MODULE_NAME = "META-INF/services/org.codehaus.groovy.runtime.ExtensionModule"; + private List<String> extensionClassesList = new ArrayList<String>(); + private List<String> staticExtensionClassesList = new ArrayList<String>(); + String extModuleName = "no-module-name"; + String extModuleVersion = "1.0"; + + @Override + public boolean canTransformResource( String resource ) + { + return EXT_MODULE_NAME.equals( resource ); + } + + @Override + public void processResource( String resource, InputStream is, List<Relocator> relocators ) throws IOException + { + Properties out = new Properties(); + try + { + out.load( is ); + } + finally + { + is.close(); + } + String extensionClasses = out.getProperty( "extensionClasses" , "" ).trim(); + if ( extensionClasses.length() > 0 ) + { + append( extensionClasses, extensionClassesList ); + } + String staticExtensionClasses = out.getProperty( "staticExtensionClasses", "" ).trim(); + if ( staticExtensionClasses.length() > 0 ) + { + append( staticExtensionClasses, staticExtensionClassesList ); + } + } + + private void append( String entry, List<String> list ) + { + if ( entry != null ) + { + Collections.addAll( list, entry.split( "\\s*,\\s*" ) ); + } + } + + @Override + public boolean hasTransformedResource() + { + return extensionClassesList.size() > 0 && staticExtensionClassesList.size() > 0; + } + + @Override + public void modifyOutputStream( JarOutputStream os ) throws IOException + { + if ( hasTransformedResource() ) + { + os.putNextEntry( new JarEntry( EXT_MODULE_NAME ) ); + Properties desc = new Properties(); + desc.put( "moduleName", extModuleName ); + desc.put( "moduleVersion", extModuleVersion ); + if ( extensionClassesList.size() > 0 ) + { + desc.put( "extensionClasses", join( extensionClassesList ) ); + } + if ( staticExtensionClassesList.size() > 0 ) + { + desc.put( "staticExtensionClasses", join( staticExtensionClassesList ) ); + } + desc.store( os, null ); + } + } + + private String join( Collection<String> strings ) + { + Iterator<String> it = strings.iterator(); + switch ( strings.size() ) + { + case 0: + return ""; + case 1: + return it.next(); + default: + StringBuilder buff = new StringBuilder( it.next() ); + while ( it.hasNext() ) + { + buff.append( "," ).append( it.next() ); + } + return buff.toString(); + } + } +} Propchange: maven/plugins/trunk/maven-shade-plugin/src/main/java/org/apache/maven/plugins/shade/resource/GroovyResourceTransformer.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: maven/plugins/trunk/maven-shade-plugin/src/main/java/org/apache/maven/plugins/shade/resource/GroovyResourceTransformer.java ------------------------------------------------------------------------------ svn:keywords = Author Date Id Revision Modified: maven/plugins/trunk/maven-shade-plugin/src/site/apt/examples/resource-transformers.apt.vm URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-shade-plugin/src/site/apt/examples/resource-transformers.apt.vm?rev=1771458&r1=1771457&r2=1771458&view=diff ============================================================================== --- maven/plugins/trunk/maven-shade-plugin/src/site/apt/examples/resource-transformers.apt.vm (original) +++ maven/plugins/trunk/maven-shade-plugin/src/site/apt/examples/resource-transformers.apt.vm Sat Nov 26 11:03:21 2016 @@ -51,6 +51,8 @@ Resource Transformers *-----------------------------------------+------------------------------------------+ | {{XmlAppendingTransformer}} | Adds XML content to an XML resource | *-----------------------------------------+------------------------------------------+ +| {{GroovyResourceTransformer}} | Merge Apache Groovy extends modules | +*-----------------------------------------+------------------------------------------+ Transformers in <<<org.apache.maven.plugins.shade.resource>>> * Merging Plexus Component Descriptors with the {ComponentsXmlResourceTransformer} @@ -471,4 +473,44 @@ Transformers in <<<org.apache.maven.plug </build> ... </project> -+----- ++----- + +** Aggregating Apache Groovy extension modules descriptors with the {GroovyResourceTransformer} + +The Apache Groovy language provides extension modules located at +<<<META-INF/services/org.codehaus.groovy.runtime.ExtensionModule>>>, these modules use the property file format. +<<<GroovyResourceTransformer>>> automates the assembly of Groovy extension modules <<<NOTICE>>>. + +For example, to simply merge the extension modules of several jars: + ++----- +<project> + ... + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-shade-plugin</artifactId> + <version>${project.version}</version> + <executions> + <execution> + <phase>package</phase> + <goals> + <goal>shade</goal> + </goals> + <configuration> + <transformers> + <transformer implementation="org.apache.maven.plugins.shade.resource.GroovyResourceTransformer"> + <extModuleName>the-aggregated-module</extModuleName> + <extModuleVersion>1.0.0</extModuleVersion> + </transformer> + </transformers> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> + ... +</project> ++----- Added: maven/plugins/trunk/maven-shade-plugin/src/test/java/org/apache/maven/plugins/shade/resource/GroovyResourceTransformerTest.java URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-shade-plugin/src/test/java/org/apache/maven/plugins/shade/resource/GroovyResourceTransformerTest.java?rev=1771458&view=auto ============================================================================== --- maven/plugins/trunk/maven-shade-plugin/src/test/java/org/apache/maven/plugins/shade/resource/GroovyResourceTransformerTest.java (added) +++ maven/plugins/trunk/maven-shade-plugin/src/test/java/org/apache/maven/plugins/shade/resource/GroovyResourceTransformerTest.java Sat Nov 26 11:03:21 2016 @@ -0,0 +1,135 @@ +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 junit.framework.TestCase; +import org.apache.maven.plugins.shade.relocation.Relocator; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.util.Collections; +import java.util.Properties; +import java.util.jar.JarFile; +import java.util.jar.JarOutputStream; +import java.util.zip.ZipEntry; + +/** + * Test for {@link XmlAppendingTransformer}. + * + * @author Benjamin Bentmann + * @version $Id$ + */ +public class GroovyResourceTransformerTest + extends TestCase +{ + + private static InputStream stream( Properties props ) throws Exception + { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + props.store( baos, null ); + return new ByteArrayInputStream( baos.toByteArray() ); + + } + + private static InputStream module( String name, String version, String extensionClasses, String staticExtensionClasses ) throws Exception + { + Properties desc = new Properties(); + desc.setProperty( "moduleName", name ); + desc.setProperty( "moduleVersion", version ); + if ( extensionClasses != null ) + { + desc.setProperty( "extensionClasses", extensionClasses ); + } + if ( staticExtensionClasses != null ) + { + desc.setProperty( "staticExtensionClasses", staticExtensionClasses ); + } + return stream( desc ); + } + + private static Properties transform( GroovyResourceTransformer transformer ) throws Exception + { + File tempJar = File.createTempFile( "shade.", ".jar" ); + tempJar.deleteOnExit(); + FileOutputStream fos = new FileOutputStream( tempJar ); + JarOutputStream jaos = new JarOutputStream( fos ); + transformer.modifyOutputStream( jaos ); + jaos.close(); + JarFile jar = new JarFile( tempJar ); + Properties desc = null; + ZipEntry entry = jar.getEntry( GroovyResourceTransformer.EXT_MODULE_NAME ); + if ( entry != null ) + { + desc = new Properties(); + desc.load( jar.getInputStream( entry ) ); + } + return desc; + } + + public void testFilter() throws Exception + { + GroovyResourceTransformer transformer = new GroovyResourceTransformer(); + assertTrue( transformer.canTransformResource( GroovyResourceTransformer.EXT_MODULE_NAME ) ); + assertFalse( transformer.canTransformResource( "somethingElse" ) ); + assertFalse( transformer.canTransformResource( JarFile.MANIFEST_NAME ) ); + } + + public void testEmpty() throws Exception + { + GroovyResourceTransformer transformer = new GroovyResourceTransformer(); + assertFalse( transformer.hasTransformedResource() ); + assertNull( transform( transformer ) ); + } + + public void testSpecifyModuleName() throws Exception + { + GroovyResourceTransformer transformer = new GroovyResourceTransformer(); + transformer.extModuleName = "the-module-name"; + transformer.extModuleVersion = "2.0"; + transformer.processResource( GroovyResourceTransformer.EXT_MODULE_NAME, + module("mod1", "1.0", "some.ext", "some.staticExt"), Collections.<Relocator>emptyList() ); + Properties desc = transform( transformer ); + assertEquals( "the-module-name", desc.getProperty( "moduleName" ) ); + assertEquals( "2.0", desc.getProperty( "moduleVersion" ) ); + assertEquals( "some.ext", desc.getProperty( "extensionClasses" ) ); + assertEquals( "some.staticExt", desc.getProperty( "staticExtensionClasses" ) ); + } + + public void testConcatenation() throws Exception + { + GroovyResourceTransformer transformer = new GroovyResourceTransformer(); + transformer.processResource( GroovyResourceTransformer.EXT_MODULE_NAME, + module( "mod1", "1.0", "some.ext1", null ), Collections.<Relocator>emptyList() ); + transformer.processResource(GroovyResourceTransformer.EXT_MODULE_NAME, + module( "mod2", "1.0", null, "some.staticExt1" ), Collections.<Relocator>emptyList()); + transformer.processResource(GroovyResourceTransformer.EXT_MODULE_NAME, + module( "mod3", "1.0", "", "" ), Collections.<Relocator>emptyList()); + transformer.processResource(GroovyResourceTransformer.EXT_MODULE_NAME, + module( "mod4", "1.0", "some.ext2", "some.staticExt2" ), Collections.<Relocator>emptyList()); + Properties desc = transform( transformer ); + assertEquals( "no-module-name", desc.getProperty( "moduleName" ) ); + assertEquals( "1.0", desc.getProperty( "moduleVersion" ) ); + assertEquals( "some.ext1,some.ext2", desc.getProperty( "extensionClasses" ) ); + assertEquals( "some.staticExt1,some.staticExt2", desc.getProperty( "staticExtensionClasses" ) ); + } +} Propchange: maven/plugins/trunk/maven-shade-plugin/src/test/java/org/apache/maven/plugins/shade/resource/GroovyResourceTransformerTest.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: maven/plugins/trunk/maven-shade-plugin/src/test/java/org/apache/maven/plugins/shade/resource/GroovyResourceTransformerTest.java ------------------------------------------------------------------------------ svn:keywords = Author Date Id Revision