+++ /dev/null
-/** @file\r
- OverrideProcess class.\r
- \r
- OverrideProcess class is used to override surface area information. \r
-\r
-Copyright (c) 2006, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-package org.tianocore.build.global;\r
-\r
-import java.util.HashMap;\r
-import java.util.Map;\r
-\r
-import javax.xml.namespace.QName;\r
-\r
-import org.apache.tools.ant.BuildException;\r
-import org.apache.xmlbeans.XmlCursor;\r
-import org.apache.xmlbeans.XmlObject;\r
-import org.tianocore.BootModesDocument;\r
-import org.tianocore.BuildOptionsDocument;\r
-import org.tianocore.DataHubsDocument;\r
-import org.tianocore.EventsDocument;\r
-import org.tianocore.ExternsDocument;\r
-import org.tianocore.FormsetsDocument;\r
-import org.tianocore.GuidsDocument;\r
-import org.tianocore.HobsDocument;\r
-import org.tianocore.IncludesDocument;\r
-import org.tianocore.LibrariesDocument;\r
-import org.tianocore.LibraryClassDefinitionsDocument;\r
-import org.tianocore.MsaHeaderDocument;\r
-import org.tianocore.MsaLibHeaderDocument;\r
-import org.tianocore.PcdCodedDocument;\r
-import org.tianocore.PPIsDocument;\r
-import org.tianocore.ProtocolsDocument;\r
-import org.tianocore.SourceFilesDocument;\r
-import org.tianocore.SystemTablesDocument;\r
-import org.tianocore.VariablesDocument;\r
-import org.tianocore.PackageDependenciesDocument;\r
-\r
-/**\r
- This class is used to override surface area information. For example, MBD can\r
- overried MSA, Platform can override all information of the module. \r
- \r
- <p>Override will take effect if two element satisfy one of following two condition: </p>\r
- <ul>\r
- <li>Element name and its attribute OverrideID equal each other. </li>\r
- <li>Element is defined as exclusive which mean such element can be\r
- only appeared in the surface area. </li>\r
- </ul>\r
- \r
- <p>For example, here OutputDirectory element is exclusive: </p>\r
- \r
- <pre>\r
- Low priority Xml Document fragment:\r
- <Libraries>\r
- <Arch ArchType="IA32">\r
- <Library OverrideID="8888">EdkPeCoffLoaderLib</Library>\r
- <Library OverrideID="8888">BasePeCoffLib</Library>\r
- </Arch>\r
- </Libraries> \r
- <BuildOptions>\r
- <OutputDirectory IntermediateDirectories="MODULE"/>\r
- <Option>CC_FLAGS = "/NOLOGO", "/C"</Option>\r
- <BuildOptions>\r
- \r
- High priority Xml Document fragment:\r
- <Libraries>\r
- <Arch ArchType="IA32">\r
- <Library OverrideID="8888">Nt32PeCoffLoaderLib</Library>\r
- </Arch>\r
- </Libraries>\r
- <BuildOptions>\r
- <OutputDirectory IntermediateDirectories="UNIFIED"/>\r
- <Option>LIB_FLAGS = "/NOLOGO"</Option>\r
- <BuildOptions>\r
- \r
- The result is: \r
- <Libraries>\r
- <Arch ArchType="IA32">\r
- <Library OverrideID="8888">Nt32PeCoffLoaderLib</Library>\r
- </Arch>\r
- </Libraries>\r
- <BuildOptions>\r
- <OutputDirectory IntermediateDirectories="UNIFIED"/>\r
- <Option>CC_FLAGS = "/NOLOGO", "/C"</Option>\r
- <Option>LIB_FLAGS = "/NOLOGO"</Option>\r
- <BuildOptions>\r
- \r
- </pre>\r
- \r
- <p>Note that using XmlBeans to walk through the whole XML document tree.</p> \r
- \r
- @since GenBuild 1.0\r
- @see org.apache.xmlbeans.XmlBeans\r
-**/\r
-public class OverrideProcess {\r
-\r
- ///\r
- /// URI, the namespace of current XML schema\r
- ///\r
- public static String prefix = "http://www.TianoCore.org/2006/Edk2.0";\r
-\r
- ///\r
- /// list of top elements of surface area\r
- ///\r
- public static String[] topElements = { "LibraryClassDefinitions",\r
- "SourceFiles", "Includes", "PackageDependencies", "Libraries", "Protocols",\r
- "Events", "Hobs", "PPIs", "Variables", "BootModes",\r
- "SystemTables", "DataHubs", "Formsets", "Guids", "Externs",\r
- "PcdCoded", "BuildOptions" };\r
-\r
- ///\r
- /// list of exclusive elements\r
- ///\r
- public static String[] exclusiveElements = {"OutputDirectory"};\r
- \r
- /**\r
- Recursively find out all elements specified with OverrideId attribute\r
- and exclusive elements in current XML object. \r
- \r
- @param o curent parsing XML object\r
- @param map Map to list elements specified OverrideID attribute\r
- @param execlusiveMap Map to list exclusive elements appeared in current XMl object\r
- @param level the depth in XML document tree\r
- **/\r
- private void listOverrideID(XmlObject o, Map<String,Object> map, Map<String,Object> execlusiveMap, int level) {\r
- XmlCursor cursor = o.newCursor();\r
- String name = cursor.getName().getLocalPart();\r
- for (int i = 0 ; i < exclusiveElements.length; i++){\r
- if (name.equalsIgnoreCase(exclusiveElements[i])){\r
- execlusiveMap.put(exclusiveElements[i], cursor.getObject());\r
- }\r
- }\r
- String overrideID = cursor.getAttributeText(new QName("OverrideID"));\r
- if (overrideID != null) {\r
- map.put(name + ":" + overrideID, cursor.getObject());\r
- }\r
- if (cursor.toFirstChild()) {\r
- do {\r
- listOverrideID(cursor.getObject(), map, execlusiveMap, level + 1);\r
- } while (cursor.toNextSibling());\r
- }\r
- }\r
-\r
- /**\r
- This function is used to prepare for overriding with changing data. \r
- \r
- @param map original surface area information \r
- @return after normalize surface area information\r
- **/\r
- public synchronized static Map<String, XmlObject> deal(Map<String, XmlObject> map) {\r
- Map<String, XmlObject> newMap = new HashMap<String, XmlObject>();\r
- if (map.get("MsaHeader") != null) {\r
- newMap.put("MsaHeader", ((MsaHeaderDocument) map.get("MsaHeader"))\r
- .getMsaHeader());\r
- }\r
- if (map.get("MsaLibHeader") != null) {\r
- newMap.put("MsaLibHeader", ((MsaLibHeaderDocument) map\r
- .get("MsaLibHeader")).getMsaLibHeader());\r
- }\r
- if (map.get("LibraryClassDefinitions") != null) {\r
- newMap.put("LibraryClassDefinitions",\r
- ((LibraryClassDefinitionsDocument) map\r
- .get("LibraryClassDefinitions"))\r
- .getLibraryClassDefinitions());\r
- }\r
- if (map.get("SourceFiles") != null) {\r
- newMap.put("SourceFiles", ((SourceFilesDocument) map\r
- .get("SourceFiles")).getSourceFiles());\r
- }\r
- if (map.get("Includes") != null) {\r
- newMap.put("Includes", ((IncludesDocument) map.get("Includes"))\r
- .getIncludes());\r
- }\r
- if (map.get("PackageDependencies") != null) {\r
- newMap.put("PackageDependencies", ((PackageDependenciesDocument) map.get("PackageDependencies"))\r
- .getPackageDependencies());\r
- }\r
- if (map.get("Libraries") != null) {\r
- newMap.put("Libraries", ((LibrariesDocument) map.get("Libraries"))\r
- .getLibraries());\r
- }\r
- if (map.get("Protocols") != null) {\r
- newMap.put("Protocols", ((ProtocolsDocument) map.get("Protocols"))\r
- .getProtocols());\r
- }\r
- if (map.get("Events") != null) {\r
- newMap.put("Events", ((EventsDocument) map.get("Events"))\r
- .getEvents());\r
- }\r
- if (map.get("Hobs") != null) {\r
- newMap.put("Hobs", ((HobsDocument) map.get("Hobs")).getHobs());\r
- }\r
- if (map.get("PPIs") != null) {\r
- newMap.put("PPIs", ((PPIsDocument) map.get("PPIs")).getPPIs());\r
- }\r
- if (map.get("Variables") != null) {\r
- newMap.put("Variables", ((VariablesDocument) map.get("Variables"))\r
- .getVariables());\r
- }\r
- if (map.get("BootModes") != null) {\r
- newMap.put("BootModes", ((BootModesDocument) map.get("BootModes"))\r
- .getBootModes());\r
- }\r
- if (map.get("SystemTables") != null) {\r
- newMap.put("SystemTables", ((SystemTablesDocument) map\r
- .get("SystemTables")).getSystemTables());\r
- }\r
- if (map.get("DataHubs") != null) {\r
- newMap.put("DataHubs", ((DataHubsDocument) map.get("DataHubs"))\r
- .getDataHubs());\r
- }\r
- if (map.get("Formsets") != null) {\r
- newMap.put("Formsets", ((FormsetsDocument) map.get("Formsets"))\r
- .getFormsets());\r
- }\r
- if (map.get("Guids") != null) {\r
- newMap.put("Guids", ((GuidsDocument) map.get("Guids")).getGuids());\r
- }\r
- if (map.get("Externs") != null) {\r
- newMap.put("Externs", ((ExternsDocument) map.get("Externs"))\r
- .getExterns());\r
- }\r
- if (map.get("PcdCoded") != null) {\r
- newMap.put("PcdCoded", ((PcdCodedDocument) map.get("PcdCoded")).getPcdCoded());\r
- }\r
- if (map.get("BuildOptions") != null) {\r
- newMap.put("BuildOptions", ((BuildOptionsDocument) map\r
- .get("BuildOptions")).getBuildOptions());\r
- }\r
- return newMap;\r
- }\r
-\r
- /**\r
- Recursively remove all subelement in Xml Object l (with low priority) \r
- based on OverrideID or exclusive elements. \r
- \r
- @param l the XML object to process\r
- @param map list of elements with OverrideID in high priority XML object\r
- @param execusiveMap list of exclusive elements in high priority XML object\r
- **/\r
- private void cut(XmlCursor l, Map map, Map execusiveMap) {\r
- String name = l.getName().getLocalPart();\r
- if (execusiveMap.containsKey(name)){\r
- l.removeXml();\r
- return;\r
- }\r
- String overrideID = l.getAttributeText(new QName("OverrideID"));\r
- if (overrideID != null) {\r
- if (map.containsKey(name + ":" + overrideID)) {\r
- l.removeXml();\r
- return;\r
- }\r
- }\r
- if (l.toFirstChild()) {\r
- do {\r
- cut(l, map, execusiveMap);\r
- } while (l.toNextSibling());\r
- }\r
- }\r
-\r
- private XmlObject cloneXmlObject(XmlObject object, boolean deep) throws BuildException {\r
- XmlObject result = null;\r
- try {\r
- result = XmlObject.Factory.parse(object.getDomNode()\r
- .cloneNode(deep));\r
- } catch (Exception ex) {\r
- throw new BuildException(ex.getMessage());\r
- }\r
- return result;\r
- }\r
-\r
- /**\r
- Process every item list in h and l.\r
- \r
- @param h surface area info with high priority\r
- @param l surface area info with low priority\r
- @return surface area after override\r
- **/\r
- public Map<String, XmlObject> override(Map<String, XmlObject> h,\r
- Map<String, XmlObject> l) {\r
- Map<String, XmlObject> result = new HashMap<String, XmlObject>();\r
- result.put("MsaHeader", override(l.get("MsaHeader"), null));\r
- result.put("MsaLibHeader", override(l.get("MsaLibHeader"), null));\r
- for (int i = 0; i < topElements.length; i++) {\r
- if (h != null) {\r
- result.put(topElements[i], override(h.get(topElements[i]), l.get(topElements[i])));\r
- } else {\r
- result.put(topElements[i], override(l.get(topElements[i]), null));\r
- }\r
- }\r
- return result;\r
- }\r
-\r
- /**\r
- Recursively override two Xml Objects.\r
- \r
- @param h Xml Object info with high priority\r
- @param l Xml Object info with low priority\r
- @return Xml Object after area\r
- **/\r
- public XmlObject override(XmlObject h, XmlObject l) {\r
- if (l == null && h == null) {\r
- return null;\r
- }\r
- if (h == null) {\r
- return cloneXmlObject(l, true);\r
- }\r
- if (l == null) {\r
- return cloneXmlObject(h, true);\r
- }\r
- XmlCursor hc = h.newCursor();\r
- if (h.getClass() != l.getClass()) {\r
- System.out.println("Error: Two XmlObject does not with compliant format.");\r
- return null;\r
- }\r
- if (!hc.toFirstChild()) {\r
- return cloneXmlObject(l, true);\r
- }\r
-\r
- XmlCursor result = cloneXmlObject(h, true).newCursor();\r
- XmlCursor lcursor = cloneXmlObject(l, true).newCursor();\r
- result.push();\r
- result.toNextToken();\r
- result.insertNamespace("", prefix);\r
- result.toFirstChild();\r
- //\r
- // found out all element specified a OverrideID\r
- //\r
- Map<String,Object> hmap = new HashMap<String,Object>();\r
- Map<String,Object> execlusiveMap = new HashMap<String,Object>();\r
- listOverrideID(h, hmap, execlusiveMap, 0);\r
- lcursor.toNextToken();\r
- lcursor.push();\r
- //\r
- // for every direct subelement of l, cut all element satisfied with\r
- // override rule\r
- //\r
- if (lcursor.toFirstChild()) {\r
- do {\r
- cut(lcursor, hmap, execlusiveMap);\r
- } while (lcursor.toNextSibling());\r
- }\r
- lcursor.pop();\r
- if (lcursor.toFirstChild()) {\r
- do {\r
- lcursor.copyXml(result);\r
- result.insertChars("\n");\r
- } while (lcursor.toNextSibling());\r
- }\r
- result.pop();\r
- return result.getObject();\r
- }\r
-}
\ No newline at end of file