]> git.proxmox.com Git - mirror_edk2.git/blob - Tools/Source/GenBuild/org/tianocore/build/pcd/action/PlatformPcdPreprocessActionForBuilding.java
2013b74706f62fb16cd8474bc1151f74d58f867e
[mirror_edk2.git] / Tools / Source / GenBuild / org / tianocore / build / pcd / action / PlatformPcdPreprocessActionForBuilding.java
1 /** @file
2 PlatformPcdPreprocessActionForBuilding class.
3
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.
7
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
13
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.
16
17 **/
18 package org.tianocore.build.pcd.action;
19
20 import java.io.File;
21 import java.io.IOException;
22 import java.util.ArrayList;
23 import java.util.Iterator;
24 import java.util.List;
25 import java.util.Map;
26
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.ActionMessage;
36 import org.tianocore.pcd.action.PlatformPcdPreprocessAction;
37 import org.tianocore.pcd.entity.MemoryDatabaseManager;
38 import org.tianocore.pcd.entity.ModulePcdInfoFromFpd;
39 import org.tianocore.pcd.entity.Token;
40 import org.tianocore.pcd.entity.UsageIdentification;
41 import org.tianocore.pcd.exception.EntityException;
42 import org.tianocore.pcd.exception.PlatformPcdPreprocessException;
43
44 /**
45 This action class is to collect PCD information from MSA, SPD, FPD xml file.
46 This class will be used for wizard and build tools, So it can *not* inherit
47 from buildAction or UIAction.
48 **/
49 public class PlatformPcdPreprocessActionForBuilding extends PlatformPcdPreprocessAction {
50 ///
51 /// FPD file path.
52 ///
53 private String fpdFilePath;
54
55 ///
56 /// Message level for CollectPCDAction.
57 ///
58 private int originalMessageLevel;
59
60 ///
61 /// Cache the fpd docment instance for private usage.
62 ///
63 private PlatformSurfaceAreaDocument fpdDocInstance;
64
65 /**
66 Set action message level for CollectPcdAction tool.
67
68 The message should be restored when this action exit.
69
70 @param actionMessageLevel parameter for this action
71 **/
72 public void setActionMessageLevel(int actionMessageLevel) {
73 originalMessageLevel = ActionMessage.messageLevel;
74 ActionMessage.messageLevel = actionMessageLevel;
75 }
76
77 /**
78 Set FPDFileName parameter for this action class.
79
80 @param fpdFilePath fpd file path
81 **/
82 public void setFPDFilePath(String fpdFilePath) {
83 this.fpdFilePath = fpdFilePath;
84 }
85
86 /**
87 Common function interface for outer.
88
89 @param fpdFilePath The fpd file path of current build or processing.
90 @param messageLevel The message level for this Action.
91
92 @throws PlatformPreprocessBuildException
93 The exception of this function. Because it can *not* be predict
94 where the action class will be used. So only Exception can be throw.
95
96 **/
97 public void perform(String fpdFilePath, int messageLevel)
98 throws PlatformPcdPreprocessBuildException {
99 this.fpdFilePath = fpdFilePath;
100 setActionMessageLevel(messageLevel);
101 checkParameter();
102 execute();
103 ActionMessage.messageLevel = originalMessageLevel;
104 }
105
106 /**
107 Core execution function for this action class.
108
109 This function work flows will be:
110 1) Collect and prepocess PCD information from FPD file, all PCD
111 information will be stored into memory database.
112 2) Generate 3 strings for
113 a) All modules using Dynamic(Ex) PCD entry.(Token Number)
114 b) PEI PCDDatabase (C Structure) for PCD Service PEIM.
115 c) DXE PCD Database (C structure) for PCD Service DXE.
116
117
118 @throws EntityException Exception indicate failed to execute this action.
119
120 **/
121 public void execute() throws PlatformPcdPreprocessBuildException {
122 String errorMessageHeader = "Failed to initialize the Pcd memory database because: ";
123 String errorsForPreprocess = null;
124
125 //
126 // Get memoryDatabaseManager instance from GlobalData.
127 // The memoryDatabaseManager should be initialized as static variable
128 // in some Pre-process class.
129 //
130 setPcdDbManager(GlobalData.getPCDMemoryDBManager());
131
132 //
133 // Collect all PCD information defined in FPD file.
134 // Evenry token defind in FPD will be created as an token into
135 // memory database.
136 //
137 try {
138 initPcdMemoryDbWithPlatformInfo();
139 } catch (PlatformPcdPreprocessException exp) {
140 throw new PlatformPcdPreprocessBuildException(errorMessageHeader + exp.getMessage());
141 }
142 errorsForPreprocess = this.getErrorString();
143 if (errorsForPreprocess != null) {
144 throw new PlatformPcdPreprocessBuildException(errorMessageHeader + "\r\n" + errorsForPreprocess);
145 }
146
147 //
148 // Generate for PEI, DXE PCD DATABASE's definition and initialization.
149 //
150 try {
151 genPcdDatabaseSourceCode ();
152 } catch (EntityException exp) {
153 throw new PlatformPcdPreprocessBuildException(errorMessageHeader + "\r\n" + exp.getMessage());
154 }
155 }
156
157 /**
158 Override function: implementate the method of get Guid string information from SPD file.
159
160 @param guidCName Guid CName string.
161
162 @return String Guid information from SPD file.
163 @throws PlatformPcdPreprocessException
164 Fail to get Guid information from SPD file.
165 **/
166 public String getGuidInfoFromSpd(String guidCName) throws PlatformPcdPreprocessException {
167 String tokenSpaceStrRet = null;
168 try {
169 tokenSpaceStrRet = GlobalData.getGuidInfoFromCname(guidCName);
170 } catch ( Exception e ) {
171 throw new PlatformPcdPreprocessException ("Failed to get Guid CName " + guidCName + " from the SPD file!");
172 }
173 return tokenSpaceStrRet;
174 }
175
176 /**
177 This function generates source code for PCD Database.
178
179 @throws EntityException If the token does *not* exist in memory database.
180
181 **/
182 private void genPcdDatabaseSourceCode()
183 throws EntityException {
184 String PcdCommonHeaderString = PcdDatabase.getPcdDatabaseCommonDefinitions();
185
186 ArrayList<Token> alPei = new ArrayList<Token> ();
187 ArrayList<Token> alDxe = new ArrayList<Token> ();
188
189 getPcdDbManager().getTwoPhaseDynamicRecordArray(alPei, alDxe);
190 PcdDatabase pcdPeiDatabase = new PcdDatabase (alPei, "PEI", 0);
191 pcdPeiDatabase.genCode();
192 MemoryDatabaseManager.PcdPeimHString = PcdCommonHeaderString + pcdPeiDatabase.getHString() +
193 PcdDatabase.getPcdPeiDatabaseDefinitions();
194 MemoryDatabaseManager.PcdPeimCString = pcdPeiDatabase.getCString();
195
196 PcdDatabase pcdDxeDatabase = new PcdDatabase(alDxe, "DXE", alPei.size());
197 pcdDxeDatabase.genCode();
198 MemoryDatabaseManager.PcdDxeHString = MemoryDatabaseManager.PcdPeimHString + pcdDxeDatabase.getHString() +
199 PcdDatabase.getPcdDxeDatabaseDefinitions();
200 MemoryDatabaseManager.PcdDxeCString = pcdDxeDatabase.getCString();
201 }
202
203 /**
204 Override function: Get component array from FPD.
205
206 This function maybe provided by some Global class.
207
208 @return List<ModuleInfo> the component array.
209 @throws PlatformPcdPreprocessException get all modules in <ModuleSA> in FPD file.
210
211 **/
212 public List<ModulePcdInfoFromFpd> getComponentsFromFpd()
213 throws PlatformPcdPreprocessException {
214 List<ModulePcdInfoFromFpd> allModules = new ArrayList<ModulePcdInfoFromFpd>();
215 Map<FpdModuleIdentification, XmlObject> pcdBuildDefinitions = null;
216 UsageIdentification usageId = null;
217
218 pcdBuildDefinitions = GlobalData.getFpdPcdBuildDefinitions();
219 if (pcdBuildDefinitions == null) {
220 return null;
221 }
222
223 //
224 // Loop map to retrieve all PCD build definition and Module id
225 //
226 Iterator item = pcdBuildDefinitions.keySet().iterator();
227 while (item.hasNext()){
228 FpdModuleIdentification id = (FpdModuleIdentification) item.next();
229 usageId = new UsageIdentification(id.getModule().getName(),
230 id.getModule().getGuid(),
231 id.getModule().getPackage().getName(),
232 id.getModule().getPackage().getGuid(),
233 id.getArch(),
234 id.getModule().getVersion(),
235 id.getModule().getModuleType());
236 allModules.add(
237 new ModulePcdInfoFromFpd(
238 usageId,
239 ((PcdBuildDefinitionDocument)pcdBuildDefinitions.get(id)).getPcdBuildDefinition()));
240 }
241 return allModules;
242 }
243
244 /**
245 Override function: Verify the datum value according its datum size and datum type, this
246 function maybe moved to FPD verification tools in future.
247
248 @param cName The token name
249 @param moduleName The module who use this PCD token
250 @param datum The PCD's datum
251 @param datumType The PCD's datum type
252 @param maxDatumSize The max size for PCD's Datum.
253
254 @return String exception strings.
255 */
256 public String verifyDatum(String cName,
257 String moduleName,
258 String datum,
259 Token.DATUM_TYPE datumType,
260 int maxDatumSize) {
261 //
262 // In building system, datum should not be checked, the checking work
263 // should be done by wizard tools or PCD verification tools.
264 //
265 return null;
266 }
267
268 /**
269 Override function: Get dynamic information for a dynamic PCD from <DynamicPcdBuildDefinition> seciton in FPD file.
270
271 This function should be implemented in GlobalData in future.
272
273 @param token The token instance which has hold module's PCD information
274 @param moduleName The name of module who will use this Dynamic PCD.
275
276 @return DynamicPcdBuildDefinitions.PcdBuildData
277 **/
278 public DynamicPcdBuildDefinitions.PcdBuildData getDynamicInfoFromFpd(Token token,
279 String moduleName)
280 throws PlatformPcdPreprocessException {
281 int index = 0;
282 String exceptionString = null;
283 String dynamicPrimaryKey = null;
284 DynamicPcdBuildDefinitions dynamicPcdBuildDefinitions = null;
285 List<DynamicPcdBuildDefinitions.PcdBuildData> dynamicPcdBuildDataArray = null;
286 String tokenSpaceStrRet = null;
287
288 //
289 // If FPD document is not be opened, open and initialize it.
290 // BUGBUG: The code should be moved into GlobalData in future.
291 //
292 if (fpdDocInstance == null) {
293 try {
294 fpdDocInstance = (PlatformSurfaceAreaDocument)XmlObject.Factory.parse(new File(fpdFilePath));
295 } catch(IOException ioE) {
296 throw new PlatformPcdPreprocessException("File IO error for xml file:" + fpdFilePath + "\n" + ioE.getMessage());
297 } catch(XmlException xmlE) {
298 throw new PlatformPcdPreprocessException("Can't parse the FPD xml fle:" + fpdFilePath + "\n" + xmlE.getMessage());
299 }
300 }
301
302 dynamicPcdBuildDefinitions = fpdDocInstance.getPlatformSurfaceArea().getDynamicPcdBuildDefinitions();
303 if (dynamicPcdBuildDefinitions == null) {
304 exceptionString = String.format("[FPD file error] There are no <PcdDynamicBuildDescriptions> elements in FPD file but there are Dynamic type "+
305 "PCD entries %s in module %s!",
306 token.cName,
307 moduleName);
308 putError(exceptionString);
309 return null;
310 }
311
312 dynamicPcdBuildDataArray = dynamicPcdBuildDefinitions.getPcdBuildDataList();
313 for (index = 0; index < dynamicPcdBuildDataArray.size(); index ++) {
314 tokenSpaceStrRet = getGuidInfoFromSpd(dynamicPcdBuildDataArray.get(index).getTokenSpaceGuidCName());
315
316 if (tokenSpaceStrRet == null) {
317 exceptionString = "Fail to get token space guid for token " + dynamicPcdBuildDataArray.get(index).getCName();
318 putError(exceptionString);
319 continue;
320 }
321
322 dynamicPrimaryKey = Token.getPrimaryKeyString(dynamicPcdBuildDataArray.get(index).getCName(),
323 tokenSpaceStrRet);
324 if (dynamicPrimaryKey.equals(token.getPrimaryKeyString())) {
325 return dynamicPcdBuildDataArray.get(index);
326 }
327 }
328
329 return null;
330 }
331
332 /**
333 Override function: get all <DynamicPcdBuildDefinition> from FPD file.
334
335 @return List<DynamicPcdBuildDefinitions.PcdBuildData> All DYNAMIC PCD list in <DynamicPcdBuildDefinitions> in FPD file.
336 @throws PlatformPcdPreprocessBuildException Failure to get dynamic information list.
337
338 **/
339 public List<DynamicPcdBuildDefinitions.PcdBuildData>
340 getAllDynamicPcdInfoFromFpd()
341 throws PlatformPcdPreprocessException {
342 DynamicPcdBuildDefinitions dynamicPcdBuildDefinitions = null;
343
344 //
345 // Open fpd document to get <DynamicPcdBuildDefinition> Section.
346 // BUGBUG: the function should be move GlobalData in furture.
347 //
348 if (fpdDocInstance == null) {
349 try {
350 fpdDocInstance = (PlatformSurfaceAreaDocument)XmlObject.Factory.parse(new File(fpdFilePath));
351 } catch(IOException ioE) {
352 throw new PlatformPcdPreprocessException("File IO error for xml file:" + fpdFilePath + "\n" + ioE.getMessage());
353 } catch(XmlException xmlE) {
354 throw new PlatformPcdPreprocessException("Can't parse the FPD xml fle:" + fpdFilePath + "\n" + xmlE.getMessage());
355 }
356 }
357
358 dynamicPcdBuildDefinitions = fpdDocInstance.getPlatformSurfaceArea().getDynamicPcdBuildDefinitions();
359 if (dynamicPcdBuildDefinitions == null) {
360 return null;
361 }
362
363 return dynamicPcdBuildDefinitions.getPcdBuildDataList();
364 }
365
366 /**
367 check parameter for this action.
368
369 @throws PlatformPcdPreprocessBuildException Bad parameter.
370 **/
371 private void checkParameter() throws PlatformPcdPreprocessBuildException {
372 File file = null;
373
374 if (fpdFilePath == null) {
375 throw new PlatformPcdPreprocessBuildException("FPDFileName should be empty for CollectPCDAtion!");
376 }
377
378 if (fpdFilePath.length() == 0) {
379 throw new PlatformPcdPreprocessBuildException("FPDFileName should be empty for CollectPCDAtion!");
380 }
381
382 file = new File(fpdFilePath);
383
384 if(!file.exists()) {
385 throw new PlatformPcdPreprocessBuildException("FPD File " + fpdFilePath + " does not exist!");
386 }
387 }
388 }