]> git.proxmox.com Git - mirror_edk2.git/blobdiff - Tools/Source/GenBuild/org/tianocore/build/pcd/action/PlatformPcdPreprocessActionForBuilding.java
Abstract the logic of Platform pcd preprocess according to FPD file to a class. And...
[mirror_edk2.git] / Tools / Source / GenBuild / org / tianocore / build / pcd / action / PlatformPcdPreprocessActionForBuilding.java
diff --git a/Tools/Source/GenBuild/org/tianocore/build/pcd/action/PlatformPcdPreprocessActionForBuilding.java b/Tools/Source/GenBuild/org/tianocore/build/pcd/action/PlatformPcdPreprocessActionForBuilding.java
new file mode 100644 (file)
index 0000000..2e50531
--- /dev/null
@@ -0,0 +1,719 @@
+/** @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.math.BigInteger;\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.PlatformSurfaceAreaDocument;\r
+import org.tianocore.build.fpd.FpdParserTask;\r
+import org.tianocore.build.global.GlobalData;\r
+import org.tianocore.build.id.FpdModuleIdentification;\r
+import org.tianocore.pcd.action.ActionMessage;\r
+import org.tianocore.pcd.entity.ModulePcdInfoFromFpd;\r
+import org.tianocore.pcd.entity.MemoryDatabaseManager;\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.action.PlatformPcdPreprocessAction;\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
+    /// Workspacepath hold the workspace information.\r
+    ///\r
+    private String                      workspacePath;\r
+\r
+    ///\r
+    /// FPD file is the root file.\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 WorkspacePath parameter for this action class.\r
+\r
+      @param workspacePath parameter for this action\r
+    **/\r
+    public void setWorkspacePath(String workspacePath) {\r
+        this.workspacePath = workspacePath;\r
+    }\r
+\r
+    /**\r
+      Set action message level for CollectPcdAction tool.\r
+\r
+      The message should be restored when this action exit.\r
+\r
+      @param actionMessageLevel parameter for this action\r
+    **/\r
+    public void setActionMessageLevel(int actionMessageLevel) {\r
+        originalMessageLevel       = ActionMessage.messageLevel;\r
+        ActionMessage.messageLevel = actionMessageLevel;\r
+    }\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 workspacePath The path of workspace of current build or analysis.\r
+      @param fpdFilePath   The fpd file path of current build or analysis.\r
+      @param messageLevel  The message level for this Action.\r
+\r
+      @throws  Exception 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 workspacePath, String fpdFilePath,\r
+                        int messageLevel) throws Exception {\r
+        setWorkspacePath(workspacePath);\r
+        setFPDFilePath(fpdFilePath);\r
+        setActionMessageLevel(messageLevel);\r
+        checkParameter();\r
+        execute();\r
+        ActionMessage.messageLevel = originalMessageLevel;\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 EntityException {\r
+        MemoryDatabaseManager pcdDbManager = null;\r
+\r
+        //\r
+        // Get memoryDatabaseManager instance from GlobalData.\r
+        // The memoryDatabaseManager should be initialized for whatever build\r
+        // tools or wizard tools\r
+        //\r
+        if((pcdDbManager = GlobalData.getPCDMemoryDBManager()) == null) {\r
+            throw new EntityException("The instance of PCD memory database manager is null");\r
+        }\r
+\r
+        this.setPcdDbManager(pcdDbManager);\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
+        initPcdMemoryDbWithPlatformInfo();\r
+\r
+        //\r
+        // Generate for PEI, DXE PCD DATABASE's definition and initialization.\r
+        //\r
+        genPcdDatabaseSourceCode ();\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
+    **/\r
+    public String[] getGuidInfoFromSpd(String guidCName) throws EntityException {\r
+        String[] tokenSpaceStrRet = null;\r
+        try {\r
+            tokenSpaceStrRet = GlobalData.getGuidInfoFromCname(guidCName);\r
+        } catch ( Exception e ) {\r
+            throw new EntityException ("Failed get Guid CName " + guidCName + "from SPD file!");\r
+        }\r
+        return tokenSpaceStrRet;\r
+    }\r
+\r
+    /**\r
+      This function generates source code for PCD Database.\r
+\r
+      @param void\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
+\r
+     */\r
+    public List<ModulePcdInfoFromFpd> getComponentsFromFpd()\r
+        throws EntityException {\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(new ModulePcdInfoFromFpd(usageId, pcdBuildDefinitions.get(id)));\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\r
+       @param moduleName\r
+       @param datum\r
+       @param datumType\r
+       @param maxDatumSize\r
+\r
+       @return String\r
+     */\r
+    /***/\r
+    public String verifyDatum(String            cName,\r
+                              String            moduleName,\r
+                              String            datum,\r
+                              Token.DATUM_TYPE  datumType,\r
+                              int               maxDatumSize) {\r
+        String      exceptionString = null;\r
+        int         value;\r
+        BigInteger  value64;\r
+        String      subStr;\r
+        int         index;\r
+\r
+        if (moduleName == null) {\r
+            moduleName = "section <DynamicPcdBuildDefinitions>";\r
+        } else {\r
+            moduleName = "module " + moduleName;\r
+        }\r
+\r
+        if (maxDatumSize == 0) {\r
+            exceptionString = String.format("[FPD file error] You maybe miss <MaxDatumSize> for PCD %s in %s",\r
+                                            cName,\r
+                                            moduleName);\r
+            return exceptionString;\r
+        }\r
+\r
+        switch (datumType) {\r
+        case UINT8:\r
+            if (maxDatumSize != 1) {\r
+                exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+\r
+                                                "is UINT8, but datum size is %d, they are not matched!",\r
+                                                 cName,\r
+                                                 moduleName,\r
+                                                 maxDatumSize);\r
+                return exceptionString;\r
+            }\r
+\r
+            if (datum != null) {\r
+                try {\r
+                    value = Integer.decode(datum);\r
+                } catch (NumberFormatException nfeExp) {\r
+                    exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is not valid "+\r
+                                                    "digital format of UINT8",\r
+                                                    cName,\r
+                                                    moduleName);\r
+                    return exceptionString;\r
+                }\r
+                if (value > 0xFF) {\r
+                    exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is %s exceed"+\r
+                                                    " the max size of UINT8 - 0xFF",\r
+                                                    cName,\r
+                                                    moduleName,\r
+                                                    datum);\r
+                    return exceptionString;\r
+                }\r
+            }\r
+            break;\r
+        case UINT16:\r
+            if (maxDatumSize != 2) {\r
+                exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+\r
+                                                "is UINT16, but datum size is %d, they are not matched!",\r
+                                                 cName,\r
+                                                 moduleName,\r
+                                                 maxDatumSize);\r
+                return exceptionString;\r
+            }\r
+            if (datum != null) {\r
+                try {\r
+                    value = Integer.decode(datum);\r
+                } catch (NumberFormatException nfeExp) {\r
+                    exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is "+\r
+                                                    "not valid digital of UINT16",\r
+                                                    cName,\r
+                                                    moduleName);\r
+                    return exceptionString;\r
+                }\r
+                if (value > 0xFFFF) {\r
+                    exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is %s "+\r
+                                                    "which exceed the range of UINT16 - 0xFFFF",\r
+                                                    cName,\r
+                                                    moduleName,\r
+                                                    datum);\r
+                    return exceptionString;\r
+                }\r
+            }\r
+            break;\r
+        case UINT32:\r
+            if (maxDatumSize != 4) {\r
+                exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+\r
+                                                "is UINT32, but datum size is %d, they are not matched!",\r
+                                                 cName,\r
+                                                 moduleName,\r
+                                                 maxDatumSize);\r
+                return exceptionString;\r
+            }\r
+\r
+            if (datum != null) {\r
+                try {\r
+                    if (datum.length() > 2) {\r
+                        if ((datum.charAt(0) == '0')        &&\r
+                            ((datum.charAt(1) == 'x') || (datum.charAt(1) == 'X'))){\r
+                            subStr = datum.substring(2, datum.length());\r
+                            value64 = new BigInteger(subStr, 16);\r
+                        } else {\r
+                            value64 = new BigInteger(datum);\r
+                        }\r
+                    } else {\r
+                        value64 = new BigInteger(datum);\r
+                    }\r
+                } catch (NumberFormatException nfeExp) {\r
+                    exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is not "+\r
+                                                    "valid digital of UINT32",\r
+                                                    cName,\r
+                                                    moduleName);\r
+                    return exceptionString;\r
+                }\r
+\r
+                if (value64.bitLength() > 32) {\r
+                    exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is %s which "+\r
+                                                    "exceed the range of UINT32 - 0xFFFFFFFF",\r
+                                                    cName,\r
+                                                    moduleName,\r
+                                                    datum);\r
+                    return exceptionString;\r
+                }\r
+            }\r
+            break;\r
+        case UINT64:\r
+            if (maxDatumSize != 8) {\r
+                exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+\r
+                                                "is UINT64, but datum size is %d, they are not matched!",\r
+                                                 cName,\r
+                                                 moduleName,\r
+                                                 maxDatumSize);\r
+                return exceptionString;\r
+            }\r
+\r
+            if (datum != null) {\r
+                try {\r
+                    if (datum.length() > 2) {\r
+                        if ((datum.charAt(0) == '0')        &&\r
+                            ((datum.charAt(1) == 'x') || (datum.charAt(1) == 'X'))){\r
+                            subStr = datum.substring(2, datum.length());\r
+                            value64 = new BigInteger(subStr, 16);\r
+                        } else {\r
+                            value64 = new BigInteger(datum);\r
+                        }\r
+                    } else {\r
+                        value64 = new BigInteger(datum);\r
+                    }\r
+                } catch (NumberFormatException nfeExp) {\r
+                    exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is not valid"+\r
+                                                    " digital of UINT64",\r
+                                                    cName,\r
+                                                    moduleName);\r
+                    return exceptionString;\r
+                }\r
+\r
+                if (value64.bitLength() > 64) {\r
+                    exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is %s "+\r
+                                                    "exceed the range of UINT64 - 0xFFFFFFFFFFFFFFFF",\r
+                                                    cName,\r
+                                                    moduleName,\r
+                                                    datum);\r
+                    return exceptionString;\r
+                }\r
+            }\r
+            break;\r
+        case BOOLEAN:\r
+            if (maxDatumSize != 1) {\r
+                exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+\r
+                                                "is BOOLEAN, but datum size is %d, they are not matched!",\r
+                                                 cName,\r
+                                                 moduleName,\r
+                                                 maxDatumSize);\r
+                return exceptionString;\r
+            }\r
+\r
+            if (datum != null) {\r
+                if (!(datum.equalsIgnoreCase("TRUE") ||\r
+                     datum.equalsIgnoreCase("FALSE"))) {\r
+                    exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+\r
+                                                    "is BOOELAN, but value is not 'true'/'TRUE' or 'FALSE'/'false'",\r
+                                                    cName,\r
+                                                    moduleName);\r
+                    return exceptionString;\r
+                }\r
+\r
+            }\r
+            break;\r
+        case POINTER:\r
+            if (datum == null) {\r
+                break;\r
+            }\r
+\r
+            char    ch     = datum.charAt(0);\r
+            int     start, end;\r
+            String  strValue;\r
+            //\r
+            // For void* type PCD, only three datum is support:\r
+            // 1) Unicode: string with start char is "L"\r
+            // 2) Ansci: String start char is ""\r
+            // 3) byte array: String start char "{"\r
+            //\r
+            if (ch == 'L') {\r
+                start       = datum.indexOf('\"');\r
+                end         = datum.lastIndexOf('\"');\r
+                if ((start > end)           ||\r
+                    (end   > datum.length())||\r
+                    ((start == end) && (datum.length() > 0))) {\r
+                    exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID* and datum is "+\r
+                                                    "a UNICODE string because start with L\", but format maybe"+\r
+                                                    "is not right, correct UNICODE string is L\"...\"!",\r
+                                                    cName,\r
+                                                    moduleName);\r
+                    return exceptionString;\r
+                }\r
+\r
+                strValue    = datum.substring(start + 1, end);\r
+                if ((strValue.length() * 2) > maxDatumSize) {\r
+                    exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID*, and datum is "+\r
+                                                    "a UNICODE string, but the datum size is %d exceed to <MaxDatumSize> : %d",\r
+                                                    cName,\r
+                                                    moduleName,\r
+                                                    strValue.length() * 2,\r
+                                                    maxDatumSize);\r
+                    return exceptionString;\r
+                }\r
+            } else if (ch == '\"'){\r
+                start       = datum.indexOf('\"');\r
+                end         = datum.lastIndexOf('\"');\r
+                if ((start > end)           ||\r
+                    (end   > datum.length())||\r
+                    ((start == end) && (datum.length() > 0))) {\r
+                    exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID* and datum is "+\r
+                                                    "a ANSCII string because start with \", but format maybe"+\r
+                                                    "is not right, correct ANSIC string is \"...\"!",\r
+                                                    cName,\r
+                                                    moduleName);\r
+                    return exceptionString;\r
+                }\r
+                strValue    = datum.substring(start + 1, end);\r
+                if ((strValue.length()) > maxDatumSize) {\r
+                    exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID*, and datum is "+\r
+                                                    "a ANSCI string, but the datum size is %d which exceed to <MaxDatumSize> : %d",\r
+                                                    cName,\r
+                                                    moduleName,\r
+                                                    strValue.length(),\r
+                                                    maxDatumSize);\r
+                    return exceptionString;\r
+                }\r
+            } else if (ch =='{') {\r
+                String[]  strValueArray;\r
+\r
+                start           = datum.indexOf('{');\r
+                end             = datum.lastIndexOf('}');\r
+                strValue        = datum.substring(start + 1, end);\r
+                strValue        = strValue.trim();\r
+                if (strValue.length() == 0) {\r
+                    exceptionString = String.format ("[FPD file error] The datum type of PCD %s in %s is VOID*, and "+\r
+                                                     "it is byte array in fact, but '{}' is not valid for NULL datam but"+\r
+                                                     " need use '{0}'",\r
+                                                     cName,\r
+                                                     moduleName);\r
+                    return exceptionString;\r
+                }\r
+                strValueArray   = strValue.split(",");\r
+                for (index = 0; index < strValueArray.length; index ++) {\r
+                    try{\r
+                        value = Integer.decode(strValueArray[index].trim());\r
+                    } catch (NumberFormatException nfeEx) {\r
+                        exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID*, and "+\r
+                                                         "it is byte array in fact. For every byte in array should be a valid"+\r
+                                                         "byte digital, but element %s is not a valid byte digital!",\r
+                                                         cName,\r
+                                                         moduleName,\r
+                                                         strValueArray[index]);\r
+                        return exceptionString;\r
+                    }\r
+                    if (value > 0xFF) {\r
+                        exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID*, "+\r
+                                                        "it is byte array in fact. But the element of %s exceed the byte range",\r
+                                                        cName,\r
+                                                        moduleName,\r
+                                                        strValueArray[index]);\r
+                        return exceptionString;\r
+                    }\r
+                }\r
+\r
+                if (strValueArray.length > maxDatumSize) {\r
+                    exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID*, and datum is byte"+\r
+                                                    "array, but the number of bytes is %d which exceed to <MaxDatumSzie> : %d!",\r
+                                                    cName,\r
+                                                    moduleName,\r
+                                                    strValueArray.length,\r
+                                                    maxDatumSize);\r
+                    return exceptionString;\r
+                }\r
+            } else {\r
+                exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID*. For VOID* type, you have three format choise:\n "+\r
+                                                "1) UNICODE string: like L\"xxxx\";\r\n"+\r
+                                                "2) ANSIC string: like \"xxx\";\r\n"+\r
+                                                "3) Byte array: like {0x2, 0x45, 0x23}\r\n"+\r
+                                                "But the datum in seems does not following above format!",\r
+                                                cName,\r
+                                                moduleName);\r
+                return exceptionString;\r
+            }\r
+            break;\r
+        default:\r
+            exceptionString = String.format("[FPD file error] For PCD entry %s in %s, datum type is unknown, it should be one of "+\r
+                                            "UINT8, UINT16, UINT32, UINT64, VOID*, BOOLEAN",\r
+                                            cName,\r
+                                            moduleName);\r
+            return exceptionString;\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 EntityException {\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 EntityException("File IO error for xml file:" + fpdFilePath + "\n" + ioE.getMessage());\r
+            } catch(XmlException xmlE) {\r
+                throw new EntityException("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> in FPD file but contains Dynamic type "+\r
+                                            "PCD entry %s in module %s!",\r
+                                            token.cName,\r
+                                            moduleName);\r
+            throw new EntityException(exceptionString);\r
+        }\r
+\r
+        dynamicPcdBuildDataArray = dynamicPcdBuildDefinitions.getPcdBuildDataList();\r
+        for (index = 0; index < dynamicPcdBuildDataArray.size(); index ++) {\r
+            try {\r
+                tokenSpaceStrRet = GlobalData.getGuidInfoFromCname(dynamicPcdBuildDataArray.get(index).getTokenSpaceGuidCName());\r
+            } catch (Exception e) {\r
+                throw new EntityException ("Fail to get token space guid for token " + dynamicPcdBuildDataArray.get(index).getCName());\r
+            }\r
+\r
+            if (tokenSpaceStrRet == null) {\r
+                throw new EntityException ("Fail to get token space guid for token " + dynamicPcdBuildDataArray.get(index).getCName());\r
+            }\r
+\r
+            dynamicPrimaryKey = Token.getPrimaryKeyString(dynamicPcdBuildDataArray.get(index).getCName(),\r
+                                                          tokenSpaceStrRet[1]);\r
+            if (dynamicPrimaryKey.equalsIgnoreCase(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>\r
+    **/\r
+    public List<DynamicPcdBuildDefinitions.PcdBuildData>\r
+                                            getAllDynamicPcdInfoFromFpd()\r
+        throws EntityException {\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 EntityException("File IO error for xml file:" + fpdFilePath + "\n" + ioE.getMessage());\r
+            } catch(XmlException xmlE) {\r
+                throw new EntityException("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 EntityException  Bad parameter.\r
+    **/\r
+    private void checkParameter() throws EntityException {\r
+        File file = null;\r
+\r
+        if((fpdFilePath    == null) ||(workspacePath  == null)) {\r
+            throw new EntityException("WorkspacePath and FPDFileName should be blank for CollectPCDAtion!");\r
+        }\r
+\r
+        if(fpdFilePath.length() == 0 || workspacePath.length() == 0) {\r
+            throw new EntityException("WorkspacePath and FPDFileName should be blank for CollectPCDAtion!");\r
+        }\r
+\r
+        file = new File(workspacePath);\r
+        if(!file.exists()) {\r
+            throw new EntityException("WorkpacePath " + workspacePath + " does not exist!");\r
+        }\r
+\r
+        file = new File(fpdFilePath);\r
+\r
+        if(!file.exists()) {\r
+            throw new EntityException("FPD File " + fpdFilePath + " does not exist!");\r
+        }\r
+    }\r
+\r
+    /**\r
+      Test case function\r
+\r
+      @param argv  parameter from command line\r
+    **/\r
+    public static void main(String argv[]) throws EntityException {\r
+        PlatformPcdPreprocessActionForBuilding ca = new PlatformPcdPreprocessActionForBuilding();\r
+        String projectDir = "x:/edk2";\r
+        ca.setWorkspacePath(projectDir);\r
+        ca.setFPDFilePath(projectDir + "/EdkNt32Pkg/Nt32.fpd");\r
+        ca.setActionMessageLevel(ActionMessage.MAX_MESSAGE_LEVEL);\r
+        GlobalData.initInfo("Tools" + File.separator + "Conf" + File.separator + "FrameworkDatabase.db",\r
+                            projectDir,\r
+                            "tools_def.txt");\r
+        System.out.println("After initInfo!");\r
+        FpdParserTask fpt = new FpdParserTask();\r
+        fpt.parseFpdFile(new File(projectDir + "/EdkNt32Pkg/Nt32.fpd"));\r
+        ca.execute();\r
+    }\r
+}\r