0acdad094854759d46a737813068916c5a966725
[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 /** Database hold all PCD information comes from SPD, MSA, FPD file in memory.
34 **/
35 public class MemoryDatabaseManager {
36 ///
37 /// Memory database. The string "cName + SpaceNameGuid" is primary key.
38 /// memory database is in global scope, and it will be used for others PCD tools.
39 ///
40 private static Map<String, Token> memoryDatabase = null;
41 ///
42 /// The log file name for dumping memory database.
43 ///
44 private static String logFileName = null;
45
46 public static String PcdPeimHString = "";
47 public static String PcdPeimCString = "";
48 public static String PcdDxeHString = "";
49 public static String PcdDxeCString = "";
50
51 /**
52 Constructure function
53 **/
54 public MemoryDatabaseManager() {
55 //
56 // Allocate memory for new database in global scope.
57 //
58 if (memoryDatabase == null) {
59 memoryDatabase = new HashMap<String, Token>();
60 }
61 }
62
63 /**
64 Get the log file name.
65 **/
66 public String getLogFileName() {
67 return logFileName;
68 }
69
70 /**
71 Set parameter log file name.
72
73 @param fileName log file name parameter.
74 **/
75 public void setLogFileName(String fileName) {
76 logFileName = fileName;
77 }
78
79 /**
80 Judege whether token exists in memory database
81
82 @param primaryKey the primaryKey for searching token
83
84 @retval TRUE - token already exist in database.
85 @retval FALSE - token does not exist in database.
86 **/
87 public boolean isTokenInDatabase(String primaryKey) {
88 return (memoryDatabase.get(primaryKey) != null);
89 }
90
91 /**
92 Add a pcd token into memory database.
93
94 @param primaryKey the primary key for searching token
95 @param token token instance
96 **/
97 public void addTokenToDatabase(String primaryKey, Token token) {
98 memoryDatabase.put(primaryKey, token);
99 }
100
101 /**
102 Get a token instance from memory database with primary key.
103
104 @param primaryKey the primary key for searching token
105
106 @return token instance.
107 **/
108 public Token getTokenByKey(String primaryKey) {
109 return memoryDatabase.get(primaryKey);
110 }
111
112 /**
113 Get the number of PCD token record in memory database.
114
115 @return the number of PCD token record in memory database.
116 **/
117 public int getDBSize() {
118 return memoryDatabase.size();
119 }
120
121 /**
122 Get the token record array contained all PCD token in memory database.
123
124 @return the token record array contained all PCD token in memory database.
125 **/
126 public Token[] getRecordArray() {
127 Token[] tokenArray = null;
128 Object[] dataArray = null;
129 Map.Entry entry = null;
130 int index = 0;
131
132 if (memoryDatabase == null) {
133 return null;
134 }
135
136 dataArray = memoryDatabase.entrySet().toArray();
137 tokenArray = new Token[memoryDatabase.size()];
138 for (index = 0; index < memoryDatabase.size(); index ++) {
139 entry =(Map.Entry) dataArray [index];
140 tokenArray[index] =(Token) entry.getValue();
141 }
142
143 return tokenArray;
144 }
145
146
147 private ArrayList<Token> getDynamicRecordArray() {
148 Token[] tokenArray = getRecordArray();
149 int index = 0;
150 int count = 0;
151 ArrayList<Token> al = new ArrayList<Token>();
152
153 for (index = 0; index < tokenArray.length; index++) {
154 if (tokenArray[index].pcdType == Token.PCD_TYPE.DYNAMIC ||
155 tokenArray[index].pcdType == Token.PCD_TYPE.DYNAMIC_EX) {
156 al.add(tokenArray[index]);
157 }
158 }
159
160 return al;
161 }
162
163
164 /**
165 Get the token record array contained all PCD token referenced by PEI phase.
166 The output array is sorted based on descending order of the size of alignment for each feilds.
167
168 @return the token record array contained all PCD token referenced in PEI phase.
169 **/
170 public void getTwoPhaseDynamicRecordArray(ArrayList<Token> pei, ArrayList<Token> dxe) {
171 int usageInstanceIndex = 0;
172 int index = 0;
173 ArrayList<Token> tokenArrayList = getDynamicRecordArray();
174 List<UsageInstance> usageInstanceArray = null;
175 UsageInstance usageInstance = null;
176
177 for (index = 0; index < tokenArrayList.size(); index++) {
178 boolean found = false;
179 Token token = (Token) tokenArrayList.get(index);
180 if (token.producers != null) {
181 usageInstanceArray = token.producers;
182 for (usageInstanceIndex = 0; usageInstanceIndex < usageInstanceArray.size(); usageInstanceIndex++) {
183 usageInstance = (UsageInstance) usageInstanceArray.get(usageInstanceIndex);
184 if (CommonDefinition.isPeiPhaseComponent(usageInstance.componentType)) {
185 pei.add(token);
186 found = true;
187 break;
188 }
189 }
190
191 }
192 if (!found) {
193 if (token.consumers != null) {
194 usageInstanceArray = token.consumers;
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
206 //
207 // If no PEI components reference the PCD entry, we insert it to DXE list
208 //
209 if (!found) {
210 dxe.add(token);
211 }
212 }
213
214 return;
215 }
216
217 /**
218 Get all PCD record for a module according to module's name.
219
220 @param moduleName the name of module.
221
222 @return all usage instance for this module in memory database.
223 **/
224 public List<UsageInstance> getUsageInstanceArrayByModuleName(String moduleName) {
225 Token[] tokenArray = null;
226 int recordIndex = 0;
227 int usageInstanceIndex = 0;
228 List<UsageInstance> usageInstanceArray = null;
229 UsageInstance usageInstance = null;
230 List<UsageInstance> returnArray = new ArrayList<UsageInstance>();
231
232 tokenArray = getRecordArray();
233
234 //
235 // Loop to find all PCD record related to current module
236 //
237 for (recordIndex = 0; recordIndex < getDBSize(); recordIndex ++) {
238 if (tokenArray[recordIndex].producers != null) {
239 usageInstanceArray = tokenArray[recordIndex].producers;
240 for (usageInstanceIndex = 0; usageInstanceIndex < usageInstanceArray.size(); usageInstanceIndex ++) {
241 usageInstance =(UsageInstance) usageInstanceArray.get(usageInstanceIndex);
242 if (usageInstance.moduleName.equalsIgnoreCase(moduleName)) {
243 returnArray.add(usageInstance);
244 }
245 }
246 }
247
248 if (tokenArray[recordIndex].consumers != null) {
249 usageInstanceArray = tokenArray[recordIndex].consumers;
250 for (usageInstanceIndex = 0; usageInstanceIndex < usageInstanceArray.size(); usageInstanceIndex ++) {
251 usageInstance =(UsageInstance) usageInstanceArray.get(usageInstanceIndex);
252 if (usageInstance.moduleName.equalsIgnoreCase(moduleName)) {
253 returnArray.add(usageInstance);
254 }
255 }
256 }
257 }
258
259 if (returnArray.size() == 0) {
260 ActionMessage.warning(this, "Can *not* find any usage instance for " + moduleName + " !");
261 }
262
263 return returnArray;
264 }
265
266 /**
267 Get all modules name who contains PCD information
268
269 @return Array for module name
270 **/
271 public List<String> getAllModuleArray()
272 {
273 int indexToken = 0;
274 int usageIndex = 0;
275 int moduleIndex = 0;
276 Token[] tokenArray = null;
277 List<String> moduleNames = new ArrayList<String>();
278 UsageInstance usageInstance = null;
279 boolean bFound = false;
280
281 tokenArray = this.getRecordArray();
282 //
283 // Find all producer usage instance for retrieving module's name
284 //
285 for (indexToken = 0; indexToken < getDBSize(); indexToken ++) {
286 for (usageIndex = 0; usageIndex < tokenArray[indexToken].producers.size(); usageIndex ++) {
287 usageInstance = tokenArray[indexToken].producers.get(usageIndex);
288 bFound = false;
289 for (moduleIndex = 0; moduleIndex < moduleNames.size(); moduleIndex ++) {
290 if (moduleNames.get(moduleIndex).equalsIgnoreCase(usageInstance.moduleName)) {
291 bFound = true;
292 break;
293 }
294 }
295 if (!bFound) {
296 moduleNames.add(usageInstance.moduleName);
297 }
298 }
299 }
300
301 //
302 // Find all consumer usage instance for retrieving module's name
303 //
304 for (indexToken = 0; indexToken < getDBSize(); indexToken ++) {
305 for (usageIndex = 0; usageIndex < tokenArray[indexToken].consumers.size(); usageIndex ++) {
306 usageInstance = tokenArray[indexToken].consumers.get(usageIndex);
307 bFound = false;
308 for (moduleIndex = 0; moduleIndex < moduleNames.size(); moduleIndex ++) {
309 if (moduleNames.get(moduleIndex).equalsIgnoreCase(usageInstance.moduleName)) {
310 bFound = true;
311 break;
312 }
313 }
314 if (!bFound) {
315 moduleNames.add(usageInstance.moduleName);
316 }
317 }
318 }
319 return moduleNames;
320 }
321
322 /**
323 Dump all PCD record into file for reviewing.
324 **/
325 public void DumpAllRecords() {
326 BufferedWriter bWriter = null;
327 Object[] tokenArray = null;
328 Map.Entry entry = null;
329 Token token = null;
330 int index = 0;
331 int usageIndex = 0;
332 UsageInstance usageInstance = null;
333 String inheritString = null;
334 String componentTypeName = null;
335
336 try {
337 bWriter = new BufferedWriter(new FileWriter(new File(logFileName)));
338 tokenArray = memoryDatabase.entrySet().toArray();
339 for (index = 0; index < memoryDatabase.size(); index ++) {
340 entry =(Map.Entry) tokenArray [index];
341 token =(Token) entry.getValue();
342 bWriter.write("****** token [" + Integer.toString(index) + "] ******\r\n");
343 bWriter.write(" cName:" + token.cName + "\r\n");
344 for (usageIndex = 0; usageIndex < token.producers.size(); usageIndex ++) {
345 usageInstance =(UsageInstance)token.producers.get(usageIndex);
346 componentTypeName = CommonDefinition.getComponentTypeString(usageInstance.componentType);
347
348 if (usageInstance.isInherit) {
349 inheritString = "Inherit";
350 } else {
351 inheritString = "";
352 }
353 bWriter.write(String.format(" (Producer)#%d: %s:%s Package:%s %s\r\n",
354 usageIndex,
355 componentTypeName,
356 usageInstance.moduleName,
357 usageInstance.packageName,
358 inheritString
359 )
360 );
361 }
362 for (usageIndex = 0; usageIndex < token.consumers.size(); usageIndex ++) {
363 usageInstance =(UsageInstance)token.consumers.get(usageIndex);
364 componentTypeName = CommonDefinition.getComponentTypeString(usageInstance.componentType);
365 if (usageInstance.isInherit) {
366 inheritString = "Inherit";
367 } else {
368 inheritString = "";
369 }
370 bWriter.write(String.format(" (Consumer)#%d: %s:%s Package:%s %s\r\n",
371 usageIndex,
372 componentTypeName,
373 usageInstance.moduleName,
374 usageInstance.packageName,
375 inheritString
376 )
377 );
378 }
379 }
380 bWriter.close();
381 } catch (IOException exp) {
382 ActionMessage.warning(this, "Failed to open database log file: " + logFileName);
383 }
384 }
385 }