1 package org.apache.maven.model.inheritance;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.util.ArrayList;
23 import java.util.HashMap;
24 import java.util.LinkedHashMap;
25 import java.util.List;
26 import java.util.Map;
27
28 import org.apache.maven.model.Model;
29 import org.apache.maven.model.Plugin;
30 import org.apache.maven.model.PluginContainer;
31 import org.apache.maven.model.ReportPlugin;
32 import org.apache.maven.model.Reporting;
33 import org.apache.maven.model.building.ModelBuildingRequest;
34 import org.apache.maven.model.building.ModelProblemCollector;
35 import org.apache.maven.model.merge.MavenModelMerger;
36 import org.codehaus.plexus.component.annotations.Component;
37
38
39
40
41
42
43 @Component( role = InheritanceAssembler.class )
44 public class DefaultInheritanceAssembler
45 implements InheritanceAssembler
46 {
47
48 private InheritanceModelMerger merger = new InheritanceModelMerger();
49
50 public void assembleModelInheritance( Model child, Model parent, ModelBuildingRequest request,
51 ModelProblemCollector problems )
52 {
53 Map<Object, Object> hints = new HashMap<Object, Object>();
54 hints.put( MavenModelMerger.CHILD_PATH_ADJUSTMENT, getChildPathAdjustment( child, parent ) );
55 merger.merge( child, parent, false, hints );
56 }
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71 private String getChildPathAdjustment( Model child, Model parent )
72 {
73 String adjustment = "";
74
75 if ( parent != null )
76 {
77 String childArtifactId = child.getArtifactId();
78
79 for ( String module : parent.getModules() )
80 {
81 module = module.replace( '\\', '/' );
82
83 if ( module.regionMatches( true, module.length() - 4, ".xml", 0, 4 ) )
84 {
85 module = module.substring( 0, module.lastIndexOf( '/' ) + 1 );
86 }
87
88 String moduleName = module;
89 if ( moduleName.endsWith( "/" ) )
90 {
91 moduleName = moduleName.substring( 0, moduleName.length() - 1 );
92 }
93
94 int lastSlash = moduleName.lastIndexOf( '/' );
95
96 moduleName = moduleName.substring( lastSlash + 1 );
97
98 if ( moduleName.equals( childArtifactId ) && lastSlash >= 0 )
99 {
100 adjustment = module.substring( 0, lastSlash );
101 break;
102 }
103 }
104 }
105
106 return adjustment;
107 }
108
109 private static class InheritanceModelMerger
110 extends MavenModelMerger
111 {
112
113 @Override
114 protected void mergePluginContainer_Plugins( PluginContainer target, PluginContainer source,
115 boolean sourceDominant, Map<Object, Object> context )
116 {
117 List<Plugin> src = source.getPlugins();
118 if ( !src.isEmpty() )
119 {
120 List<Plugin> tgt = target.getPlugins();
121 Map<Object, Plugin> master = new LinkedHashMap<Object, Plugin>( src.size() * 2 );
122
123 for ( Plugin element : src )
124 {
125 if ( element.isInherited() || !element.getExecutions().isEmpty() )
126 {
127
128 Plugin plugin = new Plugin();
129 plugin.setGroupId( null );
130 mergePlugin( plugin, element, sourceDominant, context );
131
132 Object key = getPluginKey( element );
133
134 master.put( key, plugin );
135 }
136 }
137
138 Map<Object, List<Plugin>> predecessors = new LinkedHashMap<Object, List<Plugin>>();
139 List<Plugin> pending = new ArrayList<Plugin>();
140 for ( Plugin element : tgt )
141 {
142 Object key = getPluginKey( element );
143 Plugin existing = master.get( key );
144 if ( existing != null )
145 {
146 mergePlugin( element, existing, sourceDominant, context );
147
148 master.put( key, element );
149
150 if ( !pending.isEmpty() )
151 {
152 predecessors.put( key, pending );
153 pending = new ArrayList<Plugin>();
154 }
155 }
156 else
157 {
158 pending.add( element );
159 }
160 }
161
162 List<Plugin> result = new ArrayList<Plugin>( src.size() + tgt.size() );
163 for ( Map.Entry<Object, Plugin> entry : master.entrySet() )
164 {
165 List<Plugin> pre = predecessors.get( entry.getKey() );
166 if ( pre != null )
167 {
168 result.addAll( pre );
169 }
170 result.add( entry.getValue() );
171 }
172 result.addAll( pending );
173
174 target.setPlugins( result );
175 }
176 }
177
178 @Override
179 protected void mergePlugin( Plugin target, Plugin source, boolean sourceDominant, Map<Object, Object> context )
180 {
181 if ( source.isInherited() )
182 {
183 mergeConfigurationContainer( target, source, sourceDominant, context );
184 }
185 mergePlugin_GroupId( target, source, sourceDominant, context );
186 mergePlugin_ArtifactId( target, source, sourceDominant, context );
187 mergePlugin_Version( target, source, sourceDominant, context );
188 mergePlugin_Extensions( target, source, sourceDominant, context );
189 mergePlugin_Dependencies( target, source, sourceDominant, context );
190 mergePlugin_Executions( target, source, sourceDominant, context );
191 }
192
193 @Override
194 protected void mergeReporting_Plugins( Reporting target, Reporting source, boolean sourceDominant,
195 Map<Object, Object> context )
196 {
197 List<ReportPlugin> src = source.getPlugins();
198 if ( !src.isEmpty() )
199 {
200 List<ReportPlugin> tgt = target.getPlugins();
201 Map<Object, ReportPlugin> merged =
202 new LinkedHashMap<Object, ReportPlugin>( ( src.size() + tgt.size() ) * 2 );
203
204 for ( ReportPlugin element : src )
205 {
206 Object key = getReportPluginKey( element );
207 if ( element.isInherited() )
208 {
209
210 ReportPlugin plugin = new ReportPlugin();
211 plugin.setGroupId( null );
212 mergeReportPlugin( plugin, element, sourceDominant, context );
213
214 merged.put( key, plugin );
215 }
216 }
217
218 for ( ReportPlugin element : tgt )
219 {
220 Object key = getReportPluginKey( element );
221 ReportPlugin existing = merged.get( key );
222 if ( existing != null )
223 {
224 mergeReportPlugin( element, existing, sourceDominant, context );
225 }
226 merged.put( key, element );
227 }
228
229 target.setPlugins( new ArrayList<ReportPlugin>( merged.values() ) );
230 }
231 }
232 }
233
234 }