1 package org.apache.maven.project.inheritance;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.maven.model.Build;
23 import org.apache.maven.model.Dependency;
24 import org.apache.maven.model.DependencyManagement;
25 import org.apache.maven.model.DeploymentRepository;
26 import org.apache.maven.model.DistributionManagement;
27 import org.apache.maven.model.Model;
28 import org.apache.maven.model.PluginManagement;
29 import org.apache.maven.model.Reporting;
30 import org.apache.maven.model.Scm;
31 import org.apache.maven.model.Site;
32 import org.apache.maven.project.ModelUtils;
33 import org.codehaus.plexus.util.StringUtils;
34
35 import java.util.ArrayList;
36 import java.util.Iterator;
37 import java.util.LinkedList;
38 import java.util.List;
39 import java.util.Map;
40 import java.util.Properties;
41 import java.util.StringTokenizer;
42 import java.util.TreeMap;
43
44
45
46
47
48
49
50 public class DefaultModelInheritanceAssembler
51 implements ModelInheritanceAssembler
52 {
53 public void copyModel( Model dest, Model source )
54 {
55 assembleModelInheritance( dest, source, null, false );
56 }
57
58 public void assembleModelInheritance( Model child, Model parent, String childPathAdjustment )
59 {
60 assembleModelInheritance( child, parent, childPathAdjustment, true );
61 }
62
63 public void assembleModelInheritance( Model child, Model parent )
64 {
65 assembleModelInheritance( child, parent, null, true );
66 }
67
68 private void assembleModelInheritance( Model child, Model parent, String childPathAdjustment, boolean appendPaths )
69 {
70
71 if ( parent == null )
72 {
73 return;
74 }
75
76
77 if ( child.getGroupId() == null )
78 {
79 child.setGroupId( parent.getGroupId() );
80 }
81
82
83 if ( child.getVersion() == null )
84 {
85
86
87
88 if ( child.getParent() != null )
89 {
90 child.setVersion( child.getParent().getVersion() );
91 }
92 }
93
94
95 if ( child.getInceptionYear() == null )
96 {
97 child.setInceptionYear( parent.getInceptionYear() );
98 }
99
100
101 if ( child.getUrl() == null )
102 {
103 if ( parent.getUrl() != null )
104 {
105 child.setUrl( appendPath( parent.getUrl(), child.getArtifactId(), childPathAdjustment, appendPaths ) );
106 }
107 else
108 {
109 child.setUrl( parent.getUrl() );
110 }
111 }
112
113 assembleDistributionInheritence( child, parent, childPathAdjustment, appendPaths );
114
115
116 if ( child.getIssueManagement() == null )
117 {
118 child.setIssueManagement( parent.getIssueManagement() );
119 }
120
121
122 if ( child.getDescription() == null )
123 {
124 child.setDescription( parent.getDescription() );
125 }
126
127
128 if ( child.getOrganization() == null )
129 {
130 child.setOrganization( parent.getOrganization() );
131 }
132
133
134 assembleScmInheritance( child, parent, childPathAdjustment, appendPaths );
135
136
137 if ( child.getCiManagement() == null )
138 {
139 child.setCiManagement( parent.getCiManagement() );
140 }
141
142
143 if ( child.getDevelopers().size() == 0 )
144 {
145 child.setDevelopers( parent.getDevelopers() );
146 }
147
148
149 if ( child.getLicenses().size() == 0 )
150 {
151 child.setLicenses( parent.getLicenses() );
152 }
153
154
155 if ( child.getContributors().size() == 0 )
156 {
157 child.setContributors( parent.getContributors() );
158 }
159
160
161 if ( child.getMailingLists().size() == 0 )
162 {
163 child.setMailingLists( parent.getMailingLists() );
164 }
165
166
167 assembleBuildInheritance( child, parent );
168
169 assembleDependencyInheritance( child, parent );
170
171 child.setRepositories( ModelUtils.mergeRepositoryLists( child.getRepositories(), parent.getRepositories() ) );
172 child.setPluginRepositories(
173 ModelUtils.mergeRepositoryLists( child.getPluginRepositories(), parent.getPluginRepositories() ) );
174
175 assembleReportingInheritance( child, parent );
176
177 assembleDependencyManagementInheritance( child, parent );
178
179 Properties props = new Properties();
180 props.putAll( parent.getProperties() );
181 props.putAll( child.getProperties() );
182
183 child.setProperties( props );
184 }
185
186 private void assembleDependencyManagementInheritance( Model child, Model parent )
187 {
188 DependencyManagement parentDepMgmt = parent.getDependencyManagement();
189
190 DependencyManagement childDepMgmt = child.getDependencyManagement();
191
192 if ( parentDepMgmt != null )
193 {
194 if ( childDepMgmt == null )
195 {
196 child.setDependencyManagement( parentDepMgmt );
197 }
198 else
199 {
200 List childDeps = childDepMgmt.getDependencies();
201
202 Map mappedChildDeps = new TreeMap();
203 for ( Iterator it = childDeps.iterator(); it.hasNext(); )
204 {
205 Dependency dep = (Dependency) it.next();
206 mappedChildDeps.put( dep.getManagementKey(), dep );
207 }
208
209 for ( Iterator it = parentDepMgmt.getDependencies().iterator(); it.hasNext(); )
210 {
211 Dependency dep = (Dependency) it.next();
212 if ( !mappedChildDeps.containsKey( dep.getManagementKey() ) )
213 {
214 childDepMgmt.addDependency( dep );
215 }
216 }
217 }
218 }
219 }
220
221 private void assembleReportingInheritance( Model child, Model parent )
222 {
223
224 Reporting childReporting = child.getReporting();
225 Reporting parentReporting = parent.getReporting();
226
227 if ( parentReporting != null )
228 {
229 if ( childReporting == null )
230 {
231 childReporting = new Reporting();
232 child.setReporting( childReporting );
233 }
234
235 if ( childReporting.isExcludeDefaultsValue() == null )
236 {
237 childReporting.setExcludeDefaultsValue( parentReporting.isExcludeDefaultsValue() );
238 }
239
240 if ( StringUtils.isEmpty( childReporting.getOutputDirectory() ) )
241 {
242 childReporting.setOutputDirectory( parentReporting.getOutputDirectory() );
243 }
244
245 ModelUtils.mergeReportPluginLists( childReporting, parentReporting, true );
246 }
247 }
248
249 private void assembleDependencyInheritance( Model child, Model parent )
250 {
251 child.setDependencies( ModelUtils.mergeDependencyList( child.getDependencies(), parent.getDependencies() ) );
252 }
253
254 private void assembleBuildInheritance( Model child, Model parent )
255 {
256 Build childBuild = child.getBuild();
257 Build parentBuild = parent.getBuild();
258
259 if ( parentBuild != null )
260 {
261 if ( childBuild == null )
262 {
263 childBuild = new Build();
264 child.setBuild( childBuild );
265 }
266
267
268
269
270 if ( childBuild.getSourceDirectory() == null )
271 {
272 childBuild.setSourceDirectory( parentBuild.getSourceDirectory() );
273 }
274
275 if ( childBuild.getScriptSourceDirectory() == null )
276 {
277 childBuild.setScriptSourceDirectory( parentBuild.getScriptSourceDirectory() );
278 }
279
280 if ( childBuild.getTestSourceDirectory() == null )
281 {
282 childBuild.setTestSourceDirectory( parentBuild.getTestSourceDirectory() );
283 }
284
285 if ( childBuild.getOutputDirectory() == null )
286 {
287 childBuild.setOutputDirectory( parentBuild.getOutputDirectory() );
288 }
289
290 if ( childBuild.getTestOutputDirectory() == null )
291 {
292 childBuild.setTestOutputDirectory( parentBuild.getTestOutputDirectory() );
293 }
294
295
296 ModelUtils.mergeExtensionLists( childBuild, parentBuild );
297
298 if ( childBuild.getDirectory() == null )
299 {
300 childBuild.setDirectory( parentBuild.getDirectory() );
301 }
302
303 if ( childBuild.getDefaultGoal() == null )
304 {
305 childBuild.setDefaultGoal( parentBuild.getDefaultGoal() );
306 }
307
308 if ( childBuild.getFinalName() == null )
309 {
310 childBuild.setFinalName( parentBuild.getFinalName() );
311 }
312
313 ModelUtils.mergeFilterLists( childBuild.getFilters(), parentBuild.getFilters() );
314
315 List resources = childBuild.getResources();
316 if ( ( resources == null ) || resources.isEmpty() )
317 {
318 childBuild.setResources( parentBuild.getResources() );
319 }
320
321 resources = childBuild.getTestResources();
322 if ( ( resources == null ) || resources.isEmpty() )
323 {
324 childBuild.setTestResources( parentBuild.getTestResources() );
325 }
326
327
328 ModelUtils.mergePluginLists( childBuild, parentBuild, true );
329
330
331 PluginManagement dominantPM = childBuild.getPluginManagement();
332 PluginManagement recessivePM = parentBuild.getPluginManagement();
333
334 if ( ( dominantPM == null ) && ( recessivePM != null ) )
335 {
336
337 childBuild.setPluginManagement( recessivePM );
338 }
339 else
340 {
341 ModelUtils.mergePluginLists( childBuild.getPluginManagement(), parentBuild.getPluginManagement(),
342 false );
343 }
344 }
345 }
346
347 private void assembleScmInheritance( Model child, Model parent, String childPathAdjustment, boolean appendPaths )
348 {
349 if ( parent.getScm() != null )
350 {
351 Scm parentScm = parent.getScm();
352
353 Scm childScm = child.getScm();
354
355 if ( childScm == null )
356 {
357 childScm = new Scm();
358
359 child.setScm( childScm );
360 }
361
362 if ( StringUtils.isEmpty( childScm.getConnection() ) && !StringUtils.isEmpty( parentScm.getConnection() ) )
363 {
364 childScm.setConnection(
365 appendPath( parentScm.getConnection(), child.getArtifactId(), childPathAdjustment, appendPaths ) );
366 }
367
368 if ( StringUtils.isEmpty( childScm.getDeveloperConnection() ) &&
369 !StringUtils.isEmpty( parentScm.getDeveloperConnection() ) )
370 {
371 childScm
372 .setDeveloperConnection( appendPath( parentScm.getDeveloperConnection(), child.getArtifactId(),
373 childPathAdjustment, appendPaths ) );
374 }
375
376 if ( StringUtils.isEmpty( childScm.getUrl() ) && !StringUtils.isEmpty( parentScm.getUrl() ) )
377 {
378 childScm.setUrl(
379 appendPath( parentScm.getUrl(), child.getArtifactId(), childPathAdjustment, appendPaths ) );
380 }
381 }
382 }
383
384 private void assembleDistributionInheritence( Model child, Model parent, String childPathAdjustment, boolean appendPaths )
385 {
386 if ( parent.getDistributionManagement() != null )
387 {
388 DistributionManagement parentDistMgmt = parent.getDistributionManagement();
389
390 DistributionManagement childDistMgmt = child.getDistributionManagement();
391
392 if ( childDistMgmt == null )
393 {
394 childDistMgmt = new DistributionManagement();
395
396 child.setDistributionManagement( childDistMgmt );
397 }
398
399 if ( childDistMgmt.getSite() == null )
400 {
401 if ( parentDistMgmt.getSite() != null )
402 {
403 Site site = new Site();
404
405 childDistMgmt.setSite( site );
406
407 site.setId( parentDistMgmt.getSite().getId() );
408
409 site.setName( parentDistMgmt.getSite().getName() );
410
411 site.setUrl( parentDistMgmt.getSite().getUrl() );
412
413 if ( site.getUrl() != null )
414 {
415 site.setUrl(
416 appendPath( site.getUrl(), child.getArtifactId(), childPathAdjustment, appendPaths ) );
417 }
418 }
419 }
420
421 if ( childDistMgmt.getRepository() == null )
422 {
423 if ( parentDistMgmt.getRepository() != null )
424 {
425 DeploymentRepository repository = copyDistributionRepository( parentDistMgmt.getRepository() );
426 childDistMgmt.setRepository( repository );
427 }
428 }
429
430 if ( childDistMgmt.getSnapshotRepository() == null )
431 {
432 if ( parentDistMgmt.getSnapshotRepository() != null )
433 {
434 DeploymentRepository repository =
435 copyDistributionRepository( parentDistMgmt.getSnapshotRepository() );
436 childDistMgmt.setSnapshotRepository( repository );
437 }
438 }
439
440 if ( StringUtils.isEmpty( childDistMgmt.getDownloadUrl() ) )
441 {
442 childDistMgmt.setDownloadUrl( parentDistMgmt.getDownloadUrl() );
443 }
444
445
446
447 }
448 }
449
450 private static DeploymentRepository copyDistributionRepository( DeploymentRepository parentRepository )
451 {
452 DeploymentRepository repository = new DeploymentRepository();
453
454 repository.setId( parentRepository.getId() );
455
456 repository.setName( parentRepository.getName() );
457
458 repository.setUrl( parentRepository.getUrl() );
459
460 repository.setLayout( parentRepository.getLayout() );
461
462 repository.setUniqueVersion( parentRepository.isUniqueVersion() );
463
464 return repository;
465 }
466
467
468 protected String appendPath( String parentPath, String childPath, String pathAdjustment, boolean appendPaths )
469 {
470 String uncleanPath = parentPath;
471
472 if ( appendPaths )
473 {
474 if ( pathAdjustment != null )
475 {
476 uncleanPath += "/" + pathAdjustment;
477 }
478
479 if ( childPath != null )
480 {
481 uncleanPath += "/" + childPath;
482 }
483 }
484
485 String cleanedPath = "";
486
487 int protocolIdx = uncleanPath.indexOf( "://" );
488
489 if ( protocolIdx > -1 )
490 {
491 cleanedPath = uncleanPath.substring( 0, protocolIdx + 3 );
492 uncleanPath = uncleanPath.substring( protocolIdx + 3 );
493 }
494
495 if ( uncleanPath.startsWith( "//" ) )
496 {
497
498 cleanedPath += "//";
499 }
500 else if ( uncleanPath.startsWith( "/" ) )
501 {
502 cleanedPath += "/";
503 }
504
505 return cleanedPath + resolvePath( uncleanPath );
506 }
507
508
509 private static String resolvePath( String uncleanPath )
510 {
511 LinkedList pathElements = new LinkedList();
512
513 StringTokenizer tokenizer = new StringTokenizer( uncleanPath, "/" );
514
515 while ( tokenizer.hasMoreTokens() )
516 {
517 String token = tokenizer.nextToken();
518
519 if ( token.equals( "" ) )
520 {
521
522 }
523 else if ( token.equals( ".." ) )
524 {
525 if ( pathElements.isEmpty() )
526 {
527
528
529
530 }
531 else
532 {
533 pathElements.removeLast();
534 }
535 }
536 else
537 {
538 pathElements.addLast( token );
539 }
540 }
541
542
543 StringBuffer cleanedPath = new StringBuffer();
544
545 while ( !pathElements.isEmpty() )
546 {
547 cleanedPath.append( pathElements.removeFirst() );
548 if ( !pathElements.isEmpty() )
549 {
550 cleanedPath.append( '/' );
551 }
552 }
553
554 return cleanedPath.toString();
555 }
556
557 }