]> git.proxmox.com Git - mirror_edk2.git/blob - Tools/Source/FrameworkWizard/src/org/tianocore/frameworkwizard/platform/ui/global/GlobalData.java
some bug fixing for FpdFrameworkModules
[mirror_edk2.git] / Tools / Source / FrameworkWizard / src / org / tianocore / frameworkwizard / platform / ui / global / GlobalData.java
1 /** @file
2 GlobalData class.
3
4 GlobalData provide initializing, instoring, querying and update global data.
5 It is a bridge to intercommunicate between multiple component, such as AutoGen,
6 PCD and so on.
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 package org.tianocore.frameworkwizard.platform.ui.global;
18
19 import org.apache.xmlbeans.XmlObject;
20 import org.tianocore.DbPathAndFilename;
21 import org.tianocore.FrameworkDatabaseDocument;
22 import org.tianocore.ModuleSurfaceAreaDocument;
23 import org.tianocore.ModuleSurfaceAreaDocument.ModuleSurfaceArea;
24 import org.tianocore.frameworkwizard.platform.ui.id.FpdModuleIdentification;
25 import org.tianocore.frameworkwizard.platform.ui.id.ModuleIdentification;
26 import org.tianocore.frameworkwizard.platform.ui.id.PackageIdentification;
27 import org.tianocore.frameworkwizard.platform.ui.id.PlatformIdentification;
28
29 import java.io.File;
30 import java.util.Comparator;
31 import java.util.HashMap;
32 import java.util.HashSet;
33 import java.util.Iterator;
34 import java.util.List;
35 import java.util.Map;
36 import java.util.Set;
37 import java.util.logging.Logger;
38
39 /**
40 GlobalData provide initializing, instoring, querying and update global data.
41 It is a bridge to intercommunicate between multiple component, such as AutoGen,
42 PCD and so on.
43
44 <p>Note that all global information are initialized incrementally. All data will
45 parse and record only of necessary during build time. </p>
46
47 @since GenBuild 1.0
48 **/
49 public class GlobalData {
50
51
52 public static Logger log = Logger.getAnonymousLogger();
53 public static KeyComparator comparator = new KeyComparator();
54 ///
55 /// Record current WORKSPACE Directory
56 ///
57 private static String workspaceDir = "";
58
59 ///
60 /// Be used to ensure Global data will be initialized only once.
61 ///
62 private static boolean globalFlag = false;
63
64 ///
65 /// Framework Database information: package list and platform list
66 ///
67 private static Set<PackageIdentification> packageList = new HashSet<PackageIdentification>();
68
69 private static Set<PlatformIdentification> platformList = new HashSet<PlatformIdentification>();
70
71 ///
72 /// Every detail SPD informations: Module list, Library class definition,
73 /// Package header file, GUID/PPI/Protocol definitions
74 ///
75 private static final Map<PackageIdentification, Spd> spdTable = new HashMap<PackageIdentification, Spd>();
76
77 ///
78 /// Build informations are divided into three parts:
79 /// 1. From MSA 2. From FPD 3. From FPD' ModuleSA
80 ///
81 private static Map<ModuleIdentification, Map<String, XmlObject>> nativeMsa = new HashMap<ModuleIdentification, Map<String, XmlObject>>();
82
83 private static Map<FpdModuleIdentification, Map<String, XmlObject>> fpdModuleSA= new HashMap<FpdModuleIdentification, Map<String, XmlObject>>();
84
85 private static XmlObject fpdBuildOptions;
86
87 private static XmlObject fpdDynamicPcds;
88
89 ///
90 /// Parsed modules list
91 ///
92 private static Map<FpdModuleIdentification, Map<String, XmlObject>> parsedModules = new HashMap<FpdModuleIdentification, Map<String, XmlObject>>();
93
94 ///
95 /// built modules list with ARCH, TARGET, TOOLCHAIN
96 ///
97 private static Set<FpdModuleIdentification> builtModules = new HashSet<FpdModuleIdentification>();
98
99 ///
100 /// PCD memory database stored all PCD information which collected from FPD,MSA and SPD.
101 ///
102 // private static final MemoryDatabaseManager pcdDbManager = new MemoryDatabaseManager();
103
104 ///
105 /// build target + tool chain family/tag name + arch + command types + command options
106 ///
107 private static Map<String, Object> toolChainOptions;
108 private static Map<String, Object> toolChainFamilyOptions;
109 private static Map<String, String> toolChainDefinitions;
110 ///
111 ///
112 ///
113 private static Set<String> targets;
114 ///
115 ///
116 ///
117 private static Set<String> toolChainFamilies;
118 ///
119 ///
120 ///
121 private static Set<String> toolChains;
122 ///
123 /// keep track which toolchain family a toolchain tag belongs to
124 ///
125 private static Map<String, Set<String>> toolChainFamilyMap;
126 private static Map<String, Set<String>> toolChainCommandMap;
127
128 ///
129 /// list of Arch: EBC, ARM, IA32, X64, IPF, PPC
130 ///
131 private static Set<String> archs;
132
133 ///
134 /// list of Command Type: CC, LIB, LINK, ASL, ASM, ASMLINK, PP
135 ///
136 private static Set<String> commandTypes;
137
138 /**
139 Parse framework database (DB) and all SPD files listed in DB to initialize
140 the environment for next build. This method will only be executed only once
141 in the whole build process.
142
143 @param workspaceDatabaseFile the file name of framework database
144 @param workspaceDir current workspace directory path
145 @throws Exception
146 Framework Dababase or SPD or MSA file is not valid
147 **/
148 public synchronized static void initInfo(String workspaceDatabaseFile, String workspaceDir) throws Exception {
149 //
150 // ensure this method will be revoked only once
151 //
152 if (globalFlag) {
153 return;
154 }
155 globalFlag = true;
156
157 //
158 // Backup workspace directory. It will be used by other method
159 //
160 GlobalData.workspaceDir = workspaceDir.replaceAll("(\\\\)", "/");
161 File dbFile = new File(workspaceDir + File.separatorChar + workspaceDatabaseFile);
162 try {
163 FrameworkDatabaseDocument db = (FrameworkDatabaseDocument) XmlObject.Factory.parse(dbFile);
164 //
165 // validate FrameworkDatabaseFile
166 //
167 // if (! db.validate()) {
168 // throw new Exception("Framework Database file [" + dbFile.getPath() + "] is invalid.");
169 // }
170 //
171 // Get package list
172 //
173 List<DbPathAndFilename> packages = db.getFrameworkDatabase().getPackageList().getFilenameList();
174
175 Iterator iter = packages.iterator();
176 while (iter.hasNext()) {
177 DbPathAndFilename dbPath = (DbPathAndFilename)iter.next();
178 String fileName = dbPath.getStringValue();
179 Spd spd = new Spd(new File(workspaceDir + File.separatorChar + fileName));
180 packageList.add(spd.getPackageId());
181 spdTable.put(spd.getPackageId(), spd);
182 }
183
184
185 } catch (Exception e) {
186 e.printStackTrace();
187 throw new Exception("Parse workspace Database [" + dbFile.getPath() + "] Error.\n" + e.getMessage());
188 }
189 }
190
191 /**
192 Get the current WORKSPACE Directory.
193
194 @return current workspace directory
195 **/
196 public synchronized static String getWorkspacePath() {
197 return workspaceDir;
198 }
199
200
201 /**
202 Get the MSA file name with absolute path
203 */
204 public synchronized static File getMsaFile(ModuleIdentification moduleId) throws Exception {
205 File msaFile = null;
206 //
207 // TBD. Do only when package is null.
208 //
209 Iterator iter = packageList.iterator();
210 while (iter.hasNext()) {
211 PackageIdentification packageId = (PackageIdentification)iter.next();
212 Spd spd = spdTable.get(packageId);
213 msaFile = spd.getModuleFile(moduleId);
214 if (msaFile != null ) {
215 break ;
216 }
217 }
218 if (msaFile == null){
219 throw new Exception("Can't find Module [" + moduleId.getName() + "] in all packages. ");
220 }
221 else {
222 return msaFile;
223 }
224 }
225
226 public synchronized static PackageIdentification getPackageForModule(ModuleIdentification moduleId) {
227 //
228 // If package already defined in module
229 //
230 if (moduleId.getPackage() != null) {
231 return moduleId.getPackage();
232 }
233
234 PackageIdentification packageId = null;
235 Iterator iter = packageList.iterator();
236 while (iter.hasNext()) {
237 packageId = (PackageIdentification)iter.next();
238
239 Spd spd = spdTable.get(packageId);
240 if (spd.getModuleFile(moduleId) != null ) {
241 moduleId.setPackage(packageId);
242 break ;
243 }
244 }
245 if (packageId == null){
246 return null;
247 }
248 else {
249 return packageId;
250 }
251 }
252
253 /**
254 Difference between build and parse: ToolChain and Target
255 **/
256 public synchronized static boolean isModuleBuilt(FpdModuleIdentification moduleId) {
257 return builtModules.contains(moduleId);
258 }
259
260 public synchronized static void registerBuiltModule(FpdModuleIdentification fpdModuleId) {
261 builtModules.add(fpdModuleId);
262 }
263
264
265 public synchronized static void registerFpdModuleSA(FpdModuleIdentification fpdModuleId, Map<String, XmlObject> doc) throws Exception{
266 Map<String, XmlObject> result = new HashMap<String, XmlObject>();
267 Set keySet = doc.keySet();
268 Iterator iter = keySet.iterator();
269 while (iter.hasNext()){
270 String key = (String)iter.next();
271 XmlObject item = cloneXmlObject(doc.get(key), true);
272 result.put(key, item);
273 }
274 fpdModuleSA.put(fpdModuleId, result);
275 }
276
277 /**
278 Query overrided module surface area information. If current is Package
279 or Platform build, also include the information from FPD file.
280
281 <p>Note that surface area parsing is incremental. That means the method will
282 only parse the MSA and MBD files if necessary. </p>
283
284 @param moduleName the base name of the module
285 @return the overrided module surface area information
286 @throws Exception
287 MSA or MBD is not valid
288 **/
289 public synchronized static Map<String, XmlObject> getDoc(FpdModuleIdentification fpdModuleId) throws Exception {
290 if (parsedModules.containsKey(fpdModuleId)) {
291 return parsedModules.get(fpdModuleId);
292 }
293 Map<String, XmlObject> doc = new HashMap<String, XmlObject>();
294 ModuleIdentification moduleId = fpdModuleId.getModule();
295 //
296 // First part: get the MSA files info
297 //
298 doc = getNativeMsa(moduleId);
299
300 //
301 // Second part: put build options
302 //
303 doc.put("BuildOptions", fpdBuildOptions);
304
305 //
306 // Third part: get Module info from FPD, such as Library instances, PCDs
307 //
308 if (fpdModuleSA.containsKey(fpdModuleId)){
309 //
310 // merge module info in FPD to final Doc
311 // For Library Module, do nothing here
312 //
313 doc.putAll(fpdModuleSA.get(fpdModuleId));
314 }
315 parsedModules.put(fpdModuleId, doc);
316 return doc;
317 }
318
319 public synchronized static Map<String, XmlObject> getDoc(ModuleIdentification moduleId, String arch) throws Exception {
320 FpdModuleIdentification fpdModuleId = new FpdModuleIdentification(moduleId, arch);
321 return getDoc(fpdModuleId);
322 }
323 /**
324 Query the native MSA information with module base name.
325
326 <p>Note that MSA parsing is incremental. That means the method will
327 only to parse the MSA files when never parsed before. </p>
328
329 @param moduleName the base name of the module
330 @return the native MSA information
331 @throws Exception
332 MSA file is not valid
333 **/
334 public synchronized static Map<String, XmlObject> getNativeMsa(ModuleIdentification moduleId) throws Exception {
335 if (nativeMsa.containsKey(moduleId)) {
336 return nativeMsa.get(moduleId);
337 }
338 File msaFile = getMsaFile(moduleId);
339 Map<String, XmlObject> msaMap = getNativeMsa(msaFile);
340 nativeMsa.put(moduleId, msaMap);
341 return msaMap;
342 }
343
344 public synchronized static Map<String, XmlObject> getNativeMsa(File msaFile) throws Exception {
345 if (! msaFile.exists()) {
346 throw new Exception("Surface Area file [" + msaFile.getPath() + "] can't found.");
347 }
348 try {
349 ModuleSurfaceAreaDocument doc = (ModuleSurfaceAreaDocument)XmlObject.Factory.parse(msaFile);
350 //
351 // Validate File if they accord with XML Schema
352 //
353 // if ( ! doc.validate()){
354 // throw new Exception("Module Surface Area file [" + msaFile.getPath() + "] is invalid.");
355 // }
356 //
357 // parse MSA file
358 //
359 ModuleSurfaceArea msa= doc.getModuleSurfaceArea();
360 Map<String, XmlObject> msaMap = new HashMap<String, XmlObject>();
361 msaMap.put("ModuleSurfaceArea", msa);
362 msaMap.put("MsaHeader", cloneXmlObject(msa.getMsaHeader(), true));
363 msaMap.put("LibraryClassDefinitions", cloneXmlObject(msa.getLibraryClassDefinitions(), true));
364 msaMap.put("SourceFiles", cloneXmlObject(msa.getSourceFiles(), true));
365 msaMap.put("PackageDependencies", cloneXmlObject(msa.getPackageDependencies(), true));
366 msaMap.put("Protocols", cloneXmlObject(msa.getProtocols(), true));
367 msaMap.put("PPIs", cloneXmlObject(msa.getPPIs(), true));
368 msaMap.put("Guids", cloneXmlObject(msa.getGuids(), true));
369 msaMap.put("Externs", cloneXmlObject(msa.getExterns(), true));
370 return msaMap;
371 }
372 catch (Exception ex){
373 throw new Exception(ex.getMessage());
374 }
375 }
376
377 public static Map<String, XmlObject> getFpdBuildOptions() {
378 Map<String, XmlObject> map = new HashMap<String, XmlObject>();
379 map.put("BuildOptions", fpdBuildOptions);
380 return map;
381 }
382
383 public static void setFpdBuildOptions(XmlObject fpdBuildOptions) throws Exception{
384 GlobalData.fpdBuildOptions = cloneXmlObject(fpdBuildOptions, true);
385 }
386
387 public static XmlObject getFpdDynamicPcds() {
388 return fpdDynamicPcds;
389 }
390
391 public static void setFpdDynamicPcds(XmlObject fpdDynamicPcds) {
392 GlobalData.fpdDynamicPcds = fpdDynamicPcds;
393 }
394
395 //////////////////////////////////////////////
396 //////////////////////////////////////////////
397
398 public static Set<ModuleIdentification> getModules(PackageIdentification packageId){
399 Spd spd = spdTable.get(packageId);
400 if (spd == null ) {
401 Set<ModuleIdentification> dummy = new HashSet<ModuleIdentification>();
402 return dummy;
403 }
404 else {
405 return spd.getModules();
406 }
407 }
408
409 /**
410 The header file path is relative to workspace dir
411 **/
412 public static String[] getLibraryClassHeaderFiles(PackageIdentification[] packages, String name) {
413 if (packages == null ){
414 // throw Exception or not????
415 return new String[0];
416 }
417 String[] result = null;
418 for (int i = 0; i < packages.length; i++){
419 Spd spd = spdTable.get(packages[i]);
420 //
421 // If find one package defined the library class
422 //
423 if( (result = spd.getLibClassIncluder(name)) != null){
424 return result;
425 }
426 }
427 return null;
428
429 }
430
431 /**
432 The header file path is relative to workspace dir
433 **/
434 public static String getPackageHeaderFiles(PackageIdentification packages, String moduleType) throws Exception {
435 if (packages == null ){
436 return new String("");
437 }
438 Spd spd = spdTable.get(packages);
439 //
440 // If can't find package header file, skip it
441 //
442 String temp = null;
443 if (spd != null){
444 if( (temp = spd.getPackageIncluder(moduleType)) != null){
445 return temp;
446 }else {
447 temp = "";
448 return temp;
449 }
450 }else {
451 return null;
452 }
453 }
454
455 /**
456 return two values: {cName, GuidValue}
457 **/
458 public static String[] getGuid(PackageIdentification[] packages, String name) throws Exception {
459 if (packages == null ){
460 // throw Exception or not????
461 return new String[0];
462 }
463 String[] result = null;
464 for (int i = 0; i < packages.length; i++){
465 Spd spd = spdTable.get(packages[i]);
466 //
467 // If find one package defined the GUID
468 //
469 if( (result = spd.getGuid(name)) != null){
470 return result;
471 }
472 }
473 return null;
474 }
475
476 /**
477 return two values: {cName, GuidValue}
478 **/
479 public static String[] getPpiGuid(PackageIdentification[] packages, String name) throws Exception {
480 if (packages == null ){
481 return new String[0];
482 }
483 String[] result = null;
484 for (int i = 0; i < packages.length; i++){
485 Spd spd = spdTable.get(packages[i]);
486 //
487 // If find one package defined the Ppi GUID
488 //
489 if( (result = spd.getPpi(name)) != null){
490 return result;
491 }
492 }
493 return null;
494
495 }
496
497 /**
498 return two values: {cName, GuidValue}
499 **/
500 public static String[] getProtocolGuid(PackageIdentification[] packages, String name) throws Exception {
501 if (packages == null ){
502 return new String[0];
503 }
504 String[] result = null;
505 for (int i = 0; i < packages.length; i++){
506 Spd spd = spdTable.get(packages[i]);
507 //
508 // If find one package defined the protocol GUID
509 //
510 if( (result = spd.getProtocol(name)) != null){
511 return result;
512 }
513 }
514 return null;
515
516 }
517
518 /////////////////////////// Update!! Update!! Update!!
519 // public synchronized static MemoryDatabaseManager getPCDMemoryDBManager() {
520 // return pcdDbManager;
521 // }
522 ///////////////////////////
523 public synchronized static PlatformIdentification getPlatform(String name) throws Exception {
524 Iterator iter = platformList.iterator();
525 while(iter.hasNext()){
526 PlatformIdentification platformId = (PlatformIdentification)iter.next();
527 if (platformId.getName().equalsIgnoreCase(name)) {
528 GlobalData.log.info("Platform: " + platformId + platformId.getFpdFile());
529 return platformId;
530 }
531 }
532 throw new Exception("Can't find platform [" + name + "] in current workspace. ");
533 }
534
535 public synchronized static File getPackageFile(PackageIdentification packageId) throws Exception {
536 Iterator iter = packageList.iterator();
537 while(iter.hasNext()){
538 PackageIdentification packageItem = (PackageIdentification)iter.next();
539 if (packageItem.equals(packageId)) {
540 packageId.setName(packageItem.getName());
541 return packageItem.getSpdFile();
542 }
543 }
544 throw new Exception("Can't find " + packageId + " in current workspace. ");
545 }
546
547 public synchronized static File getModuleFile(ModuleIdentification moduleId) throws Exception {
548 PackageIdentification packageId = getPackageForModule(moduleId);
549 moduleId.setPackage(packageId);
550 Spd spd = spdTable.get(packageId);
551 return spd.getModuleFile(moduleId);
552 }
553 //
554 // expanded by FrameworkWizard
555 //
556 public synchronized static XmlObject getModuleXmlObject(ModuleIdentification moduleId) throws Exception {
557 PackageIdentification packageId = getPackageForModule(moduleId);
558 moduleId.setPackage(packageId);
559 Spd spd = spdTable.get(packageId);
560 return spd.msaDocMap.get(moduleId);
561 }
562
563 public synchronized static XmlObject getPackageXmlObject(PackageIdentification packageId) {
564 Spd spd = spdTable.get(packageId);
565 if (spd != null){
566 return spd.spdDocMap.get("PackageSurfaceArea");
567 }
568 return null;
569 }
570
571 public synchronized static Set<PackageIdentification> getPackageList(){
572 return packageList;
573 }
574 ///// remove!!
575 private static XmlObject cloneXmlObject(XmlObject object, boolean deep) throws Exception {
576 if ( object == null) {
577 return null;
578 }
579 XmlObject result = null;
580 try {
581 result = XmlObject.Factory.parse(object.getDomNode()
582 .cloneNode(deep));
583 } catch (Exception ex) {
584 throw new Exception(ex.getMessage());
585 }
586 return result;
587 }
588
589 ////// Tool Chain Related, try to refine and put some logic process to ToolChainFactory
590 public static void setBuildToolChainFamilyOptions(Map<String, Object> map) {
591 toolChainFamilyOptions = map;
592 }
593
594 public static Map<String, Object> getToolChainFamilyOptions() {
595 return toolChainFamilyOptions;
596 }
597
598 public static void setBuildToolChainOptions(Map<String, Object> map) {
599 toolChainOptions = map;
600 }
601
602 public static Map<String, Object> getToolChainOptions() {
603 return toolChainOptions;
604 }
605
606 public static void setTargets(Set<String> targetSet) {
607 GlobalData.log.info("TargetSet: " + targetSet);
608 targets = targetSet;
609 }
610
611 public static String[] getTargets() {
612 return (String[])targets.toArray(new String[targets.size()]);
613 }
614
615 public static void setToolChains(Set<String> toolChainSet) {
616 toolChains = toolChainSet;
617 }
618
619 public static String[] getToolChains() {
620 String[] toolChainList = new String[toolChains.size()];
621 return (String[])toolChains.toArray(toolChainList);
622 }
623
624 public static void setToolChainFamilies(Set<String> toolChainFamilySet) {
625 toolChainFamilies = toolChainFamilySet;
626 }
627
628 public static void setToolChainFamiliyMap(Map<String, Set<String>> map) {
629 /*
630 Set<String> keys = map.keySet();
631 Iterator it = keys.iterator();
632 while (it.hasNext()) {
633 String toolchain = (String)it.next();
634 Set<String> familyMap = (Set<String>)map.get(toolchain);
635 Iterator fit = familyMap.iterator();
636 System.out.print(toolchain + ": ");
637 while (fit.hasNext()) {
638 System.out.print((String)fit.next() + " ");
639 }
640 System.out.println("");
641 }
642 */
643 toolChainFamilyMap = map;
644 }
645
646 public static String[] getToolChainFamilies() {
647 String[] toolChainFamilyList = new String[toolChainFamilies.size()];
648 return (String[])toolChainFamilies.toArray(toolChainFamilyList);
649 }
650
651 public static String[] getToolChainFamilies(String toolChain) {
652 Set<String> familySet = (Set<String>)toolChainFamilyMap.get(toolChain);
653 String[] toolChainFamilyList = new String[familySet.size()];
654 return (String[])familySet.toArray(toolChainFamilyList);
655 }
656
657 public static Set<String> getToolChainFamilySet(String toolChain) {
658 return (Set<String>)toolChainFamilyMap.get(toolChain);
659 }
660
661 public static void setArchs(Set<String> archSet) {
662 archs = archSet;
663 }
664
665 public static String[] getArchs() {
666 String[] archList = new String[archs.size()];
667 return (String[])archs.toArray(archList);
668 }
669 /*
670
671 */
672 public static void SetCommandTypes(Set<String> commandTypeSet) {
673 commandTypes = commandTypeSet;
674 }
675 /*
676
677 */
678 public static void SetCommandTypes(Map<String, Set<String>> commandTypeMap) {
679 toolChainCommandMap = commandTypeMap;
680 }
681 /*
682
683 */
684 public static String[] getCommandTypes() {
685 String[] commandList = new String[commandTypes.size()];
686 return (String[])commandTypes.toArray(commandList);
687 }
688 /*
689
690 */
691 public static String[] getCommandTypes(String toolChain) {
692 Set<String> commands = (Set<String>)toolChainCommandMap.get(toolChain);
693 if (commands == null) {
694 return new String[0];
695 }
696
697 String[] commandList = new String[commands.size()];
698 return (String[])commands.toArray(commandList);
699 }
700 /*
701
702 */
703 public static String getCommandSetting(String commandDescString) {
704 return (String)toolChainDefinitions.get(commandDescString);
705 }
706 /*
707
708 */
709 public static void setToolChainDefinitions(Map<String, String> def) {
710 toolChainDefinitions = def;
711 }
712
713 public static Map<String, String> getToolChainDefinitions() {
714 return toolChainDefinitions;
715 }
716
717 }
718
719 final class KeyComparator implements Comparator<String> {
720 public int compare(String x, String y) {
721 return x.compareToIgnoreCase(y);
722 }
723
724 }
725