PCD tools update:
[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 import java.util.UUID;
30
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 ///
43 /// Before build a module, the used libary will be build firstly, the PCD of these
44 /// libarry is inheritted by the module, so stored module's PCD information as PCD
45 /// context of building libary.
46 ///
47 public static List<UsageInstance> UsageInstanceContext = null;
48 ///
49 ///
50 ///
51 public static String CurrentModuleName = null;
52 public static String PcdPeimHString = "";
53 public static String PcdPeimCString = "";
54 public static String PcdDxeHString = "";
55 public static String PcdDxeCString = "";
56
57 /**
58 Constructure function
59 **/
60 public MemoryDatabaseManager() {
61 //
62 // Allocate memory for new database in global scope.
63 //
64 if (memoryDatabase == null) {
65 memoryDatabase = new HashMap<String, Token>();
66 }
67 }
68
69 /**
70 Judege whether token exists in memory database
71
72 @param primaryKey the primaryKey for searching token
73
74 @retval TRUE - token already exist in database.
75 @retval FALSE - token does not exist in database.
76 **/
77 public boolean isTokenInDatabase(String primaryKey) {
78 return (memoryDatabase.get(primaryKey) != null);
79 }
80
81 /**
82 Add a pcd token into memory database.
83
84 @param primaryKey the primary key for searching token
85 @param token token instance
86 **/
87 public void addTokenToDatabase(String primaryKey, Token token) {
88 memoryDatabase.put(primaryKey, token);
89 }
90
91 /**
92 Get a token instance from memory database with primary key.
93
94 @param primaryKey the primary key for searching token
95
96 @return token instance.
97 **/
98 public Token getTokenByKey(String primaryKey) {
99 return memoryDatabase.get(primaryKey);
100 }
101
102 /**
103 Get the number of PCD token record in memory database.
104
105 @return the number of PCD token record in memory database.
106 **/
107 public int getDBSize() {
108 return memoryDatabase.size();
109 }
110
111 /**
112 Get the token record array contained all PCD token in memory database.
113
114 @return the token record array contained all PCD token in memory database.
115 **/
116 public Token[] getRecordArray() {
117 Token[] tokenArray = null;
118 Object[] dataArray = null;
119 Map.Entry entry = null;
120 int index = 0;
121
122 if (memoryDatabase == null) {
123 return null;
124 }
125
126 dataArray = memoryDatabase.entrySet().toArray();
127 tokenArray = new Token[memoryDatabase.size()];
128 for (index = 0; index < memoryDatabase.size(); index ++) {
129 entry =(Map.Entry) dataArray [index];
130 tokenArray[index] =(Token) entry.getValue();
131 }
132
133 return tokenArray;
134 }
135
136 /**
137 Get record array only contains DYNAMIC or DYNAMIC_EX type PCD.
138
139 @return ArrayList
140 */
141 private ArrayList getDynamicRecordArray() {
142 Token[] tokenArray = getRecordArray();
143 int index = 0;
144 int count = 0;
145 ArrayList<Token> al = new ArrayList<Token>();
146
147 for (index = 0; index < tokenArray.length; index++) {
148 if (tokenArray[index].pcdType == Token.PCD_TYPE.DYNAMIC ||
149 tokenArray[index].pcdType == Token.PCD_TYPE.DYNAMIC_EX) {
150 al.add(tokenArray[index]);
151 }
152 }
153
154 return al;
155 }
156
157
158 /**
159 Get the token record array contained all PCD token referenced by PEI phase.
160 The output array is sorted based on descending order of the size of alignment for each feilds.
161
162 @return the token record array contained all PCD token referenced in PEI phase.
163 **/
164 public void getTwoPhaseDynamicRecordArray(ArrayList<Token> pei, ArrayList<Token> dxe) {
165 int usageInstanceIndex = 0;
166 int index = 0;
167 ArrayList tokenArrayList = getDynamicRecordArray();
168 Object[] usageInstanceArray = null;
169 UsageInstance usageInstance = null;
170
171 //pei = new ArrayList<Token>();
172 //dxe = new ArrayList<Token>();
173
174 for (index = 0; index < tokenArrayList.size(); index++) {
175 boolean found = false;
176 Token token = (Token) tokenArrayList.get(index);
177 if (token.consumers != null) {
178 usageInstanceArray = token.consumers.entrySet().toArray();
179 for (usageInstanceIndex = 0; usageInstanceIndex < token.consumers.size(); usageInstanceIndex ++) {
180 usageInstance =(UsageInstance) (((Map.Entry)usageInstanceArray[usageInstanceIndex]).getValue());
181 if (usageInstance.isPeiPhaseComponent()) {
182 pei.add(token);
183 found = true;
184 break;
185 }
186 }
187 }
188
189 // If no PEI components reference the PCD entry, we insert it to DXE list
190 //
191 if (!found) {
192 dxe.add(token);
193 }
194 }
195
196 return;
197 }
198
199 /**
200 Get all PCD record for a module according to module's name, module's GUID,
201 package name, package GUID, arch, version information.
202
203 @param moduleName the name of module.
204
205 @return all usage instance for this module in memory database.
206 **/
207 public List<UsageInstance> getUsageInstanceArrayByModuleName(String moduleName,
208 UUID moduleGuid,
209 String packageName,
210 UUID packageGuid,
211 String arch,
212 String version) {
213
214 String primaryKey = UsageInstance.getPrimaryKey(moduleName,
215 moduleGuid,
216 packageName,
217 packageGuid,
218 arch,
219 version);
220
221 return getUsageInstanceArrayByKeyString(primaryKey);
222 }
223
224 /**
225 Get all PCD token for a usage instance according to primary key.
226
227 @param primaryKey the primary key of usage instance.
228
229 @return List<UsageInstance>
230 */
231 public List<UsageInstance> getUsageInstanceArrayByKeyString(String primaryKey) {
232 Token[] tokenArray = null;
233 int recordIndex = 0;
234 UsageInstance usageInstance = null;
235 List<UsageInstance> returnArray = new ArrayList<UsageInstance>();
236
237 tokenArray = getRecordArray();
238
239 //
240 // Loop to find all PCD record related to current module
241 //
242 for (recordIndex = 0; recordIndex < getDBSize(); recordIndex ++) {
243 if (tokenArray[recordIndex].consumers.size() != 0) {
244 usageInstance = tokenArray[recordIndex].consumers.get(primaryKey);
245 if (usageInstance != null) {
246 returnArray.add(usageInstance);
247 }
248 }
249 }
250
251 return returnArray;
252 }
253
254 /**
255 Get all modules name who contains PCD information
256
257 @return Array for module name
258 **/
259 public List<String> getAllModuleArray()
260 {
261 int indexToken = 0;
262 int usageIndex = 0;
263 int moduleIndex = 0;
264 Token[] tokenArray = null;
265 Object[] usageInstanceArray = null;
266 List<String> moduleNames = new ArrayList<String>();
267 UsageInstance usageInstance = null;
268 boolean bFound = false;
269
270 tokenArray = getRecordArray();
271 //
272 // Find all consumer usage instance for retrieving module's name
273 //
274 for (indexToken = 0; indexToken < getDBSize(); indexToken ++) {
275 usageInstanceArray = tokenArray[indexToken].consumers.entrySet().toArray();
276 for (usageIndex = 0; usageIndex < tokenArray[indexToken].consumers.size(); usageIndex ++) {
277 usageInstance = (UsageInstance)((Map.Entry)usageInstanceArray[usageIndex]).getValue();
278 bFound = false;
279 for (moduleIndex = 0; moduleIndex < moduleNames.size(); moduleIndex ++) {
280 if (moduleNames.get(moduleIndex).equalsIgnoreCase(usageInstance.getPrimaryKey())) {
281 bFound = true;
282 break;
283 }
284 }
285 if (!bFound) {
286 moduleNames.add(usageInstance.getPrimaryKey());
287 }
288 }
289 }
290 return moduleNames;
291 }
292 }