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
73
74
75
76
77 private String getChildPathAdjustment( Model child, Model parent )
78 {
79 String adjustment = "";
80
81 if ( parent != null )
82 {
83 String childName = child.getArtifactId();
84
85
86
87
88
89
90
91 File childDirectory = child.getProjectDirectory();
92 if ( childDirectory != null )
93 {
94 childName = childDirectory.getName();
95 }
96
97 for ( String module : parent.getModules() )
98 {
99 module = module.replace( '\\', '/' );
100
101 if ( module.regionMatches( true, module.length() - 4, ".xml", 0, 4 ) )
102 {
103 module = module.substring( 0, module.lastIndexOf( '/' ) + 1 );
104 }
105
106 String moduleName = module;
107 if ( moduleName.endsWith( "/" ) )
108 {
109 moduleName = moduleName.substring( 0, moduleName.length() - 1 );
110 }
111
112 int lastSlash = moduleName.lastIndexOf( '/' );
113
114 moduleName = moduleName.substring( lastSlash + 1 );
115
116 if ( moduleName.equals( childName ) && lastSlash >= 0 )
117 {
118 adjustment = module.substring( 0, lastSlash );
119 break;
120 }
121 }
122 }
123
124 return adjustment;
125 }
126
127 protected static class InheritanceModelMerger
128 extends MavenModelMerger
129 {
130
131 @Override
132 protected void mergePluginContainer_Plugins( PluginContainer target, PluginContainer source,
133 boolean sourceDominant, Map<Object, Object> context )
134 {
135 List<Plugin> src = source.getPlugins();
136 if ( !src.isEmpty() )
137 {
138 List<Plugin> tgt = target.getPlugins();
139 Map<Object, Plugin> master = new LinkedHashMap<Object, Plugin>( src.size() * 2 );
140
141 for ( Plugin element : src )
142 {
143 if ( element.isInherited() || !element.getExecutions().isEmpty() )
144 {
145
146 Plugin plugin = new Plugin();
147 plugin.setLocation( "", element.getLocation( "" ) );
148 plugin.setGroupId( null );
149 mergePlugin( plugin, element, sourceDominant, context );
150
151 Object key = getPluginKey( element );
152
153 master.put( key, plugin );
154 }
155 }
156
157 Map<Object, List<Plugin>> predecessors = new LinkedHashMap<Object, List<Plugin>>();
158 List<Plugin> pending = new ArrayList<Plugin>();
159 for ( Plugin element : tgt )
160 {
161 Object key = getPluginKey( element );
162 Plugin existing = master.get( key );
163 if ( existing != null )
164 {
165 mergePlugin( element, existing, sourceDominant, context );
166
167 master.put( key, element );
168
169 if ( !pending.isEmpty() )
170 {
171 predecessors.put( key, pending );
172 pending = new ArrayList<Plugin>();
173 }
174 }
175 else
176 {
177 pending.add( element );
178 }
179 }
180
181 List<Plugin> result = new ArrayList<Plugin>( src.size() + tgt.size() );
182 for ( Map.Entry<Object, Plugin> entry : master.entrySet() )
183 {
184 List<Plugin> pre = predecessors.get( entry.getKey() );
185 if ( pre != null )
186 {
187 result.addAll( pre );
188 }
189 result.add( entry.getValue() );
190 }
191 result.addAll( pending );
192
193 target.setPlugins( result );
194 }
195 }
196
197 @Override
198 protected void mergePlugin( Plugin target, Plugin source, boolean sourceDominant, Map<Object, Object> context )
199 {
200 if ( source.isInherited() )
201 {
202 mergeConfigurationContainer( target, source, sourceDominant, context );
203 }
204 mergePlugin_GroupId( target, source, sourceDominant, context );
205 mergePlugin_ArtifactId( target, source, sourceDominant, context );
206 mergePlugin_Version( target, source, sourceDominant, context );
207 mergePlugin_Extensions( target, source, sourceDominant, context );
208 mergePlugin_Dependencies( target, source, sourceDominant, context );
209 mergePlugin_Executions( target, source, sourceDominant, context );
210 }
211
212 @Override
213 protected void mergeReporting_Plugins( Reporting target, Reporting source, boolean sourceDominant,
214 Map<Object, Object> context )
215 {
216 List<ReportPlugin> src = source.getPlugins();
217 if ( !src.isEmpty() )
218 {
219 List<ReportPlugin> tgt = target.getPlugins();
220 Map<Object, ReportPlugin> merged =
221 new LinkedHashMap<Object, ReportPlugin>( ( src.size() + tgt.size() ) * 2 );
222
223 for ( ReportPlugin element : src )
224 {
225 Object key = getReportPluginKey( element );
226 if ( element.isInherited() )
227 {
228
229 ReportPlugin plugin = new ReportPlugin();
230 plugin.setLocation( "", element.getLocation( "" ) );
231 plugin.setGroupId( null );
232 mergeReportPlugin( plugin, element, sourceDominant, context );
233
234 merged.put( key, plugin );
235 }
236 }
237
238 for ( ReportPlugin element : tgt )
239 {
240 Object key = getReportPluginKey( element );
241 ReportPlugin existing = merged.get( key );
242 if ( existing != null )
243 {
244 mergeReportPlugin( element, existing, sourceDominant, context );
245 }
246 merged.put( key, element );
247 }
248
249 target.setPlugins( new ArrayList<ReportPlugin>( merged.values() ) );
250 }
251 }
252 }
253
254 }