KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > tasklist > javaparser > ReplaceSymbolPerformer


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.tasklist.javaparser;
21
22 import javax.swing.text.*;
23 import javax.swing.event.*;
24 import java.awt.*;
25 import java.awt.event.*;
26 import javax.swing.*;
27 import java.util.List JavaDoc;
28 import java.util.ArrayList JavaDoc;
29 import java.util.Arrays JavaDoc;
30 import java.util.Collections JavaDoc;
31 import java.util.Comparator JavaDoc;
32 import java.util.Iterator JavaDoc;
33 import org.openide.ErrorManager;
34 import org.openide.cookies.SourceCookie;
35 import org.openide.explorer.view.*;
36 import org.openide.nodes.*;
37 import org.netbeans.modules.java.*;
38
39
40
41 import org.openide.src.Identifier;
42 import org.openide.src.Import;
43 import org.openide.src.SourceElement;
44 import org.openide.src.SourceException;
45 import org.openide.util.NbBundle;
46 import org.openide.util.Utilities;
47
48 import org.openide.cookies.LineCookie;
49 import org.openide.loaders.DataObject;
50 import org.openide.text.Line;
51 import org.openide.ErrorManager;
52
53 import java.util.TreeSet JavaDoc;
54 import java.lang.reflect.Modifier JavaDoc;
55 import org.netbeans.editor.ext.java.*;
56 import org.netbeans.modules.editor.java.*;
57
58 import org.netbeans.modules.tasklist.core.ConfPanel;
59 import org.netbeans.modules.tasklist.core.TLUtils;
60 import org.netbeans.modules.tasklist.client.Suggestion;
61 import org.netbeans.modules.tasklist.client.SuggestionPerformer;
62
63
64 /**
65  * This class performs symbol replacement suggestions
66  *
67  * @author Tor Norbye
68  */

69 class ReplaceSymbolPerformer implements SuggestionPerformer {
70     
71     private int lineno;
72     private int col;
73     private Line line;
74     private DataObject dobj;
75     private Document doc;
76     private String JavaDoc oldSymbol;
77     private String JavaDoc newSymbol;
78     private String JavaDoc beforeDesc;
79     private String JavaDoc afterDesc;
80     private JCClass importClass;
81     private boolean makeMethod;
82
83     ReplaceSymbolPerformer(int lineno, int col, Line line, DataObject dobj,
84                            Document doc,
85                            String JavaDoc oldSymbol, String JavaDoc newSymbol,
86                            String JavaDoc beforeDesc, String JavaDoc afterDesc,
87                            JCClass importClass, boolean makeMethod) {
88         this.lineno = lineno;
89         this.col = col;
90         this.line = line;
91         this.dobj = dobj;
92         this.doc = doc;
93         this.oldSymbol = oldSymbol;
94         this.newSymbol = newSymbol;
95         this.beforeDesc = beforeDesc;
96         this.afterDesc = afterDesc;
97         this.importClass = importClass;
98         this.makeMethod = false;
99
100     }
101
102     // Yay - it's a casing-error
103
public void perform(Suggestion s) {
104         if (makeMethod) {
105             makeMethod();
106         } else {
107             replaceSymbol();
108             if (importClass != null) {
109                 ImportPerformer.importClass(doc, importClass);
110             }
111         }
112     }
113
114      public boolean hasConfirmation() {
115          return true;
116      }
117      
118      public Object JavaDoc getConfirmation(Suggestion s) {
119          String JavaDoc filename =
120              dobj.getPrimaryFile().getNameExt();
121          StringBuffer JavaDoc sb = new StringBuffer JavaDoc(200);
122          Line l = line;
123          String JavaDoc text = l.getText();
124          
125          // Underline differences
126
int fd = TLUtils.firstDiff(oldSymbol, newSymbol);
127          int ldo = oldSymbol.length()- TLUtils.lastDiff(oldSymbol, newSymbol);
128          int ldn = newSymbol.length() - TLUtils.lastDiff(oldSymbol, newSymbol);
129          sb.append("<html>"); // NOI18N
130
TLUtils.appendSurroundingLine(sb, l, -1);
131          JPUtils.replaceSymbol(sb, text, col, oldSymbol, oldSymbol,
132                                true, fd, ldo);
133          TLUtils.appendSurroundingLine(sb, l, +1);
134          sb.append("</html>"); // NOI18N
135
String JavaDoc beforeContents = sb.toString();
136          
137          sb.setLength(0);
138          sb.append("<html>");
139          if (importClass != null) {
140              sb.append("<b>import "); // NOI18N
141
sb.append(importClass.toString());
142              sb.append(";</b><br>...<br>"); // NOI18N
143
}
144          TLUtils.appendSurroundingLine(sb, l, -1);
145          JPUtils.replaceSymbol(sb, text, col, oldSymbol, newSymbol,
146                                true, fd, ldn);
147          TLUtils.appendSurroundingLine(sb, l, +1);
148          sb.append("</html>"); // NOI18N
149
String JavaDoc afterContents = sb.toString();
150          return new ConfPanel(beforeDesc, beforeContents, afterDesc,
151                               afterContents, filename, lineno, null);
152      }
153
154     /** Replace one symbol reference with another */
155      boolean replaceSymbol() {
156         //System.out.println("ReplaceSymbol '" + symbol + "' with '" + newSymbol + "')");
157
//System.out.println("line=" + lineno);
158
if (!(doc instanceof StyledDocument)) {
159             return false;
160         }
161         
162         // HACK
163
lineno--;
164         
165         StyledDocument sdoc = (StyledDocument)doc;
166         Element e = sdoc.getParagraphElement(0).getParentElement();
167         if (e == null) {
168             // try default root (should work for text/plain)
169
e = sdoc.getDefaultRootElement();
170         }
171         Element elm = e.getElement(lineno);
172         if (elm == null) {
173             return false;
174         }
175         int offset = elm.getStartOffset();
176         int endOffset = elm.getEndOffset();
177
178         try {
179             String JavaDoc text = sdoc.getText(offset, endOffset-offset);
180             // "dumb" implementation - do multiple replacements
181

182             // iterate backwards, look for hits; when one is found,
183
// ensure that it's bracketed by non javaidentifierparts
184
// and if so, substitute
185
// (we go backwards such that our substitutions don't
186
// affect the document indices!)
187
int symLen = oldSymbol.length();
188             int texLen = text.length();
189             int n = texLen-symLen;
190             while (true) {
191                 if (n < 0) {
192                     break;
193                 }
194
195                 if (text.startsWith(oldSymbol, n)) {
196                     // Found match
197
if ((n > 0) &&
198                         Character.isJavaIdentifierPart(text.charAt(n-1))) {
199                         n--;
200                         continue;
201                     }
202                     if ((n+symLen+1 < texLen-1) &&
203                         Character.isJavaIdentifierPart(text.charAt(n+symLen))) {
204                         n--; // XXX could I jump back by symLen here?
205
// What if the symbol is "aaa" ? Not a problem
206
continue;
207                     }
208
209                     int pos = offset + n;
210                     sdoc.remove(pos, symLen);
211                     sdoc.insertString(pos, newSymbol, null);
212                    // See XXX jump comment earlier - can I jump symLen-1 here?
213
}
214                 n--;
215             }
216         } catch (BadLocationException ex) {
217             ErrorManager.getDefault().notify(ErrorManager.WARNING, ex);
218         }
219         return false;
220     }
221
222
223     /** Make a method out of the given symbol
224      * <p>
225      * @todo NOTE that this is very similar to replaceSymbol (because
226      * we cannnot trust the column number handed to us by the compiler.
227      * The difference seems to be that here we want to make a single
228      * substitution, whereas the other replacements replace all.
229      * Make THAT the flag differentiator (replaceAll, replaceSingle)
230      * rather than focus on this usage as a method with the makeMethod
231      * flag!
232      */

233     boolean makeMethod() {
234         //System.out.println("MakeMethod out of '" + oldSymbol + "' where the identified method was " + mtd + " (" + mtd.getClass().getName() + ")");
235
//System.out.println("line=" + lineno + " and col = " + col);
236
// TODO
237
if (!(doc instanceof StyledDocument)) {
238             return false;
239         }
240         
241         // HACK
242
lineno--;
243         
244         StyledDocument sdoc = (StyledDocument)doc;
245         
246         Element e = sdoc.getParagraphElement(0).getParentElement();
247         if (e == null) {
248             // try default root (should work for text/plain)
249
e = sdoc.getDefaultRootElement();
250         }
251         Element elm = e.getElement(lineno);
252         if (elm == null) {
253             return false;
254         }
255         int offset = elm.getStartOffset();
256         int endOffset = elm.getEndOffset();
257         
258         try {
259             String JavaDoc text = sdoc.getText(offset, endOffset-offset);
260             col--; // The position should be zero based!
261

262             if (text.substring(col).startsWith(oldSymbol)) {
263                 int pos = offset + col + oldSymbol.length();
264                 sdoc.insertString(pos, "()", null);
265             } else if (text.substring(col+1).startsWith(oldSymbol)) {
266                 // For some reason, on some systems (like OSX) I've seen
267
// a 0-based position too!
268
int pos = offset + col+1 + oldSymbol.length();
269                 sdoc.insertString(pos, "()", null);
270             } else {
271                 // Interestingly, at least on OSX with jdk1.3, I may get
272
// a "wrong" column, e.g. it will point at "foo" in
273
// "foo".length
274
// ^
275
// So I've gotta start searching forward
276
int x = text.indexOf(oldSymbol, col+2); // +2: already checked 0,1
277
int nx = x+oldSymbol.length();
278                 if ((x+oldSymbol.length() < text.length()-1) ||
279                     !Character.isJavaIdentifierPart(text.charAt(nx))) {
280                     int pos = offset + nx;
281                     sdoc.insertString(pos, "()", null);
282                 }
283             }
284         } catch (BadLocationException ex) {
285             ErrorManager.getDefault().notify(ErrorManager.WARNING, ex);
286         }
287         return false;
288     }
289     
290     
291
292 }
293
294
Popular Tags