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