1 package org.apache.maven.plugins.help;
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.StringWriter;
24 import java.io.Writer;
25 import java.lang.reflect.InvocationTargetException;
26 import java.lang.reflect.Method;
27 import java.util.List;
28 import java.util.Properties;
29
30 import org.apache.maven.model.InputLocation;
31 import org.apache.maven.model.Model;
32 import org.apache.maven.model.InputSource;
33 import org.apache.maven.model.io.xpp3.MavenXpp3Writer;
34 import org.apache.maven.model.io.xpp3.MavenXpp3WriterExOldSupport;
35 import org.apache.maven.plugin.MojoExecution;
36 import org.apache.maven.plugin.MojoExecution.Source;
37 import org.apache.maven.plugin.MojoExecutionException;
38 import org.apache.maven.plugins.annotations.Mojo;
39 import org.apache.maven.plugins.annotations.Parameter;
40 import org.apache.maven.project.MavenProject;
41 import org.apache.maven.shared.utils.logging.MessageUtils;
42 import org.codehaus.plexus.util.StringUtils;
43 import org.codehaus.plexus.util.xml.PrettyPrintXMLWriter;
44 import org.codehaus.plexus.util.xml.XMLWriter;
45 import org.codehaus.plexus.util.xml.XmlWriterUtil;
46 import org.codehaus.plexus.util.xml.Xpp3Dom;
47 import org.codehaus.plexus.util.xml.pull.XmlSerializer;
48
49
50
51
52
53
54
55 @Mojo( name = "effective-pom", aggregator = true )
56 public class EffectivePomMojo
57 extends AbstractEffectiveMojo
58 {
59
60
61
62
63
64
65
66
67
68 @Parameter( defaultValue = "${project}", readonly = true, required = true )
69 private MavenProject project;
70
71
72
73
74
75 @Parameter( defaultValue = "${reactorProjects}", required = true, readonly = true )
76 private List<MavenProject> projects;
77
78
79
80
81 @Parameter( defaultValue = "${mojo}", required = true, readonly = true )
82 private MojoExecution mojoExecution;
83
84
85
86
87
88
89
90
91
92 @Parameter( property = "artifact" )
93 private String artifact;
94
95
96
97
98
99
100 @Parameter( property = "verbose", defaultValue = "false" )
101 private boolean verbose = false;
102
103
104
105
106
107
108 public void execute()
109 throws MojoExecutionException
110 {
111 if ( StringUtils.isNotEmpty( artifact ) )
112 {
113 project = getMavenProject( artifact );
114 }
115
116 StringWriter w = new StringWriter();
117 String encoding = output != null ? project.getModel().getModelEncoding()
118 : System.getProperty( "file.encoding" );
119 XMLWriter writer =
120 new PrettyPrintXMLWriter( w, StringUtils.repeat( " ", XmlWriterUtil.DEFAULT_INDENTATION_SIZE ),
121 encoding, null );
122
123 writeHeader( writer );
124
125 if ( shouldWriteAllEffectivePOMsInReactor() )
126 {
127
128 writer.startElement( "projects" );
129 for ( MavenProject subProject : projects )
130 {
131 writeEffectivePom( subProject, writer );
132 }
133 writer.endElement();
134 }
135 else
136 {
137 writeEffectivePom( project, writer );
138 }
139
140 String effectivePom = prettyFormat( w.toString(), encoding, false );
141 if ( verbose )
142 {
143
144 effectivePom = effectivePom.replaceAll( "(?m)>\\s+<!--}", "> <!-- " );
145 }
146
147 if ( output != null )
148 {
149 try
150 {
151 writeXmlFile( output, effectivePom );
152 }
153 catch ( IOException e )
154 {
155 throw new MojoExecutionException( "Cannot write effective-POM to output: " + output, e );
156 }
157
158 getLog().info( "Effective-POM written to: " + output );
159 }
160 else
161 {
162 if ( MessageUtils.isColorEnabled() )
163 {
164
165 String comment = MessageUtils.buffer().project( "<!--.-->" ).toString();
166 int dotIndex = comment.indexOf( "." );
167 String commentStart = comment.substring( 0, dotIndex );
168 String commentEnd = comment.substring( dotIndex + 1 );
169 effectivePom = effectivePom.replaceAll( "<!--", commentStart ).replaceAll( "-->", commentEnd );
170 }
171
172 StringBuilder message = new StringBuilder();
173
174 message.append( LS );
175 message.append( "Effective POMs, after inheritance, interpolation, and profiles are applied:" );
176 message.append( LS ).append( LS );
177 message.append( effectivePom );
178 message.append( LS );
179
180 getLog().info( message.toString() );
181 }
182 }
183
184
185
186
187
188
189
190
191 private boolean shouldWriteAllEffectivePOMsInReactor()
192 {
193 Source source = mojoExecution.getSource();
194
195 return projects.size() > 1
196 && ( source == Source.CLI || source != Source.CLI && projects.get( 0 ).equals( project ) );
197 }
198
199
200
201
202
203
204
205
206
207
208
209
210 private void writeEffectivePom( MavenProject project, XMLWriter writer )
211 throws MojoExecutionException
212 {
213 Model pom = project.getModel();
214 cleanModel( pom );
215
216 StringWriter sWriter = new StringWriter();
217 try
218 {
219 if ( verbose )
220 {
221
222 if ( ! writeMavenXpp3WriterEx( sWriter, pom ) )
223 {
224
225 new EffectiveWriterExOldSupport().write( sWriter, pom );
226 }
227 }
228 else
229 {
230 new MavenXpp3Writer().write( sWriter, pom );
231 }
232 }
233 catch ( IOException e )
234 {
235 throw new MojoExecutionException( "Cannot serialize POM to XML.", e );
236 }
237
238
239 String effectivePom = prettyFormat( sWriter.toString(), null, true );
240
241 writeComment( writer, "Effective POM for project \'" + project.getId() + "\'" );
242
243 writer.writeMarkup( effectivePom );
244 }
245
246
247
248
249
250
251 private static void cleanModel( Model pom )
252 {
253 Properties properties = new SortedProperties();
254 properties.putAll( pom.getProperties() );
255 pom.setProperties( properties );
256 }
257
258 private void warnWriteMavenXpp3WriterEx( Throwable t )
259 {
260 getLog().warn( "Unexpected exception while running Maven Model Extended Writer, "
261 + "falling back to old internal implementation.", t );
262 }
263
264 private boolean writeMavenXpp3WriterEx( Writer writer, Model model )
265 throws IOException
266 {
267 try
268 {
269 Class<?> mavenXpp3WriterExClass = Class.forName( "org.apache.maven.model.io.xpp3.MavenXpp3WriterEx" );
270 Object mavenXpp3WriterEx = mavenXpp3WriterExClass.newInstance();
271
272 Method setStringFormatter =
273 mavenXpp3WriterExClass.getMethod( "setStringFormatter", InputLocation.StringFormatter.class );
274 setStringFormatter.invoke( mavenXpp3WriterEx, new InputLocationStringFormatter() );
275
276 Method write = mavenXpp3WriterExClass.getMethod( "write", Writer.class, Model.class );
277 write.invoke( mavenXpp3WriterEx, writer, model );
278
279 return true;
280 }
281 catch ( ClassNotFoundException e )
282 {
283
284 }
285 catch ( NoSuchMethodException e )
286 {
287 warnWriteMavenXpp3WriterEx( e );
288 }
289 catch ( SecurityException e )
290 {
291 warnWriteMavenXpp3WriterEx( e );
292 }
293 catch ( InstantiationException e )
294 {
295 warnWriteMavenXpp3WriterEx( e );
296 }
297 catch ( IllegalAccessException e )
298 {
299 warnWriteMavenXpp3WriterEx( e );
300 }
301 catch ( IllegalArgumentException e )
302 {
303 warnWriteMavenXpp3WriterEx( e );
304 }
305 catch ( InvocationTargetException e )
306 {
307 if ( e.getTargetException() instanceof IOException )
308 {
309 throw (IOException) e.getTargetException();
310 }
311 else if ( e.getTargetException() instanceof RuntimeException )
312 {
313 throw (RuntimeException) e.getTargetException();
314 }
315 warnWriteMavenXpp3WriterEx( e );
316 }
317 return false;
318 }
319
320 private static String toString( InputLocation location )
321 {
322 InputSource source = location.getSource();
323
324 String s = source.getModelId();
325
326 if ( StringUtils.isBlank( s ) || s.contains( "[unknown-version]" ) )
327 {
328
329 s = source.toString();
330 }
331
332 return '}' + s + ( ( location.getLineNumber() >= 0 ) ? ", line " + location.getLineNumber() : "" ) + ' ';
333 }
334
335 private static class InputLocationStringFormatter
336 extends InputLocation.StringFormatter
337 {
338
339 public String toString( InputLocation location )
340 {
341 return EffectivePomMojo.toString( location );
342 }
343
344 }
345
346
347
348
349 private static class EffectiveWriterExOldSupport
350 extends MavenXpp3WriterExOldSupport
351 {
352
353 @Override
354 public String toString( InputLocation location )
355 {
356 return EffectivePomMojo.toString( location );
357 }
358
359 @Override
360 protected void writeXpp3DomToSerializer( Xpp3Dom dom, XmlSerializer serializer )
361 throws java.io.IOException
362 {
363
364
365 dom.writeToSerializer( null, serializer );
366 }
367 }
368 }