git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@250 6f19259b...
[mirror_edk2.git] / Tools / Source / GenBuild / org / tianocore / build / pcd / entity / MemoryDatabaseManager.java
1 /** @file
2 MemoryDatabaseManager class.
3
4 Database hold all PCD information comes from SPD, MSA, FPD file in memory.
5
6 Copyright (c) 2006, Intel Corporation
7 All rights reserved. This program and the accompanying materials
8 are licensed and made available under the terms and conditions of the BSD License
9 which accompanies this distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
11
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14
15 **/
16 package org.tianocore.build.pcd.entity;
17
18 import java.io.BufferedWriter;
19 import java.io.File;
20 import java.io.FileWriter;
21 import java.io.IOException;
22 import java.util.ArrayList;
23 import java.util.Collections;
24 import java.util.Comparator;
25 import java.util.HashMap;
26 import java.util.Hashtable;
27 import java.util.List;
28 import java.util.Map;
29
30 import org.tianocore.build.autogen.CommonDefinition;
31 import org.tianocore.build.pcd.action.ActionMessage;
32
33 class AlignmentSizeComp implements Comparator {
34 public int compare (Object a, Object b) {
35 Token tA = (Token) a;
36 Token tB = (Token) b;
37
38 return Token.getAutogendatumTypeAlignmentSize(tA.datumType)
39 - Token.getAutogendatumTypeAlignmentSize(tB.datumType);
40 }
41 }
42
43 /** Database hold all PCD information comes from SPD, MSA, FPD file in memory.
44 **/
45 public class MemoryDatabaseManager {
46 ///
47 /// Memory database. The string "cName + SpaceNameGuid" is primary key.
48 /// memory database is in global scope, and it will be used for others PCD tools.
49 ///
50 private static Map<String, Token> memoryDatabase = null;
51 ///
52 /// The log file name for dumping memory database.
53 ///
54 private static String logFileName = null;
55
56 public static String PcdPeimHString = "";
57 public static String PcdPeimCString = "";
58 public static String PcdDxeHString = "";
59 public static String PcdDxeCString = "";
60
61 /**
62 Constructure function
63 **/
64 public MemoryDatabaseManager() {
65 //
66 // Allocate memory for new database in global scope.
67 //
68 if (memoryDatabase == null) {
69 memoryDatabase = new HashMap<String, Token>();
70 }
71 }
72
73 /**
74 Get the log file name.
75 **/
76 public String getLogFileName() {
77 return logFileName;
78 }
79
80 /**
81 Set parameter log file name.
82
83 @param fileName log file name parameter.
84 **/
85 public void setLogFileName(String fileName) {
86 logFileName = fileName;
87 }
88
89 /**
90 Judege whether token exists in memory database
91
92 @param primaryKey the primaryKey for searching token
93
94 @retval TRUE - token already exist in database.
95 @retval FALSE - token does not exist in database.
96 **/
97 public boolean isTokenInDatabase(String primaryKey) {
98 return (memoryDatabase.get(primaryKey) != null);
99 }
100
101 /**
102 Add a pcd token into memory database.
103
104 @param primaryKey the primary key for searching token
105 @param token token instance
106 **/
107 public void addTokenToDatabase(String primaryKey, Token token) {
108 memoryDatabase.put(primaryKey, token);
109 }
110
111 /**
112 Get a token instance from memory database with primary key.
113
114 @param primaryKey the primary key for searching token
115
116 @return token instance.
117 **/
118 public Token getTokenByKey(String primaryKey) {
119 return memoryDatabase.get(primaryKey);
120 }
121
122 /**
123 Get the number of PCD token record in memory database.
124
125 @return the number of PCD token record in memory database.
126 **/
127 public int getDBSize() {
128 return memoryDatabase.size();
129 }
130
131 /**
132 Get the token record array contained all PCD token in memory database.
133
134 @return the token record array contained all PCD token in memory database.
135 **/
136 public Token[] getRecordArray() {
137 Token[] tokenArray = null;
138 Object[] dataArray = null;
139 Map.Entry entry = null;
140 int index = 0;
141
142 if (memoryDatabase == null) {
143 return null;
144 }
145
146 dataArray = memoryDatabase.entrySet().toArray();
147 tokenArray = new Token[memoryDatabase.size()];
148 for (index = 0; index < memoryDatabase.size(); index ++) {
149 entry =(Map.Entry) dataArray [index];
150 tokenArray[index] =(Token) entry.getValue();
151 }
152
153 return tokenArray;
154 }
155
156
157 private ArrayList getDynamicRecordArray() {
158 Token[] tokenArray = getRecordArray();
159 int index = 0;
160 int count = 0;
161 ArrayList al = new ArrayList();
162
163 for (index = 0; index < tokenArray.length; index++) {
164 if (tokenArray[index].pcdType == Token.PCD_TYPE.DYNAMIC ||
165 tokenArray[index].pcdType == Token.PCD_TYPE.DYNAMIC_EX) {
166 al.add(tokenArray[index]);
167 }
168 }
169
170 return al;
171 }
172
173
174 /**
175 Get the token record array contained all PCD token referenced by PEI phase.
176 The output array is sorted based on descending order of the size of alignment for each feilds.
177
178 @return the token record array contained all PCD token referenced in PEI phase.
179 **/
180 public void getTwoPhaseDynamicRecordArray(ArrayList<Token> pei, ArrayList<Token> dxe) {
181 int usageInstanceIndex = 0;
182 int index = 0;
183 ArrayList tokenArrayList = getDynamicRecordArray();
184 List<UsageInstance> usageInstanceArray = null;
185 UsageInstance usageInstance = null;
186
187 //pei = new ArrayList<Token>();
188 //dxe = new ArrayList<Token>();
189
190 for (index = 0; index < tokenArrayList.size(); index++) {
191 boolean found = false;
192 Token token = (Token) tokenArrayList.get(index);
193 if (token.producers != null) {
194 usageInstanceArray = token.producers;
195 for (usageInstanceIndex = 0; usageInstanceIndex < usageInstanceArray.size(); usageInstanceIndex++) {
196 usageInstance = (UsageInstance) usageInstanceArray.get(usageInstanceIndex);
197 if (CommonDefinition.isPeiPhaseComponent(usageInstance.componentType)) {
198 pei.add(token);
199 found = true;
200 break;
201 }
202 }
203
204 }
205 if (!found) {
206 if (token.consumers != null) {
207 usageInstanceArray = token.consumers;
208 for (usageInstanceIndex = 0; usageInstanceIndex < usageInstanceArray.size(); usageInstanceIndex ++) {
209 usageInstance =(UsageInstance) usageInstanceArray.get(usageInstanceIndex);
210 if (CommonDefinition.isPeiPhaseComponent(usageInstance.componentType)) {
211 pei.add(token);
212 found = true;
213 break;
214 }
215 }
216 }
217 }
218
219 //
220 // If no PEI components reference the PCD entry, we insert it to DXE list
221 //
222 if (!found) {
223 dxe.add(token);
224 }
225 }
226
227 return;
228 }
229
230 /**
231 Get all PCD record for a module according to module's name.
232
233 @param moduleName the name of module.
234
235 @return all usage instance for this module in memory database.
236 **/
237 public List<UsageInstance> getUsageInstanceArrayByModuleName(String moduleName) {
238 Token[] tokenArray = null;
239 int recordIndex = 0;
240 int usageInstanceIndex = 0;
241 List<UsageInstance> usageInstanceArray = null;
242 UsageInstance usageInstance = null;
243 List<UsageInstance> returnArray = new ArrayList<UsageInstance>();
244
245 tokenArray = getRecordArray();
246
247 //
248 // Loop to find all PCD record related to current module
249 //
250 for (recordIndex = 0; recordIndex < getDBSize(); recordIndex ++) {
251 if (tokenArray[recordIndex].producers != null) {
252 usageInstanceArray = tokenArray[recordIndex].producers;
253 for (usageInstanceIndex = 0; usageInstanceIndex < usageInstanceArray.size(); usageInstanceIndex ++) {
254 usageInstance =(UsageInstance) usageInstanceArray.get(usageInstanceIndex);
255 if (usageInstance.moduleName.equalsIgnoreCase(moduleName)) {
256 returnArray.add(usageInstance);
257 }
258 }
259 }
260
261 if (tokenArray[recordIndex].consumers != null) {
262 usageInstanceArray = tokenArray[recordIndex].consumers;
263 for (usageInstanceIndex = 0; usageInstanceIndex < usageInstanceArray.size(); usageInstanceIndex ++) {
264 usageInstance =(UsageInstance) usageInstanceArray.get(usageInstanceIndex);
265 if (usageInstance.moduleName.equalsIgnoreCase(moduleName)) {
266 returnArray.add(usageInstance);
267 }
268 }
269 }
270 }
271
272 if (returnArray.size() == 0) {
273 ActionMessage.warning(this, "Can *not* find any usage instance for " + moduleName + " !");
274 }
275
276 return returnArray;
277 }
278
279 /**
280 Get all modules name who contains PCD information
281
282 @return Array for module name
283 **/
284 public List<String> getAllModuleArray()
285 {
286 int indexToken = 0;
287 int usageIndex = 0;
288 int moduleIndex = 0;
289 Token[] tokenArray = null;
290 List<String> moduleNames = new ArrayList<String>();
291 UsageInstance usageInstance = null;
292 boolean bFound = false;
293
294 tokenArray = this.getRecordArray();
295 //
296 // Find all producer usage instance for retrieving module's name
297 //
298 for (indexToken = 0; indexToken < getDBSize(); indexToken ++) {
299 for (usageIndex = 0; usageIndex < tokenArray[indexToken].producers.size(); usageIndex ++) {
300 usageInstance = tokenArray[indexToken].producers.get(usageIndex);
301 bFound = false;
302 for (moduleIndex = 0; moduleIndex < moduleNames.size(); moduleIndex ++) {
303 if (moduleNames.get(moduleIndex).equalsIgnoreCase(usageInstance.moduleName)) {
304 bFound = true;
305 break;
306 }
307 }
308 if (!bFound) {
309 moduleNames.add(usageInstance.moduleName);
310 }
311 }
312 }
313
314 //
315 // Find all consumer usage instance for retrieving module's name
316 //
317 for (indexToken = 0; indexToken < getDBSize(); indexToken ++) {
318 for (usageIndex = 0; usageIndex < tokenArray[indexToken].consumers.size(); usageIndex ++) {
319 usageInstance = tokenArray[indexToken].consumers.get(usageIndex);
320 bFound = false;
321 for (moduleIndex = 0; moduleIndex < moduleNames.size(); moduleIndex ++) {
322 if (moduleNames.get(moduleIndex).equalsIgnoreCase(usageInstance.moduleName)) {
323 bFound = true;
324 break;
325 }
326 }
327 if (!bFound) {
328 moduleNames.add(usageInstance.moduleName);
329 }
330 }
331 }
332 return moduleNames;
333 }
334
335 /**
336 Dump all PCD record into file for reviewing.
337 **/
338 public void DumpAllRecords() {
339 BufferedWriter bWriter = null;
340 Object[] tokenArray = null;
341 Map.Entry entry = null;
342 Token token = null;
343 int index = 0;
344 int usageIndex = 0;
345 UsageInstance usageInstance = null;
346 String inheritString = null;
347 String componentTypeName = null;
348
349 try {
350 bWriter = new BufferedWriter(new FileWriter(new File(logFileName)));
351 tokenArray = memoryDatabase.entrySet().toArray();
352 for (index = 0; index < memoryDatabase.size(); index ++) {
353 entry =(Map.Entry) tokenArray [index];
354 token =(Token) entry.getValue();
355 bWriter.write("****** token [" + Integer.toString(index) + "] ******\r\n");
356 bWriter.write(" cName:" + token.cName + "\r\n");
357 for (usageIndex = 0; usageIndex < token.producers.size(); usageIndex ++) {
358 usageInstance =(UsageInstance)token.producers.get(usageIndex);
359 componentTypeName = CommonDefinition.getComponentTypeString(usageInstance.componentType);
360
361 if (usageInstance.isInherit) {
362 inheritString = "Inherit";
363 } else {
364 inheritString = "";
365 }
366 bWriter.write(String.format(" (Producer)#%d: %s:%s Package:%s %s\r\n",
367 usageIndex,
368 componentTypeName,
369 usageInstance.moduleName,
370 usageInstance.packageName,
371 inheritString
372 )
373 );
374 }
375 for (usageIndex = 0; usageIndex < token.consumers.size(); usageIndex ++) {
376 usageInstance =(UsageInstance)token.consumers.get(usageIndex);
377 componentTypeName = CommonDefinition.getComponentTypeString(usageInstance.componentType);
378 if (usageInstance.isInherit) {
379 inheritString = "Inherit";
380 } else {
381 inheritString = "";
382 }
383 bWriter.write(String.format(" (Consumer)#%d: %s:%s Package:%s %s\r\n",
384 usageIndex,
385 componentTypeName,
386 usageInstance.moduleName,
387 usageInstance.packageName,
388 inheritString
389 )
390 );
391 }
392 }
393 bWriter.close();
394 } catch (IOException exp) {
395 ActionMessage.warning(this, "Failed to open database log file: " + logFileName);
396 }
397 }
398 }