4 This class is to reorder library instance sequence according to library
7 Copyright (c) 2006, Intel Corporation
8 All rights reserved. This program and the accompanying materials
9 are licensed and made available under the terms and conditions of the BSD License
10 which accompanies this distribution. The full text of the license may be found at
11 http://opensource.org/licenses/bsd-license.php
13 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
14 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 package org
.tianocore
.build
.autogen
;
19 import java
.util
.ArrayList
;
20 import java
.util
.HashMap
;
21 import java
.util
.List
;
24 import org
.apache
.xmlbeans
.XmlObject
;
25 import org
.tianocore
.build
.global
.GlobalData
;
26 import org
.tianocore
.build
.global
.SurfaceAreaQuery
;
27 import org
.tianocore
.build
.id
.ModuleIdentification
;
30 This class This class is to reorder library instance sequence according to
33 public class AutogenLibOrder
{
35 /// The map of library class and its library instance.
37 private Map
<String
, ModuleIdentification
> libClassMap
= new HashMap
<String
, ModuleIdentification
>();
40 /// The map of library instance and its implemet libraryClass.
42 private Map
<ModuleIdentification
, String
[]> libInstanceMap
= new HashMap
<ModuleIdentification
, String
[]>();
45 /// List of library instance. It is String[3] list, String[0] is libraryName,
46 /// String[1] is libraryConstructor name, String[2] is libDestructor name.
48 private List
<LibraryInstanceNode
> libInstanceList
= new ArrayList
<LibraryInstanceNode
>();
53 This function mainly initialize some member variable.
55 @param libraryList List of the library instance.
58 AutogenLibOrder(ModuleIdentification
[] libraryList
, String arch
) throws Exception
{
59 LibraryInstanceNode libInstanceNode
;
60 String
[] libClassDeclList
= null;
61 String
[] libClassConsmList
= null;
63 for (int i
= 0; i
< libraryList
.length
; i
++) {
65 // Add libraryInstance in to libInstanceList.
67 Map
<String
, XmlObject
> libDoc
= GlobalData
.getDoc(libraryList
[i
], arch
);
68 SurfaceAreaQuery
.push(libDoc
);
69 libInstanceNode
= new LibraryInstanceNode (libraryList
[i
],SurfaceAreaQuery
.getLibConstructorName(), SurfaceAreaQuery
.getLibDestructorName());
70 libInstanceList
.add(libInstanceNode
);
73 // Add library instance and consumed library class list to
76 libClassConsmList
= SurfaceAreaQuery
77 .getLibraryClasses(CommonDefinition
.ALWAYSCONSUMED
, arch
);
78 if (libClassConsmList
!= null) {
79 String
[] classStr
= new String
[libClassConsmList
.length
];
80 for (int k
= 0; k
< libClassConsmList
.length
; k
++) {
81 classStr
[k
] = libClassConsmList
[k
];
83 if (this.libInstanceMap
.containsKey(libraryList
[i
])) {
85 libraryList
[i
].getName()
86 + "this library instance already exists, please check the library instance list!");
88 this.libInstanceMap
.put(libraryList
[i
], classStr
);
93 // Add library class and library instance map.
95 libClassDeclList
= SurfaceAreaQuery
96 .getLibraryClasses(CommonDefinition
.ALWAYSPRODUCED
, arch
);
97 if (libClassDeclList
!= null) {
98 for (int j
= 0; j
< libClassDeclList
.length
; j
++) {
99 if (this.libClassMap
.containsKey(libClassDeclList
[j
])) {
100 System
.out
.println(libClassDeclList
[j
]
101 + " class is already implement by "
102 + this.libClassMap
.get(libClassDeclList
[j
]));
103 throw new Exception("Library Class: " + libClassDeclList
104 + " already has a library instance!");
106 this.libClassMap
.put(libClassDeclList
[j
], libraryList
[i
]);
110 SurfaceAreaQuery
.pop();
114 // Check is the library instance list meet the require;
116 //for (int s = 0; s < this.libInstanceList.size(); s++) {
117 // String[] libClass = this.libInstanceMap.get(this.libInstanceList
119 // if (libClass != null) {
120 // for (int t = 0; t < libClass.length; t++) {
121 // if (this.libClassMap.get(libClass[t]) == null) {
123 // Note: There exist a kind of module which depend on
124 // library class with no instance or whose instance will
125 // never be linked into the module.
126 // For this satuation, the module has the description of
127 // library class in MSA file but no description of
128 // corresponding library instance in MBD file. There
129 // will be a warnig message given here after a standard
130 // log way has been decided.
141 This function reorder the library instance according the library class
144 @return List which content the ordered library instance.
146 List
<ModuleIdentification
> orderLibInstance() {
147 List
<ModuleIdentification
> orderList
= new ArrayList
<ModuleIdentification
>();
149 // Stack of node which track the library instance name ant its visiting
152 List
<Node
> stackList
= new ArrayList
<Node
>();
154 ModuleIdentification libInstanceId
= null;
155 if (libInstanceList
.size() < 0) {
160 // Reorder the library instance.
162 for (int i
= 0; i
< libInstanceList
.size(); i
++) {
164 // If library instance is already in the order list skip it.
166 if (isInLibInstance(orderList
, libInstanceList
.get(i
).libId
)) {
170 Node node
= new Node(libInstanceList
.get(i
).libId
, false);
172 // Use stack to reorder library instance.
173 // Push node to stack.
176 while (stackList
.size() > 0) {
177 stackSize
= stackList
.size() - 1;
179 // Pop the first node in stack. If the node flag has been visited
180 // add this node to orderlist and remove it from stack.
182 if (stackList
.get(stackSize
).isVisit
) {
183 if (!isInLibInstance(orderList
,
184 stackList
.get(stackSize
).nodeId
)) {
185 orderList
.add(stackList
.get(stackSize
).nodeId
);
186 stackList
.remove(stackSize
);
191 // Get the node value and set visit flag as true.
193 stackList
.get(stackList
.size() - 1).isVisit
= true;
194 String
[] libClassList
= this.libInstanceMap
.get(stackList
195 .get(stackSize
).nodeId
);
197 // Push the node dependence library instance to the stack.
199 if (libClassList
!= null) {
200 for (int j
= 0; j
< libClassList
.length
; j
++) {
201 libInstanceId
= this.libClassMap
.get(libClassList
[j
]);
202 if (libInstanceId
!= null
203 && !isInLibInstance(orderList
, libInstanceId
)) {
205 // If and only if the currently library instance
206 // is not in stack and it have constructor or
207 // destructor function, push this library
208 // instacne in stack.
210 if (!isInStackList(stackList
, this.libClassMap
211 .get(libClassList
[j
])) && isHaveConsDestructor(libInstanceId
)) {
212 stackList
.add(new Node(this.libClassMap
213 .get(libClassList
[j
]), false));
227 This function check does the library instance already in the list.
229 @param list List of the library instance.
230 @param instanceName Name of library instance.
231 @return "true" the library instance in list |
232 "false" the library instance is not in list.
234 private boolean isInLibInstance(List
<ModuleIdentification
> list
, ModuleIdentification instanceId
) {
235 for (int i
= 0; i
< list
.size(); i
++) {
237 if (instanceId
.equals(list
.get(i
))) {
247 This function check if the node already in the stack.
250 @param nodeName Name of node.
251 @return "true" if node have in stack |
252 "false" if node don't in stack.
254 private boolean isInStackList(List
<Node
> list
, ModuleIdentification instanceId
) {
255 for (int i
= 0; i
< list
.size(); i
++) {
256 if (instanceId
.equals(list
.get(i
).nodeId
)) {
266 This function check if the library have constructor or destructor
269 @param libName Name of library
270 @return "true" if library have constructor or desconstructor |
271 "false" if library don't have constructor
274 private boolean isHaveConsDestructor (ModuleIdentification libNode
){
275 for (int i
= 0; i
< libInstanceList
.size(); i
++){
276 if (libInstanceList
.get(i
).libId
.equals(libNode
)){
277 if (libInstanceList
.get(i
).constructorName
!= null || libInstanceList
.get(i
).deconstructorName
!= null){
289 This class is used as stack node.
293 ModuleIdentification nodeId
;
297 Node(ModuleIdentification nodeId
, boolean isVisit
) {
298 this.nodeId
= nodeId
;
299 this.isVisit
= false;
305 This class is used to store LibrayInstance and it's deconstructor and constructor
308 class LibraryInstanceNode
{
309 ModuleIdentification libId
;
310 String deconstructorName
;
311 String constructorName
;
313 LibraryInstanceNode (ModuleIdentification libId
, String deconstructor
, String constructor
){
315 this.deconstructorName
= deconstructor
;
316 this.constructorName
= constructor
;