4 GlobalData provide initializing, instoring, querying and update global data.
5 It is a bridge to intercommunicate between multiple component, such as AutoGen,
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.
17 package org
.tianocore
.frameworkwizard
.platform
.ui
.global
;
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
;
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
.ListIterator
;
38 import java
.util
.Vector
;
39 import java
.util
.logging
.Logger
;
42 GlobalData provide initializing, instoring, querying and update global data.
43 It is a bridge to intercommunicate between multiple component, such as AutoGen,
46 <p>Note that all global information are initialized incrementally. All data will
47 parse and record only of necessary during build time. </p>
51 public class GlobalData
{
54 public static Logger log
= Logger
.getAnonymousLogger();
55 public static KeyComparator comparator
= new KeyComparator();
57 /// Record current WORKSPACE Directory
59 private static String workspaceDir
= "";
62 /// Be used to ensure Global data will be initialized only once.
64 // private static boolean globalFlag = false;
67 /// Framework Database information: package list and platform list
69 private static Set
<PackageIdentification
> packageList
= new HashSet
<PackageIdentification
>();
71 private static Set
<PlatformIdentification
> platformList
= new HashSet
<PlatformIdentification
>();
74 /// Every detail SPD informations: Module list, Library class definition,
75 /// Package header file, GUID/PPI/Protocol definitions
77 private static final Map
<PackageIdentification
, Spd
> spdTable
= new HashMap
<PackageIdentification
, Spd
>();
80 /// Build informations are divided into three parts:
81 /// 1. From MSA 2. From FPD 3. From FPD' ModuleSA
83 private static Map
<ModuleIdentification
, Map
<String
, XmlObject
>> nativeMsa
= new HashMap
<ModuleIdentification
, Map
<String
, XmlObject
>>();
85 private static Map
<FpdModuleIdentification
, Map
<String
, XmlObject
>> fpdModuleSA
= new HashMap
<FpdModuleIdentification
, Map
<String
, XmlObject
>>();
87 private static XmlObject fpdBuildOptions
;
89 private static XmlObject fpdDynamicPcds
;
92 /// Parsed modules list
94 private static Map
<FpdModuleIdentification
, Map
<String
, XmlObject
>> parsedModules
= new HashMap
<FpdModuleIdentification
, Map
<String
, XmlObject
>>();
97 /// built modules list with ARCH, TARGET, TOOLCHAIN
99 private static Set
<FpdModuleIdentification
> builtModules
= new HashSet
<FpdModuleIdentification
>();
102 Parse framework database (DB) and all SPD files listed in DB to initialize
103 the environment for next build. This method will only be executed only once
104 in the whole build process.
106 @param workspaceDatabaseFile the file name of framework database
107 @param workspaceDir current workspace directory path
109 Framework Dababase or SPD or MSA file is not valid
111 public synchronized static void initInfo(String workspaceDatabaseFile
, String workspaceDir
) throws Exception
{
114 // Backup workspace directory. It will be used by other method
116 GlobalData
.workspaceDir
= workspaceDir
.replaceAll("(\\\\)", "/");
117 File dbFile
= new File(workspaceDir
+ File
.separatorChar
+ workspaceDatabaseFile
);
119 FrameworkDatabaseDocument db
= (FrameworkDatabaseDocument
) XmlObject
.Factory
.parse(dbFile
);
121 // validate FrameworkDatabaseFile
123 // if (! db.validate()) {
124 // throw new Exception("Framework Database file [" + dbFile.getPath() + "] is invalid.");
130 List
<DbPathAndFilename
> packages
= db
.getFrameworkDatabase().getPackageList().getFilenameList();
132 Iterator iter
= packages
.iterator();
133 while (iter
.hasNext()) {
134 DbPathAndFilename dbPath
= (DbPathAndFilename
)iter
.next();
135 String fileName
= dbPath
.getStringValue();
136 Spd spd
= new Spd(new File(workspaceDir
+ File
.separatorChar
+ fileName
));
137 packageList
.add(spd
.getPackageId());
138 spdTable
.put(spd
.getPackageId(), spd
);
142 } catch (Exception e
) {
144 throw new Exception("Parse workspace Database [" + dbFile
.getPath() + "] Error.\n" + e
.getMessage());
149 Get the current WORKSPACE Directory.
151 @return current workspace directory
153 public synchronized static String
getWorkspacePath() {
159 Get the MSA file name with absolute path
161 public synchronized static File
getMsaFile(ModuleIdentification moduleId
) throws Exception
{
164 // TBD. Do only when package is null.
166 Iterator iter
= packageList
.iterator();
167 while (iter
.hasNext()) {
168 PackageIdentification packageId
= (PackageIdentification
)iter
.next();
169 Spd spd
= spdTable
.get(packageId
);
170 msaFile
= spd
.getModuleFile(moduleId
);
171 if (msaFile
!= null ) {
175 if (msaFile
== null){
176 throw new Exception("Can't find Module [" + moduleId
.getName() + "] in all packages. ");
183 public synchronized static PackageIdentification
getPackageForModule(ModuleIdentification moduleId
) {
185 // If package already defined in module
187 if (moduleId
.getPackage() != null) {
188 return moduleId
.getPackage();
191 PackageIdentification packageId
= null;
192 Iterator iter
= packageList
.iterator();
193 while (iter
.hasNext()) {
194 packageId
= (PackageIdentification
)iter
.next();
196 Spd spd
= spdTable
.get(packageId
);
197 if (spd
.getModuleFile(moduleId
) != null ) {
198 moduleId
.setPackage(packageId
);
202 if (packageId
== null){
211 Difference between build and parse: ToolChain and Target
213 public synchronized static boolean isModuleBuilt(FpdModuleIdentification moduleId
) {
214 return builtModules
.contains(moduleId
);
217 public synchronized static void registerBuiltModule(FpdModuleIdentification fpdModuleId
) {
218 builtModules
.add(fpdModuleId
);
222 public synchronized static void registerFpdModuleSA(FpdModuleIdentification fpdModuleId
, Map
<String
, XmlObject
> doc
) throws Exception
{
223 Map
<String
, XmlObject
> result
= new HashMap
<String
, XmlObject
>();
224 Set keySet
= doc
.keySet();
225 Iterator iter
= keySet
.iterator();
226 while (iter
.hasNext()){
227 String key
= (String
)iter
.next();
228 XmlObject item
= cloneXmlObject(doc
.get(key
), true);
229 result
.put(key
, item
);
231 fpdModuleSA
.put(fpdModuleId
, result
);
235 Query overrided module surface area information. If current is Package
236 or Platform build, also include the information from FPD file.
238 <p>Note that surface area parsing is incremental. That means the method will
239 only parse the MSA and MBD files if necessary. </p>
241 @param moduleName the base name of the module
242 @return the overrided module surface area information
244 MSA or MBD is not valid
246 public synchronized static Map
<String
, XmlObject
> getDoc(FpdModuleIdentification fpdModuleId
) throws Exception
{
247 if (parsedModules
.containsKey(fpdModuleId
)) {
248 return parsedModules
.get(fpdModuleId
);
250 Map
<String
, XmlObject
> doc
= new HashMap
<String
, XmlObject
>();
251 ModuleIdentification moduleId
= fpdModuleId
.getModule();
253 // First part: get the MSA files info
255 doc
= getNativeMsa(moduleId
);
258 // Second part: put build options
260 doc
.put("BuildOptions", fpdBuildOptions
);
263 // Third part: get Module info from FPD, such as Library instances, PCDs
265 if (fpdModuleSA
.containsKey(fpdModuleId
)){
267 // merge module info in FPD to final Doc
268 // For Library Module, do nothing here
270 doc
.putAll(fpdModuleSA
.get(fpdModuleId
));
272 parsedModules
.put(fpdModuleId
, doc
);
276 public synchronized static Map
<String
, XmlObject
> getDoc(ModuleIdentification moduleId
, String arch
) throws Exception
{
277 FpdModuleIdentification fpdModuleId
= new FpdModuleIdentification(moduleId
, arch
);
278 return getDoc(fpdModuleId
);
281 Query the native MSA information with module base name.
283 <p>Note that MSA parsing is incremental. That means the method will
284 only to parse the MSA files when never parsed before. </p>
286 @param moduleName the base name of the module
287 @return the native MSA information
289 MSA file is not valid
291 public synchronized static Map
<String
, XmlObject
> getNativeMsa(ModuleIdentification moduleId
) throws Exception
{
292 if (nativeMsa
.containsKey(moduleId
)) {
293 return nativeMsa
.get(moduleId
);
295 File msaFile
= getMsaFile(moduleId
);
296 Map
<String
, XmlObject
> msaMap
= getNativeMsa(msaFile
);
297 nativeMsa
.put(moduleId
, msaMap
);
301 public synchronized static Map
<String
, XmlObject
> getNativeMsa(File msaFile
) throws Exception
{
304 ModuleSurfaceAreaDocument doc
= (ModuleSurfaceAreaDocument
)XmlObject
.Factory
.parse(msaFile
);
306 // Validate File if they accord with XML Schema
308 // if ( ! doc.validate()){
309 // throw new Exception("Module Surface Area file [" + msaFile.getPath() + "] is invalid.");
314 ModuleSurfaceArea msa
= doc
.getModuleSurfaceArea();
315 Map
<String
, XmlObject
> msaMap
= new HashMap
<String
, XmlObject
>();
316 msaMap
.put("ModuleSurfaceArea", msa
);
317 msaMap
.put("MsaHeader", cloneXmlObject(msa
.getMsaHeader(), true));
318 msaMap
.put("LibraryClassDefinitions", cloneXmlObject(msa
.getLibraryClassDefinitions(), true));
319 msaMap
.put("SourceFiles", cloneXmlObject(msa
.getSourceFiles(), true));
320 msaMap
.put("PackageDependencies", cloneXmlObject(msa
.getPackageDependencies(), true));
321 msaMap
.put("Protocols", cloneXmlObject(msa
.getProtocols(), true));
322 msaMap
.put("PPIs", cloneXmlObject(msa
.getPPIs(), true));
323 msaMap
.put("Guids", cloneXmlObject(msa
.getGuids(), true));
324 msaMap
.put("Externs", cloneXmlObject(msa
.getExterns(), true));
327 catch (Exception ex
){
328 throw new Exception(ex
.getMessage());
332 public static Map
<String
, XmlObject
> getFpdBuildOptions() {
333 Map
<String
, XmlObject
> map
= new HashMap
<String
, XmlObject
>();
334 map
.put("BuildOptions", fpdBuildOptions
);
338 public static void setFpdBuildOptions(XmlObject fpdBuildOptions
) throws Exception
{
339 GlobalData
.fpdBuildOptions
= cloneXmlObject(fpdBuildOptions
, true);
342 public static XmlObject
getFpdDynamicPcds() {
343 return fpdDynamicPcds
;
346 public static void setFpdDynamicPcds(XmlObject fpdDynamicPcds
) {
347 GlobalData
.fpdDynamicPcds
= fpdDynamicPcds
;
350 //////////////////////////////////////////////
351 //////////////////////////////////////////////
353 public static Set
<ModuleIdentification
> getModules(PackageIdentification packageId
){
354 Spd spd
= spdTable
.get(packageId
);
356 Set
<ModuleIdentification
> dummy
= new HashSet
<ModuleIdentification
>();
360 return spd
.getModules();
364 public synchronized static PlatformIdentification
getPlatform(String name
) throws Exception
{
365 Iterator iter
= platformList
.iterator();
366 while(iter
.hasNext()){
367 PlatformIdentification platformId
= (PlatformIdentification
)iter
.next();
368 if (platformId
.getName().equalsIgnoreCase(name
)) {
369 GlobalData
.log
.info("Platform: " + platformId
+ platformId
.getFpdFile());
373 throw new Exception("Can't find platform [" + name
+ "] in current workspace. ");
376 public synchronized static File
getPackageFile(PackageIdentification packageId
) throws Exception
{
377 Iterator iter
= packageList
.iterator();
378 while(iter
.hasNext()){
379 PackageIdentification packageItem
= (PackageIdentification
)iter
.next();
380 if (packageItem
.equals(packageId
)) {
381 packageId
.setName(packageItem
.getName());
382 return packageItem
.getSpdFile();
385 throw new Exception("Can't find " + packageId
+ " in current workspace. ");
388 public synchronized static File
getModuleFile(ModuleIdentification moduleId
) throws Exception
{
389 PackageIdentification packageId
= getPackageForModule(moduleId
);
390 moduleId
.setPackage(packageId
);
391 Spd spd
= spdTable
.get(packageId
);
392 return spd
.getModuleFile(moduleId
);
395 // expanded by FrameworkWizard
397 public synchronized static XmlObject
getModuleXmlObject(ModuleIdentification moduleId
) throws Exception
{
398 PackageIdentification packageId
= getPackageForModule(moduleId
);
399 moduleId
.setPackage(packageId
);
400 Spd spd
= spdTable
.get(packageId
);
401 return spd
.msaDocMap
.get(moduleId
);
404 public synchronized static XmlObject
getPackageXmlObject(PackageIdentification packageId
) {
405 Spd spd
= spdTable
.get(packageId
);
407 return spd
.spdDocMap
.get("PackageSurfaceArea");
412 public synchronized static Set
<PackageIdentification
> getPackageList(){
416 private static XmlObject
cloneXmlObject(XmlObject object
, boolean deep
) throws Exception
{
417 if ( object
== null) {
420 XmlObject result
= null;
422 result
= XmlObject
.Factory
.parse(object
.getDomNode()
424 } catch (Exception ex
) {
425 throw new Exception(ex
.getMessage());
430 public static ModuleIdentification
getModuleId(String key
){
432 // Get ModuleGuid, ModuleVersion, PackageGuid, PackageVersion, Arch into string array.
434 String
[] keyPart
= key
.split(" ");
435 Set
<PackageIdentification
> spi
= GlobalData
.getPackageList();
436 Iterator ispi
= spi
.iterator();
438 while(ispi
.hasNext()) {
439 PackageIdentification pi
= (PackageIdentification
)ispi
.next();
440 if ( !pi
.getGuid().equalsIgnoreCase(keyPart
[2])){
444 if (keyPart
[3] != null && keyPart
[3].length() > 0 && !keyPart
[3].equals("null")){
445 if(!pi
.getVersion().equals(keyPart
[3])){
449 Set
<ModuleIdentification
> smi
= GlobalData
.getModules(pi
);
450 Iterator ismi
= smi
.iterator();
451 while(ismi
.hasNext()) {
452 ModuleIdentification mi
= (ModuleIdentification
)ismi
.next();
453 if (mi
.getGuid().equalsIgnoreCase(keyPart
[0])){
454 if (keyPart
[1] != null && keyPart
[1].length() > 0 && !keyPart
[1].equals("null")){
455 if(!mi
.getVersion().equals(keyPart
[1])){
467 public static Vector
<String
> getModuleSupArchs(ModuleIdentification mi
) throws Exception
{
468 Vector
<String
> vArchs
= null;
469 ModuleSurfaceAreaDocument
.ModuleSurfaceArea msa
= (ModuleSurfaceAreaDocument
.ModuleSurfaceArea
)getModuleXmlObject(mi
);
470 if (msa
.getModuleDefinitions() == null || msa
.getModuleDefinitions().getSupportedArchitectures() == null) {
473 ListIterator li
= msa
.getModuleDefinitions().getSupportedArchitectures().listIterator();
474 while (li
.hasNext()) {
475 if (vArchs
== null) {
476 vArchs
= new Vector
<String
>();
478 vArchs
.add((String
)li
.next());
486 final class KeyComparator
implements Comparator
<String
> {
487 public int compare(String x
, String y
) {
488 return x
.compareToIgnoreCase(y
);