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