]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - Tools/Java/Source/GenBuild/org/tianocore/build/autogen/AutogenLibOrder.java
fix some minor warning
[mirror_edk2.git] / Tools / Java / Source / GenBuild / org / tianocore / build / autogen / AutogenLibOrder.java
... / ...
CommitLineData
1/**@file\r
2 AutogenLibOrder class.\r
3\r
4 This class is to reorder library instance sequence according to library \r
5 dependence.\r
6 \r
7 Copyright (c) 2006, Intel Corporation\r
8 All rights reserved. This program and the accompanying materials\r
9 are licensed and made available under the terms and conditions of the BSD License\r
10 which accompanies this distribution. The full text of the license may be found at\r
11 http://opensource.org/licenses/bsd-license.php\r
12 \r
13 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
14 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
15\r
16 **/\r
17package org.tianocore.build.autogen;\r
18\r
19import java.util.ArrayList;\r
20import java.util.HashMap;\r
21import java.util.Iterator;\r
22import java.util.LinkedList;\r
23import java.util.List;\r
24import java.util.Map;\r
25import java.util.Stack;\r
26import java.util.HashSet;\r
27\r
28import org.apache.xmlbeans.XmlObject;\r
29import org.tianocore.build.exception.AutoGenException;\r
30import org.tianocore.build.global.GlobalData;\r
31import org.tianocore.build.global.SurfaceAreaQuery;\r
32import org.tianocore.build.id.ModuleIdentification;\r
33import org.tianocore.common.exception.EdkException;\r
34import org.tianocore.common.logger.EdkLog;\r
35/**\r
36 This class This class is to reorder library instance sequence according to\r
37 library dependence.\r
38**/\r
39public class AutogenLibOrder {\r
40 ///\r
41 /// The map of library class and its library instance.\r
42 ///\r
43 private Map<String, ModuleIdentification> libClassMap = new HashMap<String, ModuleIdentification>();\r
44\r
45 ///\r
46 /// The map of library instance and its implemet libraryClass.\r
47 ///\r
48 private Map<ModuleIdentification, String[]> libInstanceMap = new HashMap<ModuleIdentification, String[]>();\r
49\r
50 ///\r
51 /// List of library instance. It is String[3] list, String[0] is libraryName,\r
52 /// String[1] is libraryConstructor name, String[2] is libDestructor name.\r
53 ///\r
54 private List<LibraryInstanceNode> libInstanceList = new ArrayList<LibraryInstanceNode>();\r
55 \r
56 /**\r
57 Constructor function\r
58 \r
59 This function mainly initialize some member variable.\r
60 \r
61 @param libraryList List of the library instance.\r
62 @throws Exception\r
63 **/\r
64 AutogenLibOrder(ModuleIdentification[] libraryList, String arch) throws EdkException {\r
65 LibraryInstanceNode libInstanceNode;\r
66 String[] libClassDeclList = null;\r
67 String[] libClassConsmList = null;\r
68 \r
69 for (int i = 0; i < libraryList.length; i++) {\r
70 //\r
71 // Add libraryInstance in to libInstanceList.\r
72 // \r
73 Map<String, XmlObject> libDoc = GlobalData.getDoc(libraryList[i], arch);\r
74 SurfaceAreaQuery saq = new SurfaceAreaQuery(libDoc);\r
75 libInstanceNode = new LibraryInstanceNode (libraryList[i],saq.getLibConstructorName(), saq.getLibDestructorName());\r
76 libInstanceList.add(libInstanceNode);\r
77 \r
78 //\r
79 // Add library instance and consumed library class list to\r
80 // libInstanceMap.\r
81 //\r
82 libClassConsmList = saq.getLibraryClasses(CommonDefinition.ALWAYSCONSUMED, arch);\r
83 if (libClassConsmList != null) {\r
84 String[] classStr = new String[libClassConsmList.length];\r
85 for (int k = 0; k < libClassConsmList.length; k++) {\r
86 classStr[k] = libClassConsmList[k];\r
87 }\r
88 if (this.libInstanceMap.containsKey(libraryList[i])) {\r
89 throw new AutoGenException(\r
90 libraryList[i].getName()\r
91 + "-- this library instance already exists, please check the library instance list!");\r
92 } else {\r
93 this.libInstanceMap.put(libraryList[i], classStr);\r
94 }\r
95 }\r
96\r
97 //\r
98 // Add library class and library instance map.\r
99 //\r
100 libClassDeclList = saq.getLibraryClasses(CommonDefinition.ALWAYSPRODUCED, arch);\r
101 if (libClassDeclList != null) {\r
102 for (int j = 0; j < libClassDeclList.length; j++) {\r
103 if (this.libClassMap.containsKey(libClassDeclList[j])) {\r
104 EdkLog.log(EdkLog.EDK_ERROR,libClassDeclList[j]\r
105 + " class is already implement by "\r
106 + this.libClassMap.get(libClassDeclList[j]));\r
107 throw new AutoGenException("Library Class: " + libClassDeclList\r
108 + " already has a library instance!");\r
109 } else {\r
110 this.libClassMap.put(libClassDeclList[j], libraryList[i]);\r
111 }\r
112 }\r
113 }\r
114 }\r
115 }\r
116\r
117 /**\r
118 orderLibInstance\r
119 \r
120 This function reorder the library instance according the library class \r
121 dependency.\r
122 \r
123 @return List which content the ordered library instance.\r
124 **/\r
125 List<ModuleIdentification> orderLibInstance() {\r
126 LinkedList<ModuleIdentification> orderList = new LinkedList<ModuleIdentification>();\r
127 for (int i = 0; i < libInstanceList.size(); ++i) {\r
128 ModuleIdentification current = libInstanceList.get(i).libId;\r
129 int insertPoint = orderList.size();\r
130 //\r
131 // check current library instance against orderred ones in orderList\r
132 // \r
133 for (int j = 0; j < orderList.size(); ++j) {\r
134 ModuleIdentification old = orderList.get(j);\r
135 if (consumes(current, old)) {\r
136 //\r
137 // if current library instance consumes the one in orderList\r
138 // it must be put after\r
139 // \r
140 insertPoint = j + 1;\r
141 } else if (consumes(old, current)) {\r
142 //\r
143 // if current library instance is consumed by the one in orderList\r
144 // it must be put before. And no further check is needed.\r
145 // \r
146 insertPoint = j;\r
147 break;\r
148 }\r
149 }\r
150 orderList.add(insertPoint, current);\r
151 }\r
152\r
153 return orderList;\r
154 }\r
155\r
156 //\r
157 // Test if one library consumes another library\r
158 // \r
159 private boolean consumes(ModuleIdentification lib1, ModuleIdentification lib2) {\r
160 LinkedList<ModuleIdentification> stack = new LinkedList<ModuleIdentification>();\r
161\r
162 stack.add(lib1);\r
163 int j = 0;\r
164 while (j < stack.size()) {\r
165 //\r
166 // get the last library instance in stack, which hasn't been checked\r
167 // \r
168 ModuleIdentification lib = stack.get(j++);\r
169 //\r
170 // get the library classes consumed by it\r
171 // \r
172 String[] consumedClasses = libInstanceMap.get(lib);\r
173 for (int i = 0; i < consumedClasses.length; ++i) {\r
174 //\r
175 // for each library class, find its corresponding library instance\r
176 // \r
177 ModuleIdentification consumedLib = libClassMap.get(consumedClasses[i]);\r
178 //\r
179 // if the corresponding instance is the "lib2", we can say that\r
180 // "lib1" consumes "lib2"\r
181 // \r
182 if (consumedLib == lib2) {\r
183 EdkLog.log(EdkLog.EDK_DEBUG, lib1 + "\n consumes\n" + lib2 + "\n");\r
184 return true;\r
185 }\r
186 //\r
187 // otherwise, we put it back into the stack to check it later\r
188 // to see if it consumes "lib2" or not. If the library instance\r
189 // consumed by "lib1" consumes "lib2", we can also say that "lib1"\r
190 // consumes "lib2"\r
191 // \r
192 if (consumedLib != null && !stack.contains(consumedLib)) {\r
193 stack.offer(consumedLib);\r
194 } else if (consumedLib == lib1) {\r
195 //\r
196 // found circular consume, do nothing now but just print\r
197 // out message for debugging\r
198 // \r
199 String msg = "!!! Library consumes circularly: ";\r
200 for (int k = 0; k < j; k++) {\r
201 msg += stack.get(k).getName() + "->";\r
202 }\r
203 msg += lib1.getName();\r
204 EdkLog.log(EdkLog.EDK_DEBUG, msg);\r
205 }\r
206 }\r
207 }\r
208 return false;\r
209 }\r
210\r
211 /**\r
212 isInLibInstance\r
213 \r
214 This function check does the library instance already in the list.\r
215 \r
216 @param list List of the library instance.\r
217 @param instanceName Name of library instance.\r
218 @return "true" the library instance in list |\r
219 "false" the library instance is not in list.\r
220 **/\r
221 private boolean isInLibInstance(List<ModuleIdentification> list, ModuleIdentification instanceId) {\r
222 for (int i = 0; i < list.size(); i++) {\r
223 \r
224 if (instanceId.equals(list.get(i))) {\r
225 return true;\r
226 }\r
227 }\r
228 return false;\r
229 }\r
230\r
231 /**\r
232 isInStackList \r
233 \r
234 This function check if the node already in the stack.\r
235 \r
236 @param list Stack.\r
237 @param nodeName Name of node.\r
238 @return "true" if node have in stack |\r
239 "false" if node don't in stack.\r
240 **/ \r
241 private boolean isInStackList(List<Node> list, ModuleIdentification instanceId) {\r
242 for (int i = 0; i < list.size(); i++) {\r
243 if (instanceId.equals(list.get(i).nodeId)) {\r
244 return true;\r
245 }\r
246 }\r
247 return false;\r
248 }\r
249 \r
250 /**\r
251 isHaveConsDestructor\r
252 \r
253 This function check if the library have constructor or destructor \r
254 function.\r
255 \r
256 @param libName Name of library\r
257 @return "true" if library have constructor or desconstructor |\r
258 "false" if library don't have constructor \r
259 and desconstructor.\r
260 **/\r
261 private boolean isHaveConsDestructor (ModuleIdentification libNode){\r
262 for (int i = 0; i < libInstanceList.size(); i++){\r
263 if (libInstanceList.get(i).libId.equals(libNode)){\r
264 if (libInstanceList.get(i).constructorName != null || libInstanceList.get(i).deconstructorName != null){\r
265 return true;\r
266 }\r
267 }\r
268 }\r
269 return false;\r
270 }\r
271}\r
272\r
273/**\r
274 Node \r
275 \r
276 This class is used as stack node.\r
277 \r
278 **/\r
279class Node {\r
280 ModuleIdentification nodeId;\r
281\r
282 boolean isVisit;\r
283\r
284 Node(ModuleIdentification nodeId, boolean isVisit) {\r
285 this.nodeId = nodeId;\r
286 this.isVisit = false;\r
287 }\r
288} \r
289/**\r
290 LibraryInstance Node \r
291 \r
292 This class is used to store LibrayInstance and it's deconstructor and constructor\r
293**/\r
294 \r
295class LibraryInstanceNode {\r
296 ModuleIdentification libId;\r
297 String deconstructorName;\r
298 String constructorName;\r
299 \r
300 LibraryInstanceNode (ModuleIdentification libId, String deconstructor, String constructor){\r
301 this.libId = libId;\r
302 this.deconstructorName = deconstructor;\r
303 this.constructorName = constructor;\r
304 }\r
305}\r