5ce11c546a32fc9f3f9cd3e41f7e5054e213de85
[mirror_edk2.git] / Tools / Java / 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.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;
42
43 /**
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.
47 **/
48 public class PlatformPcdPreprocessActionForBuilding extends PlatformPcdPreprocessAction {
49 ///
50 /// FPD file path.
51 ///
52 private String fpdFilePath;
53
54 ///
55 /// Cache the fpd docment instance for private usage.
56 ///
57 private PlatformSurfaceAreaDocument fpdDocInstance;
58
59 /**
60 Set FPDFileName parameter for this action class.
61
62 @param fpdFilePath fpd file path
63 **/
64 public void setFPDFilePath(String fpdFilePath) {
65 this.fpdFilePath = fpdFilePath;
66 }
67
68 /**
69 Common function interface for outer.
70
71 @param fpdFilePath The fpd file path of current build or processing.
72
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.
76
77 **/
78 public void perform(String fpdFilePath)
79 throws PlatformPcdPreprocessBuildException {
80 this.fpdFilePath = fpdFilePath;
81 checkParameter();
82 execute();
83 }
84
85 /**
86 Core execution function for this action class.
87
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.
95
96
97 @throws EntityException Exception indicate failed to execute this action.
98
99 **/
100 public void execute() throws PlatformPcdPreprocessBuildException {
101 String errorMessageHeader = "Failed to initialize the Pcd memory database because: ";
102 String errorsForPreprocess = null;
103
104 //
105 // Get memoryDatabaseManager instance from GlobalData.
106 // The memoryDatabaseManager should be initialized as static variable
107 // in some Pre-process class.
108 //
109 setPcdDbManager(GlobalData.getPCDMemoryDBManager());
110
111 //
112 // Collect all PCD information defined in FPD file.
113 // Evenry token defind in FPD will be created as an token into
114 // memory database.
115 //
116 try {
117 initPcdMemoryDbWithPlatformInfo();
118 } catch (PlatformPcdPreprocessException exp) {
119 throw new PlatformPcdPreprocessBuildException(errorMessageHeader + exp.getMessage());
120 }
121 errorsForPreprocess = this.getErrorString();
122 if (errorsForPreprocess != null) {
123 throw new PlatformPcdPreprocessBuildException(errorMessageHeader + "\r\n" + errorsForPreprocess);
124 }
125
126 //
127 // Generate for PEI, DXE PCD DATABASE's definition and initialization.
128 //
129 try {
130 genPcdDatabaseSourceCode ();
131 } catch (EntityException exp) {
132 throw new PlatformPcdPreprocessBuildException(errorMessageHeader + "\r\n" + exp.getMessage());
133 }
134 }
135
136 /**
137 Override function: implementate the method of get Guid string information from SPD file.
138
139 @param guidCName Guid CName string.
140
141 @return String Guid information from SPD file.
142 @throws PlatformPcdPreprocessException
143 Fail to get Guid information from SPD file.
144 **/
145 public String getGuidInfoFromSpd(String guidCName) throws PlatformPcdPreprocessException {
146 String tokenSpaceStrRet = null;
147 try {
148 tokenSpaceStrRet = GlobalData.getGuidInfoFromCname(guidCName);
149 } catch ( Exception e ) {
150 throw new PlatformPcdPreprocessException ("Failed to get Guid CName " + guidCName + " from the SPD file!");
151 }
152 return tokenSpaceStrRet;
153 }
154
155 /**
156 This function generates source code for PCD Database.
157
158 @throws EntityException If the token does *not* exist in memory database.
159
160 **/
161 private void genPcdDatabaseSourceCode()
162 throws EntityException {
163 String PcdCommonHeaderString = PcdDatabase.getPcdDatabaseCommonDefinitions();
164
165 ArrayList<Token> alPei = new ArrayList<Token> ();
166 ArrayList<Token> alDxe = new ArrayList<Token> ();
167
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();
174
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();
180 }
181
182 /**
183 Override function: Get component array from FPD.
184
185 This function maybe provided by some Global class.
186
187 @return List<ModuleInfo> the component array.
188 @throws PlatformPcdPreprocessException get all modules in <ModuleSA> in FPD file.
189
190 **/
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;
196
197 pcdBuildDefinitions = GlobalData.getFpdPcdBuildDefinitions();
198 if (pcdBuildDefinitions == null) {
199 return null;
200 }
201
202 //
203 // Loop map to retrieve all PCD build definition and Module id
204 //
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(),
212 id.getArch(),
213 id.getModule().getVersion(),
214 id.getModule().getModuleType());
215 allModules.add(
216 new ModulePcdInfoFromFpd(
217 usageId,
218 ((PcdBuildDefinitionDocument)pcdBuildDefinitions.get(id)).getPcdBuildDefinition()));
219 }
220 return allModules;
221 }
222
223 /**
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.
226
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.
232
233 @return String exception strings.
234 */
235 public String verifyDatum(String cName,
236 String moduleName,
237 String datum,
238 Token.DATUM_TYPE datumType,
239 int maxDatumSize) {
240 //
241 // In building system, datum should not be checked, the checking work
242 // should be done by wizard tools or PCD verification tools.
243 //
244 return null;
245 }
246
247 /**
248 Override function: Get dynamic information for a dynamic PCD from <DynamicPcdBuildDefinition> seciton in FPD file.
249
250 This function should be implemented in GlobalData in future.
251
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.
254
255 @return DynamicPcdBuildDefinitions.PcdBuildData
256 **/
257 public DynamicPcdBuildDefinitions.PcdBuildData getDynamicInfoFromFpd(Token token,
258 String moduleName)
259 throws PlatformPcdPreprocessException {
260 int index = 0;
261 String exceptionString = null;
262 String dynamicPrimaryKey = null;
263 DynamicPcdBuildDefinitions dynamicPcdBuildDefinitions = null;
264 List<DynamicPcdBuildDefinitions.PcdBuildData> dynamicPcdBuildDataArray = null;
265 String tokenSpaceStrRet = null;
266
267 //
268 // If FPD document is not be opened, open and initialize it.
269 // BUGBUG: The code should be moved into GlobalData in future.
270 //
271 if (fpdDocInstance == null) {
272 try {
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());
278 }
279 }
280
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!",
285 token.cName,
286 moduleName);
287 putError(exceptionString);
288 return null;
289 }
290
291 dynamicPcdBuildDataArray = dynamicPcdBuildDefinitions.getPcdBuildDataList();
292 for (index = 0; index < dynamicPcdBuildDataArray.size(); index ++) {
293 tokenSpaceStrRet = getGuidInfoFromSpd(dynamicPcdBuildDataArray.get(index).getTokenSpaceGuidCName());
294
295 if (tokenSpaceStrRet == null) {
296 exceptionString = "Fail to get token space guid for token " + dynamicPcdBuildDataArray.get(index).getCName();
297 putError(exceptionString);
298 continue;
299 }
300
301 dynamicPrimaryKey = Token.getPrimaryKeyString(dynamicPcdBuildDataArray.get(index).getCName(),
302 tokenSpaceStrRet);
303 if (dynamicPrimaryKey.equals(token.getPrimaryKeyString())) {
304 return dynamicPcdBuildDataArray.get(index);
305 }
306 }
307
308 return null;
309 }
310
311 /**
312 Override function: get all <DynamicPcdBuildDefinition> from FPD file.
313
314 @return List<DynamicPcdBuildDefinitions.PcdBuildData> All DYNAMIC PCD list in <DynamicPcdBuildDefinitions> in FPD file.
315 @throws PlatformPcdPreprocessBuildException Failure to get dynamic information list.
316
317 **/
318 public List<DynamicPcdBuildDefinitions.PcdBuildData>
319 getAllDynamicPcdInfoFromFpd()
320 throws PlatformPcdPreprocessException {
321 DynamicPcdBuildDefinitions dynamicPcdBuildDefinitions = null;
322
323 //
324 // Open fpd document to get <DynamicPcdBuildDefinition> Section.
325 // BUGBUG: the function should be move GlobalData in furture.
326 //
327 if (fpdDocInstance == null) {
328 try {
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());
334 }
335 }
336
337 dynamicPcdBuildDefinitions = fpdDocInstance.getPlatformSurfaceArea().getDynamicPcdBuildDefinitions();
338 if (dynamicPcdBuildDefinitions == null) {
339 return null;
340 }
341
342 return dynamicPcdBuildDefinitions.getPcdBuildDataList();
343 }
344
345 /**
346 check parameter for this action.
347
348 @throws PlatformPcdPreprocessBuildException Bad parameter.
349 **/
350 private void checkParameter() throws PlatformPcdPreprocessBuildException {
351 File file = null;
352
353 if (fpdFilePath == null) {
354 throw new PlatformPcdPreprocessBuildException("FPDFileName should be empty for CollectPCDAtion!");
355 }
356
357 if (fpdFilePath.length() == 0) {
358 throw new PlatformPcdPreprocessBuildException("FPDFileName should be empty for CollectPCDAtion!");
359 }
360
361 file = new File(fpdFilePath);
362
363 if(!file.exists()) {
364 throw new PlatformPcdPreprocessBuildException("FPD File " + fpdFilePath + " does not exist!");
365 }
366 }
367 }