KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > de > gulden > util > javasource > Code


1 /*
2  * Project: BeautyJ - Customizable Java Source Code Transformer
3  * Class: de.gulden.util.javasource.Code
4  * Version: 1.1
5  *
6  * Date: 2004-09-29
7  *
8  * Note: Contains auto-generated Javadoc comments created by BeautyJ.
9  *
10  * This is licensed under the GNU General Public License (GPL)
11  * and comes with NO WARRANTY. See file license.txt for details.
12  *
13  * Author: Jens Gulden
14  * Email: beautyj@jensgulden.de
15  */

16
17 package de.gulden.util.javasource;
18
19 import de.gulden.util.javasource.jjt.Node;
20 import de.gulden.util.javasource.jjt.*;
21 import de.gulden.util.xml.XMLToolbox;
22 import de.gulden.util.Toolbox;
23 import javax.xml.parsers.*;
24 import org.w3c.dom.*;
25 import java.io.*;
26 import java.util.*;
27
28 /**
29  * Represents code in a method/constructor body, and in a static class initializer.
30  *
31  * @author Jens Gulden
32  * @version 1.1
33  */

34 public class Code extends Implementation {
35
36     // ------------------------------------------------------------------------
37
// --- field ---
38
// ------------------------------------------------------------------------
39

40     /**
41      * The raw code string.
42      */

43     protected String JavaDoc raw;
44
45
46     // ------------------------------------------------------------------------
47
// --- constructor ---
48
// ------------------------------------------------------------------------
49

50     /**
51      * Creates a new instance of Code.
52      */

53     public Code() {
54         super();
55     }
56
57
58     // ------------------------------------------------------------------------
59
// --- methods ---
60
// ------------------------------------------------------------------------
61

62     /**
63      * Returns the raw code string.
64      */

65     public String JavaDoc getRaw() {
66         return raw;
67     }
68
69     /**
70      * Sets the raw code string.
71      */

72     public void setRaw(String JavaDoc s) {
73         raw=s;
74     }
75
76     /**
77      * Output this object as XML.
78      *
79      * @return The XML tag.
80      * @see #initFromXML
81      */

82     public Element buildXML(Document d) {
83         Element e=d.createElement("code");
84         String JavaDoc raw=getRaw();
85         e.appendChild(d.createTextNode(raw));
86         return e;
87     }
88
89     /**
90      * Initialize this object from XML.
91      *
92      * @param element The XML tag.
93      * @throws IOException if an i/o error occurs
94      */

95     public void initFromXML(Element element) throws IOException {
96         raw=XMLToolbox.getText(element);
97         if (raw==null) {
98             raw="";
99         }
100     }
101
102     /**
103      * Initialize this object from parsed Java code.
104      *
105      * @param rootnode The corresponding node in the abstract syntax tree (AST).
106      */

107     void initFromAST(Node rootnode) {
108         // special way of invoking!!!
109
// rootnode is rootnode of the _declaration_ of the code block
110
// from there, following code will be rebuilt
111
// (this is necessary because due to lookahead in constructors, code start would be missing)
112
StringBuffer JavaDoc sb=new StringBuffer JavaDoc();
113         // find first "{"
114
Token t=rootnode.getStartToken();
115         while ((t.kind!=ParserConstants.LBRACE)&&(t.kind!=ParserConstants.ASSIGN)) // ASSIGN for field initializers
116
{
117             t=t.next;
118         }
119         Token endT;
120         if (t.kind==ParserConstants.LBRACE) // code block { ... }
121
{
122             endT=findCodeEnd(t);
123         }
124         else // ASSIGN: field initializer
125
{
126             endT=rootnode.getEndToken();
127         }
128         raw=rootnode.getTextImage().getRange(t.beginLine,t.beginColumn,endT.endLine,endT.endColumn);
129         raw=raw.trim();
130         raw=raw.substring(1,raw.length()-1); // remove { } or = ;
131
// remove left part if only blanks before first \n:
132
int npos = raw.indexOf('\n');
133         if (npos != -1) {
134             String JavaDoc left = raw.substring(0, npos);
135             if (left.trim().length()==0) {
136                 raw = raw.substring(npos+1);
137             }
138         }
139         if (raw.indexOf("...fields")!=-1) {
140         System.out.println("AAA");
141         }
142         raw = unindent(raw);
143         raw = SourceParser.workaroundRestoreUnicodeSingleChar(raw); // @see SourceParser#parsePass1()
144
}
145
146
147     // ------------------------------------------------------------------------
148
// --- static methods ---
149
// ------------------------------------------------------------------------
150

151     static Token findCodeEnd(Token t) {
152         int cnt=1;
153         while (cnt>0) {
154         t=t.next;
155         switch (t.kind) {
156         case ParserConstants.LBRACE: cnt++;
157         break;
158         case ParserConstants.RBRACE: cnt--;
159         break;
160         }
161         }
162         return t;
163     }
164
165     static Token findCodeEndInitializer(Token t) {
166         while ((t.kind!=ParserConstants.SEMICOLON)&&(t.kind!=ParserConstants.COMMA)) {
167             t=t.next;
168             if (t.kind==ParserConstants.LBRACE) {
169                 t=findCodeEnd(t).next;
170             }
171         }
172         return t;
173     }
174
175     /**
176      * Creates an unindented representation of a code block by shifting all lines to the left so that
177      * the first line will start at column 0. All other lines are shifted relative to the shift of the first line.
178      * The specified code block is expected to be passed without enclosing braces.
179      *
180      * @return unindented code
181      */

182     static String JavaDoc unindent(String JavaDoc code) {
183         List l = Toolbox.getLines(code);
184         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
185         String JavaDoc nl = System.getProperty("line.separator");
186         int shift = -1;
187            for (ListIterator it = l.listIterator(); it.hasNext(); ) {
188             String JavaDoc line = (String JavaDoc)it.next();
189             if (line.trim().length()==0) { // blank line
190
if ( it.hasNext() ) { // skip last line if empty, it is just the remaining part until '}'
191
sb.append( nl );
192                 }
193             } else {
194                 String JavaDoc newLine;
195                 if (shift == -1) { // first line
196
newLine = Toolbox.trimLeft(line);
197                     shift = line.length() - newLine.length();
198                 } else {
199                     if (line.length() > shift) {
200                         String JavaDoc cutoff = line.substring(0, shift);
201                         if (cutoff.trim().length()==0) { // no content would be cut off by shifting: normal shift
202
newLine = line.substring(shift);
203                         } else {
204                             newLine = Toolbox.trimLeft(line); // otherwise just trim all left whitespace, original relative shift to first line will be lost
205
}
206                     } else {
207                         newLine = Toolbox.trimLeft(line); // otherwise just trim all left whitespace, original relative shift to first line will be lost
208
}
209                 }
210                 sb.append(Toolbox.trimRight(newLine));
211                 if (it.hasNext() /*&& (
212                      ( !
213                             ( ((String)it.next()).trim().length()==0 ) && ( !it.hasNext() ) // append new line only if not last line or line before an empty last line
214          )
215          & ( dummy(it.previous()) )
216         ) */
) {
217                     sb.append(nl);
218                 }
219             }
220            }
221            String JavaDoc s = sb.toString();
222            if (s.endsWith(nl)) { // truncate very last line-break, if there (very last blank line is rest until '}' and will be auto-generated anyway)
223
s = s.substring(0, s.length()-nl.length());
224            }
225            return s;
226     }
227
228     private static boolean dummy(Object JavaDoc o) {
229         // (allows to call it.previous()) from within boolean expression
230
return true;
231     }
232
233 } // end Code
234
Popular Tags