--- /dev/null
+/** @file\r
+ PlatformPcdPreprocessActionForBuilding class.\r
+\r
+ This action class is to collect PCD information from MSA, SPD, FPD xml file.\r
+ This class will be used for wizard and build tools, So it can *not* inherit\r
+ from buildAction or wizardAction.\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.pcd.action;\r
+\r
+import java.io.File;\r
+import java.io.IOException;\r
+import java.util.ArrayList;\r
+import java.util.Iterator;\r
+import java.util.List;\r
+import java.util.Map;\r
+\r
+import org.apache.xmlbeans.XmlException;\r
+import org.apache.xmlbeans.XmlObject;\r
+import org.tianocore.DynamicPcdBuildDefinitionsDocument.DynamicPcdBuildDefinitions;\r
+import org.tianocore.PcdBuildDefinitionDocument;\r
+import org.tianocore.PlatformSurfaceAreaDocument;\r
+import org.tianocore.build.exception.PlatformPcdPreprocessBuildException;\r
+import org.tianocore.build.global.GlobalData;\r
+import org.tianocore.build.id.FpdModuleIdentification;\r
+import org.tianocore.pcd.action.PlatformPcdPreprocessAction;\r
+import org.tianocore.pcd.entity.MemoryDatabaseManager;\r
+import org.tianocore.pcd.entity.ModulePcdInfoFromFpd;\r
+import org.tianocore.pcd.entity.Token;\r
+import org.tianocore.pcd.entity.UsageIdentification;\r
+import org.tianocore.pcd.exception.EntityException;\r
+import org.tianocore.pcd.exception.PlatformPcdPreprocessException;\r
+\r
+/**\r
+ This action class is to collect PCD information from MSA, SPD, FPD xml file.\r
+ This class will be used for wizard and build tools, So it can *not* inherit\r
+ from buildAction or UIAction.\r
+**/\r
+public class PlatformPcdPreprocessActionForBuilding extends PlatformPcdPreprocessAction {\r
+ ///\r
+ /// FPD file path.\r
+ ///\r
+ private String fpdFilePath;\r
+\r
+ ///\r
+ /// Message level for CollectPCDAction.\r
+ ///\r
+ private int originalMessageLevel;\r
+\r
+ ///\r
+ /// Cache the fpd docment instance for private usage.\r
+ ///\r
+ private PlatformSurfaceAreaDocument fpdDocInstance;\r
+\r
+ /**\r
+ Set FPDFileName parameter for this action class.\r
+\r
+ @param fpdFilePath fpd file path\r
+ **/\r
+ public void setFPDFilePath(String fpdFilePath) {\r
+ this.fpdFilePath = fpdFilePath;\r
+ }\r
+\r
+ /**\r
+ Common function interface for outer.\r
+\r
+ @param fpdFilePath The fpd file path of current build or processing.\r
+\r
+ @throws PlatformPreprocessBuildException \r
+ The exception of this function. Because it can *not* be predict\r
+ where the action class will be used. So only Exception can be throw.\r
+\r
+ **/\r
+ public void perform(String fpdFilePath) \r
+ throws PlatformPcdPreprocessBuildException {\r
+ this.fpdFilePath = fpdFilePath;\r
+ checkParameter();\r
+ execute();\r
+ }\r
+\r
+ /**\r
+ Core execution function for this action class.\r
+\r
+ This function work flows will be:\r
+ 1) Collect and prepocess PCD information from FPD file, all PCD\r
+ information will be stored into memory database.\r
+ 2) Generate 3 strings for\r
+ a) All modules using Dynamic(Ex) PCD entry.(Token Number)\r
+ b) PEI PCDDatabase (C Structure) for PCD Service PEIM.\r
+ c) DXE PCD Database (C structure) for PCD Service DXE.\r
+\r
+\r
+ @throws EntityException Exception indicate failed to execute this action.\r
+\r
+ **/\r
+ public void execute() throws PlatformPcdPreprocessBuildException {\r
+ String errorMessageHeader = "Failed to initialize the Pcd memory database because: ";\r
+ String errorsForPreprocess = null;\r
+\r
+ //\r
+ // Get memoryDatabaseManager instance from GlobalData.\r
+ // The memoryDatabaseManager should be initialized as static variable\r
+ // in some Pre-process class.\r
+ //\r
+ setPcdDbManager(GlobalData.getPCDMemoryDBManager());\r
+\r
+ //\r
+ // Collect all PCD information defined in FPD file.\r
+ // Evenry token defind in FPD will be created as an token into\r
+ // memory database.\r
+ //\r
+ try {\r
+ initPcdMemoryDbWithPlatformInfo();\r
+ } catch (PlatformPcdPreprocessException exp) {\r
+ throw new PlatformPcdPreprocessBuildException(errorMessageHeader + exp.getMessage());\r
+ }\r
+ errorsForPreprocess = this.getErrorString();\r
+ if (errorsForPreprocess != null) {\r
+ throw new PlatformPcdPreprocessBuildException(errorMessageHeader + "\r\n" + errorsForPreprocess);\r
+ }\r
+\r
+ //\r
+ // Generate for PEI, DXE PCD DATABASE's definition and initialization.\r
+ //\r
+ try {\r
+ genPcdDatabaseSourceCode ();\r
+ } catch (EntityException exp) {\r
+ throw new PlatformPcdPreprocessBuildException(errorMessageHeader + "\r\n" + exp.getMessage());\r
+ }\r
+ }\r
+\r
+ /**\r
+ Override function: implementate the method of get Guid string information from SPD file.\r
+\r
+ @param guidCName Guid CName string.\r
+\r
+ @return String Guid information from SPD file.\r
+ @throws PlatformPcdPreprocessException\r
+ Fail to get Guid information from SPD file.\r
+ **/\r
+ public String getGuidInfoFromSpd(String guidCName) throws PlatformPcdPreprocessException {\r
+ String tokenSpaceStrRet = null;\r
+ try {\r
+ tokenSpaceStrRet = GlobalData.getGuidInfoFromCname(guidCName);\r
+ } catch ( Exception e ) {\r
+ throw new PlatformPcdPreprocessException ("Failed to get Guid CName " + guidCName + " from the SPD file!");\r
+ }\r
+ return tokenSpaceStrRet;\r
+ }\r
+\r
+ /**\r
+ This function generates source code for PCD Database.\r
+\r
+ @throws EntityException If the token does *not* exist in memory database.\r
+\r
+ **/\r
+ private void genPcdDatabaseSourceCode()\r
+ throws EntityException {\r
+ String PcdCommonHeaderString = PcdDatabase.getPcdDatabaseCommonDefinitions();\r
+\r
+ ArrayList<Token> alPei = new ArrayList<Token> ();\r
+ ArrayList<Token> alDxe = new ArrayList<Token> ();\r
+\r
+ getPcdDbManager().getTwoPhaseDynamicRecordArray(alPei, alDxe);\r
+ PcdDatabase pcdPeiDatabase = new PcdDatabase (alPei, "PEI", 0);\r
+ pcdPeiDatabase.genCode();\r
+ MemoryDatabaseManager.PcdPeimHString = PcdCommonHeaderString + pcdPeiDatabase.getHString() +\r
+ PcdDatabase.getPcdPeiDatabaseDefinitions();\r
+ MemoryDatabaseManager.PcdPeimCString = pcdPeiDatabase.getCString();\r
+\r
+ PcdDatabase pcdDxeDatabase = new PcdDatabase(alDxe, "DXE", alPei.size());\r
+ pcdDxeDatabase.genCode();\r
+ MemoryDatabaseManager.PcdDxeHString = MemoryDatabaseManager.PcdPeimHString + pcdDxeDatabase.getHString() +\r
+ PcdDatabase.getPcdDxeDatabaseDefinitions();\r
+ MemoryDatabaseManager.PcdDxeCString = pcdDxeDatabase.getCString();\r
+ }\r
+\r
+ /**\r
+ Override function: Get component array from FPD.\r
+\r
+ This function maybe provided by some Global class.\r
+\r
+ @return List<ModuleInfo> the component array.\r
+ @throws PlatformPcdPreprocessException get all modules in <ModuleSA> in FPD file.\r
+\r
+ **/\r
+ public List<ModulePcdInfoFromFpd> getComponentsFromFpd()\r
+ throws PlatformPcdPreprocessException {\r
+ List<ModulePcdInfoFromFpd> allModules = new ArrayList<ModulePcdInfoFromFpd>();\r
+ Map<FpdModuleIdentification, XmlObject> pcdBuildDefinitions = null;\r
+ UsageIdentification usageId = null;\r
+\r
+ pcdBuildDefinitions = GlobalData.getFpdPcdBuildDefinitions();\r
+ if (pcdBuildDefinitions == null) {\r
+ return null;\r
+ }\r
+\r
+ //\r
+ // Loop map to retrieve all PCD build definition and Module id\r
+ //\r
+ Iterator item = pcdBuildDefinitions.keySet().iterator();\r
+ while (item.hasNext()){\r
+ FpdModuleIdentification id = (FpdModuleIdentification) item.next();\r
+ usageId = new UsageIdentification(id.getModule().getName(),\r
+ id.getModule().getGuid(),\r
+ id.getModule().getPackage().getName(),\r
+ id.getModule().getPackage().getGuid(),\r
+ id.getArch(),\r
+ id.getModule().getVersion(),\r
+ id.getModule().getModuleType());\r
+ allModules.add(\r
+ new ModulePcdInfoFromFpd(\r
+ usageId, \r
+ ((PcdBuildDefinitionDocument)pcdBuildDefinitions.get(id)).getPcdBuildDefinition()));\r
+ }\r
+ return allModules;\r
+ }\r
+\r
+ /**\r
+ Override function: Verify the datum value according its datum size and datum type, this\r
+ function maybe moved to FPD verification tools in future.\r
+\r
+ @param cName The token name\r
+ @param moduleName The module who use this PCD token\r
+ @param datum The PCD's datum\r
+ @param datumType The PCD's datum type\r
+ @param maxDatumSize The max size for PCD's Datum.\r
+\r
+ @return String exception strings.\r
+ */\r
+ public String verifyDatum(String cName,\r
+ String moduleName,\r
+ String datum,\r
+ Token.DATUM_TYPE datumType,\r
+ int maxDatumSize) {\r
+ //\r
+ // In building system, datum should not be checked, the checking work\r
+ // should be done by wizard tools or PCD verification tools.\r
+ // \r
+ return null;\r
+ }\r
+\r
+ /**\r
+ Override function: Get dynamic information for a dynamic PCD from <DynamicPcdBuildDefinition> seciton in FPD file.\r
+\r
+ This function should be implemented in GlobalData in future.\r
+\r
+ @param token The token instance which has hold module's PCD information\r
+ @param moduleName The name of module who will use this Dynamic PCD.\r
+\r
+ @return DynamicPcdBuildDefinitions.PcdBuildData\r
+ **/\r
+ public DynamicPcdBuildDefinitions.PcdBuildData getDynamicInfoFromFpd(Token token,\r
+ String moduleName)\r
+ throws PlatformPcdPreprocessException {\r
+ int index = 0;\r
+ String exceptionString = null;\r
+ String dynamicPrimaryKey = null;\r
+ DynamicPcdBuildDefinitions dynamicPcdBuildDefinitions = null;\r
+ List<DynamicPcdBuildDefinitions.PcdBuildData> dynamicPcdBuildDataArray = null;\r
+ String tokenSpaceStrRet = null;\r
+\r
+ //\r
+ // If FPD document is not be opened, open and initialize it.\r
+ // BUGBUG: The code should be moved into GlobalData in future.\r
+ //\r
+ if (fpdDocInstance == null) {\r
+ try {\r
+ fpdDocInstance = (PlatformSurfaceAreaDocument)XmlObject.Factory.parse(new File(fpdFilePath));\r
+ } catch(IOException ioE) {\r
+ throw new PlatformPcdPreprocessException("File IO error for xml file:" + fpdFilePath + "\n" + ioE.getMessage());\r
+ } catch(XmlException xmlE) {\r
+ throw new PlatformPcdPreprocessException("Can't parse the FPD xml fle:" + fpdFilePath + "\n" + xmlE.getMessage());\r
+ }\r
+ }\r
+\r
+ dynamicPcdBuildDefinitions = fpdDocInstance.getPlatformSurfaceArea().getDynamicPcdBuildDefinitions();\r
+ if (dynamicPcdBuildDefinitions == null) {\r
+ exceptionString = String.format("[FPD file error] There are no <PcdDynamicBuildDescriptions> elements in FPD file but there are Dynamic type "+\r
+ "PCD entries %s in module %s!",\r
+ token.cName,\r
+ moduleName);\r
+ putError(exceptionString);\r
+ return null;\r
+ }\r
+\r
+ dynamicPcdBuildDataArray = dynamicPcdBuildDefinitions.getPcdBuildDataList();\r
+ for (index = 0; index < dynamicPcdBuildDataArray.size(); index ++) {\r
+ tokenSpaceStrRet = getGuidInfoFromSpd(dynamicPcdBuildDataArray.get(index).getTokenSpaceGuidCName());\r
+\r
+ if (tokenSpaceStrRet == null) {\r
+ exceptionString = "Fail to get token space guid for token " + dynamicPcdBuildDataArray.get(index).getCName();\r
+ putError(exceptionString);\r
+ continue;\r
+ }\r
+\r
+ dynamicPrimaryKey = Token.getPrimaryKeyString(dynamicPcdBuildDataArray.get(index).getCName(),\r
+ tokenSpaceStrRet);\r
+ if (dynamicPrimaryKey.equals(token.getPrimaryKeyString())) {\r
+ return dynamicPcdBuildDataArray.get(index);\r
+ }\r
+ }\r
+\r
+ return null;\r
+ }\r
+\r
+ /**\r
+ Override function: get all <DynamicPcdBuildDefinition> from FPD file.\r
+\r
+ @return List<DynamicPcdBuildDefinitions.PcdBuildData> All DYNAMIC PCD list in <DynamicPcdBuildDefinitions> in FPD file.\r
+ @throws PlatformPcdPreprocessBuildException Failure to get dynamic information list.\r
+\r
+ **/\r
+ public List<DynamicPcdBuildDefinitions.PcdBuildData>\r
+ getAllDynamicPcdInfoFromFpd()\r
+ throws PlatformPcdPreprocessException {\r
+ DynamicPcdBuildDefinitions dynamicPcdBuildDefinitions = null;\r
+\r
+ //\r
+ // Open fpd document to get <DynamicPcdBuildDefinition> Section.\r
+ // BUGBUG: the function should be move GlobalData in furture.\r
+ //\r
+ if (fpdDocInstance == null) {\r
+ try {\r
+ fpdDocInstance = (PlatformSurfaceAreaDocument)XmlObject.Factory.parse(new File(fpdFilePath));\r
+ } catch(IOException ioE) {\r
+ throw new PlatformPcdPreprocessException("File IO error for xml file:" + fpdFilePath + "\n" + ioE.getMessage());\r
+ } catch(XmlException xmlE) {\r
+ throw new PlatformPcdPreprocessException("Can't parse the FPD xml fle:" + fpdFilePath + "\n" + xmlE.getMessage());\r
+ }\r
+ }\r
+\r
+ dynamicPcdBuildDefinitions = fpdDocInstance.getPlatformSurfaceArea().getDynamicPcdBuildDefinitions();\r
+ if (dynamicPcdBuildDefinitions == null) {\r
+ return null;\r
+ }\r
+\r
+ return dynamicPcdBuildDefinitions.getPcdBuildDataList();\r
+ }\r
+\r
+ /**\r
+ check parameter for this action.\r
+\r
+ @throws PlatformPcdPreprocessBuildException Bad parameter.\r
+ **/\r
+ private void checkParameter() throws PlatformPcdPreprocessBuildException {\r
+ File file = null;\r
+\r
+ if (fpdFilePath == null) {\r
+ throw new PlatformPcdPreprocessBuildException("FPDFileName should be empty for CollectPCDAtion!");\r
+ }\r
+\r
+ if (fpdFilePath.length() == 0) {\r
+ throw new PlatformPcdPreprocessBuildException("FPDFileName should be empty for CollectPCDAtion!");\r
+ }\r
+\r
+ file = new File(fpdFilePath);\r
+\r
+ if(!file.exists()) {\r
+ throw new PlatformPcdPreprocessBuildException("FPD File " + fpdFilePath + " does not exist!");\r
+ }\r
+ }\r
+}\r