]> git.proxmox.com Git - mirror_edk2.git/blame - Tools/Source/GenBuild/org/tianocore/build/global/OverrideProcess.java
added the support for new schema and old schema at the same time
[mirror_edk2.git] / Tools / Source / GenBuild / org / tianocore / build / global / OverrideProcess.java
CommitLineData
878ddf1f 1/** @file\r
2 OverrideProcess class.\r
3 \r
4 OverrideProcess class is used to override surface area information. \r
5\r
6Copyright (c) 2006, Intel Corporation\r
7All rights reserved. This program and the accompanying materials\r
8are licensed and made available under the terms and conditions of the BSD License\r
9which accompanies this distribution. The full text of the license may be found at\r
10http://opensource.org/licenses/bsd-license.php\r
11\r
12THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
13WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
14\r
15**/\r
16package org.tianocore.build.global;\r
17\r
18import java.util.HashMap;\r
19import java.util.Map;\r
20\r
21import javax.xml.namespace.QName;\r
22\r
23import org.apache.tools.ant.BuildException;\r
24import org.apache.xmlbeans.XmlCursor;\r
25import org.apache.xmlbeans.XmlObject;\r
26import org.tianocore.BootModesDocument;\r
27import org.tianocore.BuildOptionsDocument;\r
28import org.tianocore.DataHubsDocument;\r
29import org.tianocore.EventsDocument;\r
30import org.tianocore.ExternsDocument;\r
31import org.tianocore.FormsetsDocument;\r
32import org.tianocore.GuidsDocument;\r
33import org.tianocore.HobsDocument;\r
34import org.tianocore.IncludesDocument;\r
35import org.tianocore.LibrariesDocument;\r
36import org.tianocore.LibraryClassDefinitionsDocument;\r
37import org.tianocore.MsaHeaderDocument;\r
38import org.tianocore.MsaLibHeaderDocument;\r
ad82307c 39import org.tianocore.PcdCodedDocument;\r
878ddf1f 40import org.tianocore.PPIsDocument;\r
41import org.tianocore.ProtocolsDocument;\r
42import org.tianocore.SourceFilesDocument;\r
43import org.tianocore.SystemTablesDocument;\r
44import org.tianocore.VariablesDocument;\r
250258de 45import org.tianocore.PackageDependenciesDocument;\r
878ddf1f 46\r
47/**\r
48 This class is used to override surface area information. For example, MBD can\r
49 overried MSA, Platform can override all information of the module. \r
50 \r
51 <p>Override will take effect if two element satisfy one of following two condition: </p>\r
52 <ul>\r
53 <li>Element name and its attribute OverrideID equal each other. </li>\r
54 <li>Element is defined as exclusive which mean such element can be\r
55 only appeared in the surface area. </li>\r
56 </ul>\r
57 \r
58 <p>For example, here OutputDirectory element is exclusive: </p>\r
59 \r
60 <pre>\r
61 Low priority Xml Document fragment:\r
62 &lt;Libraries&gt;\r
63 &lt;Arch ArchType="IA32"&gt;\r
64 &lt;Library OverrideID="8888"&gt;EdkPeCoffLoaderLib&lt;/Library&gt;\r
65 &lt;Library OverrideID="8888"&gt;BasePeCoffLib&lt;/Library&gt;\r
66 &lt;/Arch&gt;\r
67 &lt;/Libraries&gt; \r
68 &lt;BuildOptions&gt;\r
69 &lt;OutputDirectory IntermediateDirectories="MODULE"/&gt;\r
70 &lt;Option&gt;CC_FLAGS = "/NOLOGO", "/C"&lt;/Option&gt;\r
71 &lt;BuildOptions&gt;\r
72 \r
73 High priority Xml Document fragment:\r
74 &lt;Libraries&gt;\r
75 &lt;Arch ArchType="IA32"&gt;\r
76 &lt;Library OverrideID="8888">Nt32PeCoffLoaderLib&lt;/Library&gt;\r
77 &lt;/Arch&gt;\r
78 &lt;/Libraries&gt;\r
79 &lt;BuildOptions&gt;\r
80 &lt;OutputDirectory IntermediateDirectories="UNIFIED"/&gt;\r
81 &lt;Option&gt;LIB_FLAGS = "/NOLOGO"&lt;/Option&gt;\r
82 &lt;BuildOptions&gt;\r
83 \r
84 The result is: \r
85 &lt;Libraries&gt;\r
86 &lt;Arch ArchType="IA32"&gt;\r
87 &lt;Library OverrideID="8888"&gt;Nt32PeCoffLoaderLib&lt;/Library&gt;\r
88 &lt;/Arch&gt;\r
89 &lt;/Libraries&gt;\r
90 &lt;BuildOptions&gt;\r
91 &lt;OutputDirectory IntermediateDirectories="UNIFIED"/&gt;\r
92 &lt;Option&gt;CC_FLAGS = "/NOLOGO", "/C"&lt;/Option&gt;\r
93 &lt;Option&gt;LIB_FLAGS = "/NOLOGO"&lt;/Option&gt;\r
94 &lt;BuildOptions&gt;\r
95 \r
96 </pre>\r
97 \r
98 <p>Note that using XmlBeans to walk through the whole XML document tree.</p> \r
99 \r
100 @since GenBuild 1.0\r
101 @see org.apache.xmlbeans.XmlBeans\r
102**/\r
103public class OverrideProcess {\r
104\r
105 ///\r
106 /// URI, the namespace of current XML schema\r
107 ///\r
108 public static String prefix = "http://www.TianoCore.org/2006/Edk2.0";\r
109\r
110 ///\r
111 /// list of top elements of surface area\r
112 ///\r
113 public static String[] topElements = { "LibraryClassDefinitions",\r
250258de 114 "SourceFiles", "Includes", "PackageDependencies", "Libraries", "Protocols",\r
878ddf1f 115 "Events", "Hobs", "PPIs", "Variables", "BootModes",\r
116 "SystemTables", "DataHubs", "Formsets", "Guids", "Externs",\r
ad82307c 117 "PcdCoded", "BuildOptions" };\r
878ddf1f 118\r
119 ///\r
120 /// list of exclusive elements\r
121 ///\r
122 public static String[] exclusiveElements = {"OutputDirectory"};\r
123 \r
124 /**\r
125 Recursively find out all elements specified with OverrideId attribute\r
126 and exclusive elements in current XML object. \r
127 \r
128 @param o curent parsing XML object\r
129 @param map Map to list elements specified OverrideID attribute\r
130 @param execlusiveMap Map to list exclusive elements appeared in current XMl object\r
131 @param level the depth in XML document tree\r
132 **/\r
133 private void listOverrideID(XmlObject o, Map<String,Object> map, Map<String,Object> execlusiveMap, int level) {\r
134 XmlCursor cursor = o.newCursor();\r
135 String name = cursor.getName().getLocalPart();\r
136 for (int i = 0 ; i < exclusiveElements.length; i++){\r
137 if (name.equalsIgnoreCase(exclusiveElements[i])){\r
138 execlusiveMap.put(exclusiveElements[i], cursor.getObject());\r
139 }\r
140 }\r
141 String overrideID = cursor.getAttributeText(new QName("OverrideID"));\r
142 if (overrideID != null) {\r
143 map.put(name + ":" + overrideID, cursor.getObject());\r
144 }\r
145 if (cursor.toFirstChild()) {\r
146 do {\r
147 listOverrideID(cursor.getObject(), map, execlusiveMap, level + 1);\r
148 } while (cursor.toNextSibling());\r
149 }\r
150 }\r
151\r
152 /**\r
153 This function is used to prepare for overriding with changing data. \r
154 \r
155 @param map original surface area information \r
156 @return after normalize surface area information\r
157 **/\r
158 public synchronized static Map<String, XmlObject> deal(Map<String, XmlObject> map) {\r
159 Map<String, XmlObject> newMap = new HashMap<String, XmlObject>();\r
160 if (map.get("MsaHeader") != null) {\r
161 newMap.put("MsaHeader", ((MsaHeaderDocument) map.get("MsaHeader"))\r
162 .getMsaHeader());\r
163 }\r
164 if (map.get("MsaLibHeader") != null) {\r
165 newMap.put("MsaLibHeader", ((MsaLibHeaderDocument) map\r
166 .get("MsaLibHeader")).getMsaLibHeader());\r
167 }\r
168 if (map.get("LibraryClassDefinitions") != null) {\r
169 newMap.put("LibraryClassDefinitions",\r
170 ((LibraryClassDefinitionsDocument) map\r
171 .get("LibraryClassDefinitions"))\r
172 .getLibraryClassDefinitions());\r
173 }\r
174 if (map.get("SourceFiles") != null) {\r
175 newMap.put("SourceFiles", ((SourceFilesDocument) map\r
176 .get("SourceFiles")).getSourceFiles());\r
177 }\r
178 if (map.get("Includes") != null) {\r
179 newMap.put("Includes", ((IncludesDocument) map.get("Includes"))\r
180 .getIncludes());\r
181 }\r
250258de 182 if (map.get("PackageDependencies") != null) {\r
183 newMap.put("PackageDependencies", ((PackageDependenciesDocument) map.get("PackageDependencies"))\r
184 .getPackageDependencies());\r
185 }\r
878ddf1f 186 if (map.get("Libraries") != null) {\r
187 newMap.put("Libraries", ((LibrariesDocument) map.get("Libraries"))\r
188 .getLibraries());\r
189 }\r
190 if (map.get("Protocols") != null) {\r
191 newMap.put("Protocols", ((ProtocolsDocument) map.get("Protocols"))\r
192 .getProtocols());\r
193 }\r
194 if (map.get("Events") != null) {\r
195 newMap.put("Events", ((EventsDocument) map.get("Events"))\r
196 .getEvents());\r
197 }\r
198 if (map.get("Hobs") != null) {\r
199 newMap.put("Hobs", ((HobsDocument) map.get("Hobs")).getHobs());\r
200 }\r
201 if (map.get("PPIs") != null) {\r
202 newMap.put("PPIs", ((PPIsDocument) map.get("PPIs")).getPPIs());\r
203 }\r
204 if (map.get("Variables") != null) {\r
205 newMap.put("Variables", ((VariablesDocument) map.get("Variables"))\r
206 .getVariables());\r
207 }\r
208 if (map.get("BootModes") != null) {\r
209 newMap.put("BootModes", ((BootModesDocument) map.get("BootModes"))\r
210 .getBootModes());\r
211 }\r
212 if (map.get("SystemTables") != null) {\r
213 newMap.put("SystemTables", ((SystemTablesDocument) map\r
214 .get("SystemTables")).getSystemTables());\r
215 }\r
216 if (map.get("DataHubs") != null) {\r
217 newMap.put("DataHubs", ((DataHubsDocument) map.get("DataHubs"))\r
218 .getDataHubs());\r
219 }\r
220 if (map.get("Formsets") != null) {\r
221 newMap.put("Formsets", ((FormsetsDocument) map.get("Formsets"))\r
222 .getFormsets());\r
223 }\r
224 if (map.get("Guids") != null) {\r
225 newMap.put("Guids", ((GuidsDocument) map.get("Guids")).getGuids());\r
226 }\r
227 if (map.get("Externs") != null) {\r
228 newMap.put("Externs", ((ExternsDocument) map.get("Externs"))\r
229 .getExterns());\r
230 }\r
ad82307c 231 if (map.get("PcdCoded") != null) {\r
232 newMap.put("PcdCoded", ((PcdCodedDocument) map.get("PcdCoded")).getPcdCoded());\r
878ddf1f 233 }\r
234 if (map.get("BuildOptions") != null) {\r
235 newMap.put("BuildOptions", ((BuildOptionsDocument) map\r
236 .get("BuildOptions")).getBuildOptions());\r
237 }\r
238 return newMap;\r
239 }\r
240\r
241 /**\r
242 Recursively remove all subelement in Xml Object l (with low priority) \r
243 based on OverrideID or exclusive elements. \r
244 \r
245 @param l the XML object to process\r
246 @param map list of elements with OverrideID in high priority XML object\r
247 @param execusiveMap list of exclusive elements in high priority XML object\r
248 **/\r
249 private void cut(XmlCursor l, Map map, Map execusiveMap) {\r
250 String name = l.getName().getLocalPart();\r
251 if (execusiveMap.containsKey(name)){\r
252 l.removeXml();\r
253 return;\r
254 }\r
255 String overrideID = l.getAttributeText(new QName("OverrideID"));\r
256 if (overrideID != null) {\r
257 if (map.containsKey(name + ":" + overrideID)) {\r
258 l.removeXml();\r
259 return;\r
260 }\r
261 }\r
262 if (l.toFirstChild()) {\r
263 do {\r
264 cut(l, map, execusiveMap);\r
265 } while (l.toNextSibling());\r
266 }\r
267 }\r
268\r
269 private XmlObject cloneXmlObject(XmlObject object, boolean deep) throws BuildException {\r
270 XmlObject result = null;\r
271 try {\r
272 result = XmlObject.Factory.parse(object.getDomNode()\r
273 .cloneNode(deep));\r
274 } catch (Exception ex) {\r
275 throw new BuildException(ex.getMessage());\r
276 }\r
277 return result;\r
278 }\r
279\r
280 /**\r
281 Process every item list in h and l.\r
282 \r
283 @param h surface area info with high priority\r
284 @param l surface area info with low priority\r
285 @return surface area after override\r
286 **/\r
287 public Map<String, XmlObject> override(Map<String, XmlObject> h,\r
288 Map<String, XmlObject> l) {\r
289 Map<String, XmlObject> result = new HashMap<String, XmlObject>();\r
290 result.put("MsaHeader", override(l.get("MsaHeader"), null));\r
291 result.put("MsaLibHeader", override(l.get("MsaLibHeader"), null));\r
292 for (int i = 0; i < topElements.length; i++) {\r
250258de 293 if (h != null) {\r
294 result.put(topElements[i], override(h.get(topElements[i]), l.get(topElements[i])));\r
295 } else {\r
296 result.put(topElements[i], override(l.get(topElements[i]), null));\r
297 }\r
878ddf1f 298 }\r
299 return result;\r
300 }\r
301\r
302 /**\r
303 Recursively override two Xml Objects.\r
304 \r
305 @param h Xml Object info with high priority\r
306 @param l Xml Object info with low priority\r
307 @return Xml Object after area\r
308 **/\r
309 public XmlObject override(XmlObject h, XmlObject l) {\r
310 if (l == null && h == null) {\r
311 return null;\r
312 }\r
313 if (h == null) {\r
314 return cloneXmlObject(l, true);\r
315 }\r
316 if (l == null) {\r
317 return cloneXmlObject(h, true);\r
318 }\r
319 XmlCursor hc = h.newCursor();\r
320 if (h.getClass() != l.getClass()) {\r
250258de 321 System.out.println("Error: Two XmlObject does not with compliant format.");\r
878ddf1f 322 return null;\r
323 }\r
324 if (!hc.toFirstChild()) {\r
325 return cloneXmlObject(l, true);\r
326 }\r
327\r
328 XmlCursor result = cloneXmlObject(h, true).newCursor();\r
329 XmlCursor lcursor = cloneXmlObject(l, true).newCursor();\r
330 result.push();\r
331 result.toNextToken();\r
332 result.insertNamespace("", prefix);\r
333 result.toFirstChild();\r
334 //\r
335 // found out all element specified a OverrideID\r
336 //\r
337 Map<String,Object> hmap = new HashMap<String,Object>();\r
338 Map<String,Object> execlusiveMap = new HashMap<String,Object>();\r
339 listOverrideID(h, hmap, execlusiveMap, 0);\r
340 lcursor.toNextToken();\r
341 lcursor.push();\r
342 //\r
343 // for every direct subelement of l, cut all element satisfied with\r
344 // override rule\r
345 //\r
346 if (lcursor.toFirstChild()) {\r
347 do {\r
348 cut(lcursor, hmap, execlusiveMap);\r
349 } while (lcursor.toNextSibling());\r
350 }\r
351 lcursor.pop();\r
352 if (lcursor.toFirstChild()) {\r
353 do {\r
354 lcursor.copyXml(result);\r
355 result.insertChars("\n");\r
356 } while (lcursor.toNextSibling());\r
357 }\r
358 result.pop();\r
359 return result.getObject();\r
360 }\r
361}