]> git.proxmox.com Git - mirror_edk2.git/blame - Tools/Source/PcdTools/org/tianocore/pcd/action/PlatformPcdPreprocessAction.java
Modify code according to Wang, jian's comments.
[mirror_edk2.git] / Tools / Source / PcdTools / org / tianocore / pcd / action / PlatformPcdPreprocessAction.java
CommitLineData
bc262841 1/** @file\r
2 PlatformPcdPreprocessAction class.\r
3\r
4 The abstract parent class PlatformPcdPreprocessAction, This class is to collect platform's\r
5 pcd build information from fpd file.\r
6 This class will be extended by building tools and wizard tools.\r
7\r
8Copyright (c) 2006, Intel Corporation\r
9All rights reserved. This program and the accompanying materials\r
10are licensed and made available under the terms and conditions of the BSD License\r
11which accompanies this distribution. The full text of the license may be found at\r
12http://opensource.org/licenses/bsd-license.php\r
13\r
14THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
15WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
16\r
17**/\r
18package org.tianocore.pcd.action;\r
19\r
20import java.util.ArrayList;\r
21import java.util.List;\r
22import java.util.UUID;\r
23import java.util.regex.Matcher;\r
24import java.util.regex.Pattern;\r
25\r
26import org.tianocore.DynamicPcdBuildDefinitionsDocument.DynamicPcdBuildDefinitions;\r
27import org.tianocore.PcdBuildDefinitionDocument.PcdBuildDefinition;\r
28import org.tianocore.pcd.entity.MemoryDatabaseManager;\r
29import org.tianocore.pcd.exception.EntityException;\r
30import org.tianocore.pcd.entity.*;\r
31import org.tianocore.pcd.entity.Token;\r
32\r
33/**\r
34 The abstract parent class PlatformPcdPreprocessAction, This class is to collect platform's\r
35 pcd build information from fpd file.\r
36 This class will be extended by building tools and wizard tools.\r
37\r
38**/\r
39public abstract class PlatformPcdPreprocessAction {\r
40 ///\r
41 /// PCD memory database\r
42 ///\r
43 private MemoryDatabaseManager pcdDbManager;\r
44\r
45 /**\r
46 Set parameter pcdDbManager\r
47\r
48 @param pcdDbManager\r
49 **/\r
50 public void setPcdDbManager(MemoryDatabaseManager pcdDbManager) {\r
51 this.pcdDbManager = pcdDbManager;\r
52 }\r
53\r
54 /**\r
55 Get parameter pcdDbManager\r
56 \r
57 @return MemoryDatabaseManager\r
58 **/\r
59 public MemoryDatabaseManager getPcdDbManager() {\r
60 return pcdDbManager;\r
61 }\r
62 /**\r
63 Abstract function: retrieve module information from FPD file.\r
64\r
65 In building environement, this function will be implementated by FpdParserTask.\r
66\r
67 @return List<ModuleInfoFromFpd>\r
68 **/\r
69 public abstract List<ModulePcdInfoFromFpd> getComponentsFromFpd()\r
70 throws EntityException;\r
71\r
72 /**\r
73 Abstract function to get GUID string from SPD file.\r
74\r
75 In building evnironment, this function will be implementated by GlobaData.\r
76\r
77 @param guidCName the CName of GUID\r
78\r
79 @return String[] Guid Info array contains CName and Guid String\r
80 **/\r
81 public abstract String[] getGuidInfoFromSpd(String guidCName)\r
82 throws EntityException;\r
83\r
84 /**\r
85 Abstract function: Verification the PCD data.\r
86\r
87 In different environment, such as building environment and wizard environment,\r
88 it has different implementation according to optimization.\r
89\r
90 @param cName\r
91 @param moduleName\r
92 @param datum\r
93 @param datumType\r
94 @param maxDatumSize\r
95\r
96 @return String\r
97 **/\r
98 public abstract String verifyDatum(String cName,\r
99 String moduleName,\r
100 String datum,\r
101 Token.DATUM_TYPE datumType,\r
102 int maxDatumSize);\r
103\r
104 /**\r
105 Abstract function: Get dynamic information for a token\r
106\r
107 @param token\r
108 @param moduleName\r
109\r
110 @return DynamicPcdBuildDefinitions.PcdBuildData\r
111 **/\r
112 public abstract DynamicPcdBuildDefinitions.PcdBuildData\r
113 getDynamicInfoFromFpd(Token token,\r
114 String moduleName)\r
115 throws EntityException;\r
116\r
117 /**\r
118 Abstract function: Get all dynamic PCD information from FPD file.\r
119\r
120 @return List<DynamicPcdBuildDefinitions.PcdBuildData>\r
121 **/\r
122 public abstract List<DynamicPcdBuildDefinitions.PcdBuildData>\r
123 getAllDynamicPcdInfoFromFpd()\r
124 throws EntityException;\r
125\r
126 /**\r
127 Collect all PCD information from FPD file into PCD memory database.\r
128\r
129 **/\r
130 public void initPcdMemoryDbWithPlatformInfo()\r
131 throws EntityException {\r
132 int index = 0;\r
133 int pcdIndex = 0;\r
134 List<PcdBuildDefinition.PcdData> pcdBuildDataArray = new ArrayList<PcdBuildDefinition.PcdData>();\r
135 PcdBuildDefinition.PcdData pcdBuildData = null;\r
136 Token token = null;\r
137 List<ModulePcdInfoFromFpd> modules = null;\r
138 String primaryKey = null;\r
139 String exceptionString = null;\r
140 UsageInstance usageInstance = null;\r
141 Token.PCD_TYPE pcdType = Token.PCD_TYPE.UNKNOWN;\r
142 Token.DATUM_TYPE datumType = Token.DATUM_TYPE.UNKNOWN;\r
143 long tokenNumber = 0;\r
144 String moduleName = null;\r
145 String datum = null;\r
146 int maxDatumSize = 0;\r
147 String[] tokenSpaceStrRet = null;\r
148\r
149 //\r
150 // ----------------------------------------------\r
151 // 1), Get all <ModuleSA> from FPD file.\r
152 // ----------------------------------------------\r
153 //\r
154 modules = getComponentsFromFpd();\r
155\r
156 if (modules == null) {\r
157 throw new EntityException("[FPD file error] No modules in FPD file, Please check whether there are elements in <FrameworkModules> in FPD file!");\r
158 }\r
159\r
160 //\r
161 // -------------------------------------------------------------------\r
162 // 2), Loop all modules to process <PcdBuildDeclarations> for each module.\r
163 // -------------------------------------------------------------------\r
164 //\r
f28c0830 165 for (index = 0; index < modules.size(); index++) {\r
bc262841 166 //\r
167 // It is legal for a module does not contains ANY pcd build definitions.\r
168 //\r
169 if (modules.get(index).pcdBuildDefinition == null) {\r
170 continue;\r
171 }\r
172\r
173 pcdBuildDataArray = modules.get(index).pcdBuildDefinition.getPcdDataList();\r
174\r
175 moduleName = modules.get(index).usageId.moduleName;\r
176\r
177 //\r
178 // ----------------------------------------------------------------------\r
179 // 2.1), Loop all Pcd entry for a module and add it into memory database.\r
180 // ----------------------------------------------------------------------\r
181 //\r
f28c0830 182 for (pcdIndex = 0; pcdIndex < pcdBuildDataArray.size(); pcdIndex++) {\r
bc262841 183 pcdBuildData = pcdBuildDataArray.get(pcdIndex);\r
184\r
185 tokenSpaceStrRet = getGuidInfoFromSpd(pcdBuildData.getTokenSpaceGuidCName());\r
186\r
187 if (tokenSpaceStrRet == null) {\r
188 throw new EntityException ("Fail to get Token space guid for token" + pcdBuildData.getCName());\r
189 }\r
190\r
191 primaryKey = Token.getPrimaryKeyString(pcdBuildData.getCName(), tokenSpaceStrRet[1]);\r
f28c0830 192 pcdType = Token.getPcdTypeFromString(pcdBuildData.getItemType().toString());\r
bc262841 193 datumType = Token.getdatumTypeFromString(pcdBuildData.getDatumType().toString());\r
194 tokenNumber = Long.decode(pcdBuildData.getToken().toString());\r
195 if (pcdBuildData.getValue() != null) {\r
196 datum = pcdBuildData.getValue().toString();\r
197 } else {\r
198 datum = null;\r
199 }\r
200 maxDatumSize = pcdBuildData.getMaxDatumSize();\r
201\r
202 if ((pcdType == Token.PCD_TYPE.FEATURE_FLAG) &&\r
203 (datumType != Token.DATUM_TYPE.BOOLEAN)){\r
204 exceptionString = String.format("[FPD file error] For PCD %s in module %s, the PCD type is FEATRUE_FLAG but "+\r
205 "datum type of this PCD entry is not BOOLEAN!",\r
206 pcdBuildData.getCName(),\r
207 moduleName);\r
208 throw new EntityException(exceptionString);\r
209 }\r
210\r
211 //\r
212 // -------------------------------------------------------------------------------------------\r
213 // 2.1.1), Do some necessary checking work for FixedAtBuild, FeatureFlag and PatchableInModule\r
214 // -------------------------------------------------------------------------------------------\r
215 //\r
216 if (!Token.isDynamic(pcdType)) {\r
217 //\r
218 // Value is required.\r
219 //\r
220 if (datum == null) {\r
221 exceptionString = String.format("[FPD file error] There is no value for PCD entry %s in module %s!",\r
222 pcdBuildData.getCName(),\r
223 moduleName);\r
224 throw new EntityException(exceptionString);\r
225 }\r
226\r
227 //\r
228 // Check whether the datum size is matched datum type.\r
229 //\r
230 if ((exceptionString = verifyDatum(pcdBuildData.getCName(),\r
231 moduleName,\r
232 datum,\r
233 datumType,\r
234 maxDatumSize)) != null) {\r
235 throw new EntityException(exceptionString);\r
236 }\r
237 }\r
238\r
239 //\r
240 // ---------------------------------------------------------------------------------\r
241 // 2.1.2), Create token or update token information for current anaylized PCD data.\r
242 // ---------------------------------------------------------------------------------\r
243 //\r
244 if (pcdDbManager.isTokenInDatabase(primaryKey)) {\r
245 //\r
246 // If the token is already exist in database, do some necessary checking\r
247 // and add a usage instance into this token in database\r
248 //\r
249 token = pcdDbManager.getTokenByKey(primaryKey);\r
250\r
251 //\r
252 // checking for DatumType, DatumType should be unique for one PCD used in different\r
253 // modules.\r
254 //\r
255 if (token.datumType != datumType) {\r
256 exceptionString = String.format("[FPD file error] The datum type of PCD entry %s is %s, which is different with %s defined in before!",\r
257 pcdBuildData.getCName(),\r
258 pcdBuildData.getDatumType().toString(),\r
259 Token.getStringOfdatumType(token.datumType));\r
260 throw new EntityException(exceptionString);\r
261 }\r
262\r
263 //\r
264 // Check token number is valid\r
265 //\r
266 if (tokenNumber != token.tokenNumber) {\r
267 exceptionString = String.format("[FPD file error] The token number of PCD entry %s in module %s is different with same PCD entry in other modules!",\r
268 pcdBuildData.getCName(),\r
269 moduleName);\r
270 throw new EntityException(exceptionString);\r
271 }\r
272\r
273 //\r
274 // For same PCD used in different modules, the PCD type should all be dynamic or non-dynamic.\r
275 //\r
276 if (token.isDynamicPCD != Token.isDynamic(pcdType)) {\r
277 exceptionString = String.format("[FPD file error] For PCD entry %s in module %s, you define dynamic or non-dynamic PCD type which"+\r
278 "is different with others module's",\r
279 token.cName,\r
280 moduleName);\r
281 throw new EntityException(exceptionString);\r
282 }\r
283\r
284 if (token.isDynamicPCD) {\r
285 //\r
286 // Check datum is equal the datum in dynamic information.\r
287 // For dynamic PCD, you can do not write <Value> in sperated every <PcdBuildDefinition> in different <ModuleSA>,\r
288 // But if you write, the <Value> must be same as the value in <DynamicPcdBuildDefinitions>.\r
289 //\r
290 if (!token.isSkuEnable() &&\r
291 (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.DEFAULT_TYPE) &&\r
292 (datum != null)) {\r
293 if (!datum.equalsIgnoreCase(token.getDefaultSku().value)) {\r
294 exceptionString = String.format("[FPD file error] For dynamic PCD %s in module %s, the datum in <ModuleSA> is "+\r
295 "not equal to the datum in <DynamicPcdBuildDefinitions>, it is "+\r
296 "illega! You could no set <Value> in <ModuleSA> for a dynamic PCD!",\r
297 token.cName,\r
298 moduleName);\r
299 throw new EntityException(exceptionString);\r
300 }\r
301 }\r
302\r
303 if ((maxDatumSize != 0) &&\r
304 (maxDatumSize != token.datumSize)){\r
305 exceptionString = String.format("[FPD file error] For dynamic PCD %s in module %s, the max datum size is %d which "+\r
306 "is different with <MaxDatumSize> %d defined in <DynamicPcdBuildDefinitions>!",\r
307 token.cName,\r
308 moduleName,\r
309 maxDatumSize,\r
310 token.datumSize);\r
311 throw new EntityException(exceptionString);\r
312 }\r
313 }\r
314\r
315 } else {\r
316 //\r
317 // If the token is not in database, create a new token instance and add\r
318 // a usage instance into this token in database.\r
319 //\r
320 tokenSpaceStrRet = this.getGuidInfoFromSpd(pcdBuildData.getTokenSpaceGuidCName());\r
321\r
322 if (tokenSpaceStrRet == null) {\r
323 throw new EntityException("Fail to get token space guid for token " + token.cName);\r
324 }\r
325\r
326 token = new Token(pcdBuildData.getCName(), tokenSpaceStrRet[1]);\r
327\r
328 token.datumType = datumType;\r
329 token.tokenNumber = tokenNumber;\r
330 token.isDynamicPCD = Token.isDynamic(pcdType);\r
331 token.datumSize = maxDatumSize;\r
332\r
333 if (token.isDynamicPCD) {\r
334 //\r
335 // For Dynamic and Dynamic Ex type, need find the dynamic information\r
336 // in <DynamicPcdBuildDefinition> section in FPD file.\r
337 //\r
338 updateDynamicInformation(moduleName,\r
339 token,\r
340 datum,\r
341 maxDatumSize);\r
342 }\r
343\r
344 pcdDbManager.addTokenToDatabase(primaryKey, token);\r
345 }\r
346\r
347 //\r
348 // -----------------------------------------------------------------------------------\r
349 // 2.1.3), Add the PcdType in current module into this Pcd token's supported PCD type.\r
350 // -----------------------------------------------------------------------------------\r
351 //\r
352 token.updateSupportPcdType(pcdType);\r
353\r
354 //\r
355 // ------------------------------------------------\r
356 // 2.1.4), Create an usage instance for this token.\r
357 // ------------------------------------------------\r
358 //\r
359 usageInstance = new UsageInstance(token,\r
360 modules.get(index).usageId,\r
361 pcdType,\r
362 datum,\r
363 maxDatumSize);\r
364 token.addUsageInstance(usageInstance);\r
365 }\r
366 }\r
367\r
368 //\r
369 // ------------------------------------------------\r
370 // 3), Add unreference dynamic_Ex pcd token into Pcd database.\r
371 // ------------------------------------------------\r
372 //\r
373 List<Token> tokenArray = getUnreferencedDynamicPcd();\r
374 if (tokenArray != null) {\r
f28c0830 375 for (index = 0; index < tokenArray.size(); index++) {\r
bc262841 376 pcdDbManager.addTokenToDatabase(tokenArray.get(index).getPrimaryKeyString(),\r
377 tokenArray.get(index));\r
378 }\r
379 }\r
380 }\r
381\r
382 /**\r
383 Update dynamic information for PCD entry.\r
384\r
385 Dynamic information is retrieved from <PcdDynamicBuildDeclarations> in\r
386 FPD file.\r
387\r
388 @param moduleName The name of the module who use this PCD\r
389 @param token The token instance\r
390 @param datum The <datum> in module's PCD information\r
391 @param maxDatumSize The <maxDatumSize> in module's PCD information\r
392\r
393 @return Token\r
394 */\r
395 private Token updateDynamicInformation(String moduleName,\r
396 Token token,\r
397 String datum,\r
398 int maxDatumSize)\r
399 throws EntityException {\r
400 int index = 0;\r
401 int offset;\r
402 String exceptionString = null;\r
403 SkuInstance skuInstance = null;\r
404 String temp;\r
405 boolean hasSkuId0 = false;\r
406 long tokenNumber = 0;\r
407 String hiiDefaultValue = null;\r
408 String[] variableGuidString = null;\r
409\r
410 List<DynamicPcdBuildDefinitions.PcdBuildData.SkuInfo> skuInfoList = null;\r
411 DynamicPcdBuildDefinitions.PcdBuildData dynamicInfo = null;\r
412\r
413 dynamicInfo = getDynamicInfoFromFpd(token, moduleName);\r
414 if (dynamicInfo == null) {\r
415 exceptionString = String.format("[FPD file error] For Dynamic PCD %s used by module %s, "+\r
416 "there is no dynamic information in <DynamicPcdBuildDefinitions> "+\r
417 "in FPD file, but it is required!",\r
418 token.cName,\r
419 moduleName);\r
420 throw new EntityException(exceptionString);\r
421 }\r
422\r
423 token.datumSize = dynamicInfo.getMaxDatumSize();\r
424\r
425 exceptionString = verifyDatum(token.cName,\r
426 moduleName,\r
427 null,\r
428 token.datumType,\r
429 token.datumSize);\r
430 if (exceptionString != null) {\r
431 throw new EntityException(exceptionString);\r
432 }\r
433\r
434 if ((maxDatumSize != 0) &&\r
435 (maxDatumSize != token.datumSize)) {\r
436 exceptionString = String.format("FPD file error] For dynamic PCD %s, the datum size in module %s is %d, but "+\r
437 "the datum size in <DynamicPcdBuildDefinitions> is %d, they are not match!",\r
438 token.cName,\r
439 moduleName,\r
440 maxDatumSize,\r
441 dynamicInfo.getMaxDatumSize());\r
442 throw new EntityException(exceptionString);\r
443 }\r
444 tokenNumber = Long.decode(dynamicInfo.getToken().toString());\r
445 if (tokenNumber != token.tokenNumber) {\r
446 exceptionString = String.format("[FPD file error] For dynamic PCD %s, the token number in module %s is 0x%x, but"+\r
447 "in <DynamicPcdBuildDefinictions>, the token number is 0x%x, they are not match!",\r
448 token.cName,\r
449 moduleName,\r
450 token.tokenNumber,\r
451 tokenNumber);\r
452 throw new EntityException(exceptionString);\r
453 }\r
454\r
455 token.dynamicExTokenNumber = tokenNumber;\r
456\r
457 skuInfoList = dynamicInfo.getSkuInfoList();\r
458\r
459 //\r
460 // Loop all sku data\r
461 //\r
f28c0830 462 for (index = 0; index < skuInfoList.size(); index++) {\r
bc262841 463 skuInstance = new SkuInstance();\r
464 //\r
465 // Although SkuId in schema is BigInteger, but in fact, sku id is 32 bit value.\r
466 //\r
467 temp = skuInfoList.get(index).getSkuId().toString();\r
468 skuInstance.id = Integer.decode(temp);\r
469 if (skuInstance.id == 0) {\r
470 hasSkuId0 = true;\r
471 }\r
472 //\r
473 // Judge whether is DefaultGroup at first, because most case is DefautlGroup.\r
474 //\r
475 if (skuInfoList.get(index).getValue() != null) {\r
476 skuInstance.value.setValue(skuInfoList.get(index).getValue().toString());\r
477 if ((exceptionString = verifyDatum(token.cName,\r
478 null,\r
479 skuInfoList.get(index).getValue().toString(),\r
480 token.datumType,\r
481 token.datumSize)) != null) {\r
482 throw new EntityException(exceptionString);\r
483 }\r
484\r
485 token.skuData.add(skuInstance);\r
486\r
487 //\r
488 // Judege wether is same of datum between module's information\r
489 // and dynamic information.\r
490 //\r
491 if (datum != null) {\r
492 if ((skuInstance.id == 0) &&\r
493 !datum.toString().equalsIgnoreCase(skuInfoList.get(index).getValue().toString())) {\r
494 exceptionString = "[FPD file error] For dynamic PCD " + token.cName + ", the value in module " + moduleName + " is " + datum.toString() + " but the "+\r
495 "value of sku 0 data in <DynamicPcdBuildDefinition> is " + skuInstance.value.value + ". They are must be same!"+\r
496 " or you could not define value for a dynamic PCD in every <ModuleSA>!";\r
497 throw new EntityException(exceptionString);\r
498 }\r
499 }\r
500 continue;\r
501 }\r
502\r
503 //\r
504 // Judge whether is HII group case.\r
505 //\r
506 if (skuInfoList.get(index).getVariableName() != null) {\r
507 exceptionString = null;\r
508 if (skuInfoList.get(index).getVariableGuid() == null) {\r
509 exceptionString = String.format("[FPD file error] For dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+\r
510 "file, who use HII, but there is no <VariableGuid> defined for Sku %d data!",\r
511 token.cName,\r
512 index);\r
513 if (exceptionString != null) {\r
514 throw new EntityException(exceptionString);\r
515 }\r
516 }\r
517\r
518 if (skuInfoList.get(index).getVariableOffset() == null) {\r
519 exceptionString = String.format("[FPD file error] For dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+\r
520 "file, who use HII, but there is no <VariableOffset> defined for Sku %d data!",\r
521 token.cName,\r
522 index);\r
523 if (exceptionString != null) {\r
524 throw new EntityException(exceptionString);\r
525 }\r
526 }\r
527\r
528 if (skuInfoList.get(index).getHiiDefaultValue() == null) {\r
529 exceptionString = String.format("[FPD file error] For dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+\r
530 "file, who use HII, but there is no <HiiDefaultValue> defined for Sku %d data!",\r
531 token.cName,\r
532 index);\r
533 if (exceptionString != null) {\r
534 throw new EntityException(exceptionString);\r
535 }\r
536 }\r
537\r
538 if (skuInfoList.get(index).getHiiDefaultValue() != null) {\r
539 hiiDefaultValue = skuInfoList.get(index).getHiiDefaultValue().toString();\r
540 } else {\r
541 hiiDefaultValue = null;\r
542 }\r
543\r
544 if ((exceptionString = verifyDatum(token.cName,\r
545 null,\r
546 hiiDefaultValue,\r
547 token.datumType,\r
548 token.datumSize)) != null) {\r
549 throw new EntityException(exceptionString);\r
550 }\r
551\r
552 offset = Integer.decode(skuInfoList.get(index).getVariableOffset());\r
553 if (offset > 0xFFFF) {\r
554 throw new EntityException(String.format("[FPD file error] For dynamic PCD %s , the variable offset defined in sku %d data "+\r
555 "exceed 64K, it is not allowed!",\r
556 token.cName,\r
557 index));\r
558 }\r
559\r
560 //\r
561 // Get variable guid string according to the name of guid which will be mapped into a GUID in SPD file.\r
562 //\r
563 variableGuidString = getGuidInfoFromSpd(skuInfoList.get(index).getVariableGuid().toString());\r
564 if (variableGuidString == null) {\r
565 throw new EntityException(String.format("[GUID Error] For dynamic PCD %s, the variable guid %s can be found in all SPD file!",\r
566 token.cName,\r
567 skuInfoList.get(index).getVariableGuid().toString()));\r
568 }\r
569 String variableStr = skuInfoList.get(index).getVariableName();\r
570 Pattern pattern = Pattern.compile("0x([a-fA-F0-9]){4}");\r
571 Matcher matcher = pattern.matcher(variableStr);\r
572 List<String> varNameList = new ArrayList<String>();\r
573 while (matcher.find()){\r
574 String str = variableStr.substring(matcher.start(),matcher.end());\r
575 varNameList.add(str);\r
576 }\r
577\r
578 skuInstance.value.setHiiData(varNameList,\r
579 translateSchemaStringToUUID(variableGuidString[1]),\r
580 skuInfoList.get(index).getVariableOffset(),\r
581 skuInfoList.get(index).getHiiDefaultValue().toString());\r
582 token.skuData.add(skuInstance);\r
583 continue;\r
584 }\r
585\r
586 if (skuInfoList.get(index).getVpdOffset() != null) {\r
587 skuInstance.value.setVpdData(skuInfoList.get(index).getVpdOffset());\r
588 token.skuData.add(skuInstance);\r
589 continue;\r
590 }\r
591\r
592 exceptionString = String.format("[FPD file error] For dynamic PCD %s, the dynamic info must "+\r
593 "be one of 'DefaultGroup', 'HIIGroup', 'VpdGroup'.",\r
594 token.cName);\r
595 throw new EntityException(exceptionString);\r
596 }\r
597\r
598 if (!hasSkuId0) {\r
599 exceptionString = String.format("[FPD file error] For dynamic PCD %s in <DynamicPcdBuildDefinitions>, there are "+\r
600 "no sku id = 0 data, which is required for every dynamic PCD",\r
601 token.cName);\r
602 throw new EntityException(exceptionString);\r
603 }\r
604\r
605 return token;\r
606 }\r
607\r
608 /**\r
609 Get all dynamic PCD defined in <DynamicPcdBuildDefinitions> which unreferenced by \r
610 any <ModuleSA> in FPD file.\r
611 \r
612 @return List<Token> Return PCD token \r
613 **/\r
614 private List<Token> getUnreferencedDynamicPcd () throws EntityException {\r
615 List<Token> tokenArray = new ArrayList<Token>();\r
616 Token token = null;\r
617 List<DynamicPcdBuildDefinitions.PcdBuildData> dynamicPcdBuildDataArray = null;\r
618 DynamicPcdBuildDefinitions.PcdBuildData pcdBuildData = null;\r
619 List<DynamicPcdBuildDefinitions.PcdBuildData.SkuInfo> skuInfoList = null;\r
620 Token.PCD_TYPE pcdType;\r
621 SkuInstance skuInstance = null;\r
622 String primaryKey = null;\r
623 boolean hasSkuId0 = false;\r
624 int index, offset, index2;\r
625 String temp;\r
626 String exceptionString;\r
627 String hiiDefaultValue;\r
628 String tokenSpaceStrRet[];\r
629 String variableGuidString[];\r
630\r
631 dynamicPcdBuildDataArray = getAllDynamicPcdInfoFromFpd();\r
632 if (dynamicPcdBuildDataArray == null) {\r
633 return null;\r
634 }\r
635\r
f28c0830 636 for (index2 = 0; index2 < dynamicPcdBuildDataArray.size(); index2++) {\r
bc262841 637 pcdBuildData = dynamicPcdBuildDataArray.get(index2);\r
638 tokenSpaceStrRet = this.getGuidInfoFromSpd(pcdBuildData.getTokenSpaceGuidCName());\r
639\r
640 if (tokenSpaceStrRet == null) {\r
641 throw new EntityException ("Fail to get Token space guid for token" + pcdBuildData.getCName());\r
642 }\r
643\r
644 primaryKey = Token.getPrimaryKeyString(pcdBuildData.getCName(),\r
645 tokenSpaceStrRet[1]);\r
646\r
647 if (pcdDbManager.isTokenInDatabase(primaryKey)) {\r
648 continue;\r
649 }\r
650\r
f28c0830 651 pcdType = Token.getPcdTypeFromString(pcdBuildData.getItemType().toString());\r
bc262841 652 if (pcdType != Token.PCD_TYPE.DYNAMIC_EX) {\r
653 throw new EntityException (String.format("[FPD file error] It not allowed for DYNAMIC PCD %s who is no used by any module",\r
654 pcdBuildData.getCName()));\r
655 }\r
656\r
657 //\r
658 // Create new token for unreference dynamic PCD token\r
659 //\r
660 token = new Token(pcdBuildData.getCName(), tokenSpaceStrRet[1]);\r
661 token.datumSize = pcdBuildData.getMaxDatumSize();\r
662\r
663\r
664 token.datumType = Token.getdatumTypeFromString(pcdBuildData.getDatumType().toString());\r
665 token.tokenNumber = Long.decode(pcdBuildData.getToken().toString());\r
666 token.dynamicExTokenNumber = token.tokenNumber;\r
667 token.isDynamicPCD = true;\r
668 token.updateSupportPcdType(pcdType);\r
669\r
670 exceptionString = verifyDatum(token.cName,\r
671 null,\r
672 null,\r
673 token.datumType,\r
674 token.datumSize);\r
675 if (exceptionString != null) {\r
676 throw new EntityException(exceptionString);\r
677 }\r
678\r
679 skuInfoList = pcdBuildData.getSkuInfoList();\r
680\r
681 //\r
682 // Loop all sku data\r
683 //\r
f28c0830 684 for (index = 0; index < skuInfoList.size(); index++) {\r
bc262841 685 skuInstance = new SkuInstance();\r
686 //\r
687 // Although SkuId in schema is BigInteger, but in fact, sku id is 32 bit value.\r
688 //\r
689 temp = skuInfoList.get(index).getSkuId().toString();\r
690 skuInstance.id = Integer.decode(temp);\r
691 if (skuInstance.id == 0) {\r
692 hasSkuId0 = true;\r
693 }\r
694 //\r
695 // Judge whether is DefaultGroup at first, because most case is DefautlGroup.\r
696 //\r
697 if (skuInfoList.get(index).getValue() != null) {\r
698 skuInstance.value.setValue(skuInfoList.get(index).getValue().toString());\r
699 if ((exceptionString = verifyDatum(token.cName,\r
700 null,\r
701 skuInfoList.get(index).getValue().toString(),\r
702 token.datumType,\r
703 token.datumSize)) != null) {\r
704 throw new EntityException(exceptionString);\r
705 }\r
706\r
707 token.skuData.add(skuInstance);\r
708\r
709 continue;\r
710 }\r
711\r
712 //\r
713 // Judge whether is HII group case.\r
714 //\r
715 if (skuInfoList.get(index).getVariableName() != null) {\r
716 exceptionString = null;\r
717 if (skuInfoList.get(index).getVariableGuid() == null) {\r
718 exceptionString = String.format("[FPD file error] For dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+\r
719 "file, who use HII, but there is no <VariableGuid> defined for Sku %d data!",\r
720 token.cName,\r
721 index);\r
722 if (exceptionString != null) {\r
723 throw new EntityException(exceptionString);\r
724 }\r
725 }\r
726\r
727 if (skuInfoList.get(index).getVariableOffset() == null) {\r
728 exceptionString = String.format("[FPD file error] For dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+\r
729 "file, who use HII, but there is no <VariableOffset> defined for Sku %d data!",\r
730 token.cName,\r
731 index);\r
732 if (exceptionString != null) {\r
733 throw new EntityException(exceptionString);\r
734 }\r
735 }\r
736\r
737 if (skuInfoList.get(index).getHiiDefaultValue() == null) {\r
738 exceptionString = String.format("[FPD file error] For dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+\r
739 "file, who use HII, but there is no <HiiDefaultValue> defined for Sku %d data!",\r
740 token.cName,\r
741 index);\r
742 if (exceptionString != null) {\r
743 throw new EntityException(exceptionString);\r
744 }\r
745 }\r
746\r
747 if (skuInfoList.get(index).getHiiDefaultValue() != null) {\r
748 hiiDefaultValue = skuInfoList.get(index).getHiiDefaultValue().toString();\r
749 } else {\r
750 hiiDefaultValue = null;\r
751 }\r
752\r
753 if ((exceptionString = verifyDatum(token.cName,\r
754 null,\r
755 hiiDefaultValue,\r
756 token.datumType,\r
757 token.datumSize)) != null) {\r
758 throw new EntityException(exceptionString);\r
759 }\r
760\r
761 offset = Integer.decode(skuInfoList.get(index).getVariableOffset());\r
762 if (offset > 0xFFFF) {\r
763 throw new EntityException(String.format("[FPD file error] For dynamic PCD %s , the variable offset defined in sku %d data "+\r
764 "exceed 64K, it is not allowed!",\r
765 token.cName,\r
766 index));\r
767 }\r
768\r
769 //\r
770 // Get variable guid string according to the name of guid which will be mapped into a GUID in SPD file.\r
771 //\r
772 variableGuidString = this.getGuidInfoFromSpd(skuInfoList.get(index).getVariableGuid().toString());\r
773 if (variableGuidString == null) {\r
774 throw new EntityException(String.format("[GUID Error] For dynamic PCD %s, the variable guid %s can be found in all SPD file!",\r
775 token.cName,\r
776 skuInfoList.get(index).getVariableGuid().toString()));\r
777 }\r
778 String variableStr = skuInfoList.get(index).getVariableName();\r
779 Pattern pattern = Pattern.compile("0x([a-fA-F0-9]){4}");\r
780 Matcher matcher = pattern.matcher(variableStr);\r
781 List<String> varNameList = new ArrayList<String>();\r
782 while (matcher.find()){\r
783 String str = variableStr.substring(matcher.start(),matcher.end());\r
784 varNameList.add(str);\r
785 }\r
786\r
787 skuInstance.value.setHiiData(varNameList,\r
788 translateSchemaStringToUUID(variableGuidString[1]),\r
789 skuInfoList.get(index).getVariableOffset(),\r
790 skuInfoList.get(index).getHiiDefaultValue().toString());\r
791 token.skuData.add(skuInstance);\r
792 continue;\r
793 }\r
794\r
795 if (skuInfoList.get(index).getVpdOffset() != null) {\r
796 skuInstance.value.setVpdData(skuInfoList.get(index).getVpdOffset());\r
797 token.skuData.add(skuInstance);\r
798 continue;\r
799 }\r
800\r
801 exceptionString = String.format("[FPD file error] For dynamic PCD %s, the dynamic info must "+\r
802 "be one of 'DefaultGroup', 'HIIGroup', 'VpdGroup'.",\r
803 token.cName);\r
804 throw new EntityException(exceptionString);\r
805 }\r
806\r
807 if (!hasSkuId0) {\r
808 exceptionString = String.format("[FPD file error] For dynamic PCD %s in <DynamicPcdBuildDefinitions>, there are "+\r
809 "no sku id = 0 data, which is required for every dynamic PCD",\r
810 token.cName);\r
811 throw new EntityException(exceptionString);\r
812 }\r
813\r
814 tokenArray.add(token);\r
815 }\r
816\r
817 return tokenArray;\r
818 }\r
819\r
820 /**\r
821 Translate the schema string to UUID instance.\r
822\r
823 In schema, the string of UUID is defined as following two types string:\r
824 1) GuidArrayType: pattern = 0x[a-fA-F0-9]{1,8},( )*0x[a-fA-F0-9]{1,4},(\r
825 )*0x[a-fA-F0-9]{1,4}(,( )*\{)?(,?( )*0x[a-fA-F0-9]{1,2}){8}( )*(\})?\r
826\r
827 2) GuidNamingConvention: pattern =\r
828 [a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}\r
829\r
830 This function will convert string and create uuid instance.\r
831\r
832 @param uuidString UUID string in XML file\r
833\r
834 @return UUID UUID instance\r
835 **/\r
836 private UUID translateSchemaStringToUUID(String uuidString)\r
837 throws EntityException {\r
838 String temp;\r
839 String[] splitStringArray;\r
840 int index;\r
841 int chIndex;\r
842 int chLen;\r
843\r
844 if (uuidString == null) {\r
845 return null;\r
846 }\r
847\r
848 if (uuidString.length() == 0) {\r
849 return null;\r
850 }\r
851\r
852 if (uuidString.equals("0") ||\r
853 uuidString.equalsIgnoreCase("0x0")) {\r
854 return new UUID(0, 0);\r
855 }\r
856\r
857 uuidString = uuidString.replaceAll("\\{", "");\r
858 uuidString = uuidString.replaceAll("\\}", "");\r
859\r
860 //\r
861 // If the UUID schema string is GuidArrayType type then need translate\r
862 // to GuidNamingConvention type at first.\r
863 //\r
864 if ((uuidString.charAt(0) == '0') && ((uuidString.charAt(1) == 'x') || (uuidString.charAt(1) == 'X'))) {\r
865 splitStringArray = uuidString.split("," );\r
866 if (splitStringArray.length != 11) {\r
867 throw new EntityException ("[FPD file error] Wrong format for UUID string: " + uuidString);\r
868 }\r
869\r
870 //\r
871 // Remove blank space from these string and remove header string "0x"\r
872 //\r
f28c0830 873 for (index = 0; index < 11; index++) {\r
bc262841 874 splitStringArray[index] = splitStringArray[index].trim();\r
875 splitStringArray[index] = splitStringArray[index].substring(2, splitStringArray[index].length());\r
876 }\r
877\r
878 //\r
879 // Add heading '0' to normalize the string length\r
880 //\r
f28c0830 881 for (index = 3; index < 11; index++) {\r
bc262841 882 chLen = splitStringArray[index].length();\r
f28c0830 883 for (chIndex = 0; chIndex < 2 - chLen; chIndex++) {\r
bc262841 884 splitStringArray[index] = "0" + splitStringArray[index];\r
885 }\r
886 }\r
887\r
888 //\r
889 // construct the final GuidNamingConvention string\r
890 //\r
891 temp = String.format("%s-%s-%s-%s%s-%s%s%s%s%s%s",\r
892 splitStringArray[0],\r
893 splitStringArray[1],\r
894 splitStringArray[2],\r
895 splitStringArray[3],\r
896 splitStringArray[4],\r
897 splitStringArray[5],\r
898 splitStringArray[6],\r
899 splitStringArray[7],\r
900 splitStringArray[8],\r
901 splitStringArray[9],\r
902 splitStringArray[10]);\r
903 uuidString = temp;\r
904 }\r
905\r
906 return UUID.fromString(uuidString);\r
907 }\r
908}\r
909\r