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
.PcdCodedDocument
;
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
;
45 import org
.tianocore
.PackageDependenciesDocument
;
48 This class is used to override surface area information. For example, MBD can
49 overried MSA, Platform can override all information of the module.
51 <p>Override will take effect if two element satisfy one of following two condition: </p>
53 <li>Element name and its attribute OverrideID equal each other. </li>
54 <li>Element is defined as exclusive which mean such element can be
55 only appeared in the surface area. </li>
58 <p>For example, here OutputDirectory element is exclusive: </p>
61 Low priority Xml Document fragment:
63 <Arch ArchType="IA32">
64 <Library OverrideID="8888">EdkPeCoffLoaderLib</Library>
65 <Library OverrideID="8888">BasePeCoffLib</Library>
69 <OutputDirectory IntermediateDirectories="MODULE"/>
70 <Option>CC_FLAGS = "/NOLOGO", "/C"</Option>
73 High priority Xml Document fragment:
75 <Arch ArchType="IA32">
76 <Library OverrideID="8888">Nt32PeCoffLoaderLib</Library>
80 <OutputDirectory IntermediateDirectories="UNIFIED"/>
81 <Option>LIB_FLAGS = "/NOLOGO"</Option>
86 <Arch ArchType="IA32">
87 <Library OverrideID="8888">Nt32PeCoffLoaderLib</Library>
91 <OutputDirectory IntermediateDirectories="UNIFIED"/>
92 <Option>CC_FLAGS = "/NOLOGO", "/C"</Option>
93 <Option>LIB_FLAGS = "/NOLOGO"</Option>
98 <p>Note that using XmlBeans to walk through the whole XML document tree.</p>
101 @see org.apache.xmlbeans.XmlBeans
103 public class OverrideProcess
{
106 /// URI, the namespace of current XML schema
108 public static String prefix
= "http://www.TianoCore.org/2006/Edk2.0";
111 /// list of top elements of surface area
113 public static String
[] topElements
= { "LibraryClassDefinitions",
114 "SourceFiles", "Includes", "PackageDependencies", "Libraries", "Protocols",
115 "Events", "Hobs", "PPIs", "Variables", "BootModes",
116 "SystemTables", "DataHubs", "Formsets", "Guids", "Externs",
117 "PcdCoded", "BuildOptions" };
120 /// list of exclusive elements
122 public static String
[] exclusiveElements
= {"OutputDirectory"};
125 Recursively find out all elements specified with OverrideId attribute
126 and exclusive elements in current XML object.
128 @param o curent parsing XML object
129 @param map Map to list elements specified OverrideID attribute
130 @param execlusiveMap Map to list exclusive elements appeared in current XMl object
131 @param level the depth in XML document tree
133 private void listOverrideID(XmlObject o
, Map
<String
,Object
> map
, Map
<String
,Object
> execlusiveMap
, int level
) {
134 XmlCursor cursor
= o
.newCursor();
135 String name
= cursor
.getName().getLocalPart();
136 for (int i
= 0 ; i
< exclusiveElements
.length
; i
++){
137 if (name
.equalsIgnoreCase(exclusiveElements
[i
])){
138 execlusiveMap
.put(exclusiveElements
[i
], cursor
.getObject());
141 String overrideID
= cursor
.getAttributeText(new QName("OverrideID"));
142 if (overrideID
!= null) {
143 map
.put(name
+ ":" + overrideID
, cursor
.getObject());
145 if (cursor
.toFirstChild()) {
147 listOverrideID(cursor
.getObject(), map
, execlusiveMap
, level
+ 1);
148 } while (cursor
.toNextSibling());
153 This function is used to prepare for overriding with changing data.
155 @param map original surface area information
156 @return after normalize surface area information
158 public synchronized static Map
<String
, XmlObject
> deal(Map
<String
, XmlObject
> map
) {
159 Map
<String
, XmlObject
> newMap
= new HashMap
<String
, XmlObject
>();
160 if (map
.get("MsaHeader") != null) {
161 newMap
.put("MsaHeader", ((MsaHeaderDocument
) map
.get("MsaHeader"))
164 if (map
.get("MsaLibHeader") != null) {
165 newMap
.put("MsaLibHeader", ((MsaLibHeaderDocument
) map
166 .get("MsaLibHeader")).getMsaLibHeader());
168 if (map
.get("LibraryClassDefinitions") != null) {
169 newMap
.put("LibraryClassDefinitions",
170 ((LibraryClassDefinitionsDocument
) map
171 .get("LibraryClassDefinitions"))
172 .getLibraryClassDefinitions());
174 if (map
.get("SourceFiles") != null) {
175 newMap
.put("SourceFiles", ((SourceFilesDocument
) map
176 .get("SourceFiles")).getSourceFiles());
178 if (map
.get("Includes") != null) {
179 newMap
.put("Includes", ((IncludesDocument
) map
.get("Includes"))
182 if (map
.get("PackageDependencies") != null) {
183 newMap
.put("PackageDependencies", ((PackageDependenciesDocument
) map
.get("PackageDependencies"))
184 .getPackageDependencies());
186 if (map
.get("Libraries") != null) {
187 newMap
.put("Libraries", ((LibrariesDocument
) map
.get("Libraries"))
190 if (map
.get("Protocols") != null) {
191 newMap
.put("Protocols", ((ProtocolsDocument
) map
.get("Protocols"))
194 if (map
.get("Events") != null) {
195 newMap
.put("Events", ((EventsDocument
) map
.get("Events"))
198 if (map
.get("Hobs") != null) {
199 newMap
.put("Hobs", ((HobsDocument
) map
.get("Hobs")).getHobs());
201 if (map
.get("PPIs") != null) {
202 newMap
.put("PPIs", ((PPIsDocument
) map
.get("PPIs")).getPPIs());
204 if (map
.get("Variables") != null) {
205 newMap
.put("Variables", ((VariablesDocument
) map
.get("Variables"))
208 if (map
.get("BootModes") != null) {
209 newMap
.put("BootModes", ((BootModesDocument
) map
.get("BootModes"))
212 if (map
.get("SystemTables") != null) {
213 newMap
.put("SystemTables", ((SystemTablesDocument
) map
214 .get("SystemTables")).getSystemTables());
216 if (map
.get("DataHubs") != null) {
217 newMap
.put("DataHubs", ((DataHubsDocument
) map
.get("DataHubs"))
220 if (map
.get("Formsets") != null) {
221 newMap
.put("Formsets", ((FormsetsDocument
) map
.get("Formsets"))
224 if (map
.get("Guids") != null) {
225 newMap
.put("Guids", ((GuidsDocument
) map
.get("Guids")).getGuids());
227 if (map
.get("Externs") != null) {
228 newMap
.put("Externs", ((ExternsDocument
) map
.get("Externs"))
231 if (map
.get("PcdCoded") != null) {
232 newMap
.put("PcdCoded", ((PcdCodedDocument
) map
.get("PcdCoded")).getPcdCoded());
234 if (map
.get("BuildOptions") != null) {
235 newMap
.put("BuildOptions", ((BuildOptionsDocument
) map
236 .get("BuildOptions")).getBuildOptions());
242 Recursively remove all subelement in Xml Object l (with low priority)
243 based on OverrideID or exclusive elements.
245 @param l the XML object to process
246 @param map list of elements with OverrideID in high priority XML object
247 @param execusiveMap list of exclusive elements in high priority XML object
249 private void cut(XmlCursor l
, Map map
, Map execusiveMap
) {
250 String name
= l
.getName().getLocalPart();
251 if (execusiveMap
.containsKey(name
)){
255 String overrideID
= l
.getAttributeText(new QName("OverrideID"));
256 if (overrideID
!= null) {
257 if (map
.containsKey(name
+ ":" + overrideID
)) {
262 if (l
.toFirstChild()) {
264 cut(l
, map
, execusiveMap
);
265 } while (l
.toNextSibling());
269 private XmlObject
cloneXmlObject(XmlObject object
, boolean deep
) throws BuildException
{
270 XmlObject result
= null;
272 result
= XmlObject
.Factory
.parse(object
.getDomNode()
274 } catch (Exception ex
) {
275 throw new BuildException(ex
.getMessage());
281 Process every item list in h and l.
283 @param h surface area info with high priority
284 @param l surface area info with low priority
285 @return surface area after override
287 public Map
<String
, XmlObject
> override(Map
<String
, XmlObject
> h
,
288 Map
<String
, XmlObject
> l
) {
289 Map
<String
, XmlObject
> result
= new HashMap
<String
, XmlObject
>();
290 result
.put("MsaHeader", override(l
.get("MsaHeader"), null));
291 result
.put("MsaLibHeader", override(l
.get("MsaLibHeader"), null));
292 for (int i
= 0; i
< topElements
.length
; i
++) {
294 result
.put(topElements
[i
], override(h
.get(topElements
[i
]), l
.get(topElements
[i
])));
296 result
.put(topElements
[i
], override(l
.get(topElements
[i
]), null));
303 Recursively override two Xml Objects.
305 @param h Xml Object info with high priority
306 @param l Xml Object info with low priority
307 @return Xml Object after area
309 public XmlObject
override(XmlObject h
, XmlObject l
) {
310 if (l
== null && h
== null) {
314 return cloneXmlObject(l
, true);
317 return cloneXmlObject(h
, true);
319 XmlCursor hc
= h
.newCursor();
320 if (h
.getClass() != l
.getClass()) {
321 System
.out
.println("Error: Two XmlObject does not with compliant format.");
324 if (!hc
.toFirstChild()) {
325 return cloneXmlObject(l
, true);
328 XmlCursor result
= cloneXmlObject(h
, true).newCursor();
329 XmlCursor lcursor
= cloneXmlObject(l
, true).newCursor();
331 result
.toNextToken();
332 result
.insertNamespace("", prefix
);
333 result
.toFirstChild();
335 // found out all element specified a OverrideID
337 Map
<String
,Object
> hmap
= new HashMap
<String
,Object
>();
338 Map
<String
,Object
> execlusiveMap
= new HashMap
<String
,Object
>();
339 listOverrideID(h
, hmap
, execlusiveMap
, 0);
340 lcursor
.toNextToken();
343 // for every direct subelement of l, cut all element satisfied with
346 if (lcursor
.toFirstChild()) {
348 cut(lcursor
, hmap
, execlusiveMap
);
349 } while (lcursor
.toNextSibling());
352 if (lcursor
.toFirstChild()) {
354 lcursor
.copyXml(result
);
355 result
.insertChars("\n");
356 } while (lcursor
.toNextSibling());
359 return result
.getObject();