In preprocess for getting platform PCD information, if meet error, put error into...
[mirror_edk2.git] / Tools / Source / PcdTools / org / tianocore / pcd / entity / MemoryDatabaseManager.java
CommitLineData
878ddf1f 1/** @file\r
2 MemoryDatabaseManager class.\r
3\r
4 Database hold all PCD information comes from SPD, MSA, FPD file in memory.\r
bc262841 5\r
878ddf1f 6Copyright (c) 2006, Intel Corporation\r
7All rights reserved. This program and the accompanying materials\r
8are licensed and made available under the terms and conditions of the BSD License\r
9which accompanies this distribution. The full text of the license may be found at\r
10http://opensource.org/licenses/bsd-license.php\r
bc262841 11\r
878ddf1f 12THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
13WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
14\r
15**/\r
d14ebb43 16package org.tianocore.pcd.entity;\r
878ddf1f 17\r
878ddf1f 18import java.util.ArrayList;\r
19import java.util.HashMap;\r
20import java.util.List;\r
21import java.util.Map;\r
22\r
d14ebb43 23import org.tianocore.pcd.entity.UsageIdentification;\r
24import org.tianocore.pcd.exception.EntityException;\r
878ddf1f 25\r
bc262841 26/**\r
27 Database hold all PCD information comes from SPD, MSA, FPD file in memory.\r
878ddf1f 28**/\r
29public class MemoryDatabaseManager {\r
30 ///\r
31 /// Memory database. The string "cName + SpaceNameGuid" is primary key.\r
32 /// memory database is in global scope, and it will be used for others PCD tools.\r
33 ///\r
8840ad58 34 private static Map<String, Token> memoryDatabase = null;\r
35\r
878ddf1f 36 ///\r
8840ad58 37 /// Before build a module, the used libary will be build firstly, the PCD of these\r
f28c0830 38 /// library is inheritted by the module, so stored module's PCD information as PCD\r
8840ad58 39 /// context of building libary.\r
bc262841 40 ///\r
8840ad58 41 public static List<UsageInstance> UsageInstanceContext = null;\r
eece174a 42\r
878ddf1f 43 ///\r
eece174a 44 /// Current module name, if now is buiding library, this value indicate this library\r
45 /// is for building what module.\r
bc262841 46 ///\r
8840ad58 47 public static String CurrentModuleName = null;\r
eece174a 48\r
49 ///\r
50 /// String for PCD PEIM and DXE autogen file\r
bc262841 51 ///\r
eece174a 52 public static String PcdPeimHString = "";\r
53 public static String PcdPeimCString = "";\r
54 public static String PcdDxeHString = "";\r
55 public static String PcdDxeCString = "";\r
99d2c3c4 56\r
878ddf1f 57 /**\r
58 Constructure function\r
59 **/\r
60 public MemoryDatabaseManager() {\r
61 //\r
62 // Allocate memory for new database in global scope.\r
63 //\r
64 if (memoryDatabase == null) {\r
65 memoryDatabase = new HashMap<String, Token>();\r
66 }\r
67 }\r
68\r
878ddf1f 69 /**\r
70 Judege whether token exists in memory database\r
bc262841 71\r
878ddf1f 72 @param primaryKey the primaryKey for searching token\r
bc262841 73\r
878ddf1f 74 @retval TRUE - token already exist in database.\r
75 @retval FALSE - token does not exist in database.\r
76 **/\r
77 public boolean isTokenInDatabase(String primaryKey) {\r
78 return (memoryDatabase.get(primaryKey) != null);\r
79 }\r
80\r
81 /**\r
82 Add a pcd token into memory database.\r
bc262841 83\r
878ddf1f 84 @param primaryKey the primary key for searching token\r
85 @param token token instance\r
86 **/\r
87 public void addTokenToDatabase(String primaryKey, Token token) {\r
88 memoryDatabase.put(primaryKey, token);\r
89 }\r
90\r
91 /**\r
92 Get a token instance from memory database with primary key.\r
bc262841 93\r
878ddf1f 94 @param primaryKey the primary key for searching token\r
bc262841 95\r
878ddf1f 96 @return token instance.\r
97 **/\r
98 public Token getTokenByKey(String primaryKey) {\r
99 return memoryDatabase.get(primaryKey);\r
100 }\r
101\r
102 /**\r
103 Get the number of PCD token record in memory database.\r
bc262841 104\r
878ddf1f 105 @return the number of PCD token record in memory database.\r
106 **/\r
107 public int getDBSize() {\r
108 return memoryDatabase.size();\r
109 }\r
110\r
111 /**\r
112 Get the token record array contained all PCD token in memory database.\r
bc262841 113\r
878ddf1f 114 @return the token record array contained all PCD token in memory database.\r
115 **/\r
116 public Token[] getRecordArray() {\r
117 Token[] tokenArray = null;\r
118 Object[] dataArray = null;\r
119 Map.Entry entry = null;\r
120 int index = 0;\r
f28c0830 121 int size = 0;\r
878ddf1f 122\r
123 if (memoryDatabase == null) {\r
124 return null;\r
125 }\r
878ddf1f 126 dataArray = memoryDatabase.entrySet().toArray();\r
f28c0830 127 size = memoryDatabase.size();\r
878ddf1f 128 tokenArray = new Token[memoryDatabase.size()];\r
f28c0830 129 for (index = 0; index < size; index++) {\r
878ddf1f 130 entry =(Map.Entry) dataArray [index];\r
131 tokenArray[index] =(Token) entry.getValue();\r
132 }\r
878ddf1f 133 return tokenArray;\r
134 }\r
135\r
8840ad58 136 /**\r
137 Get record array only contains DYNAMIC or DYNAMIC_EX type PCD.\r
bc262841 138\r
f28c0830 139 @return ArrayList the array list contains all dynamic type PCD.\r
140 **/\r
8840ad58 141 private ArrayList getDynamicRecordArray() {\r
99d2c3c4 142 Token[] tokenArray = getRecordArray();\r
143 int index = 0;\r
6a4cae58 144 ArrayList<Token> al = new ArrayList<Token>();\r
99d2c3c4 145\r
146 for (index = 0; index < tokenArray.length; index++) {\r
6ff7a41c 147 if (tokenArray[index].isDynamicPCD) {\r
99d2c3c4 148 al.add(tokenArray[index]);\r
149 }\r
150 }\r
151\r
152 return al;\r
153 }\r
154\r
155\r
878ddf1f 156 /**\r
99d2c3c4 157 Get the token record array contained all PCD token referenced by PEI phase.\r
bc262841 158 The output array is sorted based on descending order of the size of alignment for each feilds.\r
99d2c3c4 159\r
160 @return the token record array contained all PCD token referenced in PEI phase.\r
eece174a 161 @throws EntityException\r
99d2c3c4 162 **/\r
bc262841 163 public void getTwoPhaseDynamicRecordArray(ArrayList<Token> pei, ArrayList<Token> dxe)\r
58f1099f 164 throws EntityException {\r
99d2c3c4 165 int usageInstanceIndex = 0;\r
166 int index = 0;\r
8840ad58 167 ArrayList tokenArrayList = getDynamicRecordArray();\r
168 Object[] usageInstanceArray = null;\r
99d2c3c4 169 UsageInstance usageInstance = null;\r
f28c0830 170 int size = 0;\r
171 int consumerSize = 0;\r
99d2c3c4 172\r
f28c0830 173 size = tokenArrayList.size();\r
174 for (index = 0; index < size; index++) {\r
99d2c3c4 175 boolean found = false;\r
176 Token token = (Token) tokenArrayList.get(index);\r
8840ad58 177 if (token.consumers != null) {\r
178 usageInstanceArray = token.consumers.entrySet().toArray();\r
f28c0830 179 consumerSize = token.consumers.size();\r
180 for (usageInstanceIndex = 0; usageInstanceIndex < consumerSize; usageInstanceIndex++) {\r
8840ad58 181 usageInstance =(UsageInstance) (((Map.Entry)usageInstanceArray[usageInstanceIndex]).getValue());\r
182 if (usageInstance.isPeiPhaseComponent()) {\r
99d2c3c4 183 pei.add(token);\r
184 found = true;\r
185 break;\r
186 }\r
187 }\r
99d2c3c4 188 }\r
189\r
58f1099f 190 //\r
bc262841 191 // If no PEI components reference the PCD entry,\r
192 // we check if it is referenced in DXE driver.\r
32648c62 193 //\r
194 if (!found) {\r
58f1099f 195 if (token.consumers != null) {\r
196 usageInstanceArray = token.consumers.entrySet().toArray();\r
f28c0830 197 consumerSize = token.consumers.size();\r
198 for (usageInstanceIndex = 0; usageInstanceIndex < consumerSize; usageInstanceIndex++) {\r
58f1099f 199 usageInstance =(UsageInstance) (((Map.Entry)usageInstanceArray[usageInstanceIndex]).getValue());\r
200 if (usageInstance.isDxePhaseComponent()) {\r
201 dxe.add(token);\r
202 found = true;\r
203 break;\r
204 }\r
205 }\r
206 }\r
bc262841 207\r
58f1099f 208 if (!found) {\r
8d82d611 209 if (token.isDynamicPCD && token.consumers.size() == 0) {\r
210 dxe.add(token);\r
211 } else {\r
212 //\r
213 // We only support Dynamice(EX) type for PEI and DXE phase.\r
214 // If it is not referenced in either PEI or DXE, throw exception now.\r
215 //\r
eece174a 216 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
8d82d611 217 }\r
58f1099f 218 }\r
32648c62 219 }\r
99d2c3c4 220 }\r
99d2c3c4 221 }\r
222\r
32648c62 223 /**\r
8840ad58 224 Get all PCD record for a module according to module's name, module's GUID,\r
225 package name, package GUID, arch, version information.\r
bc262841 226\r
d14ebb43 227 @param usageId the id of UsageInstance.\r
bc262841 228\r
878ddf1f 229 @return all usage instance for this module in memory database.\r
230 **/\r
d14ebb43 231 public List<UsageInstance> getUsageInstanceArrayByModuleName(UsageIdentification usageId) {\r
eece174a 232\r
d14ebb43 233 String primaryKey = UsageInstance.getPrimaryKey(usageId);\r
8840ad58 234\r
235 return getUsageInstanceArrayByKeyString(primaryKey);\r
236 }\r
237\r
e55d8a3c 238 public void clearDatabase() {\r
239 memoryDatabase.clear();\r
240 }\r
241\r
8840ad58 242 /**\r
243 Get all PCD token for a usage instance according to primary key.\r
bc262841 244\r
8840ad58 245 @param primaryKey the primary key of usage instance.\r
bc262841 246\r
f28c0830 247 @return List<UsageInstance> the list contains all usage instances.\r
248 **/\r
8840ad58 249 public List<UsageInstance> getUsageInstanceArrayByKeyString(String primaryKey) {\r
878ddf1f 250 Token[] tokenArray = null;\r
bc262841 251 int recordIndex = 0;\r
878ddf1f 252 UsageInstance usageInstance = null;\r
253 List<UsageInstance> returnArray = new ArrayList<UsageInstance>();\r
254\r
255 tokenArray = getRecordArray();\r
256\r
257 //\r
258 // Loop to find all PCD record related to current module\r
259 //\r
f28c0830 260 for (recordIndex = 0; recordIndex < getDBSize(); recordIndex++) {\r
8840ad58 261 if (tokenArray[recordIndex].consumers.size() != 0) {\r
262 usageInstance = tokenArray[recordIndex].consumers.get(primaryKey);\r
263 if (usageInstance != null) {\r
264 returnArray.add(usageInstance);\r
878ddf1f 265 }\r
266 }\r
267 }\r
268\r
878ddf1f 269 return returnArray;\r
270 }\r
271\r
272 /**\r
273 Get all modules name who contains PCD information\r
bc262841 274\r
878ddf1f 275 @return Array for module name\r
276 **/\r
277 public List<String> getAllModuleArray()\r
278 {\r
f28c0830 279 int tokenIndex = 0;\r
878ddf1f 280 int usageIndex = 0;\r
281 int moduleIndex = 0;\r
282 Token[] tokenArray = null;\r
8840ad58 283 Object[] usageInstanceArray = null;\r
878ddf1f 284 List<String> moduleNames = new ArrayList<String>();\r
285 UsageInstance usageInstance = null;\r
286 boolean bFound = false;\r
f28c0830 287 String primaryKey = null;\r
878ddf1f 288\r
8840ad58 289 tokenArray = getRecordArray();\r
878ddf1f 290 //\r
291 // Find all consumer usage instance for retrieving module's name\r
292 //\r
f28c0830 293 for (tokenIndex = 0; tokenIndex < getDBSize(); tokenIndex++) {\r
294 usageInstanceArray = tokenArray[tokenIndex].consumers.entrySet().toArray();\r
295 for (usageIndex = 0; usageIndex < tokenArray[tokenIndex].consumers.size(); usageIndex++) {\r
8840ad58 296 usageInstance = (UsageInstance)((Map.Entry)usageInstanceArray[usageIndex]).getValue();\r
f28c0830 297 primaryKey = usageInstance.getPrimaryKey();\r
878ddf1f 298 bFound = false;\r
f28c0830 299 for (moduleIndex = 0; moduleIndex < moduleNames.size(); moduleIndex++) {\r
300 if (moduleNames.get(moduleIndex).equalsIgnoreCase(primaryKey)) {\r
878ddf1f 301 bFound = true;\r
302 break;\r
303 }\r
304 }\r
305 if (!bFound) {\r
f28c0830 306 moduleNames.add(primaryKey);\r
878ddf1f 307 }\r
308 }\r
309 }\r
310 return moduleNames;\r
311 }\r
878ddf1f 312}\r