View Javadoc
1   package org.codehaus.plexus.configuration;
2   
3   import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration;
4   
5   /*
6    * Copyright 2001-2006 Codehaus Foundation.
7    *
8    * Licensed under the Apache License, Version 2.0 (the "License");
9    * you may not use this file except in compliance with the License.
10   * You may obtain a copy of the License at
11   *
12   *      http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS,
16   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17   * See the License for the specific language governing permissions and
18   * limitations under the License.
19   */
20  
21  /**
22   * TODO: This merger explicity uses the XML implementation of the plexus configuration but
23   * it must work for configurations coming from any source.
24   */
25  public class PlexusConfigurationMerger {
26      // -----------------------------------+-----------------------------------------------------------------
27      //  E L E M E N T                     |
28      // -----------------------------------+-----------------------------------------------------------------
29      // load-on-start                      | user
30      // -----------------------------------+-----------------------------------------------------------------
31      // system-properties                  | user
32      // -----------------------------------+-----------------------------------------------------------------
33      // configurations-directory           | user
34      // -----------------------------------+-----------------------------------------------------------------
35      // logging                            | user wins
36      // -----------------------------------+-----------------------------------------------------------------
37      // component-repository               | user wins
38      // -----------------------------------+-----------------------------------------------------------------
39      // resources                          | user wins, but system resources show through
40      // -----------------------------------+-----------------------------------------------------------------
41      // component-manager-manager          | user wins, but system resources show through
42      // -----------------------------------+-----------------------------------------------------------------
43      // component-discoverer-manager       | user wins, but system resources show through
44      // -----------------------------------+-----------------------------------------------------------------
45      // component-factory-manager          | user wins, but system resources show through
46      // -----------------------------------+-----------------------------------------------------------------
47      // lifecycle-handler-manager          | user wins, but system lifecycles show through
48      // -----------------------------------+-----------------------------------------------------------------
49      // component-composer-manager         | user wins, but system lifecycles show through
50      // -----------------------------------+-----------------------------------------------------------------
51      // components                         | user
52      // -----------------------------------+-----------------------------------------------------------------
53  
54      public static PlexusConfiguration merge(PlexusConfiguration user, PlexusConfiguration system) {
55          PlexusConfiguration mergedConfiguration = new XmlPlexusConfiguration("plexus");
56  
57          // ----------------------------------------------------------------------
58          // Load on start
59          // ----------------------------------------------------------------------
60  
61          PlexusConfiguration loadOnStart = user.getChild("load-on-start");
62  
63          if (loadOnStart.getChildCount() != 0) {
64              mergedConfiguration.addChild(loadOnStart);
65          }
66  
67          // ----------------------------------------------------------------------
68          // System properties
69          // ----------------------------------------------------------------------
70  
71          PlexusConfiguration systemProperties = user.getChild("system-properties");
72  
73          if (systemProperties.getChildCount() != 0) {
74              mergedConfiguration.addChild(systemProperties);
75          }
76  
77          // ----------------------------------------------------------------------
78          // Configurations directory
79          // ----------------------------------------------------------------------
80  
81          PlexusConfiguration[] configurationsDirectories = user.getChildren("configurations-directory");
82  
83          if (configurationsDirectories.length != 0) {
84              for (PlexusConfiguration configurationsDirectory : configurationsDirectories) {
85                  mergedConfiguration.addChild(configurationsDirectory);
86              }
87          }
88  
89          // ----------------------------------------------------------------------
90          // Logging
91          // ----------------------------------------------------------------------
92  
93          PlexusConfiguration logging = user.getChild("logging");
94  
95          if (logging.getChildCount() != 0) {
96              mergedConfiguration.addChild(logging);
97          } else {
98              mergedConfiguration.addChild(system.getChild("logging"));
99          }
100 
101         // ----------------------------------------------------------------------
102         // Container initialization phases
103         // ----------------------------------------------------------------------
104 
105         mergedConfiguration.addChild(system.getChild("container-initialization"));
106 
107         mergedConfiguration.addChild(system.getChild("component-lookup-manager"));
108 
109         // ----------------------------------------------------------------------
110         // Component repository
111         // ----------------------------------------------------------------------
112 
113         PlexusConfiguration componentRepository = user.getChild("component-repository");
114 
115         if (componentRepository.getChildCount() != 0) {
116             mergedConfiguration.addChild(componentRepository);
117         } else {
118             mergedConfiguration.addChild(system.getChild("component-repository"));
119         }
120 
121         // ----------------------------------------------------------------------
122         // Resources
123         // ----------------------------------------------------------------------
124 
125         copyResources(system, mergedConfiguration);
126 
127         copyResources(user, mergedConfiguration);
128 
129         // ----------------------------------------------------------------------
130         // Component manager manager
131         // ----------------------------------------------------------------------
132 
133         PlexusConfiguration componentManagerManager = user.getChild("component-manager-manager");
134 
135         if (componentManagerManager.getChildCount() != 0) {
136             mergedConfiguration.addChild(componentManagerManager);
137 
138             copyComponentManagers(system.getChild("component-manager-manager"), componentManagerManager);
139         } else {
140             mergedConfiguration.addChild(system.getChild("component-manager-manager"));
141         }
142 
143         // ----------------------------------------------------------------------
144         // Component discoverer manager
145         // ----------------------------------------------------------------------
146 
147         PlexusConfiguration componentDiscovererManager = user.getChild("component-discoverer-manager");
148 
149         if (componentDiscovererManager.getChildCount() != 0) {
150             mergedConfiguration.addChild(componentDiscovererManager);
151 
152             copyComponentDiscoverers(system.getChild("component-discoverer-manager"), componentDiscovererManager);
153         } else {
154             mergedConfiguration.addChild(system.getChild("component-discoverer-manager"));
155         }
156 
157         // ----------------------------------------------------------------------
158         // Component factory manager
159         // ----------------------------------------------------------------------
160 
161         PlexusConfiguration componentFactoryManager = user.getChild("component-factory-manager");
162 
163         if (componentFactoryManager.getChildCount() != 0) {
164             mergedConfiguration.addChild(componentFactoryManager);
165 
166             copyComponentFactories(system.getChild("component-factory-manager"), componentFactoryManager);
167         } else {
168             mergedConfiguration.addChild(system.getChild("component-factory-manager"));
169         }
170 
171         // ----------------------------------------------------------------------
172         // Lifecycle handler managers
173         // ----------------------------------------------------------------------
174 
175         PlexusConfiguration lifecycleHandlerManager = user.getChild("lifecycle-handler-manager");
176 
177         if (lifecycleHandlerManager.getChildCount() != 0) {
178             mergedConfiguration.addChild(lifecycleHandlerManager);
179 
180             copyLifecycles(system.getChild("lifecycle-handler-manager"), lifecycleHandlerManager);
181         } else {
182             mergedConfiguration.addChild(system.getChild("lifecycle-handler-manager"));
183         }
184 
185         // ----------------------------------------------------------------------
186         // Component factory manager
187         // ----------------------------------------------------------------------
188 
189         PlexusConfiguration componentComposerManager = user.getChild("component-composer-manager");
190 
191         if (componentComposerManager.getChildCount() != 0) {
192             mergedConfiguration.addChild(componentComposerManager);
193 
194             copyComponentComposers(system.getChild("component-composer-manager"), componentComposerManager);
195         } else {
196             mergedConfiguration.addChild(system.getChild("component-composer-manager"));
197         }
198 
199         // ----------------------------------------------------------------------
200         // Components
201         // ----------------------------------------------------------------------
202         // We grab the system components first and then add the user defined
203         // components so that user defined components will win. When component
204         // descriptors are processed the last definition wins because the component
205         // descriptors are stored in a Map in the component repository.
206         // ----------------------------------------------------------------------
207 
208         PlexusConfiguration components = system.getChild("components");
209 
210         mergedConfiguration.addChild(components);
211 
212         copyComponents(user.getChild("components"), components);
213 
214         return mergedConfiguration;
215     }
216 
217     private static void copyResources(PlexusConfiguration source, PlexusConfiguration destination) {
218         PlexusConfiguration handlers[] = source.getChild("resources").getChildren();
219 
220         PlexusConfiguration dest = destination.getChild("resources");
221 
222         for (PlexusConfiguration handler : handlers) {
223             dest.addChild(handler);
224         }
225     }
226 
227     private static void copyComponentManagers(PlexusConfiguration source, PlexusConfiguration destination) {
228         try {
229             PlexusConfiguration id = destination.getChild("default-component-manager-id");
230 
231             String sid = source.getChild("default-component-manager-id").getValue();
232 
233             if (id.getValue() == null) {
234                 id.setValue(sid);
235             }
236         } catch (PlexusConfigurationException e) {
237             // do nothing
238         }
239 
240         PlexusConfiguration handlers[] = source.getChild("component-managers").getChildren("component-manager");
241 
242         PlexusConfiguration dest = destination.getChild("component-managers");
243 
244         for (PlexusConfiguration handler : handlers) {
245             dest.addChild(handler);
246         }
247     }
248 
249     private static void copyComponentDiscoverers(PlexusConfiguration source, PlexusConfiguration destination) {
250         PlexusConfiguration handlers[] =
251                 source.getChild("component-discoverers").getChildren("component-discoverer");
252 
253         PlexusConfiguration dest = destination.getChild("component-discoverers");
254 
255         for (PlexusConfiguration handler : handlers) {
256             dest.addChild(handler);
257         }
258     }
259 
260     private static void copyComponentFactories(PlexusConfiguration source, PlexusConfiguration destination) {
261         PlexusConfiguration handlers[] = source.getChild("component-factories").getChildren("component-factory");
262 
263         PlexusConfiguration dest = destination.getChild("component-factories");
264 
265         for (PlexusConfiguration handler : handlers) {
266             dest.addChild(handler);
267         }
268     }
269 
270     private static void copyComponentComposers(PlexusConfiguration source, PlexusConfiguration destination) {
271         try {
272             PlexusConfiguration id = destination.getChild("default-component-composer-id");
273 
274             String sid = source.getChild("default-component-composer-id").getValue();
275 
276             if (id.getValue() == null) {
277                 id.setValue(sid);
278             }
279         } catch (PlexusConfigurationException e) {
280             // do nothing
281         }
282 
283         PlexusConfiguration composers[] = source.getChild("component-composers").getChildren("component-composer");
284 
285         PlexusConfiguration dest = destination.getChild("component-composers");
286 
287         for (PlexusConfiguration composer : composers) {
288             dest.addChild(composer);
289         }
290     }
291 
292     private static void copyLifecycles(PlexusConfiguration source, PlexusConfiguration destination) {
293         PlexusConfiguration handlers[] = source.getChild("lifecycle-handlers").getChildren("lifecycle-handler");
294 
295         PlexusConfiguration dest = destination.getChild("lifecycle-handlers");
296 
297         for (PlexusConfiguration handler : handlers) {
298             dest.addChild(handler);
299         }
300     }
301 
302     private static void copyComponents(PlexusConfiguration source, PlexusConfiguration destination) {
303         PlexusConfiguration components[] = source.getChildren("component");
304 
305         for (PlexusConfiguration component : components) {
306             destination.addChild(component);
307         }
308     }
309 }