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