KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > tools > verifier > apiscan > stdapis > APIRepository


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 /*
25  * APIHelper.java
26  *
27  * Created on September 22, 2004, 10:23 AM
28  */

29
30 package com.sun.enterprise.tools.verifier.apiscan.stdapis;
31
32 import java.io.InputStream JavaDoc;
33 import javax.xml.parsers.DocumentBuilder JavaDoc;
34 import javax.xml.parsers.DocumentBuilderFactory JavaDoc;
35
36 import java.io.File JavaDoc;
37 import java.util.ArrayList JavaDoc;
38 import java.util.Collection JavaDoc;
39 import java.util.HashMap JavaDoc;
40 import java.util.Iterator JavaDoc;
41 import java.util.StringTokenizer JavaDoc;
42 import java.util.logging.Handler JavaDoc;
43 import java.util.logging.Level JavaDoc;
44 import java.util.logging.Logger JavaDoc;
45
46 import org.w3c.dom.Document JavaDoc;
47 import org.w3c.dom.Element JavaDoc;
48 import org.w3c.dom.Node JavaDoc;
49 import org.w3c.dom.NodeList JavaDoc;
50 import org.xml.sax.SAXException JavaDoc;
51 import org.xml.sax.SAXParseException JavaDoc;
52 import org.xml.sax.helpers.DefaultHandler JavaDoc;
53
54 /**
55  * This class represents a repository of APIs. It is backed by a XML file
56  * with a predefined schema. This class is resoponsible for parsing the
57  * XML file and getting populated by the information available in that file.
58  * In verifier, this class is used in conjunction with an XML file where all
59  * the standard APIs are listed along with their respective version number.
60  * Refer to standard-apis.xml file to see how we list APIs in that file.
61  *
62  * @author Sanjeeb.Sahoo@Sun.COM
63  */

64 public class APIRepository {
65     private static Logger JavaDoc logger = Logger.getLogger("apiscan.stdapis"); // NOI18N
66
private static String JavaDoc myClsName = "APIRepository"; // NOI18N
67
private HashMap JavaDoc<String JavaDoc, API> apis = new HashMap JavaDoc<String JavaDoc, API>();
68     //singleton
69
private static APIRepository me;
70
71     /**
72      * Return the singleton instance.
73      */

74     public static APIRepository Instance() {
75         assert(me != null);
76         return me;
77     }
78
79     /**
80      * Initialize the singleton instance.
81      *
82      * @param fileName An XML file which contains the details of APIs.
83      */

84     public synchronized static void Initialize(String JavaDoc fileName)
85             throws Exception JavaDoc {
86         logger.logp(Level.FINE, myClsName, "Initialize", fileName); // NOI18N
87
//Pl refer to bug#6174887
88
// assert(me==null);
89
// if(me==null){
90
me = new APIRepository(fileName);
91 // }else throw new RuntimeException("Already Initialized");
92
}
93
94     /**
95      * This method is used to find out if a particular class is part of
96      * a standard API or not. e.g. to find out if an EJB 2.0 application is
97      * allowed to use javax.ejb.Timer.class, call this method as
98      * <blockquote><pre>
99      * isClassPartOf("javax.ejb.Timer","ejb_jar_2.0")
100      * </pre></blockquote>
101      *
102      * @param class_name name of the class (in external class name format)
103      * @param api_name_version is the name of the API along with version. It
104      * must already be defined in the XML file.
105      *
106      * @return true iff the given class is part of this API.
107      */

108     public boolean isClassPartOf(String JavaDoc class_name, String JavaDoc api_name_version) {
109         if (getClassesFor(api_name_version).contains(class_name)) {
110             return true;
111         } else if (getPackagesFor(api_name_version).
112                 contains(getPackageName(class_name))) {
113             return true;
114         } else {
115             for (String JavaDoc pattern : getPatternsFor(api_name_version)) {
116                 if (class_name.startsWith(pattern)) {
117                     return true;
118                 }
119             }
120         }
121         return false;
122     }
123     
124     /**
125      * This method is used to find out if a particular package is part of
126      * a standard API or not. e.g. to find out if an appclient (v 1.4) is
127      * allowed to import javax.persistence.* , call this method as
128      * <blockquote><pre>
129      * isPackagePartOf("javax.persistence","appclient_1.4")
130      * </pre></blockquote>
131      *
132      * @param pkg_name name of the package
133      * @param api_name_version is the name of the API along with version. It
134      * must already be defined in the XML file.
135      *
136      * @return true iff the given package is part of this API.
137      */

138     public boolean isPackagePartOf(String JavaDoc pkg_name, String JavaDoc api_name_version) {
139         if (getPackagesFor(api_name_version).contains(pkg_name)) {
140             return true;
141         } else {
142             for (String JavaDoc pattern : getPatternsFor(api_name_version)) {
143                 if (pkg_name.startsWith(pattern)) {
144                     return true;
145                 }
146             }
147         }
148         return false;
149     }
150     
151     protected Collection JavaDoc<String JavaDoc> getPackagesFor(String JavaDoc api_name_version) {
152         return ((API) apis.get(api_name_version)).getPackages();
153     }
154
155     protected Collection JavaDoc<String JavaDoc> getPatternsFor(String JavaDoc api_name_version) {
156         return ((API) apis.get(api_name_version)).getPatterns();
157     }
158
159     protected Collection JavaDoc<String JavaDoc> getClassesFor(String JavaDoc api_name_version) {
160         return ((API) apis.get(api_name_version)).getClasses();
161     }
162
163     public String JavaDoc toString() {
164         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
165         for (Iterator JavaDoc i = apis.values().iterator(); i.hasNext();) {
166             sb.append("\n").append(i.next().toString()); // NOI18N
167
}
168         return sb.toString();
169     }
170
171     private APIRepository(String JavaDoc fileName) throws Exception JavaDoc {
172         logger.entering(myClsName, "init<>", fileName); // NOI18N
173
final File JavaDoc file = new File JavaDoc(fileName);
174         Document JavaDoc d = getDocumentBuilder().parse(file);
175         traverseTree(d.getDocumentElement());
176     }
177     
178     private DocumentBuilder JavaDoc getDocumentBuilder() throws Exception JavaDoc {
179         DocumentBuilderFactory JavaDoc bf = DocumentBuilderFactory.newInstance();
180         bf.setValidating(true);
181         bf.setIgnoringComments(false);
182         bf.setIgnoringElementContentWhitespace(true);
183         bf.setCoalescing(true);
184         bf.setNamespaceAware(true);
185         bf.setAttribute(
186                 "http://java.sun.com/xml/jaxp/properties/schemaLanguage", // NOI18N
187
"http://www.w3.org/2001/XMLSchema"); // NOI18N
188
DocumentBuilder JavaDoc builder = bf.newDocumentBuilder();
189         builder.setErrorHandler(new DefaultHandler JavaDoc() {
190             public void error(SAXParseException JavaDoc e) throws SAXException JavaDoc {
191                 throw e;
192             }
193         });
194         return builder;
195     }
196
197     private void traverseTree(Node JavaDoc node) {
198         if (node == null) {
199             return;
200         }
201         if (node.getNodeType() == Node.ELEMENT_NODE) {
202             Element JavaDoc e = (Element JavaDoc) node;
203             String JavaDoc tagName = e.getTagName();
204             if (tagName.equals("api")) { // NOI18N
205
API a = new API(e);
206                 apis.put(a.name_version, a);
207             }
208             NodeList JavaDoc childNodes = node.getChildNodes();
209             for (int i = 0; i < childNodes.getLength(); i++) {
210                 traverseTree(childNodes.item(i));
211             }
212         }
213     }
214
215     //return java.util for java.util.Map$Entry
216
private static String JavaDoc getPackageName(String JavaDoc externalClassName) {
217         int idx = externalClassName.lastIndexOf('.');
218         if (idx != -1) {
219             return externalClassName.substring(0, idx);
220         } else
221             return "";
222     }
223
224     class APIRef {
225         private String JavaDoc api_name_version;
226
227         public APIRef(Element JavaDoc node) {
228             if (node.getTagName().equals("api_ref")) { // NOI18N
229
api_name_version = node.getAttribute("api_name_version"); // NOI18N
230
} else
231                 throw new IllegalArgumentException JavaDoc(node.toString());
232         }
233
234         public APIRef(String JavaDoc api_name_version) {
235             this.api_name_version = api_name_version;
236         }
237
238         public API deref() {
239             API result = (API) apis.get(api_name_version);
240             if (result == null)
241                 throw new NullPointerException JavaDoc(
242                         "No API with name_version [" + api_name_version + "]"); // NOI18N
243
return result;
244         }
245     }
246
247     class API {
248         private String JavaDoc name_version;
249         private ArrayList JavaDoc<APIRef> apiRefs = new ArrayList JavaDoc<APIRef>();
250         ArrayList JavaDoc<String JavaDoc> packages = new ArrayList JavaDoc<String JavaDoc>(), patterns = new ArrayList JavaDoc<String JavaDoc>(), classes = new ArrayList JavaDoc<String JavaDoc>();
251
252         public API(Element JavaDoc node) {
253             if (node.getTagName().equals("api")) { // NOI18N
254
name_version = node.getAttribute("name_version"); // NOI18N
255
NodeList JavaDoc refNodes = node.getElementsByTagName("api_ref"); // NOI18N
256
for (int loopIndex = 0;
257                      loopIndex < refNodes.getLength(); loopIndex++) {
258                     apiRefs.add(new APIRef((Element JavaDoc) refNodes.item(loopIndex)));
259                 }
260                 NodeList JavaDoc pkgsNodes = node.getElementsByTagName("packages"); // NOI18N
261
for (int i = 0; i < pkgsNodes.getLength(); ++i) {
262                     Element JavaDoc pkgsNode = (Element JavaDoc) pkgsNodes.item(i);
263                     NodeList JavaDoc children = pkgsNode.getChildNodes();
264                     for (int j = 0; j < children.getLength(); j++) {
265                         Node JavaDoc next = children.item(j);
266                         if (next.getNodeType() == Node.TEXT_NODE) {
267                             String JavaDoc names = next.getNodeValue().trim();
268                             for (StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(
269                                     names);
270                                  st.hasMoreTokens();) {
271                                 packages.add(st.nextToken());
272                             }
273                         }
274                     }
275                 }
276                 NodeList JavaDoc patternsNodes = node.getElementsByTagName("patterns"); // NOI18N
277
for (int i = 0; i < patternsNodes.getLength(); ++i) {
278                     Element JavaDoc patternsNode = (Element JavaDoc) patternsNodes.item(i);
279                     NodeList JavaDoc children = patternsNode.getChildNodes();
280                     for (int j = 0; j < children.getLength(); j++) {
281                         Node JavaDoc next = children.item(j);
282                         if (next.getNodeType() == Node.TEXT_NODE) {
283                             String JavaDoc names = next.getNodeValue().trim();
284                             for (StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(
285                                     names);
286                                  st.hasMoreTokens();) {
287                                 patterns.add(st.nextToken());
288                             }
289                         }
290                     }
291                 }
292                 NodeList JavaDoc classesNodes = node.getElementsByTagName("classes"); // NOI18N
293
for (int i = 0; i < classesNodes.getLength(); ++i) {
294                     Element JavaDoc classesNode = (Element JavaDoc) classesNodes.item(i);
295                     String JavaDoc package_name = classesNode.getAttribute("package") // NOI18N
296
.trim();
297                     NodeList JavaDoc children = classesNode.getChildNodes();
298                     for (int j = 0; j < children.getLength(); j++) {
299                         Node JavaDoc next = children.item(j);
300                         if (next.getNodeType() == Node.TEXT_NODE) {
301                             String JavaDoc names = next.getNodeValue().trim();
302                             for (StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(
303                                     names);
304                                  st.hasMoreTokens();) {
305                                 String JavaDoc clsName = package_name + "." + // NOI18N
306
st.nextToken();
307                                 classes.add(clsName);
308                             }
309                         }
310                     }
311                 }
312             } else {
313                 throw new IllegalArgumentException JavaDoc(node.toString());
314             }
315         }//constructor
316

317         public Collection JavaDoc<String JavaDoc> getPackages() {
318             ArrayList JavaDoc<String JavaDoc> results = new ArrayList JavaDoc<String JavaDoc>();
319             for (Iterator JavaDoc i = apiRefs.iterator(); i.hasNext();) {
320                 results.addAll(((APIRef) i.next()).deref().getPackages());
321             }
322             results.addAll(packages);
323             return results;
324         }
325
326         public Collection JavaDoc<String JavaDoc> getPatterns() {
327             ArrayList JavaDoc<String JavaDoc> results = new ArrayList JavaDoc<String JavaDoc>();
328             for (Iterator JavaDoc i = apiRefs.iterator(); i.hasNext();) {
329                 results.addAll(((APIRef) i.next()).deref().getPatterns());
330             }
331             results.addAll(patterns);
332             return results;
333         }
334
335         public Collection JavaDoc<String JavaDoc> getClasses() {
336             ArrayList JavaDoc<String JavaDoc> results = new ArrayList JavaDoc<String JavaDoc>();
337             for (Iterator JavaDoc i = apiRefs.iterator(); i.hasNext();) {
338                 results.addAll(((APIRef) i.next()).deref().getClasses());
339             }
340             results.addAll(classes);
341             return results;
342         }
343
344         public String JavaDoc toString() {
345             StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
346             sb.append("<api name_version=\"" + name_version + "\">"); // NOI18N
347
sb.append("\n\t<classes>"); // NOI18N
348
for (Iterator JavaDoc i = getClasses().iterator(); i.hasNext();) sb.append(
349                     "\n\t\t") // NOI18N
350
.append(i.next().toString());
351             sb.append("\n\t</classes>"); // NOI18N
352
sb.append("\n\t<packages>"); // NOI18N
353
for (Iterator JavaDoc i = getPackages().iterator(); i.hasNext();) sb.append(
354                     "\n\t\t") // NOI18N
355
.append(i.next().toString());
356             sb.append("\n\t</packages>"); // NOI18N
357
sb.append("\n\t<patterns>"); // NOI18N
358
for (Iterator JavaDoc i = getPatterns().iterator(); i.hasNext();) sb.append(
359                     "\n\t\t") // NOI18N
360
.append(i.next().toString());
361             sb.append("\n\t</patterns>"); // NOI18N
362
sb.append("\n</api>"); // NOI18N
363
return sb.toString();
364         }
365     }//class API
366

367     public static void main(String JavaDoc[] args) {
368         if (args.length < 1) {
369             usage();
370         }
371         Logger JavaDoc logger = Logger.getLogger("apiscan.stdapis"); // NOI18N
372
try {
373             APIRepository.Initialize(args[0]);
374             APIRepository apiRep = APIRepository.Instance();
375             switch(args.length) {
376                 case 1:
377                     System.out.println(apiRep);
378                     break;
379                 case 2:
380                     System.out.println(apiRep.apis.get(args[1]));
381                     break;
382                 case 3:
383                     System.out.println(apiRep.isClassPartOf(args[2], args[1]));
384                     break;
385                 default:
386                     usage();
387             }
388         } catch (Exception JavaDoc e) {
389             e.printStackTrace();
390         }
391     }
392     
393     private static void usage(){
394         System.out.println(
395                 "Usage: java " + APIRepository.class.getName() + // NOI18N
396
" <file_name> [api_name_version] [class_name]"); // NOI18N
397
System.out.println("\nExamples:\n"); // NOI18N
398
System.out.println(
399                 "java " + APIRepository.class.getName() + // NOI18N
400
" src/standard-apis.xml ejb_jar_2.0 javax.ejb.Timer"); // NOI18N
401
System.out.println("The above command prints true if javax.ejb.Timer is part of ejb_api_2.0 API.\n"); // NOI18N
402
System.out.println(
403                 "java " + APIRepository.class.getName() + // NOI18N
404
" src/standard-apis.xml ejb_jar_2.0"); // NOI18N
405
System.out.println("The above command prints details about all classes and packages for ejb_api_2.0 API.\n"); // NOI18N
406
System.out.println(
407                 "java " + APIRepository.class.getName() + // NOI18N
408
" src/standard-apis.xml"); // NOI18N
409
System.out.println("The above command prints details about all APIs.\n"); // NOI18N
410
System.exit(1);
411     }
412 }//class APIRespository
413
Popular Tags