4 OverrideProcess class is used to override surface area information.
6 Copyright (c) 2006, Intel Corporation
7 All rights reserved. This program and the accompanying materials
8 are licensed and made available under the terms and conditions of the BSD License
9 which accompanies this distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 package org
.tianocore
.build
.global
;
18 import java
.util
.HashMap
;
21 import javax
.xml
.namespace
.QName
;
23 import org
.apache
.tools
.ant
.BuildException
;
24 import org
.apache
.xmlbeans
.XmlCursor
;
25 import org
.apache
.xmlbeans
.XmlObject
;
26 import org
.tianocore
.BootModesDocument
;
27 import org
.tianocore
.BuildOptionsDocument
;
28 import org
.tianocore
.DataHubsDocument
;
29 import org
.tianocore
.EventsDocument
;
30 import org
.tianocore
.ExternsDocument
;
31 import org
.tianocore
.FormsetsDocument
;
32 import org
.tianocore
.GuidsDocument
;
33 import org
.tianocore
.HobsDocument
;
34 import org
.tianocore
.IncludesDocument
;
35 import org
.tianocore
.LibrariesDocument
;
36 import org
.tianocore
.LibraryClassDefinitionsDocument
;
37 import org
.tianocore
.MsaHeaderDocument
;
38 import org
.tianocore
.MsaLibHeaderDocument
;
39 import org
.tianocore
.PCDsDocument
;
40 import org
.tianocore
.PPIsDocument
;
41 import org
.tianocore
.ProtocolsDocument
;
42 import org
.tianocore
.SourceFilesDocument
;
43 import org
.tianocore
.SystemTablesDocument
;
44 import org
.tianocore
.VariablesDocument
;
47 This class is used to override surface area information. For example, MBD can
48 overried MSA, Platform can override all information of the module.
50 <p>Override will take effect if two element satisfy one of following two condition: </p>
52 <li>Element name and its attribute OverrideID equal each other. </li>
53 <li>Element is defined as exclusive which mean such element can be
54 only appeared in the surface area. </li>
57 <p>For example, here OutputDirectory element is exclusive: </p>
60 Low priority Xml Document fragment:
62 <Arch ArchType="IA32">
63 <Library OverrideID="8888">EdkPeCoffLoaderLib</Library>
64 <Library OverrideID="8888">BasePeCoffLib</Library>
68 <OutputDirectory IntermediateDirectories="MODULE"/>
69 <Option>CC_FLAGS = "/NOLOGO", "/C"</Option>
72 High priority Xml Document fragment:
74 <Arch ArchType="IA32">
75 <Library OverrideID="8888">Nt32PeCoffLoaderLib</Library>
79 <OutputDirectory IntermediateDirectories="UNIFIED"/>
80 <Option>LIB_FLAGS = "/NOLOGO"</Option>
85 <Arch ArchType="IA32">
86 <Library OverrideID="8888">Nt32PeCoffLoaderLib</Library>
90 <OutputDirectory IntermediateDirectories="UNIFIED"/>
91 <Option>CC_FLAGS = "/NOLOGO", "/C"</Option>
92 <Option>LIB_FLAGS = "/NOLOGO"</Option>
97 <p>Note that using XmlBeans to walk through the whole XML document tree.</p>
100 @see org.apache.xmlbeans.XmlBeans
102 public class OverrideProcess
{
105 /// URI, the namespace of current XML schema
107 public static String prefix
= "http://www.TianoCore.org/2006/Edk2.0";
110 /// list of top elements of surface area
112 public static String
[] topElements
= { "LibraryClassDefinitions",
113 "SourceFiles", "Includes", "Libraries", "Protocols",
114 "Events", "Hobs", "PPIs", "Variables", "BootModes",
115 "SystemTables", "DataHubs", "Formsets", "Guids", "Externs",
116 "PCDs", "BuildOptions" };
119 /// list of exclusive elements
121 public static String
[] exclusiveElements
= {"OutputDirectory"};
124 Recursively find out all elements specified with OverrideId attribute
125 and exclusive elements in current XML object.
127 @param o curent parsing XML object
128 @param map Map to list elements specified OverrideID attribute
129 @param execlusiveMap Map to list exclusive elements appeared in current XMl object
130 @param level the depth in XML document tree
132 private void listOverrideID(XmlObject o
, Map
<String
,Object
> map
, Map
<String
,Object
> execlusiveMap
, int level
) {
133 XmlCursor cursor
= o
.newCursor();
134 String name
= cursor
.getName().getLocalPart();
135 for (int i
= 0 ; i
< exclusiveElements
.length
; i
++){
136 if (name
.equalsIgnoreCase(exclusiveElements
[i
])){
137 execlusiveMap
.put(exclusiveElements
[i
], cursor
.getObject());
140 String overrideID
= cursor
.getAttributeText(new QName("OverrideID"));
141 if (overrideID
!= null) {
142 map
.put(name
+ ":" + overrideID
, cursor
.getObject());
144 if (cursor
.toFirstChild()) {
146 listOverrideID(cursor
.getObject(), map
, execlusiveMap
, level
+ 1);
147 } while (cursor
.toNextSibling());
152 This function is used to prepare for overriding with changing data.
154 @param map original surface area information
155 @return after normalize surface area information
157 public synchronized static Map
<String
, XmlObject
> deal(Map
<String
, XmlObject
> map
) {
158 Map
<String
, XmlObject
> newMap
= new HashMap
<String
, XmlObject
>();
159 if (map
.get("MsaHeader") != null) {
160 newMap
.put("MsaHeader", ((MsaHeaderDocument
) map
.get("MsaHeader"))
163 if (map
.get("MsaLibHeader") != null) {
164 newMap
.put("MsaLibHeader", ((MsaLibHeaderDocument
) map
165 .get("MsaLibHeader")).getMsaLibHeader());
167 if (map
.get("LibraryClassDefinitions") != null) {
168 newMap
.put("LibraryClassDefinitions",
169 ((LibraryClassDefinitionsDocument
) map
170 .get("LibraryClassDefinitions"))
171 .getLibraryClassDefinitions());
173 if (map
.get("SourceFiles") != null) {
174 newMap
.put("SourceFiles", ((SourceFilesDocument
) map
175 .get("SourceFiles")).getSourceFiles());
177 if (map
.get("Includes") != null) {
178 newMap
.put("Includes", ((IncludesDocument
) map
.get("Includes"))
181 if (map
.get("Libraries") != null) {
182 newMap
.put("Libraries", ((LibrariesDocument
) map
.get("Libraries"))
185 if (map
.get("Protocols") != null) {
186 newMap
.put("Protocols", ((ProtocolsDocument
) map
.get("Protocols"))
189 if (map
.get("Events") != null) {
190 newMap
.put("Events", ((EventsDocument
) map
.get("Events"))
193 if (map
.get("Hobs") != null) {
194 newMap
.put("Hobs", ((HobsDocument
) map
.get("Hobs")).getHobs());
196 if (map
.get("PPIs") != null) {
197 newMap
.put("PPIs", ((PPIsDocument
) map
.get("PPIs")).getPPIs());
199 if (map
.get("Variables") != null) {
200 newMap
.put("Variables", ((VariablesDocument
) map
.get("Variables"))
203 if (map
.get("BootModes") != null) {
204 newMap
.put("BootModes", ((BootModesDocument
) map
.get("BootModes"))
207 if (map
.get("SystemTables") != null) {
208 newMap
.put("SystemTables", ((SystemTablesDocument
) map
209 .get("SystemTables")).getSystemTables());
211 if (map
.get("DataHubs") != null) {
212 newMap
.put("DataHubs", ((DataHubsDocument
) map
.get("DataHubs"))
215 if (map
.get("Formsets") != null) {
216 newMap
.put("Formsets", ((FormsetsDocument
) map
.get("Formsets"))
219 if (map
.get("Guids") != null) {
220 newMap
.put("Guids", ((GuidsDocument
) map
.get("Guids")).getGuids());
222 if (map
.get("Externs") != null) {
223 newMap
.put("Externs", ((ExternsDocument
) map
.get("Externs"))
226 if (map
.get("PCDs") != null) {
227 newMap
.put("PCDs", ((PCDsDocument
) map
.get("PCDs")).getPCDs());
229 if (map
.get("BuildOptions") != null) {
230 newMap
.put("BuildOptions", ((BuildOptionsDocument
) map
231 .get("BuildOptions")).getBuildOptions());
237 Recursively remove all subelement in Xml Object l (with low priority)
238 based on OverrideID or exclusive elements.
240 @param l the XML object to process
241 @param map list of elements with OverrideID in high priority XML object
242 @param execusiveMap list of exclusive elements in high priority XML object
244 private void cut(XmlCursor l
, Map map
, Map execusiveMap
) {
245 String name
= l
.getName().getLocalPart();
246 if (execusiveMap
.containsKey(name
)){
250 String overrideID
= l
.getAttributeText(new QName("OverrideID"));
251 if (overrideID
!= null) {
252 if (map
.containsKey(name
+ ":" + overrideID
)) {
257 if (l
.toFirstChild()) {
259 cut(l
, map
, execusiveMap
);
260 } while (l
.toNextSibling());
264 private XmlObject
cloneXmlObject(XmlObject object
, boolean deep
) throws BuildException
{
265 XmlObject result
= null;
267 result
= XmlObject
.Factory
.parse(object
.getDomNode()
269 } catch (Exception ex
) {
270 throw new BuildException(ex
.getMessage());
276 Process every item list in h and l.
278 @param h surface area info with high priority
279 @param l surface area info with low priority
280 @return surface area after override
282 public Map
<String
, XmlObject
> override(Map
<String
, XmlObject
> h
,
283 Map
<String
, XmlObject
> l
) {
284 Map
<String
, XmlObject
> result
= new HashMap
<String
, XmlObject
>();
285 result
.put("MsaHeader", override(l
.get("MsaHeader"), null));
286 result
.put("MsaLibHeader", override(l
.get("MsaLibHeader"), null));
287 for (int i
= 0; i
< topElements
.length
; i
++) {
288 result
.put(topElements
[i
], override(h
.get(topElements
[i
]), l
289 .get(topElements
[i
])));
295 Recursively override two Xml Objects.
297 @param h Xml Object info with high priority
298 @param l Xml Object info with low priority
299 @return Xml Object after area
301 public XmlObject
override(XmlObject h
, XmlObject l
) {
302 if (l
== null && h
== null) {
306 return cloneXmlObject(l
, true);
309 return cloneXmlObject(h
, true);
311 XmlCursor hc
= h
.newCursor();
312 if (h
.getClass() != l
.getClass()) {
314 .println("Error: Two XmlObject does not with compliant format.");
317 if (!hc
.toFirstChild()) {
318 return cloneXmlObject(l
, true);
321 XmlCursor result
= cloneXmlObject(h
, true).newCursor();
322 XmlCursor lcursor
= cloneXmlObject(l
, true).newCursor();
324 result
.toNextToken();
325 result
.insertNamespace("", prefix
);
326 result
.toFirstChild();
328 // found out all element specified a OverrideID
330 Map
<String
,Object
> hmap
= new HashMap
<String
,Object
>();
331 Map
<String
,Object
> execlusiveMap
= new HashMap
<String
,Object
>();
332 listOverrideID(h
, hmap
, execlusiveMap
, 0);
333 lcursor
.toNextToken();
336 // for every direct subelement of l, cut all element satisfied with
339 if (lcursor
.toFirstChild()) {
341 cut(lcursor
, hmap
, execlusiveMap
);
342 } while (lcursor
.toNextSibling());
345 if (lcursor
.toFirstChild()) {
347 lcursor
.copyXml(result
);
348 result
.insertChars("\n");
349 } while (lcursor
.toNextSibling());
352 return result
.getObject();