View Javadoc
1   package org.apache.maven.plugins.shade.resource;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.maven.plugins.shade.relocation.Relocator;
23  
24  import java.io.IOException;
25  import java.io.InputStream;
26  import java.util.ArrayList;
27  import java.util.Collection;
28  import java.util.Collections;
29  import java.util.Iterator;
30  import java.util.List;
31  import java.util.Properties;
32  import java.util.jar.JarEntry;
33  import java.util.jar.JarOutputStream;
34  
35  /**
36   * Aggregate Apache Groovy extension modules descriptors
37   */
38  public class GroovyResourceTransformer
39      implements ResourceTransformer
40  {
41  
42      static final String EXT_MODULE_NAME_LEGACY = "META-INF/services/org.codehaus.groovy.runtime.ExtensionModule";
43  
44      // Since Groovy 2.5.x/Java 9 META-INF/services may only be used by Service Providers
45      static final String EXT_MODULE_NAME = "META-INF/groovy/org.codehaus.groovy.runtime.ExtensionModule";
46  
47      private List<String> extensionClassesList = new ArrayList<>();
48  
49      private List<String> staticExtensionClassesList = new ArrayList<>();
50  
51      private String extModuleName = "no-module-name";
52  
53      private String extModuleVersion = "1.0";
54  
55      @Override
56      public boolean canTransformResource( String resource )
57      {
58          return EXT_MODULE_NAME.equals( resource ) || EXT_MODULE_NAME_LEGACY.equals( resource );
59      }
60  
61      @Override
62      public void processResource( String resource, InputStream is, List<Relocator> relocators )
63          throws IOException
64      {
65          Properties out = new Properties();
66          try ( InputStream props = is )
67          {
68              out.load( props );
69          }
70          String extensionClasses = out.getProperty( "extensionClasses", "" ).trim();
71          if ( extensionClasses.length() > 0 )
72          {
73              append( extensionClasses, extensionClassesList );
74          }
75          String staticExtensionClasses = out.getProperty( "staticExtensionClasses", "" ).trim();
76          if ( staticExtensionClasses.length() > 0 )
77          {
78              append( staticExtensionClasses, staticExtensionClassesList );
79          }
80      }
81  
82      private void append( String entry, List<String> list )
83      {
84          if ( entry != null )
85          {
86              Collections.addAll( list, entry.split( "\\s*,\\s*" ) );
87          }
88      }
89  
90      @Override
91      public boolean hasTransformedResource()
92      {
93          return extensionClassesList.size() > 0 && staticExtensionClassesList.size() > 0;
94      }
95  
96      @Override
97      public void modifyOutputStream( JarOutputStream os )
98          throws IOException
99      {
100         if ( hasTransformedResource() )
101         {
102             os.putNextEntry( new JarEntry( EXT_MODULE_NAME ) );
103             Properties desc = new Properties();
104             desc.put( "moduleName", extModuleName );
105             desc.put( "moduleVersion", extModuleVersion );
106             if ( extensionClassesList.size() > 0 )
107             {
108                 desc.put( "extensionClasses", join( extensionClassesList ) );
109             }
110             if ( staticExtensionClassesList.size() > 0 )
111             {
112                 desc.put( "staticExtensionClasses", join( staticExtensionClassesList ) );
113             }
114             desc.store( os, null );
115         }
116     }
117 
118     private String join( Collection<String> strings )
119     {
120         Iterator<String> it = strings.iterator();
121         switch ( strings.size() )
122         {
123             case 0:
124                 return "";
125             case 1:
126                 return it.next();
127             default:
128                 StringBuilder buff = new StringBuilder( it.next() );
129                 while ( it.hasNext() )
130                 {
131                     buff.append( "," ).append( it.next() );
132                 }
133                 return buff.toString();
134         }
135     }
136 
137     public void setExtModuleName( String extModuleName )
138     {
139         this.extModuleName = extModuleName;
140     }
141 
142     public void setExtModuleVersion( String extModuleVersion )
143     {
144         this.extModuleVersion = extModuleVersion;
145     }
146 }