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