]> git.proxmox.com Git - mirror_edk2.git/blob - Tools/Source/FrameworkWizard/src/org/tianocore/frameworkwizard/platform/ui/global/WorkspaceProfile.java
71278e9a1eea5da391b5368c9050cad46196f699
[mirror_edk2.git] / Tools / Source / FrameworkWizard / src / org / tianocore / frameworkwizard / platform / ui / global / WorkspaceProfile.java
1 /** @file
2 WorkspaceProfile class.
3
4 WorkspaceProfile 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.PcdCodedDocument;
24 import org.tianocore.ModuleSurfaceAreaDocument.ModuleSurfaceArea;
25 import org.tianocore.frameworkwizard.platform.ui.id.FpdModuleIdentification;
26 import org.tianocore.frameworkwizard.platform.ui.id.ModuleIdentification;
27 import org.tianocore.frameworkwizard.platform.ui.id.PackageIdentification;
28 import org.tianocore.frameworkwizard.platform.ui.id.PlatformIdentification;
29
30 import java.io.File;
31 import java.util.Comparator;
32 import java.util.HashMap;
33 import java.util.HashSet;
34 import java.util.Iterator;
35 import java.util.List;
36 import java.util.ListIterator;
37 import java.util.Map;
38 import java.util.Set;
39 import java.util.Vector;
40 import java.util.logging.Logger;
41
42 /**
43 WorkspaceProfile provide initializing, instoring, querying and update global data.
44 It is a bridge to intercommunicate between multiple component, such as AutoGen,
45 PCD and so on.
46
47 <p>Note that all global information are initialized incrementally. All data will
48 parse and record only of necessary during build time. </p>
49
50 @since GenBuild 1.0
51 **/
52 public class WorkspaceProfile {
53
54
55 public static Logger log = Logger.getAnonymousLogger();
56 public static KeyComparator comparator = new KeyComparator();
57 ///
58 /// Record current WORKSPACE Directory
59 ///
60 private static String workspaceDir = "";
61
62 ///
63 /// Be used to ensure Global data will be initialized only once.
64 ///
65 // private static boolean globalFlag = false;
66
67 ///
68 /// Framework Database information: package list and platform list
69 ///
70 private static Set<PackageIdentification> packageList = new HashSet<PackageIdentification>();
71
72 private static Set<PlatformIdentification> platformList = new HashSet<PlatformIdentification>();
73
74 ///
75 /// Every detail SPD informations: Module list, Library class definition,
76 /// Package header file, GUID/PPI/Protocol definitions
77 ///
78 private static final Map<PackageIdentification, Spd> spdTable = new HashMap<PackageIdentification, Spd>();
79
80 ///
81 /// Build informations are divided into three parts:
82 /// 1. From MSA 2. From FPD 3. From FPD' ModuleSA
83 ///
84 private static Map<ModuleIdentification, Map<String, XmlObject>> nativeMsa = new HashMap<ModuleIdentification, Map<String, XmlObject>>();
85
86 private static Map<FpdModuleIdentification, Map<String, XmlObject>> fpdModuleSA= new HashMap<FpdModuleIdentification, Map<String, XmlObject>>();
87
88 private static XmlObject fpdBuildOptions;
89
90 private static XmlObject fpdDynamicPcds;
91
92 ///
93 /// Parsed modules list
94 ///
95 private static Map<FpdModuleIdentification, Map<String, XmlObject>> parsedModules = new HashMap<FpdModuleIdentification, Map<String, XmlObject>>();
96
97 ///
98 /// built modules list with ARCH, TARGET, TOOLCHAIN
99 ///
100 private static Set<FpdModuleIdentification> builtModules = new HashSet<FpdModuleIdentification>();
101
102 /**
103 Parse framework database (DB) and all SPD files listed in DB to initialize
104 the environment for next build. This method will only be executed only once
105 in the whole build process.
106
107 @param workspaceDatabaseFile the file name of framework database
108 @param workspaceDir current workspace directory path
109 @throws Exception
110 Framework Dababase or SPD or MSA file is not valid
111 **/
112 public synchronized static void initInfo(String workspaceDatabaseFile, String workspaceDir) throws Exception {
113
114 //
115 // Backup workspace directory. It will be used by other method
116 //
117 WorkspaceProfile.workspaceDir = workspaceDir.replaceAll("(\\\\)", "/");
118 File dbFile = new File(workspaceDir + File.separatorChar + workspaceDatabaseFile);
119 try {
120 FrameworkDatabaseDocument db = (FrameworkDatabaseDocument) XmlObject.Factory.parse(dbFile);
121 //
122 // validate FrameworkDatabaseFile
123 //
124 // if (! db.validate()) {
125 // throw new Exception("Framework Database file [" + dbFile.getPath() + "] is invalid.");
126 // }
127 //
128 // Get package list
129 //
130 packageList.clear();
131 List<DbPathAndFilename> packages = db.getFrameworkDatabase().getPackageList().getFilenameList();
132
133 Iterator iter = packages.iterator();
134 while (iter.hasNext()) {
135 DbPathAndFilename dbPath = (DbPathAndFilename)iter.next();
136 String fileName = dbPath.getStringValue();
137 Spd spd = new Spd(new File(workspaceDir + File.separatorChar + fileName));
138 packageList.add(spd.getPackageId());
139 spdTable.put(spd.getPackageId(), spd);
140 }
141
142
143 } catch (Exception e) {
144 e.printStackTrace();
145 throw new Exception("Parse workspace Database [" + dbFile.getPath() + "] Error.\n" + e.getMessage());
146 }
147 }
148
149 /**
150 Get the current WORKSPACE Directory.
151
152 @return current workspace directory
153 **/
154 public synchronized static String getWorkspacePath() {
155 return workspaceDir;
156 }
157
158
159 /**
160 Get the MSA file name with absolute path
161 */
162 public synchronized static File getMsaFile(ModuleIdentification moduleId) throws Exception {
163 File msaFile = null;
164 //
165 // TBD. Do only when package is null.
166 //
167 Iterator iter = packageList.iterator();
168 while (iter.hasNext()) {
169 PackageIdentification packageId = (PackageIdentification)iter.next();
170 Spd spd = spdTable.get(packageId);
171 msaFile = spd.getModuleFile(moduleId);
172 if (msaFile != null ) {
173 break ;
174 }
175 }
176 if (msaFile == null){
177 throw new Exception("Can not find Module [" + moduleId.getName() + "] in any packages in this workspace.");
178 }
179 else {
180 return msaFile;
181 }
182 }
183
184 public synchronized static PackageIdentification getPackageForModule(ModuleIdentification moduleId) {
185 //
186 // If package already defined in module
187 //
188 if (moduleId.getPackage() != null) {
189 return moduleId.getPackage();
190 }
191
192 PackageIdentification packageId = null;
193 Iterator iter = packageList.iterator();
194 while (iter.hasNext()) {
195 packageId = (PackageIdentification)iter.next();
196
197 Spd spd = spdTable.get(packageId);
198 if (spd.getModuleFile(moduleId) != null ) {
199 moduleId.setPackage(packageId);
200 break ;
201 }
202 }
203 if (packageId == null){
204 return null;
205 }
206 else {
207 return packageId;
208 }
209 }
210
211 /**
212 Difference between build and parse: ToolChain and Target
213 **/
214 public synchronized static boolean isModuleBuilt(FpdModuleIdentification moduleId) {
215 return builtModules.contains(moduleId);
216 }
217
218 public synchronized static void registerBuiltModule(FpdModuleIdentification fpdModuleId) {
219 builtModules.add(fpdModuleId);
220 }
221
222
223 public synchronized static void registerFpdModuleSA(FpdModuleIdentification fpdModuleId, Map<String, XmlObject> doc) throws Exception{
224 Map<String, XmlObject> result = new HashMap<String, XmlObject>();
225 Set keySet = doc.keySet();
226 Iterator iter = keySet.iterator();
227 while (iter.hasNext()){
228 String key = (String)iter.next();
229 XmlObject item = cloneXmlObject(doc.get(key), true);
230 result.put(key, item);
231 }
232 fpdModuleSA.put(fpdModuleId, result);
233 }
234
235 /**
236 Query overrided module surface area information. If current is Package
237 or Platform build, also include the information from FPD file.
238
239 <p>Note that surface area parsing is incremental. That means the method will
240 only parse the MSA and MBD files if necessary. </p>
241
242 @param moduleName the base name of the module
243 @return the overrided module surface area information
244 @throws Exception
245 MSA or MBD is not valid
246 **/
247 public synchronized static Map<String, XmlObject> getDoc(FpdModuleIdentification fpdModuleId) throws Exception {
248 if (parsedModules.containsKey(fpdModuleId)) {
249 return parsedModules.get(fpdModuleId);
250 }
251 Map<String, XmlObject> doc = new HashMap<String, XmlObject>();
252 ModuleIdentification moduleId = fpdModuleId.getModule();
253 //
254 // First part: get the MSA files info
255 //
256 doc = getNativeMsa(moduleId);
257
258 //
259 // Second part: put build options
260 //
261 doc.put("BuildOptions", fpdBuildOptions);
262
263 //
264 // Third part: get Module info from FPD, such as Library instances, PCDs
265 //
266 if (fpdModuleSA.containsKey(fpdModuleId)){
267 //
268 // merge module info in FPD to final Doc
269 // For Library Module, do nothing here
270 //
271 doc.putAll(fpdModuleSA.get(fpdModuleId));
272 }
273 parsedModules.put(fpdModuleId, doc);
274 return doc;
275 }
276
277 public synchronized static Map<String, XmlObject> getDoc(ModuleIdentification moduleId, String arch) throws Exception {
278 FpdModuleIdentification fpdModuleId = new FpdModuleIdentification(moduleId, arch);
279 return getDoc(fpdModuleId);
280 }
281 /**
282 Query the native MSA information with module base name.
283
284 <p>Note that MSA parsing is incremental. That means the method will
285 only to parse the MSA files when never parsed before. </p>
286
287 @param moduleName the base name of the module
288 @return the native MSA information
289 @throws Exception
290 MSA file is not valid
291 **/
292 public synchronized static Map<String, XmlObject> getNativeMsa(ModuleIdentification moduleId) throws Exception {
293 if (nativeMsa.containsKey(moduleId)) {
294 return nativeMsa.get(moduleId);
295 }
296 File msaFile = getMsaFile(moduleId);
297 Map<String, XmlObject> msaMap = getNativeMsa(msaFile);
298 nativeMsa.put(moduleId, msaMap);
299 return msaMap;
300 }
301
302 public synchronized static Map<String, XmlObject> getNativeMsa(File msaFile) throws Exception {
303
304 try {
305 ModuleSurfaceAreaDocument doc = (ModuleSurfaceAreaDocument)XmlObject.Factory.parse(msaFile);
306 //
307 // Validate File if they accord with XML Schema
308 //
309 // if ( ! doc.validate()){
310 // throw new Exception("Module Surface Area file [" + msaFile.getPath() + "] is invalid.");
311 // }
312 //
313 // parse MSA file
314 //
315 ModuleSurfaceArea msa= doc.getModuleSurfaceArea();
316 Map<String, XmlObject> msaMap = new HashMap<String, XmlObject>();
317 msaMap.put("ModuleSurfaceArea", msa);
318 msaMap.put("MsaHeader", cloneXmlObject(msa.getMsaHeader(), true));
319 msaMap.put("LibraryClassDefinitions", cloneXmlObject(msa.getLibraryClassDefinitions(), true));
320 msaMap.put("SourceFiles", cloneXmlObject(msa.getSourceFiles(), true));
321 msaMap.put("PackageDependencies", cloneXmlObject(msa.getPackageDependencies(), true));
322 msaMap.put("Protocols", cloneXmlObject(msa.getProtocols(), true));
323 msaMap.put("PPIs", cloneXmlObject(msa.getPPIs(), true));
324 msaMap.put("Guids", cloneXmlObject(msa.getGuids(), true));
325 msaMap.put("Externs", cloneXmlObject(msa.getExterns(), true));
326 return msaMap;
327 }
328 catch (Exception ex){
329 throw new Exception(ex.getMessage());
330 }
331 }
332
333 public static Map<String, XmlObject> getFpdBuildOptions() {
334 Map<String, XmlObject> map = new HashMap<String, XmlObject>();
335 map.put("BuildOptions", fpdBuildOptions);
336 return map;
337 }
338
339 public static void setFpdBuildOptions(XmlObject fpdBuildOptions) throws Exception{
340 WorkspaceProfile.fpdBuildOptions = cloneXmlObject(fpdBuildOptions, true);
341 }
342
343 public static XmlObject getFpdDynamicPcds() {
344 return fpdDynamicPcds;
345 }
346
347 public static void setFpdDynamicPcds(XmlObject fpdDynamicPcds) {
348 WorkspaceProfile.fpdDynamicPcds = fpdDynamicPcds;
349 }
350
351 //////////////////////////////////////////////
352 //////////////////////////////////////////////
353
354 public static Set<ModuleIdentification> getModules(PackageIdentification packageId){
355 Spd spd = spdTable.get(packageId);
356 if (spd == null ) {
357 Set<ModuleIdentification> dummy = new HashSet<ModuleIdentification>();
358 return dummy;
359 }
360 else {
361 return spd.getModules();
362 }
363 }
364
365 public synchronized static PlatformIdentification getPlatform(String name) throws Exception {
366 Iterator iter = platformList.iterator();
367 while(iter.hasNext()){
368 PlatformIdentification platformId = (PlatformIdentification)iter.next();
369 if (platformId.getName().equalsIgnoreCase(name)) {
370 WorkspaceProfile.log.info("Platform: " + platformId + platformId.getFpdFile());
371 return platformId;
372 }
373 }
374 throw new Exception("Can not find platform [" + name + "] in the current workspace. ");
375 }
376
377 public synchronized static File getPackageFile(PackageIdentification packageId) throws Exception {
378 Iterator iter = packageList.iterator();
379 while(iter.hasNext()){
380 PackageIdentification packageItem = (PackageIdentification)iter.next();
381 if (packageItem.equals(packageId)) {
382 packageId.setName(packageItem.getName());
383 return packageItem.getSpdFile();
384 }
385 }
386 throw new Exception("Can not find " + packageId + " in the current workspace. ");
387 }
388
389 public synchronized static File getModuleFile(ModuleIdentification moduleId) throws Exception {
390 PackageIdentification packageId = getPackageForModule(moduleId);
391 moduleId.setPackage(packageId);
392 Spd spd = spdTable.get(packageId);
393 return spd.getModuleFile(moduleId);
394 }
395 //
396 // expanded by FrameworkWizard
397 //
398 public synchronized static XmlObject getModuleXmlObject(ModuleIdentification moduleId) throws Exception {
399 PackageIdentification packageId = getPackageForModule(moduleId);
400 moduleId.setPackage(packageId);
401 Spd spd = spdTable.get(packageId);
402 return spd.msaDocMap.get(moduleId);
403 }
404
405 public synchronized static XmlObject getPackageXmlObject(PackageIdentification packageId) {
406 Spd spd = spdTable.get(packageId);
407 if (spd != null){
408 return spd.spdDocMap.get("PackageSurfaceArea");
409 }
410 return null;
411 }
412
413 public synchronized static Set<PackageIdentification> getPackageList(){
414 return packageList;
415 }
416 ///// remove!!
417 private static XmlObject cloneXmlObject(XmlObject object, boolean deep) throws Exception {
418 if ( object == null) {
419 return null;
420 }
421 XmlObject result = null;
422 try {
423 result = XmlObject.Factory.parse(object.getDomNode()
424 .cloneNode(deep));
425 } catch (Exception ex) {
426 throw new Exception(ex.getMessage());
427 }
428 return result;
429 }
430
431 public static ModuleIdentification getModuleId(String key){
432 //
433 // Get ModuleGuid, ModuleVersion, PackageGuid, PackageVersion, Arch into string array.
434 //
435 String[] keyPart = key.split(" ");
436 Set<PackageIdentification> spi = WorkspaceProfile.getPackageList();
437 Iterator ispi = spi.iterator();
438
439 while(ispi.hasNext()) {
440 PackageIdentification pi = (PackageIdentification)ispi.next();
441 if ( !pi.getGuid().equalsIgnoreCase(keyPart[2])){
442
443 continue;
444 }
445 if (keyPart[3] != null && keyPart[3].length() > 0 && !keyPart[3].equals("null")){
446 if(!pi.getVersion().equals(keyPart[3])){
447 continue;
448 }
449 }
450 Set<ModuleIdentification> smi = WorkspaceProfile.getModules(pi);
451 Iterator ismi = smi.iterator();
452 while(ismi.hasNext()) {
453 ModuleIdentification mi = (ModuleIdentification)ismi.next();
454 if (mi.getGuid().equalsIgnoreCase(keyPart[0])){
455 if (keyPart[1] != null && keyPart[1].length() > 0 && !keyPart[1].equals("null")){
456 if(!mi.getVersion().equals(keyPart[1])){
457 continue;
458 }
459 }
460
461 return mi;
462 }
463 }
464 }
465 return null;
466 }
467
468 public static Vector<String> getModuleSupArchs(ModuleIdentification mi) throws Exception {
469 Vector<String> vArchs = null;
470 ModuleSurfaceAreaDocument.ModuleSurfaceArea msa = (ModuleSurfaceAreaDocument.ModuleSurfaceArea)getModuleXmlObject(mi);
471 if (msa.getModuleDefinitions() == null || msa.getModuleDefinitions().getSupportedArchitectures() == null) {
472 return vArchs;
473 }
474 ListIterator li = msa.getModuleDefinitions().getSupportedArchitectures().listIterator();
475 while (li.hasNext()) {
476 if (vArchs == null) {
477 vArchs = new Vector<String>();
478 }
479 vArchs.add((String)li.next());
480 }
481
482 return vArchs;
483 }
484
485 public static boolean pcdInMsa (String cName, String tsGuid, ModuleIdentification mi) throws Exception {
486 ModuleSurfaceAreaDocument.ModuleSurfaceArea msa = (ModuleSurfaceAreaDocument.ModuleSurfaceArea)getModuleXmlObject(mi);
487 if (msa.getPcdCoded() == null || msa.getPcdCoded().getPcdEntryList() == null) {
488 return false;
489 }
490 ListIterator li = msa.getPcdCoded().getPcdEntryList().listIterator();
491 while (li.hasNext()) {
492 PcdCodedDocument.PcdCoded.PcdEntry msaPcd = (PcdCodedDocument.PcdCoded.PcdEntry)li.next();
493 if (msaPcd.getCName().equals(cName) && msaPcd.getTokenSpaceGuidCName().equals(tsGuid)) {
494 return true;
495 }
496 }
497 return false;
498 }
499
500 }
501
502 final class KeyComparator implements Comparator<String> {
503 public int compare(String x, String y) {
504 return x.compareToIgnoreCase(y);
505 }
506
507 }
508