2 PlatformPcdPreprocessActionForBuilding class.
4 This action class is to collect PCD information from MSA, SPD, FPD xml file.
5 This class will be used for wizard and build tools, So it can *not* inherit
6 from buildAction or wizardAction.
8 Copyright (c) 2006, Intel Corporation
9 All rights reserved. This program and the accompanying materials
10 are licensed and made available under the terms and conditions of the BSD License
11 which accompanies this distribution. The full text of the license may be found at
12 http://opensource.org/licenses/bsd-license.php
14 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
15 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 package org
.tianocore
.build
.pcd
.action
;
21 import java
.io
.IOException
;
22 import java
.util
.ArrayList
;
23 import java
.util
.Iterator
;
24 import java
.util
.List
;
27 import org
.apache
.xmlbeans
.XmlException
;
28 import org
.apache
.xmlbeans
.XmlObject
;
29 import org
.tianocore
.DynamicPcdBuildDefinitionsDocument
.DynamicPcdBuildDefinitions
;
30 import org
.tianocore
.PcdBuildDefinitionDocument
;
31 import org
.tianocore
.PlatformSurfaceAreaDocument
;
32 import org
.tianocore
.build
.exception
.PlatformPcdPreprocessBuildException
;
33 import org
.tianocore
.build
.global
.GlobalData
;
34 import org
.tianocore
.build
.id
.FpdModuleIdentification
;
35 import org
.tianocore
.pcd
.action
.PlatformPcdPreprocessAction
;
36 import org
.tianocore
.pcd
.entity
.MemoryDatabaseManager
;
37 import org
.tianocore
.pcd
.entity
.ModulePcdInfoFromFpd
;
38 import org
.tianocore
.pcd
.entity
.Token
;
39 import org
.tianocore
.pcd
.entity
.UsageIdentification
;
40 import org
.tianocore
.pcd
.exception
.EntityException
;
41 import org
.tianocore
.pcd
.exception
.PlatformPcdPreprocessException
;
44 This action class is to collect PCD information from MSA, SPD, FPD xml file.
45 This class will be used for wizard and build tools, So it can *not* inherit
46 from buildAction or UIAction.
48 public class PlatformPcdPreprocessActionForBuilding
extends PlatformPcdPreprocessAction
{
52 private String fpdFilePath
;
55 /// Cache the fpd docment instance for private usage.
57 private PlatformSurfaceAreaDocument fpdDocInstance
;
60 Set FPDFileName parameter for this action class.
62 @param fpdFilePath fpd file path
64 public void setFPDFilePath(String fpdFilePath
) {
65 this.fpdFilePath
= fpdFilePath
;
69 Common function interface for outer.
71 @param fpdFilePath The fpd file path of current build or processing.
73 @throws PlatformPreprocessBuildException
74 The exception of this function. Because it can *not* be predict
75 where the action class will be used. So only Exception can be throw.
78 public void perform(String fpdFilePath
)
79 throws PlatformPcdPreprocessBuildException
{
80 this.fpdFilePath
= fpdFilePath
;
86 Core execution function for this action class.
88 This function work flows will be:
89 1) Collect and prepocess PCD information from FPD file, all PCD
90 information will be stored into memory database.
91 2) Generate 3 strings for
92 a) All modules using Dynamic(Ex) PCD entry.(Token Number)
93 b) PEI PCDDatabase (C Structure) for PCD Service PEIM.
94 c) DXE PCD Database (C structure) for PCD Service DXE.
97 @throws EntityException Exception indicate failed to execute this action.
100 public void execute() throws PlatformPcdPreprocessBuildException
{
101 String errorMessageHeader
= "Failed to initialize the Pcd memory database because: ";
102 String errorsForPreprocess
= null;
105 // Get memoryDatabaseManager instance from GlobalData.
106 // The memoryDatabaseManager should be initialized as static variable
107 // in some Pre-process class.
109 setPcdDbManager(GlobalData
.getPCDMemoryDBManager());
112 // Collect all PCD information defined in FPD file.
113 // Evenry token defind in FPD will be created as an token into
117 initPcdMemoryDbWithPlatformInfo();
118 } catch (PlatformPcdPreprocessException exp
) {
119 throw new PlatformPcdPreprocessBuildException(errorMessageHeader
+ exp
.getMessage());
121 errorsForPreprocess
= this.getErrorString();
122 if (errorsForPreprocess
!= null) {
123 throw new PlatformPcdPreprocessBuildException(errorMessageHeader
+ "\r\n" + errorsForPreprocess
);
127 // Generate for PEI, DXE PCD DATABASE's definition and initialization.
130 genPcdDatabaseSourceCode ();
131 } catch (EntityException exp
) {
132 throw new PlatformPcdPreprocessBuildException(errorMessageHeader
+ "\r\n" + exp
.getMessage());
137 Override function: implementate the method of get Guid string information from SPD file.
139 @param guidCName Guid CName string.
141 @return String Guid information from SPD file.
142 @throws PlatformPcdPreprocessException
143 Fail to get Guid information from SPD file.
145 public String
getGuidInfoFromSpd(String guidCName
) throws PlatformPcdPreprocessException
{
146 String tokenSpaceStrRet
= null;
148 tokenSpaceStrRet
= GlobalData
.getGuidInfoFromCname(guidCName
);
149 } catch ( Exception e
) {
150 throw new PlatformPcdPreprocessException ("Failed to get Guid CName " + guidCName
+ " from the SPD file!");
152 return tokenSpaceStrRet
;
156 This function generates source code for PCD Database.
158 @throws EntityException If the token does *not* exist in memory database.
161 private void genPcdDatabaseSourceCode()
162 throws EntityException
{
163 String PcdCommonHeaderString
= PcdDatabase
.getPcdDatabaseCommonDefinitions();
165 ArrayList
<Token
> alPei
= new ArrayList
<Token
> ();
166 ArrayList
<Token
> alDxe
= new ArrayList
<Token
> ();
168 getPcdDbManager().getTwoPhaseDynamicRecordArray(alPei
, alDxe
);
169 PcdDatabase pcdPeiDatabase
= new PcdDatabase (alPei
, "PEI", 0);
170 pcdPeiDatabase
.genCode();
171 MemoryDatabaseManager
.PcdPeimHString
= PcdCommonHeaderString
+ pcdPeiDatabase
.getHString() +
172 PcdDatabase
.getPcdPeiDatabaseDefinitions();
173 MemoryDatabaseManager
.PcdPeimCString
= pcdPeiDatabase
.getCString();
175 PcdDatabase pcdDxeDatabase
= new PcdDatabase(alDxe
, "DXE", alPei
.size());
176 pcdDxeDatabase
.genCode();
177 MemoryDatabaseManager
.PcdDxeHString
= MemoryDatabaseManager
.PcdPeimHString
+ pcdDxeDatabase
.getHString() +
178 PcdDatabase
.getPcdDxeDatabaseDefinitions();
179 MemoryDatabaseManager
.PcdDxeCString
= pcdDxeDatabase
.getCString();
183 Override function: Get component array from FPD.
185 This function maybe provided by some Global class.
187 @return List<ModuleInfo> the component array.
188 @throws PlatformPcdPreprocessException get all modules in <ModuleSA> in FPD file.
191 public List
<ModulePcdInfoFromFpd
> getComponentsFromFpd()
192 throws PlatformPcdPreprocessException
{
193 List
<ModulePcdInfoFromFpd
> allModules
= new ArrayList
<ModulePcdInfoFromFpd
>();
194 Map
<FpdModuleIdentification
, XmlObject
> pcdBuildDefinitions
= null;
195 UsageIdentification usageId
= null;
197 pcdBuildDefinitions
= GlobalData
.getFpdPcdBuildDefinitions();
198 if (pcdBuildDefinitions
== null) {
203 // Loop map to retrieve all PCD build definition and Module id
205 Iterator item
= pcdBuildDefinitions
.keySet().iterator();
206 while (item
.hasNext()){
207 FpdModuleIdentification id
= (FpdModuleIdentification
) item
.next();
208 usageId
= new UsageIdentification(id
.getModule().getName(),
209 id
.getModule().getGuid(),
210 id
.getModule().getPackage().getName(),
211 id
.getModule().getPackage().getGuid(),
213 id
.getModule().getVersion(),
214 id
.getModule().getModuleType());
216 new ModulePcdInfoFromFpd(
218 ((PcdBuildDefinitionDocument
)pcdBuildDefinitions
.get(id
)).getPcdBuildDefinition()));
224 Override function: Verify the datum value according its datum size and datum type, this
225 function maybe moved to FPD verification tools in future.
227 @param cName The token name
228 @param moduleName The module who use this PCD token
229 @param datum The PCD's datum
230 @param datumType The PCD's datum type
231 @param maxDatumSize The max size for PCD's Datum.
233 @return String exception strings.
235 public String
verifyDatum(String cName
,
238 Token
.DATUM_TYPE datumType
,
241 // In building system, datum should not be checked, the checking work
242 // should be done by wizard tools or PCD verification tools.
248 Override function: Get dynamic information for a dynamic PCD from <DynamicPcdBuildDefinition> seciton in FPD file.
250 This function should be implemented in GlobalData in future.
252 @param token The token instance which has hold module's PCD information
253 @param moduleName The name of module who will use this Dynamic PCD.
255 @return DynamicPcdBuildDefinitions.PcdBuildData
257 public DynamicPcdBuildDefinitions
.PcdBuildData
getDynamicInfoFromFpd(Token token
,
259 throws PlatformPcdPreprocessException
{
261 String exceptionString
= null;
262 String dynamicPrimaryKey
= null;
263 DynamicPcdBuildDefinitions dynamicPcdBuildDefinitions
= null;
264 List
<DynamicPcdBuildDefinitions
.PcdBuildData
> dynamicPcdBuildDataArray
= null;
265 String tokenSpaceStrRet
= null;
268 // If FPD document is not be opened, open and initialize it.
269 // BUGBUG: The code should be moved into GlobalData in future.
271 if (fpdDocInstance
== null) {
273 fpdDocInstance
= (PlatformSurfaceAreaDocument
)XmlObject
.Factory
.parse(new File(fpdFilePath
));
274 } catch(IOException ioE
) {
275 throw new PlatformPcdPreprocessException("File IO error for xml file:" + fpdFilePath
+ "\n" + ioE
.getMessage());
276 } catch(XmlException xmlE
) {
277 throw new PlatformPcdPreprocessException("Can't parse the FPD xml fle:" + fpdFilePath
+ "\n" + xmlE
.getMessage());
281 dynamicPcdBuildDefinitions
= fpdDocInstance
.getPlatformSurfaceArea().getDynamicPcdBuildDefinitions();
282 if (dynamicPcdBuildDefinitions
== null) {
283 exceptionString
= String
.format("[FPD file error] There are no <PcdDynamicBuildDescriptions> elements in FPD file but there are Dynamic type "+
284 "PCD entries %s in module %s!",
287 putError(exceptionString
);
291 dynamicPcdBuildDataArray
= dynamicPcdBuildDefinitions
.getPcdBuildDataList();
292 for (index
= 0; index
< dynamicPcdBuildDataArray
.size(); index
++) {
293 tokenSpaceStrRet
= getGuidInfoFromSpd(dynamicPcdBuildDataArray
.get(index
).getTokenSpaceGuidCName());
295 if (tokenSpaceStrRet
== null) {
296 exceptionString
= "Fail to get token space guid for token " + dynamicPcdBuildDataArray
.get(index
).getCName();
297 putError(exceptionString
);
301 dynamicPrimaryKey
= Token
.getPrimaryKeyString(dynamicPcdBuildDataArray
.get(index
).getCName(),
303 if (dynamicPrimaryKey
.equals(token
.getPrimaryKeyString())) {
304 return dynamicPcdBuildDataArray
.get(index
);
312 Override function: get all <DynamicPcdBuildDefinition> from FPD file.
314 @return List<DynamicPcdBuildDefinitions.PcdBuildData> All DYNAMIC PCD list in <DynamicPcdBuildDefinitions> in FPD file.
315 @throws PlatformPcdPreprocessBuildException Failure to get dynamic information list.
318 public List
<DynamicPcdBuildDefinitions
.PcdBuildData
>
319 getAllDynamicPcdInfoFromFpd()
320 throws PlatformPcdPreprocessException
{
321 DynamicPcdBuildDefinitions dynamicPcdBuildDefinitions
= null;
324 // Open fpd document to get <DynamicPcdBuildDefinition> Section.
325 // BUGBUG: the function should be move GlobalData in furture.
327 if (fpdDocInstance
== null) {
329 fpdDocInstance
= (PlatformSurfaceAreaDocument
)XmlObject
.Factory
.parse(new File(fpdFilePath
));
330 } catch(IOException ioE
) {
331 throw new PlatformPcdPreprocessException("File IO error for xml file:" + fpdFilePath
+ "\n" + ioE
.getMessage());
332 } catch(XmlException xmlE
) {
333 throw new PlatformPcdPreprocessException("Can't parse the FPD xml fle:" + fpdFilePath
+ "\n" + xmlE
.getMessage());
337 dynamicPcdBuildDefinitions
= fpdDocInstance
.getPlatformSurfaceArea().getDynamicPcdBuildDefinitions();
338 if (dynamicPcdBuildDefinitions
== null) {
342 return dynamicPcdBuildDefinitions
.getPcdBuildDataList();
346 check parameter for this action.
348 @throws PlatformPcdPreprocessBuildException Bad parameter.
350 private void checkParameter() throws PlatformPcdPreprocessBuildException
{
353 if (fpdFilePath
== null) {
354 throw new PlatformPcdPreprocessBuildException("FPDFileName should be empty for CollectPCDAtion!");
357 if (fpdFilePath
.length() == 0) {
358 throw new PlatformPcdPreprocessBuildException("FPDFileName should be empty for CollectPCDAtion!");
361 file
= new File(fpdFilePath
);
364 throw new PlatformPcdPreprocessBuildException("FPD File " + fpdFilePath
+ " does not exist!");