KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > apisupport > refactoring > NbWhereUsedRefactoringPlugin


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.apisupport.refactoring;
21
22 import java.io.IOException JavaDoc;
23 import java.io.StringReader JavaDoc;
24 import javax.jmi.reflect.RefObject;
25 import javax.swing.text.Document JavaDoc;
26 import javax.xml.parsers.SAXParser JavaDoc;
27 import javax.xml.parsers.SAXParserFactory JavaDoc;
28 import org.netbeans.api.project.FileOwnerQuery;
29 import org.netbeans.api.project.Project;
30 import org.netbeans.jmi.javamodel.Constructor;
31 import org.netbeans.jmi.javamodel.JavaClass;
32 import org.netbeans.jmi.javamodel.Method;
33 import org.netbeans.jmi.javamodel.Resource;
34 import org.netbeans.modules.apisupport.project.NbModuleProject;
35 import org.netbeans.modules.apisupport.project.layers.LayerUtils;
36 import org.netbeans.modules.javacore.api.JavaModel;
37 import org.netbeans.modules.refactoring.api.AbstractRefactoring;
38 import org.netbeans.modules.refactoring.api.Problem;
39 import org.netbeans.modules.refactoring.spi.RefactoringElementImplementation;
40 import org.netbeans.modules.refactoring.spi.RefactoringElementsBag;
41 import org.netbeans.modules.refactoring.api.WhereUsedQuery;
42 import org.openide.ErrorManager;
43 import org.openide.cookies.EditorCookie;
44 import org.openide.filesystems.FileObject;
45 import org.openide.loaders.DataObject;
46 import org.openide.util.NbBundle;
47 import org.openide.xml.EntityCatalog;
48 import org.xml.sax.Attributes JavaDoc;
49 import org.xml.sax.InputSource JavaDoc;
50 import org.xml.sax.Locator JavaDoc;
51 import org.xml.sax.SAXException JavaDoc;
52 import org.xml.sax.helpers.DefaultHandler JavaDoc;
53
54 /**
55  *
56  * @author Milos Kleint - inspired by j2eerefactoring
57  */

58 public class NbWhereUsedRefactoringPlugin extends AbstractRefactoringPlugin {
59     
60     /** This one is important creature - makes sure that cycles between plugins won't appear */
61     private static ThreadLocal JavaDoc semafor = new ThreadLocal JavaDoc();
62     
63     public void cancelRequest() {
64         
65     }
66     
67     public Problem fastCheckParameters() {
68         return null;
69     }
70     
71     
72     /**
73      * Creates a new instance of NbWhereUsedRefactoringPlugin
74      */

75     public NbWhereUsedRefactoringPlugin(AbstractRefactoring refactoring) {
76         super(refactoring);
77     }
78     
79     
80     /** Collects refactoring elements for a given refactoring.
81      * @param refactoringElements Collection of refactoring elements - the implementation of this method
82      * should add refactoring elements to this collections. It should make no assumptions about the collection
83      * content.
84      * @return Problems found or null (if no problems were identified)
85      */

86     public Problem prepare(RefactoringElementsBag refactoringElements) {
87         if (semafor.get() != null) {
88             return null;
89         }
90         semafor.set(new Object JavaDoc());
91         try {
92             WhereUsedQuery whereUsedRefactor = ((WhereUsedQuery)refactoring);
93             
94             if (!whereUsedRefactor.isFindUsages()) {
95                 return null;
96             }
97             
98             Problem problem = null;
99             RefObject refObject = (RefObject) whereUsedRefactor.getRefactoredObject();
100             if (refObject instanceof JavaClass) {
101                 JavaClass clzz = (JavaClass)refObject;
102                 Resource res = clzz.getResource();
103                 FileObject fo = JavaModel.getFileObject(res);
104                 Project project = FileOwnerQuery.getOwner(fo);
105                 if (project != null && project instanceof NbModuleProject) {
106                     checkMetaInfServices(project, clzz, refactoringElements);
107                     checkManifest((NbModuleProject)project, clzz, refactoringElements);
108                     checkLayer((NbModuleProject)project, clzz, refactoringElements);
109                 }
110             }
111             if (refObject instanceof Method) {
112                 Method method = (Method)refObject;
113                 problem = checkLayer(method, refactoringElements);
114             }
115             if (refObject instanceof Constructor) {
116                 Constructor constructor = (Constructor)refObject;
117                 problem = checkLayer(constructor, refactoringElements);
118             }
119             err.log("Gonna return problem: " + problem);
120             return problem;
121         } finally {
122             semafor.set(null);
123         }
124     }
125
126     protected RefactoringElementImplementation createManifestRefactoring(JavaClass clazz,
127                                                                          FileObject manifestFile,
128                                                                          String JavaDoc attributeKey,
129                                                                          String JavaDoc attributeValue,
130                                                                          String JavaDoc section)
131     {
132         return new ManifestWhereUsedRefactoringElement(attributeValue, manifestFile,
133                                                        attributeKey, section);
134     }
135
136     protected RefactoringElementImplementation createMetaInfServicesRefactoring(JavaClass clazz, FileObject serviceFile, int line) {
137         return new ServicesWhereUsedRefactoringElement(clazz.getSimpleName(), serviceFile, line);
138     }
139     
140     protected RefactoringElementImplementation createLayerRefactoring(JavaClass clazz,
141             LayerUtils.LayerHandle handle,
142             FileObject layerFileObject,
143             String JavaDoc layerAttribute) {
144         return new LayerWhereUsedRefactoringElement(handle.getLayerFile(), layerFileObject, layerAttribute);
145     }
146     
147     protected RefactoringElementImplementation createLayerRefactoring(Method method,
148             LayerUtils.LayerHandle handle,
149             FileObject layerFileObject,
150             String JavaDoc layerAttribute) {
151         return new LayerWhereUsedRefactoringElement(handle.getLayerFile(), layerFileObject, layerAttribute);
152     }
153     
154     protected RefactoringElementImplementation createLayerRefactoring(Constructor constructor,
155             LayerUtils.LayerHandle handle,
156             FileObject layerFileObject,
157             String JavaDoc layerAttribute) {
158         return new LayerWhereUsedRefactoringElement(handle.getLayerFile(), layerFileObject, layerAttribute);
159     }
160     
161     public final class LayerWhereUsedRefactoringElement extends AbstractRefactoringElement {
162         private String JavaDoc attr;
163         private String JavaDoc path;
164         private String JavaDoc attrValue;
165         public LayerWhereUsedRefactoringElement(FileObject fo, FileObject layerFo, String JavaDoc attribute) {
166             parentFile = fo;
167             attr = attribute;
168             this.path = layerFo.getPath();
169             if (attr != null) {
170                 Object JavaDoc vl = layerFo.getAttribute("literal:" + attr); //NOI18N
171
if (vl instanceof String JavaDoc) {
172                     attrValue = ((String JavaDoc) vl).replaceFirst("^(new|method):", ""); // NOI18N
173
}
174             }
175         }
176         public String JavaDoc getDisplayText() {
177             if (attr != null && attrValue != null) {
178                 return NbBundle.getMessage(NbWhereUsedRefactoringPlugin.class, "TXT_LayerAttrValueWhereUsed", path, attr, attrValue);
179             }
180             if (attr != null) {
181                 return NbBundle.getMessage(NbWhereUsedRefactoringPlugin.class, "TXT_LayerAttrWhereUsed", path, attr);
182             }
183             return NbBundle.getMessage(NbWhereUsedRefactoringPlugin.class, "TXT_LayerWhereUsed", path);
184         }
185         protected int[] location() {
186             try {
187                 DataObject d = DataObject.find(parentFile);
188                 EditorCookie ec = (EditorCookie) d.getCookie(EditorCookie.class);
189                 Document JavaDoc doc = ec.openDocument();
190                 String JavaDoc text = doc.getText(0, doc.getLength());
191                 assert text.indexOf('\r') == -1; // should be in newline format only when a Document
192
InputSource JavaDoc in = new InputSource JavaDoc(new StringReader JavaDoc(text));
193                 in.setSystemId(parentFile.getURL().toExternalForm());
194                 SAXParserFactory JavaDoc factory = SAXParserFactory.newInstance();
195                 SAXParser JavaDoc parser = factory.newSAXParser();
196                 final int[] lineAndColStartAndEnd = new int[4];
197                 class Halt extends SAXException JavaDoc {
198                     public Halt() {
199                         super((String JavaDoc) null);
200                     }
201                 }
202                 class Handler extends DefaultHandler JavaDoc {
203                     private int state = -1; // -1 - not encountered (or already found it but Halt did not work), 0 - in matching element, 1+ - in nested element
204
private Locator JavaDoc locator;
205                     private String JavaDoc runningPath = "";
206                     public void setDocumentLocator(Locator JavaDoc l) {
207                         locator = l;
208                     }
209                     public void startElement(String JavaDoc uri, String JavaDoc localname, String JavaDoc qname, Attributes JavaDoc attr) throws SAXException JavaDoc {
210                         if (qname.equals("file") || qname.equals("folder")) { // NOI18N
211
String JavaDoc name = attr.getValue("name"); // NOI18N
212
if (name != null) {
213                                 if (runningPath.length() > 0) {
214                                     runningPath += '/';
215                                 }
216                                 runningPath += name;
217                             }
218                         }
219                         if (state == -1 && path.equals(runningPath)) {
220                             lineAndColStartAndEnd[0] = locator.getLineNumber();
221                             lineAndColStartAndEnd[1] = locator.getColumnNumber();
222                             state = 0;
223                         } else if (state != -1) {
224                             state++;
225                         }
226                     }
227                     public void endElement(String JavaDoc uri, String JavaDoc localname, String JavaDoc qname) throws SAXException JavaDoc {
228                         if (qname.equals("file") || qname.equals("folder")) { // NOI18N
229
runningPath = runningPath.substring(0, Math.max(runningPath.lastIndexOf('/'), 0));
230                         }
231                         if (state > 0) {
232                             state--;
233                         } else if (state == 0) {
234                             lineAndColStartAndEnd[2] = locator.getLineNumber();
235                             lineAndColStartAndEnd[3] = locator.getColumnNumber();
236                             state = -1;
237                             throw new Halt();
238                         }
239                     }
240                     public InputSource JavaDoc resolveEntity(String JavaDoc publicId, String JavaDoc systemId) throws SAXException JavaDoc {
241                         try {
242                             return EntityCatalog.getDefault().resolveEntity(publicId, systemId);
243                         } catch (IOException JavaDoc e) {
244                             throw new SAXException JavaDoc(e);
245                         }
246                     }
247                 }
248                 try {
249                     parser.parse(in, new Handler JavaDoc());
250                 } catch (Halt h) {
251                     // ignore
252
}
253                 if (lineAndColStartAndEnd[0] == 0 || lineAndColStartAndEnd[1] == 0 || lineAndColStartAndEnd[2] == 0 || lineAndColStartAndEnd[3] == 0) {
254                     return new int[] {0, 0};
255                 }
256                 int[] startAndEnd = new int[2];
257                 int line = 0;
258                 int col = 0;
259                 for (int i = 0; i < text.length(); i++) {
260                     if (line == lineAndColStartAndEnd[0] - 1 && col == lineAndColStartAndEnd[1] - 1) {
261                         startAndEnd[0] = i;
262                     } else if (line == lineAndColStartAndEnd[2] - 1 && col == lineAndColStartAndEnd[3] - 1) {
263                         startAndEnd[1] = i;
264                     }
265                     char c = text.charAt(i);
266                     if (c == '\n') {
267                         line++;
268                         col = 0;
269                     } else {
270                         col++;
271                     }
272                 }
273                 // Start position given by SAX locator may actually be *end* of open tag, which is not good.
274
// Try to backtrack to opening '<'. Shouldn't be any other '<' in an XML element.
275
startAndEnd[0] = Math.max(text.lastIndexOf('<', startAndEnd[0]), 0);
276                 if (startAndEnd[1] == 0) {
277                     // Minimized tag. Guess that unescaped '>' will not occur in the value.
278
startAndEnd[1] = Math.max(text.indexOf('>', startAndEnd[0]), startAndEnd[0]);
279                 }
280                 // Right now we have the containing file object. Prefer to get the actual string.
281
String JavaDoc match;
282                 if (attrValue != null) {
283                     match = attrValue;
284                 } else {
285                     match = path.substring(path.lastIndexOf('/') + 1);
286                 }
287                 int loc = text.indexOf(match, startAndEnd[0]);
288                 if (loc != -1 && loc < startAndEnd[1]) {
289                     // Found it.
290
return new int[] {loc, loc + match.length()};
291                 } else {
292                     // OK, just show the whole <file>.
293
return startAndEnd;
294                 }
295             } catch (Exception JavaDoc e) {
296                 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e);
297                 return new int[] {0, 0};
298             }
299         }
300     }
301     
302     
303     public final class ManifestWhereUsedRefactoringElement extends AbstractRefactoringElement {
304         
305         private String JavaDoc attrName;
306         private String JavaDoc sectionName = null;
307         public ManifestWhereUsedRefactoringElement(String JavaDoc name, FileObject parentFile, String JavaDoc attributeName) {
308             this.name = name;
309             this.parentFile = parentFile;
310             attrName = attributeName;
311         }
312         public ManifestWhereUsedRefactoringElement(String JavaDoc name, FileObject parentFile, String JavaDoc attributeName, String JavaDoc secName) {
313             this(name, parentFile, attributeName);
314             sectionName = secName;
315         }
316         
317         public String JavaDoc getDisplayText() {
318             if (sectionName != null) {
319                 return NbBundle.getMessage(NbWhereUsedRefactoringPlugin.class, "TXT_ManifestSectionWhereUsed", this.name, sectionName);
320             }
321             return NbBundle.getMessage(NbWhereUsedRefactoringPlugin.class, "TXT_ManifestWhereUsed", this.name, attrName);
322         }
323
324         protected int[] location() {
325             try {
326                 DataObject d = DataObject.find(parentFile);
327                 EditorCookie ec = (EditorCookie) d.getCookie(EditorCookie.class);
328                 Document JavaDoc doc = ec.openDocument();
329                 String JavaDoc text = doc.getText(0, doc.getLength());
330                 assert text.indexOf('\r') == -1; // should be in newline format only when a Document
331
int start = text.indexOf(name);
332                 if (start == -1) {
333                     return new int[] {0, 0};
334                 } else {
335                     return new int[] {start, start + name.length()};
336                 }
337             } catch (Exception JavaDoc e) {
338                 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e);
339                 return new int[] {0, 0};
340             }
341         }
342         
343     }
344     
345     public final class ServicesWhereUsedRefactoringElement extends AbstractRefactoringElement {
346         
347         private final int line;
348         
349         public ServicesWhereUsedRefactoringElement(String JavaDoc name, FileObject file, int line) {
350             this.name = name;
351             parentFile = file;
352             this.line = line;
353         }
354         
355         public String JavaDoc getDisplayText() {
356             return NbBundle.getMessage(NbWhereUsedRefactoringPlugin.class, "TXT_ServicesWhereUsed", this.name);
357         }
358
359         protected int[] location() {
360             try {
361                 DataObject d = DataObject.find(parentFile);
362                 EditorCookie ec = (EditorCookie) d.getCookie(EditorCookie.class);
363                 Document JavaDoc doc = ec.openDocument();
364                 String JavaDoc text = doc.getText(0, doc.getLength());
365                 assert text.indexOf('\r') == -1; // should be in newline format only when a Document
366
int[] startAndEnd = new int[2];
367                 int line = 0;
368                 int col = 0;
369                 for (int i = 0; i < text.length(); i++) {
370                     if (line == this.line && col == 0) {
371                         startAndEnd[0] = i;
372                     } else if (line == this.line + 1 && col == 0) {
373                         startAndEnd[1] = i - 1;
374                     }
375                     char c = text.charAt(i);
376                     if (c == '\n') {
377                         line++;
378                         col = 0;
379                     } else {
380                         col++;
381                     }
382                 }
383                 return startAndEnd;
384             } catch (Exception JavaDoc e) {
385                 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e);
386                 return new int[] {0, 0};
387             }
388         }
389         
390     }
391     
392 }
393
Popular Tags