KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ejen > ext > parsers > java_1_2 > JavaSourceToXML


1 //
2
// Ejen (code generation system)
3
// Copyright (C) 2001, 2002 François Wolff (ejen@noos.fr).
4
//
5
// This file is part of Ejen.
6
//
7
// Ejen is free software; you can redistribute it and/or modify
8
// it under the terms of the GNU General Public License as published by
9
// the Free Software Foundation; either version 2 of the License, or
10
// (at your option) any later version.
11
//
12
// Ejen is distributed in the hope that it will be useful,
13
// but WITHOUT ANY WARRANTY; without even the implied warranty of
14
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
// GNU General Public License for more details.
16
//
17
// You should have received a copy of the GNU General Public License
18
// along with Ejen; if not, write to the Free Software
19
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
//
21
package org.ejen.ext.parsers.java_1_2;
22
23 import org.ejen.util.XSLUtil;
24 import org.ejen.util.arl.ArlUtil;
25 import java.io.FileReader JavaDoc;
26 import java.io.BufferedReader JavaDoc;
27 import java.util.StringTokenizer JavaDoc;
28 import java.util.Hashtable JavaDoc;
29 import org.apache.xalan.extensions.ExpressionContext;
30 import org.apache.xml.utils.WrappedRuntimeException;
31
32 /**
33  * Java source file compilation utility (static methods).
34  * <p>
35  * <table class="usage">
36  * <tr><th class="usage">Usage (XSL stylesheet)</th></tr>
37  * <tr><td class="usage"><pre>
38  *
39  * &lt;?xml version="1.0" encoding="iso-8859-1"?&gt;
40  *
41  * &lt;xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
42  * ...
43  * <b>xmlns:jsx="org.ejen.ext.parsers.java_1_2.JavaSourceToXML"</b>
44  * version="1.0"&gt;
45  *
46  * &lt;xsl:output method="xml" encoding="iso-8859-1"/&gt;
47  *
48  * &lt;xsl:template match="ejen"&gt;
49  *
50  * &lt;xsl:copy-of select="jsx:{@link #process(ExpressionContext,String) process}('{$name}.java')"/&gt;
51  * &lt;xsl:copy-of select="jsx:{@link #process(ExpressionContext,String,boolean) process}('{$name}.java',true)"/&gt;
52  * &lt;xsl:copy-of select="jsx:{@link #process(ExpressionContext,String,String,String) process}('{$name}.java','','')"/&gt;
53  * &lt;xsl:copy-of select="jsx:{@link #process(ExpressionContext,String,String,String,boolean) process}('{$name}.java','','',true)"/&gt;
54  * &lt;xsl:copy-of select="jsx:{@link #parseJavadoc(ExpressionContext,String) parseJavadoc}(tok/stok[@ki=10])"/&gt;
55  *
56  * &lt;/xsl:template&gt;
57  *
58  * &lt;/xsl:stylesheet&gt;
59  * </pre></td></tr></table>
60  * @author F. Wolff
61  * @version 1.0
62  */

63 public class JavaSourceToXML implements JavaParserTreeConstants, JavaParserConstants {
64     
65     private static Hashtable JavaDoc _nodesMapCache = new Hashtable JavaDoc();
66     private static Hashtable JavaDoc _tokensMapCache = new Hashtable JavaDoc();
67     
68     private final static int[] DEFAULT_NODES_MAP = new int[jjtNodeName.length];
69     private final static int[] DEFAULT_TOKENS_MAP = new int[tokenImage.length];
70     static {
71         DEFAULT_NODES_MAP[JJTIMPORTDECLARATION] = ArlUtil.F_REMOVE;
72         DEFAULT_NODES_MAP[JJTTYPEDECLARATION] = ArlUtil.F_CROSS;
73         DEFAULT_NODES_MAP[JJTCLASSBODY] = ArlUtil.F_CROSS;
74         DEFAULT_NODES_MAP[JJTCLASSBODYDECLARATION] = ArlUtil.F_CROSS;
75         DEFAULT_NODES_MAP[JJTFIELDDECLARATION] = ArlUtil.F_REMOVE;
76         DEFAULT_NODES_MAP[JJTFORMALPARAMETERS] = ArlUtil.F_CROSS;
77         DEFAULT_NODES_MAP[JJTINITIALIZER] = ArlUtil.F_REMOVE;
78         DEFAULT_NODES_MAP[JJTBLOCK] = ArlUtil.F_REMOVE;
79         for (int i = 0; i <= SINGLE_LINE_COMMENT; i++) {
80             DEFAULT_TOKENS_MAP[i] = ArlUtil.F_REMOVE;
81         }
82         DEFAULT_TOKENS_MAP[MULTI_LINE_COMMENT] = ArlUtil.F_REMOVE;
83         DEFAULT_TOKENS_MAP[PACKAGE] = ArlUtil.F_REMOVE;
84         DEFAULT_TOKENS_MAP[LPAREN] = ArlUtil.F_REMOVE;
85         DEFAULT_TOKENS_MAP[RPAREN] = ArlUtil.F_REMOVE;
86         DEFAULT_TOKENS_MAP[LBRACE] = ArlUtil.F_REMOVE;
87         DEFAULT_TOKENS_MAP[RBRACE] = ArlUtil.F_REMOVE;
88         DEFAULT_TOKENS_MAP[SEMICOLON] = ArlUtil.F_REMOVE;
89         DEFAULT_TOKENS_MAP[COMMA] = ArlUtil.F_REMOVE;
90         DEFAULT_TOKENS_MAP[THROWS] = ArlUtil.F_REMOVE;
91         DEFAULT_TOKENS_MAP[IMPLEMENTS] = ArlUtil.F_REMOVE;
92         DEFAULT_TOKENS_MAP[EXTENDS] = ArlUtil.F_REMOVE;
93         _nodesMapCache.put("default", DEFAULT_NODES_MAP);
94         _tokensMapCache.put("default", DEFAULT_TOKENS_MAP);
95     }
96
97     /**
98      * Protected constructor (prevents instanciation).
99      */

100     protected JavaSourceToXML() {}
101
102     /**
103      * Returns a <code>Node</code> that represents a java source file.
104      * <p>
105      * <table class="usage"><tr><td class="usage"><pre>
106      *
107      * &lt;xsl:copy-of select="jsx:process($java-file)"/&gt;
108      * </pre></td></tr></table>
109      * <p>
110      * Token positions are not included (see
111      * {@link #process(ExpressionContext,String,boolean)}).
112      * <p>
113      * <dd><dl><dt><b>XSLT parameters:</b>
114      * <dd><b>[Mandatory/AVT]</b> name of the java source file.
115      * </dl></dd>
116      * <p>
117      * @param context automatically passed by the xalan extension mechanism.
118      * @param fileName name of the java source file.
119      * @return a <code>NodeSet</code> that represents the java source file.
120      * @throws org.apache.xml.utils.WrappedRuntimeException errors (file not found...).
121      */

122     public static org.apache.xpath.NodeSet process(ExpressionContext context, String JavaDoc fileName) {
123         return process(XSLUtil.getContextDocument(context),
124                 XSLUtil.evaluate(context, fileName), null, null, false);
125     }
126
127     /**
128      * Returns a <code>Node</code> that represents a java source file.
129      * <p>
130      * <table class="usage"><tr><td class="usage"><pre>
131      *
132      * &lt;xsl:copy-of select="jsx:process($java-file)"/&gt;
133      * </pre></td></tr></table>
134      * <p>
135      * <dd><dl><dt><b>XSLT parameters:</b>
136      * <dd><b>[Mandatory/AVT]</b> name of the java source file.
137      * </dl></dd>
138      * <p>
139      * @param context automatically passed by the xalan extension mechanism.
140      * @param fileName name of the java source file.
141      * @param tokensPos if true, each "tok" or "stok" Node will include positions
142      * coordinates (see
143      * {@link Token#toNode(org.w3c.dom.Document,org.w3c.dom.Node,int[],boolean)
144      * Token.toNode(...)}).
145      * @return a <code>NodeSet</code> that represents the java source file.
146      * @throws org.apache.xml.utils.WrappedRuntimeException errors (file not found...).
147      */

148     public static org.apache.xpath.NodeSet process(ExpressionContext context,
149             String JavaDoc fileName,
150             boolean tokensPos) {
151         return process(XSLUtil.getContextDocument(context),
152                 XSLUtil.evaluate(context, fileName), null, null, tokensPos);
153     }
154
155     /**
156      * Returns a <code>Node</code> that represents a java source file.
157      * <p>
158      * <table class="usage"><tr><td class="usage"><pre>
159      *
160      * &lt;xsl:copy-of select="jsx:process($java-file,'','')"/&gt;
161      * </pre></td></tr></table>
162      * <p>
163      * Token positions are not included (see
164      * {@link #process(ExpressionContext,String,String,String,boolean)}).
165      * <p>
166      * <dd><dl><dt><b>XSLT parameters:</b>
167      * <dd><b>[Mandatory/AVT]</b> name of the java source file.
168      * <dd><b>[Mandatory/AVT]</b> {@link org.ejen.util.arl.ArlUtil arl} sequence
169      * that defines which nodes should be accepted/removed/crossed. If the
170      * this parameter is equals to "default", then default is used.
171      * <dd><b>[Mandatory/AVT]</b> {@link org.ejen.util.arl.ArlUtil arl} sequence
172      * that defines which tokens should be accepted/removed/crossed. If the
173      * this parameter is equals to "default", then default is used.
174      * </dl></dd>
175      * <p>
176      * @param context automatically passed by the xalan extension mechanism.
177      * @param fileName name of the java source file.
178      * @param nodesArl {@link org.ejen.util.arl.ArlUtil arl} sequence that defines
179      * which nodes should be accepted/removed/crossed.
180      * @param tokensArl {@link org.ejen.util.arl.ArlUtil arl} sequence that defines
181      * which tokens should be accepted/removed/crossed.
182      * @return a <code>NodeSet</code> that represents the java source file.
183      * @throws org.apache.xml.utils.WrappedRuntimeException errors (file not found...).
184      */

185     public static org.apache.xpath.NodeSet process(ExpressionContext context,
186             String JavaDoc fileName,
187             String JavaDoc nodesArl,
188             String JavaDoc tokensArl) {
189         return process(XSLUtil.getContextDocument(context),
190                 XSLUtil.evaluate(context, fileName),
191                 XSLUtil.evaluate(context, nodesArl),
192                 XSLUtil.evaluate(context, tokensArl), false);
193     }
194
195     /**
196      * Returns a <code>Node</code> that represents a java source file.
197      * <p>
198      * <table class="usage"><tr><td class="usage"><pre>
199      *
200      * &lt;xsl:copy-of select="jsx:process($java-file,'','')"/&gt;
201      * </pre></td></tr></table>
202      * <p>
203      * <dd><dl><dt><b>XSLT parameters:</b>
204      * <dd><b>[Mandatory/AVT]</b> name of the java source file.
205      * <dd><b>[Mandatory/AVT]</b> {@link org.ejen.util.arl.ArlUtil arl} sequence
206      * that defines which nodes should be accepted/removed/crossed.
207      * <dd><b>[Mandatory/AVT]</b> {@link org.ejen.util.arl.ArlUtil arl} sequence
208      * that defines which tokens should be accepted/removed/crossed.
209      * </dl></dd>
210      * <p>
211      * @param context automatically passed by the xalan extension mechanism.
212      * @param fileName name of the java source file.
213      * @param nodesArl {@link org.ejen.util.arl.ArlUtil arl} sequence that defines
214      * which nodes should be accepted/removed/crossed. If the
215      * this parameter is equals to "default", then default is used.
216      * @param tokensArl {@link org.ejen.util.arl.ArlUtil arl} sequence that defines
217      * which tokens should be accepted/removed/crossed. If the
218      * this parameter is equals to "default", then default is used.
219      * @param tokensPos if true, each "tok" or "stok" Node will include positions
220      * coordinates (see
221      * {@link Token#toNode(org.w3c.dom.Document,org.w3c.dom.Node,int[],boolean)
222      * Token.toNode(...)}).
223      * @return a <code>NodeSet</code> that represents the java source file.
224      * @throws org.apache.xml.utils.WrappedRuntimeException errors (file not found...).
225      */

226     public static org.apache.xpath.NodeSet process(ExpressionContext context,
227             String JavaDoc fileName,
228             String JavaDoc nodesArl,
229             String JavaDoc tokensArl,
230             boolean tokensPos) {
231         return process(XSLUtil.getContextDocument(context),
232                 XSLUtil.evaluate(context, fileName),
233                 XSLUtil.evaluate(context, nodesArl),
234                 XSLUtil.evaluate(context, tokensArl), tokensPos);
235     }
236     
237     /**
238      * Returns a <code>Node</code> that represents a java source file.
239      * <p>
240      * @param fileName name of the java source file.
241      * @param nodesArl {@link org.ejen.util.arl.ArlUtil arl} sequence that defines
242      * which nodes should be accepted/removed/crossed.
243      * @param tokensArl {@link org.ejen.util.arl.ArlUtil arl} sequence that defines
244      * which tokens should be accepted/removed/crossed.
245      * @return a <code>NodeSet</code> that represents the java source file.
246      * @throws org.apache.xml.utils.WrappedRuntimeException errors (file not found...).
247      */

248     protected static org.apache.xpath.NodeSet process(org.w3c.dom.Document JavaDoc doc,
249             String JavaDoc fileName,
250             String JavaDoc nodesArl,
251             String JavaDoc tokensArl,
252             boolean tokensPos) {
253         BufferedReader JavaDoc br = null;
254
255         try {
256             br = new BufferedReader JavaDoc(new FileReader JavaDoc(fileName));
257             if (JavaParser.token_source == null) {
258                 new JavaParser(br);
259             } else {
260                 JavaParser.ReInit(br);
261             }
262             SimpleNode sn = JavaParser.CompilationUnit();
263             org.w3c.dom.Node JavaDoc root = doc.createElement("unused");
264
265             sn.toNode(doc, root,
266                     getMap(nodesArl, DEFAULT_NODES_MAP, _nodesMapCache),
267                     getMap(tokensArl, DEFAULT_TOKENS_MAP, _tokensMapCache),
268                     tokensPos);
269             return new org.apache.xpath.NodeSet(root.getChildNodes());
270         } catch (Exception JavaDoc e) {
271             throw new WrappedRuntimeException(e);
272         }
273         finally {
274             if (br != null) {
275                 try {
276                     br.close();
277                 } catch (Exception JavaDoc e) {}
278                 finally {
279                     br = null;
280                 }
281             }
282         }
283     }
284     
285     /**
286      * Returns an <code>int</code> array based on the 'arl' expression. If the 'arl'
287      * expression is already in the 'cache', just returns the existing int array, otherwise
288      * creates a new one and puts it in the 'cache'.
289      * <p>
290      * @param arl {@link org.ejen.util.arl.ArlUtil arl} expression.
291      * @param defaultMap int array used by default (if 'arl' is <code>null</code>).
292      * @param cache cache used for this kind of arl (SimpleNode or Token).
293      * @return the corresponding int array.
294      */

295     protected static int[] getMap(String JavaDoc arl, int[] defaultMap, Hashtable JavaDoc cache) {
296         if (arl == null) {
297             return defaultMap;
298         }
299         int[] map = (int[]) (cache.get(arl));
300
301         if (map == null) {
302             map = ArlUtil.process(arl, new int[defaultMap.length]);
303             cache.put(arl, map);
304         }
305         return map;
306     }
307     
308     /**
309      * Returns a <code>NodeSet</code> that contains all non empty lines in a Javadoc comment.
310      * <p>
311      * <table class="usage"><tr><td class="usage"><pre>
312      *
313      * &lt;xsl:copy-of select="jsx:parseJavadoc(tok/stok[@ki=10])"/&gt;
314      * </pre></td></tr></table>
315      * <p>
316      * For example,
317      * <p>
318      * <table class="usage"><tr><td class="usage"><pre>
319      *
320      * &#047;**
321      * * Says "Hello &lt;msg&gt; !"
322      * *
323      * * @param msg the message to use in salutation.
324      * * @throws java.lang.IllegalArgumentException ...
325      * *&#047;
326      * </pre></td></tr></table>
327      * <p>
328      * will be parsed into
329      * <p>
330      * <table class="usage"><tr><td class="usage"><pre>
331      *
332      * &lt;doc-line&gt;
333      * &lt;![CDATA[ Says "Hello &lt;msg&gt; !"]]&gt;
334      * &lt;/doc-line&gt;
335      * &lt;doc-line&gt;
336      * &lt;![CDATA[ @param msg the message to use in salutations.]]&gt;
337      * &lt;/doc-line&gt;
338      * &lt;doc-line&gt;
339      * &lt;![CDATA[ @throws java.lang.IllegalArgumentException ...]]&gt;
340      * &lt;/doc-line&gt;
341      * </pre></td></tr></table>
342      * <p>
343      * <dd><dl><dt><b>XSLT parameters:</b>
344      * <dd><b>[Mandatory]</b> Javadoc comment to be parsed.
345      * </dl></dd>
346      * <p>
347      * @param context automatically passed by the xalan extension mechanism.
348      * @param comment the Javadoc comment to be parsed.
349      * @return a <code>NodeSet</code> with parsed lines.
350      * @throws org.apache.xml.utils.WrappedRuntimeException errors (DOM error).
351      */

352     public static org.apache.xpath.NodeSet parseJavadoc(ExpressionContext context, String JavaDoc comment) {
353         org.w3c.dom.Document JavaDoc doc = XSLUtil.getContextDocument(context);
354
355         try {
356             org.apache.xpath.NodeSet ns = new org.apache.xpath.NodeSet();
357             StringTokenizer JavaDoc sTok = new StringTokenizer JavaDoc(comment, "\n\r");
358
359             while (sTok.hasMoreTokens()) {
360                 String JavaDoc line = sTok.nextToken();
361                 boolean skip = false;
362
363                 if (line.startsWith("/**")) {
364                     line = line.substring(3);
365                     skip = true;
366                 }
367                 if (line.endsWith("*/")) {
368                     line = line.substring(0, line.length() - 2);
369                 }
370                 if (!skip) {
371                     int iStar = -1;
372                     boolean done = false;
373
374                     for (int i = 0; !done && i < line.length(); i++) {
375                         switch (line.charAt(i)) {
376                         case ' ':
377                         case '\t':
378                             break;
379
380                         case '*':
381                             iStar = i;
382
383                         default:
384                             done = true;
385                             break;
386                         }
387                     }
388                     if (iStar != -1) {
389                         line = line.substring(iStar + 1);
390                     } else {
391                         line = "";
392                     }
393                 }
394                 if (line.length() > 0) {
395                     org.w3c.dom.Element JavaDoc elt = doc.createElement("doc-line");
396
397                     elt.appendChild(doc.createCDATASection(line));
398                     ns.addElement(elt);
399                 }
400             }
401             return ns;
402         } catch (org.w3c.dom.DOMException JavaDoc e) {
403             throw new WrappedRuntimeException(e);
404         }
405     }
406 }
407
Popular Tags