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 assembleBuildInheritance( childBuild, parentBuild, true );
268 }
269 }
270
271 public void assembleBuildInheritance( Build childBuild,
272 Build parentBuild,
273 boolean handleAsInheritance )
274 {
275
276
277
278 if ( childBuild.getSourceDirectory() == null )
279 {
280 childBuild.setSourceDirectory( parentBuild.getSourceDirectory() );
281 }
282
283 if ( childBuild.getScriptSourceDirectory() == null )
284 {
285 childBuild.setScriptSourceDirectory( parentBuild.getScriptSourceDirectory() );
286 }
287
288 if ( childBuild.getTestSourceDirectory() == null )
289 {
290 childBuild.setTestSourceDirectory( parentBuild.getTestSourceDirectory() );
291 }
292
293 if ( childBuild.getOutputDirectory() == null )
294 {
295 childBuild.setOutputDirectory( parentBuild.getOutputDirectory() );
296 }
297
298 if ( childBuild.getTestOutputDirectory() == null )
299 {
300 childBuild.setTestOutputDirectory( parentBuild.getTestOutputDirectory() );
301 }
302
303
304 ModelUtils.mergeExtensionLists( childBuild, parentBuild );
305
306 if ( childBuild.getDirectory() == null )
307 {
308 childBuild.setDirectory( parentBuild.getDirectory() );
309 }
310
311 if ( childBuild.getDefaultGoal() == null )
312 {
313 childBuild.setDefaultGoal( parentBuild.getDefaultGoal() );
314 }
315
316 if ( childBuild.getFinalName() == null )
317 {
318 childBuild.setFinalName( parentBuild.getFinalName() );
319 }
320
321 ModelUtils.mergeFilterLists( childBuild.getFilters(), parentBuild.getFilters() );
322
323 List resources = childBuild.getResources();
324 if ( ( resources == null ) || resources.isEmpty() )
325 {
326 childBuild.setResources( parentBuild.getResources() );
327 }
328
329 resources = childBuild.getTestResources();
330 if ( ( resources == null ) || resources.isEmpty() )
331 {
332 childBuild.setTestResources( parentBuild.getTestResources() );
333 }
334
335
336 ModelUtils.mergePluginLists( childBuild, parentBuild, handleAsInheritance );
337
338
339 PluginManagement dominantPM = childBuild.getPluginManagement();
340 PluginManagement recessivePM = parentBuild.getPluginManagement();
341
342 if ( ( dominantPM == null ) && ( recessivePM != null ) )
343 {
344
345 childBuild.setPluginManagement( recessivePM );
346 }
347 else
348 {
349 ModelUtils.mergePluginLists( childBuild.getPluginManagement(), parentBuild.getPluginManagement(),
350 false );
351 }
352 }
353
354 private void assembleScmInheritance( Model child, Model parent, String childPathAdjustment, boolean appendPaths )
355 {
356 if ( parent.getScm() != null )
357 {
358 Scm parentScm = parent.getScm();
359
360 Scm childScm = child.getScm();
361
362 if ( childScm == null )
363 {
364 childScm = new Scm();
365
366 child.setScm( childScm );
367 }
368
369 if ( StringUtils.isEmpty( childScm.getConnection() ) && !StringUtils.isEmpty( parentScm.getConnection() ) )
370 {
371 childScm.setConnection(
372 appendPath( parentScm.getConnection(), child.getArtifactId(), childPathAdjustment, appendPaths ) );
373 }
374
375 if ( StringUtils.isEmpty( childScm.getDeveloperConnection() ) &&
376 !StringUtils.isEmpty( parentScm.getDeveloperConnection() ) )
377 {
378 childScm
379 .setDeveloperConnection( appendPath( parentScm.getDeveloperConnection(), child.getArtifactId(),
380 childPathAdjustment, appendPaths ) );
381 }
382
383 if ( StringUtils.isEmpty( childScm.getUrl() ) && !StringUtils.isEmpty( parentScm.getUrl() ) )
384 {
385 childScm.setUrl(
386 appendPath( parentScm.getUrl(), child.getArtifactId(), childPathAdjustment, appendPaths ) );
387 }
388 }
389 }
390
391 private void assembleDistributionInheritence( Model child, Model parent, String childPathAdjustment, boolean appendPaths )
392 {
393 if ( parent.getDistributionManagement() != null )
394 {
395 DistributionManagement parentDistMgmt = parent.getDistributionManagement();
396
397 DistributionManagement childDistMgmt = child.getDistributionManagement();
398
399 if ( childDistMgmt == null )
400 {
401 childDistMgmt = new DistributionManagement();
402
403 child.setDistributionManagement( childDistMgmt );
404 }
405
406 if ( childDistMgmt.getSite() == null )
407 {
408 if ( parentDistMgmt.getSite() != null )
409 {
410 Site site = new Site();
411
412 childDistMgmt.setSite( site );
413
414 site.setId( parentDistMgmt.getSite().getId() );
415
416 site.setName( parentDistMgmt.getSite().getName() );
417
418 site.setUrl( parentDistMgmt.getSite().getUrl() );
419
420 if ( site.getUrl() != null )
421 {
422 site.setUrl(
423 appendPath( site.getUrl(), child.getArtifactId(), childPathAdjustment, appendPaths ) );
424 }
425 }
426 }
427
428 if ( childDistMgmt.getRepository() == null )
429 {
430 if ( parentDistMgmt.getRepository() != null )
431 {
432 DeploymentRepository repository = copyDistributionRepository( parentDistMgmt.getRepository() );
433 childDistMgmt.setRepository( repository );
434 }
435 }
436
437 if ( childDistMgmt.getSnapshotRepository() == null )
438 {
439 if ( parentDistMgmt.getSnapshotRepository() != null )
440 {
441 DeploymentRepository repository =
442 copyDistributionRepository( parentDistMgmt.getSnapshotRepository() );
443 childDistMgmt.setSnapshotRepository( repository );
444 }
445 }
446
447 if ( StringUtils.isEmpty( childDistMgmt.getDownloadUrl() ) )
448 {
449 childDistMgmt.setDownloadUrl( parentDistMgmt.getDownloadUrl() );
450 }
451
452
453
454 }
455 }
456
457 private static DeploymentRepository copyDistributionRepository( DeploymentRepository parentRepository )
458 {
459 DeploymentRepository repository = new DeploymentRepository();
460
461 repository.setId( parentRepository.getId() );
462
463 repository.setName( parentRepository.getName() );
464
465 repository.setUrl( parentRepository.getUrl() );
466
467 repository.setLayout( parentRepository.getLayout() );
468
469 repository.setUniqueVersion( parentRepository.isUniqueVersion() );
470
471 return repository;
472 }
473
474
475 protected String appendPath( String parentPath, String childPath, String pathAdjustment, boolean appendPaths )
476 {
477 String uncleanPath = parentPath;
478
479 if ( appendPaths )
480 {
481 if ( pathAdjustment != null )
482 {
483 uncleanPath += "/" + pathAdjustment;
484 }
485
486 if ( childPath != null )
487 {
488 uncleanPath += "/" + childPath;
489 }
490 }
491
492 String cleanedPath = "";
493
494 int protocolIdx = uncleanPath.indexOf( "://" );
495
496 if ( protocolIdx > -1 )
497 {
498 cleanedPath = uncleanPath.substring( 0, protocolIdx + 3 );
499 uncleanPath = uncleanPath.substring( protocolIdx + 3 );
500 }
501
502 if ( uncleanPath.startsWith( "//" ) )
503 {
504
505 cleanedPath += "//";
506 }
507 else if ( uncleanPath.startsWith( "/" ) )
508 {
509 cleanedPath += "/";
510 }
511
512 return cleanedPath + resolvePath( uncleanPath );
513 }
514
515
516 private static String resolvePath( String uncleanPath )
517 {
518 LinkedList pathElements = new LinkedList();
519
520 StringTokenizer tokenizer = new StringTokenizer( uncleanPath, "/" );
521
522 while ( tokenizer.hasMoreTokens() )
523 {
524 String token = tokenizer.nextToken();
525
526 if ( token.equals( "" ) )
527 {
528
529 }
530 else if ( token.equals( ".." ) )
531 {
532 if ( pathElements.isEmpty() )
533 {
534
535
536
537 }
538 else
539 {
540 pathElements.removeLast();
541 }
542 }
543 else
544 {
545 pathElements.addLast( token );
546 }
547 }
548
549
550 StringBuffer cleanedPath = new StringBuffer();
551
552 while ( !pathElements.isEmpty() )
553 {
554 cleanedPath.append( pathElements.removeFirst() );
555 if ( !pathElements.isEmpty() )
556 {
557 cleanedPath.append( '/' );
558 }
559 }
560
561 return cleanedPath.toString();
562 }
563
564 }