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.BufferedInputStream;
23 import java.io.ByteArrayOutputStream;
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.io.Reader;
27 import java.io.Writer;
28 import java.util.ArrayList;
29 import java.util.List;
30 import java.util.jar.JarEntry;
31 import java.util.jar.JarOutputStream;
32
33 import org.apache.maven.plugins.shade.relocation.Relocator;
34 import org.codehaus.plexus.util.ReaderFactory;
35 import org.codehaus.plexus.util.WriterFactory;
36 import org.codehaus.plexus.util.xml.Xpp3Dom;
37 import org.codehaus.plexus.util.xml.Xpp3DomBuilder;
38 import org.codehaus.plexus.util.xml.Xpp3DomWriter;
39
40
41
42
43
44
45
46 public class PluginXmlResourceTransformer
47 implements ResourceTransformer
48 {
49 private List<Xpp3Dom> mojos = new ArrayList<>();
50
51 public static final String PLUGIN_XML_PATH = "META-INF/maven/plugin.xml";
52
53 public boolean canTransformResource( String resource )
54 {
55 return PLUGIN_XML_PATH.equals( resource );
56 }
57
58 public void processResource( String resource, InputStream is, List<Relocator> relocators )
59 throws IOException
60 {
61 Xpp3Dom newDom;
62
63 try
64 {
65 BufferedInputStream bis = new BufferedInputStream( is )
66 {
67 public void close()
68 throws IOException
69 {
70
71 }
72 };
73
74 Reader reader = ReaderFactory.newXmlReader( bis );
75
76 newDom = Xpp3DomBuilder.build( reader );
77 }
78 catch ( Exception e )
79 {
80 throw new IOException( "Error parsing plugin.xml in " + is, e );
81 }
82
83
84 if ( newDom.getChild( "mojos" ) == null )
85 {
86 return;
87 }
88
89 for ( Xpp3Dom mojo : newDom.getChild( "mojos" ).getChildren( "mojo" ) )
90 {
91
92 String impl = getValue( mojo, "implementation" );
93 impl = getRelocatedClass( impl, relocators );
94 setValue( mojo, "implementation", impl );
95
96 Xpp3Dom parameters = mojo.getChild( "parameters" );
97 if ( parameters != null )
98 {
99 for ( Xpp3Dom parameter : parameters.getChildren() )
100 {
101 String type = getValue( parameter, "type" );
102 type = getRelocatedClass( type, relocators );
103 setValue( parameter, "type", type );
104 }
105 }
106
107 Xpp3Dom configuration = mojo.getChild( "configuration" );
108 if ( configuration != null )
109 {
110 for ( Xpp3Dom configurationEntry : configuration.getChildren() )
111 {
112 String implementation = getAttribute( configurationEntry, "implementation" );
113 implementation = getRelocatedClass( implementation, relocators );
114 setAttribute( configurationEntry, "implementation", implementation );
115 }
116 }
117
118 Xpp3Dom requirements = mojo.getChild( "requirements" );
119 if ( requirements != null && requirements.getChildCount() > 0 )
120 {
121 for ( Xpp3Dom requirement : requirements.getChildren() )
122 {
123 String requiredRole = getValue( requirement, "role" );
124 requiredRole = getRelocatedClass( requiredRole, relocators );
125 setValue( requirement, "role", requiredRole );
126 }
127 }
128 mojos.add( mojo );
129 }
130 }
131
132 public void modifyOutputStream( JarOutputStream jos )
133 throws IOException
134 {
135 byte[] data = getTransformedResource();
136
137 jos.putNextEntry( new JarEntry( PLUGIN_XML_PATH ) );
138
139 jos.write( data );
140
141 mojos.clear();
142 }
143
144 public boolean hasTransformedResource()
145 {
146 return !mojos.isEmpty();
147 }
148
149 byte[] getTransformedResource()
150 throws IOException
151 {
152 ByteArrayOutputStream baos = new ByteArrayOutputStream( 1024 * 4 );
153
154 try ( Writer writer = WriterFactory.newXmlWriter( baos ) )
155 {
156 Xpp3Dom dom = new Xpp3Dom( "plugin" );
157
158 Xpp3Dom componentDom = new Xpp3Dom( "mojos" );
159
160 dom.addChild( componentDom );
161
162 for ( Xpp3Dom mojo : mojos )
163 {
164 componentDom.addChild( mojo );
165 }
166
167 Xpp3DomWriter.write( writer, dom );
168 }
169
170 return baos.toByteArray();
171 }
172
173 private String getRelocatedClass( String className, List<Relocator> relocators )
174 {
175 if ( className != null && className.length() > 0 && relocators != null )
176 {
177 for ( Relocator relocator : relocators )
178 {
179 if ( relocator.canRelocateClass( className ) )
180 {
181 return relocator.relocateClass( className );
182 }
183 }
184 }
185
186 return className;
187 }
188
189 private static String getValue( Xpp3Dom dom, String element )
190 {
191 Xpp3Dom child = dom.getChild( element );
192
193 return ( child != null && child.getValue() != null ) ? child.getValue() : "";
194 }
195
196 private static void setValue( Xpp3Dom dom, String element, String value )
197 {
198 Xpp3Dom child = dom.getChild( element );
199
200 if ( child == null || value == null || value.length() <= 0 )
201 {
202 return;
203 }
204
205 child.setValue( value );
206 }
207
208 private static String getAttribute( Xpp3Dom dom, String attribute )
209 {
210 return ( dom.getAttribute( attribute ) != null ) ? dom.getAttribute( attribute ) : "";
211 }
212
213 private static void setAttribute( Xpp3Dom dom, String attribute, String value )
214 {
215 String attr = dom.getAttribute( attribute );
216
217 if ( attr == null || value == null || value.length() <= 0 )
218 {
219 return;
220 }
221
222 dom.setAttribute( attribute, value );
223 }
224
225 }