1 package org.apache.maven.plugins.shade.resource;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.util.Arrays;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.jar.Attributes;
28 import java.util.jar.JarEntry;
29 import java.util.jar.JarFile;
30 import java.util.jar.JarOutputStream;
31 import java.util.jar.Manifest;
32
33 import org.apache.maven.plugins.shade.relocation.Relocator;
34
35
36
37
38
39
40
41
42
43 public class ManifestResourceTransformer
44 implements ResourceTransformer
45 {
46 private final List<String> defaultAttributes = Arrays.asList( "Export-Package",
47 "Import-Package",
48 "Provide-Capability",
49 "Require-Capability" );
50
51
52 private String mainClass;
53
54 private Map<String, Object> manifestEntries;
55
56 private List<String> additionalAttributes;
57
58
59 private boolean manifestDiscovered;
60
61 private Manifest manifest;
62
63 public void setMainClass( String mainClass )
64 {
65 this.mainClass = mainClass;
66 }
67
68 public void setManifestEntries( Map<String, Object> manifestEntries )
69 {
70 this.manifestEntries = manifestEntries;
71 }
72
73 public void setAdditionalAttributes( List<String> additionalAttributes )
74 {
75 this.additionalAttributes = additionalAttributes;
76 }
77
78 @Override
79 public boolean canTransformResource( String resource )
80 {
81 if ( JarFile.MANIFEST_NAME.equalsIgnoreCase( resource ) )
82 {
83 return true;
84 }
85
86 return false;
87 }
88
89 @Override
90 public void processResource( String resource, InputStream is, List<Relocator> relocators )
91 throws IOException
92 {
93
94
95
96 if ( !manifestDiscovered )
97 {
98 manifest = new Manifest( is );
99
100 if ( relocators != null && !relocators.isEmpty() )
101 {
102 final Attributes attributes = manifest.getMainAttributes();
103
104 for ( final String attribute : defaultAttributes )
105 {
106 final String attributeValue = attributes.getValue( attribute );
107 if ( attributeValue != null )
108 {
109 String newValue = relocate( attributeValue, relocators );
110 attributes.putValue( attribute, newValue );
111 }
112 }
113
114 if ( additionalAttributes != null )
115 {
116 for ( final String attribute : additionalAttributes )
117 {
118 final String attributeValue = attributes.getValue( attribute );
119 if ( attributeValue != null )
120 {
121 String newValue = relocate( attributeValue, relocators );
122 attributes.putValue( attribute, newValue );
123 }
124 }
125 }
126 }
127
128 manifestDiscovered = true;
129 }
130 }
131
132 @Override
133 public boolean hasTransformedResource()
134 {
135 return true;
136 }
137
138 @Override
139 public void modifyOutputStream( JarOutputStream jos )
140 throws IOException
141 {
142
143 if ( manifest == null )
144 {
145 manifest = new Manifest();
146 }
147
148 Attributes attributes = manifest.getMainAttributes();
149
150 if ( mainClass != null )
151 {
152 attributes.put( Attributes.Name.MAIN_CLASS, mainClass );
153 }
154
155 if ( manifestEntries != null )
156 {
157 for ( Map.Entry<String, Object> entry : manifestEntries.entrySet() )
158 {
159 attributes.put( new Attributes.Name( entry.getKey() ), entry.getValue() );
160 }
161 }
162
163 jos.putNextEntry( new JarEntry( JarFile.MANIFEST_NAME ) );
164 manifest.write( jos );
165 }
166
167 private String relocate( String originalValue, List<Relocator> relocators )
168 {
169 String newValue = originalValue;
170 for ( Relocator relocator : relocators )
171 {
172 String value;
173 do
174 {
175 value = newValue;
176 newValue = relocator.relocateClass( value );
177 }
178 while ( !value.equals( newValue ) );
179 }
180 return newValue;
181 }
182 }