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 extends AbstractCompatibilityTransformer
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 private long time = Long.MIN_VALUE;
64
65 public void setMainClass( String mainClass )
66 {
67 this.mainClass = mainClass;
68 }
69
70 public void setManifestEntries( Map<String, Object> manifestEntries )
71 {
72 this.manifestEntries = manifestEntries;
73 }
74
75 public void setAdditionalAttributes( List<String> additionalAttributes )
76 {
77 this.additionalAttributes = additionalAttributes;
78 }
79
80 @Override
81 public boolean canTransformResource( String resource )
82 {
83 if ( JarFile.MANIFEST_NAME.equalsIgnoreCase( resource ) )
84 {
85 return true;
86 }
87
88 return false;
89 }
90
91 @Override
92 public void processResource( String resource, InputStream is, List<Relocator> relocators, long time )
93 throws IOException
94 {
95
96
97
98 if ( !manifestDiscovered )
99 {
100 manifest = new Manifest( is );
101
102 if ( relocators != null && !relocators.isEmpty() )
103 {
104 final Attributes attributes = manifest.getMainAttributes();
105
106 for ( final String attribute : defaultAttributes )
107 {
108 final String attributeValue = attributes.getValue( attribute );
109 if ( attributeValue != null )
110 {
111 String newValue = relocate( attributeValue, relocators );
112 attributes.putValue( attribute, newValue );
113 }
114 }
115
116 if ( additionalAttributes != null )
117 {
118 for ( final String attribute : additionalAttributes )
119 {
120 final String attributeValue = attributes.getValue( attribute );
121 if ( attributeValue != null )
122 {
123 String newValue = relocate( attributeValue, relocators );
124 attributes.putValue( attribute, newValue );
125 }
126 }
127 }
128 }
129
130 manifestDiscovered = true;
131
132 if ( time > this.time )
133 {
134 this.time = time;
135 }
136 }
137 }
138
139 @Override
140 public boolean hasTransformedResource()
141 {
142 return true;
143 }
144
145 @Override
146 public void modifyOutputStream( JarOutputStream jos )
147 throws IOException
148 {
149
150 if ( manifest == null )
151 {
152 manifest = new Manifest();
153 }
154
155 Attributes attributes = manifest.getMainAttributes();
156
157 if ( mainClass != null )
158 {
159 attributes.put( Attributes.Name.MAIN_CLASS, mainClass );
160 }
161
162 if ( manifestEntries != null )
163 {
164 for ( Map.Entry<String, Object> entry : manifestEntries.entrySet() )
165 {
166 attributes.put( new Attributes.Name( entry.getKey() ), entry.getValue() );
167 }
168 }
169
170 JarEntry jarEntry = new JarEntry( JarFile.MANIFEST_NAME );
171 jarEntry.setTime( time );
172 jos.putNextEntry( jarEntry );
173 manifest.write( jos );
174 }
175
176 private String relocate( String originalValue, List<Relocator> relocators )
177 {
178 String newValue = originalValue;
179 for ( Relocator relocator : relocators )
180 {
181 String value;
182 do
183 {
184 value = newValue;
185 newValue = relocator.relocateClass( value );
186 }
187 while ( !value.equals( newValue ) );
188 }
189 return newValue;
190 }
191 }