--- /dev/null
+/** @file\r
+ MemoryDatabaseManager class.\r
+\r
+ Database hold all PCD information comes from SPD, MSA, FPD file in memory.\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.pcd.entity;\r
+\r
+import java.util.ArrayList;\r
+import java.util.HashMap;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.UUID;\r
+\r
+import org.tianocore.pcd.entity.UsageIdentification;\r
+import org.tianocore.pcd.exception.EntityException;\r
+\r
+/** Database hold all PCD information comes from SPD, MSA, FPD file in memory.\r
+**/\r
+public class MemoryDatabaseManager {\r
+ ///\r
+ /// Memory database. The string "cName + SpaceNameGuid" is primary key.\r
+ /// memory database is in global scope, and it will be used for others PCD tools.\r
+ ///\r
+ private static Map<String, Token> memoryDatabase = null;\r
+\r
+ ///\r
+ /// Before build a module, the used libary will be build firstly, the PCD of these\r
+ /// libarry is inheritted by the module, so stored module's PCD information as PCD\r
+ /// context of building libary.\r
+ /// \r
+ public static List<UsageInstance> UsageInstanceContext = null;\r
+\r
+ ///\r
+ /// Current module name, if now is buiding library, this value indicate this library\r
+ /// is for building what module.\r
+ /// \r
+ public static String CurrentModuleName = null;\r
+\r
+ ///\r
+ /// String for PCD PEIM and DXE autogen file\r
+ /// \r
+ public static String PcdPeimHString = "";\r
+ public static String PcdPeimCString = "";\r
+ public static String PcdDxeHString = "";\r
+ public static String PcdDxeCString = "";\r
+\r
+ /**\r
+ Constructure function\r
+ **/\r
+ public MemoryDatabaseManager() {\r
+ //\r
+ // Allocate memory for new database in global scope.\r
+ //\r
+ if (memoryDatabase == null) {\r
+ memoryDatabase = new HashMap<String, Token>();\r
+ }\r
+ }\r
+\r
+ /**\r
+ Judege whether token exists in memory database\r
+ \r
+ @param primaryKey the primaryKey for searching token\r
+ \r
+ @retval TRUE - token already exist in database.\r
+ @retval FALSE - token does not exist in database.\r
+ **/\r
+ public boolean isTokenInDatabase(String primaryKey) {\r
+ return (memoryDatabase.get(primaryKey) != null);\r
+ }\r
+\r
+ /**\r
+ Add a pcd token into memory database.\r
+ \r
+ @param primaryKey the primary key for searching token\r
+ @param token token instance\r
+ **/\r
+ public void addTokenToDatabase(String primaryKey, Token token) {\r
+ memoryDatabase.put(primaryKey, token);\r
+ }\r
+\r
+ /**\r
+ Get a token instance from memory database with primary key.\r
+ \r
+ @param primaryKey the primary key for searching token\r
+ \r
+ @return token instance.\r
+ **/\r
+ public Token getTokenByKey(String primaryKey) {\r
+ return memoryDatabase.get(primaryKey);\r
+ }\r
+\r
+ /**\r
+ Get the number of PCD token record in memory database.\r
+ \r
+ @return the number of PCD token record in memory database.\r
+ **/\r
+ public int getDBSize() {\r
+ return memoryDatabase.size();\r
+ }\r
+\r
+ /**\r
+ Get the token record array contained all PCD token in memory database.\r
+ \r
+ @return the token record array contained all PCD token in memory database.\r
+ **/\r
+ public Token[] getRecordArray() {\r
+ Token[] tokenArray = null;\r
+ Object[] dataArray = null;\r
+ Map.Entry entry = null;\r
+ int index = 0;\r
+\r
+ if (memoryDatabase == null) {\r
+ return null;\r
+ }\r
+\r
+ dataArray = memoryDatabase.entrySet().toArray();\r
+ tokenArray = new Token[memoryDatabase.size()];\r
+ for (index = 0; index < memoryDatabase.size(); index ++) {\r
+ entry =(Map.Entry) dataArray [index];\r
+ tokenArray[index] =(Token) entry.getValue();\r
+ }\r
+\r
+ return tokenArray;\r
+ }\r
+\r
+ /**\r
+ Get record array only contains DYNAMIC or DYNAMIC_EX type PCD.\r
+ \r
+ @return ArrayList\r
+ */\r
+ private ArrayList getDynamicRecordArray() {\r
+ Token[] tokenArray = getRecordArray();\r
+ int index = 0;\r
+ ArrayList<Token> al = new ArrayList<Token>();\r
+\r
+ for (index = 0; index < tokenArray.length; index++) {\r
+ if (tokenArray[index].isDynamicPCD) {\r
+ al.add(tokenArray[index]);\r
+ }\r
+ }\r
+\r
+ return al;\r
+ }\r
+\r
+\r
+ /**\r
+ Get the token record array contained all PCD token referenced by PEI phase.\r
+ The output array is sorted based on descending order of the size of alignment for each feilds.\r
+\r
+ @return the token record array contained all PCD token referenced in PEI phase.\r
+ @throws EntityException\r
+ **/\r
+ public void getTwoPhaseDynamicRecordArray(ArrayList<Token> pei, ArrayList<Token> dxe) \r
+ throws EntityException {\r
+ int usageInstanceIndex = 0;\r
+ int index = 0;\r
+ ArrayList tokenArrayList = getDynamicRecordArray();\r
+ Object[] usageInstanceArray = null;\r
+ UsageInstance usageInstance = null;\r
+\r
+ //pei = new ArrayList<Token>();\r
+ //dxe = new ArrayList<Token>();\r
+\r
+ for (index = 0; index < tokenArrayList.size(); index++) {\r
+ boolean found = false;\r
+ Token token = (Token) tokenArrayList.get(index);\r
+ if (token.consumers != null) {\r
+ usageInstanceArray = token.consumers.entrySet().toArray();\r
+ for (usageInstanceIndex = 0; usageInstanceIndex < token.consumers.size(); usageInstanceIndex ++) {\r
+ usageInstance =(UsageInstance) (((Map.Entry)usageInstanceArray[usageInstanceIndex]).getValue());\r
+ if (usageInstance.isPeiPhaseComponent()) {\r
+ pei.add(token);\r
+ found = true;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+\r
+ //\r
+ // If no PEI components reference the PCD entry, \r
+ // we check if it is referenced in DXE driver. \r
+ //\r
+ if (!found) {\r
+ if (token.consumers != null) {\r
+ usageInstanceArray = token.consumers.entrySet().toArray();\r
+ for (usageInstanceIndex = 0; usageInstanceIndex < token.consumers.size(); usageInstanceIndex ++) {\r
+ usageInstance =(UsageInstance) (((Map.Entry)usageInstanceArray[usageInstanceIndex]).getValue());\r
+ if (usageInstance.isDxePhaseComponent()) {\r
+ dxe.add(token);\r
+ found = true;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ \r
+ if (!found) {\r
+ if (token.isDynamicPCD && token.consumers.size() == 0) {\r
+ dxe.add(token);\r
+ } else {\r
+ //\r
+ // We only support Dynamice(EX) type for PEI and DXE phase.\r
+ // If it is not referenced in either PEI or DXE, throw exception now.\r
+ //\r
+ throw new EntityException("[PCD tool Internal Error] Dynamic(EX) PCD Entries are referenced in module that is not in PEI phase nor in DXE phase.");\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ return;\r
+ }\r
+\r
+ /**\r
+ Get all PCD record for a module according to module's name, module's GUID,\r
+ package name, package GUID, arch, version information.\r
+ \r
+ @param usageId the id of UsageInstance.\r
+ \r
+ @return all usage instance for this module in memory database.\r
+ **/\r
+ public List<UsageInstance> getUsageInstanceArrayByModuleName(UsageIdentification usageId) {\r
+\r
+ String primaryKey = UsageInstance.getPrimaryKey(usageId);\r
+\r
+ return getUsageInstanceArrayByKeyString(primaryKey);\r
+ }\r
+\r
+ /**\r
+ Get all PCD token for a usage instance according to primary key.\r
+ \r
+ @param primaryKey the primary key of usage instance.\r
+ \r
+ @return List<UsageInstance>\r
+ */\r
+ public List<UsageInstance> getUsageInstanceArrayByKeyString(String primaryKey) {\r
+ Token[] tokenArray = null;\r
+ int recordIndex = 0; \r
+ UsageInstance usageInstance = null;\r
+ List<UsageInstance> returnArray = new ArrayList<UsageInstance>();\r
+\r
+ tokenArray = getRecordArray();\r
+\r
+ //\r
+ // Loop to find all PCD record related to current module\r
+ //\r
+ for (recordIndex = 0; recordIndex < getDBSize(); recordIndex ++) {\r
+ if (tokenArray[recordIndex].consumers.size() != 0) {\r
+ usageInstance = tokenArray[recordIndex].consumers.get(primaryKey);\r
+ if (usageInstance != null) {\r
+ returnArray.add(usageInstance);\r
+ }\r
+ }\r
+ }\r
+\r
+ return returnArray;\r
+ }\r
+\r
+ /**\r
+ Get all modules name who contains PCD information\r
+ \r
+ @return Array for module name\r
+ **/\r
+ public List<String> getAllModuleArray()\r
+ {\r
+ int indexToken = 0;\r
+ int usageIndex = 0;\r
+ int moduleIndex = 0;\r
+ Token[] tokenArray = null;\r
+ Object[] usageInstanceArray = null;\r
+ List<String> moduleNames = new ArrayList<String>();\r
+ UsageInstance usageInstance = null;\r
+ boolean bFound = false;\r
+\r
+ tokenArray = getRecordArray();\r
+ //\r
+ // Find all consumer usage instance for retrieving module's name\r
+ //\r
+ for (indexToken = 0; indexToken < getDBSize(); indexToken ++) {\r
+ usageInstanceArray = tokenArray[indexToken].consumers.entrySet().toArray();\r
+ for (usageIndex = 0; usageIndex < tokenArray[indexToken].consumers.size(); usageIndex ++) {\r
+ usageInstance = (UsageInstance)((Map.Entry)usageInstanceArray[usageIndex]).getValue();\r
+ bFound = false;\r
+ for (moduleIndex = 0; moduleIndex < moduleNames.size(); moduleIndex ++) {\r
+ if (moduleNames.get(moduleIndex).equalsIgnoreCase(usageInstance.getPrimaryKey())) {\r
+ bFound = true;\r
+ break;\r
+ }\r
+ }\r
+ if (!bFound) {\r
+ moduleNames.add(usageInstance.getPrimaryKey());\r
+ }\r
+ }\r
+ }\r
+ return moduleNames;\r
+ }\r
+}\r