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 java.io.ByteArrayInputStream;
23  import java.io.ByteArrayOutputStream;
24  import java.io.IOException;
25  import java.io.InputStream;
26  import java.util.HashMap;
27  import java.util.Iterator;
28  import java.util.List;
29  import java.util.Map;
30  import java.util.jar.JarEntry;
31  import java.util.jar.JarOutputStream;
32  
33  import org.codehaus.plexus.util.IOUtil;
34  
35  /**
36   * Resources transformer that appends entries in META-INF/services resources into
37   * a single resource. For example, if there are several META-INF/services/org.apache.maven.project.ProjectBuilder
38   * resources spread across many JARs the individual entries will all be concatenated into a single
39   * META-INF/services/org.apache.maven.project.ProjectBuilder resource packaged into the resultant JAR produced
40   * by the shading process.
41   *
42   * @author jvanzyl
43   */
44  public class ServicesResourceTransformer
45      implements ResourceTransformer
46  {
47  
48      private static final String SERVICES_PATH = "META-INF/services";
49  
50      private Map serviceEntries = new HashMap();
51  
52      public boolean canTransformResource( String resource )
53      {
54          if ( resource.startsWith( SERVICES_PATH ) )
55          {
56              return true;
57          }
58  
59          return false;
60      }
61  
62      public void processResource( String resource, InputStream is, List relocators )
63          throws IOException
64      {
65          ServiceStream out = (ServiceStream) serviceEntries.get( resource );
66          if ( out == null )
67          {
68              out = new ServiceStream();
69              serviceEntries.put( resource, out );
70          }
71  
72          out.append( is );
73          is.close();
74      }
75  
76      public boolean hasTransformedResource()
77      {
78          return serviceEntries.size() > 0;
79      }
80  
81      public void modifyOutputStream( JarOutputStream jos )
82          throws IOException
83      {
84          for ( Iterator i = serviceEntries.keySet().iterator(); i.hasNext(); )
85          {
86              String key = (String) i.next();
87              ServiceStream data = (ServiceStream) serviceEntries.get( key );
88              jos.putNextEntry( new JarEntry( key ) );
89              IOUtil.copy( data.toInputStream(), jos );
90              data.reset();
91          }
92      }
93  
94      static class ServiceStream
95          extends ByteArrayOutputStream
96      {
97  
98          public ServiceStream()
99          {
100             super( 1024 );
101         }
102 
103         public void append( InputStream is )
104             throws IOException
105         {
106             if ( count > 0 && buf[count - 1] != '\n' && buf[count - 1] != '\r' )
107             {
108                 write( '\n' );
109             }
110 
111             IOUtil.copy( is, this );
112         }
113 
114         public InputStream toInputStream()
115         {
116             return new ByteArrayInputStream( buf, 0, count );
117         }
118 
119     }
120 
121 }