KickJava   Java API By Example, From Geeks To Geeks.

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


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 javax.jmi.reflect.RefObject;
24 import org.netbeans.api.project.FileOwnerQuery;
25 import org.netbeans.api.project.Project;
26 import org.netbeans.jmi.javamodel.Constructor;
27 import org.netbeans.jmi.javamodel.JavaClass;
28 import org.netbeans.jmi.javamodel.JavaPackage;
29 import org.netbeans.jmi.javamodel.Method;
30 import org.netbeans.jmi.javamodel.Resource;
31 import org.netbeans.modules.apisupport.project.NbModuleProject;
32 import org.netbeans.modules.apisupport.project.layers.LayerUtils;
33 import org.netbeans.modules.javacore.api.JavaModel;
34 import org.netbeans.modules.javacore.internalapi.ExternalChange;
35 import org.netbeans.modules.javacore.internalapi.JavaMetamodel;
36 import org.netbeans.modules.refactoring.api.AbstractRefactoring;
37 import org.netbeans.modules.refactoring.api.Problem;
38 import org.netbeans.modules.refactoring.api.RenameRefactoring;
39 import org.netbeans.modules.refactoring.spi.RefactoringElementImplementation;
40 import org.netbeans.modules.refactoring.spi.RefactoringElementsBag;
41 import org.openide.ErrorManager;
42 import org.openide.filesystems.FileLock;
43 import org.openide.filesystems.FileObject;
44 import org.openide.util.NbBundle;
45
46 /**
47  *
48  * @author Milos Kleint - inspired by j2eerefactoring
49  */

50 public class NbRenameRefactoringPlugin extends AbstractRefactoringPlugin {
51     
52     /** This one is important creature - makes sure that cycles between plugins won't appear */
53     private static ThreadLocal JavaDoc semafor = new ThreadLocal JavaDoc();
54     private RenameRefactoring rename;
55     
56     /**
57      * Creates a new instance of NbRenameRefactoringPlugin
58      */

59     public NbRenameRefactoringPlugin(AbstractRefactoring refactoring) {
60         super(refactoring);
61     }
62     
63     public void cancelRequest() {
64         
65     }
66     
67     public Problem fastCheckParameters() {
68         return null;
69     }
70     
71     /** Collects refactoring elements for a given refactoring.
72      * @param refactoringElements Collection of refactoring elements - the implementation of this method
73      * should add refactoring elements to this collections. It should make no assumptions about the collection
74      * content.
75      * @return Problems found or null (if no problems were identified)
76      */

77     public Problem prepare(RefactoringElementsBag refactoringElements) {
78         if (semafor.get() != null) {
79             return null;
80         }
81         semafor.set(new Object JavaDoc());
82         try {
83             rename = (RenameRefactoring)refactoring;
84             Problem problem = null;
85             RefObject refObject = (RefObject) rename.getRefactoredObject();
86             if (refObject instanceof JavaClass) {
87                 JavaClass clzz = (JavaClass)refObject;
88                 Resource res = clzz.getResource();
89                 FileObject fo = JavaModel.getFileObject(res);
90                 Project project = FileOwnerQuery.getOwner(fo);
91                 if (project != null && project instanceof NbModuleProject) {
92                     checkMetaInfServices(project, clzz, refactoringElements);
93                     checkManifest((NbModuleProject)project, clzz, refactoringElements);
94                     checkLayer((NbModuleProject)project, clzz, refactoringElements);
95                 }
96             }
97             if (refObject instanceof JavaPackage) {
98                 JavaPackage pack = (JavaPackage)refObject;
99                 Resource res = pack.getResource();
100                 FileObject fo = JavaModel.getFileObject(res);
101                 if (fo != null) {
102                     //#62636 for some reason in refactoring tests, fileobject is null.
103
Project project = FileOwnerQuery.getOwner(fo);
104                     if (project != null && project instanceof NbModuleProject) {
105                         checkMetaInfServices(project, pack, refactoringElements);
106                     }
107                 }
108             }
109             if (refObject instanceof Method) {
110                 Method method = (Method)refObject;
111                 problem = checkLayer(method, refactoringElements);
112             }
113             
114             err.log("Gonna return problem: " + problem);
115             return problem;
116         } finally {
117             semafor.set(null);
118         }
119     }
120    
121     protected RefactoringElementImplementation createManifestRefactoring(JavaClass clazz,
122             FileObject manifestFile,
123             String JavaDoc attributeKey,
124             String JavaDoc attributeValue,
125             String JavaDoc section) {
126         return new ManifestRenameRefactoringElement(clazz, manifestFile, attributeValue,
127                 attributeKey, section);
128     }
129     
130     protected RefactoringElementImplementation createMetaInfServicesRefactoring(JavaClass clazz, FileObject serviceFile, int line) {
131         return new ServicesRenameRefactoringElement(clazz, serviceFile);
132     }
133
134     protected final void checkMetaInfServices(Project project, JavaPackage pack, RefactoringElementsBag refactoringElements) {
135         FileObject services = Utility.findMetaInfServices(project);
136         if (services == null) {
137             return;
138         }
139         
140         String JavaDoc name = pack.getName();
141         // Easiest to check them all; otherwise would need to find all interfaces and superclasses:
142
FileObject[] files = services.getChildren();
143         for (int i = 0; i < files.length; i++) {
144             int line = checkContentOfFile(files[i], name);
145             if (line != -1) {
146                 RefactoringElementImplementation elem =
147                         new ServicesPackageRenameRefactoringElement(pack, files[i]);
148                 if (elem != null) {
149                     refactoringElements.add(refactoring, elem);
150                 }
151             }
152         }
153     }
154     
155     protected RefactoringElementImplementation createLayerRefactoring(Constructor constructor,
156             LayerUtils.LayerHandle handle,
157             FileObject layerFileObject,
158             String JavaDoc layerAttribute) {
159         // cannot rename a constructor.. is always a class rename
160
return null;
161     }
162     
163     protected RefactoringElementImplementation createLayerRefactoring(JavaClass clazz,
164             LayerUtils.LayerHandle handle,
165             FileObject layerFileObject,
166             String JavaDoc layerAttribute) {
167         return new LayerClassRefactoringElement(clazz, handle, layerFileObject,layerAttribute);
168     }
169     
170     protected RefactoringElementImplementation createLayerRefactoring(Method method,
171             LayerUtils.LayerHandle handle,
172             FileObject layerFileObject,
173             String JavaDoc layerAttribute) {
174         return new LayerMethodRefactoringElement(method, handle, layerFileObject, layerAttribute);
175     }
176     
177     public abstract class LayerAbstractRefactoringElement extends AbstractRefactoringElement implements ExternalChange {
178         
179         protected FileObject layerFile;
180         protected LayerUtils.LayerHandle handle;
181         protected String JavaDoc oldFileName;
182         protected String JavaDoc oldAttrName;
183         protected String JavaDoc oldAttrValue;
184         protected String JavaDoc valueType;
185         
186         public LayerAbstractRefactoringElement(
187                 LayerUtils.LayerHandle handle,
188                 FileObject layerFile,
189                 String JavaDoc attributeName) {
190             this.layerFile = layerFile;
191             this.parentFile = handle.getLayerFile();
192             this.handle = handle;
193             
194             oldFileName = layerFile.getName();
195             oldAttrName = attributeName;
196             if (attributeName != null) {
197                 Object JavaDoc val = layerFile.getAttribute("literal:" + attributeName);
198                 if (val == null) {
199                     throw new IllegalStateException JavaDoc();
200                 }
201                 if (val instanceof String JavaDoc) {
202                     oldAttrValue = (String JavaDoc)val;
203                     if (oldAttrValue.startsWith("new:")) {
204                         oldAttrValue = ((String JavaDoc)val).substring("new:".length());
205                         valueType = "newvalue:";
206                     } else if (oldAttrValue.startsWith("method:")) {
207                         oldAttrValue = ((String JavaDoc)val).substring("method:".length());
208                         valueType = "methodvalue:";
209                     }
210                 }
211             }
212         }
213         
214         public void performChange() {
215             JavaMetamodel.getManager().registerExtChange(this);
216         }
217         
218         protected void doAttributeValueChange(String JavaDoc newOne, String JavaDoc type) {
219             boolean on = handle.isAutosave();
220             if (!on) {
221                 //TODO is this a hack or not?
222
handle.setAutosave(true);
223             }
224             try {
225                 layerFile.setAttribute(oldAttrName, (type != null ? type : "") + newOne);
226             } catch (IOException JavaDoc exc) {
227                 ErrorManager.getDefault().notify(exc);
228             }
229             if (!on) {
230                 handle.setAutosave(false);
231             }
232         }
233         
234         protected void doAttributeMove(String JavaDoc oldKey, String JavaDoc newKey) {
235             boolean on = handle.isAutosave();
236             if (!on) {
237                 //TODO is this a hack or not?
238
handle.setAutosave(true);
239             }
240             try {
241                 Object JavaDoc obj = layerFile.getAttribute(oldKey);
242                 // now assume we're just moving ordering attributes..
243
layerFile.setAttribute(oldKey, null);
244                 layerFile.setAttribute(newKey, obj);
245             } catch (IOException JavaDoc exc) {
246                 ErrorManager.getDefault().notify(exc);
247             }
248             if (!on) {
249                 handle.setAutosave(false);
250             }
251         }
252         
253         protected void doFileMove(String JavaDoc newName) {
254             boolean on = handle.isAutosave();
255             if (!on) {
256                 //TODO is this a hack or not?
257
handle.setAutosave(true);
258             }
259             FileLock lock = null;
260             try {
261                 lock = layerFile.lock();
262                 layerFile.rename(lock, newName, layerFile.getExt());
263             } catch (IOException JavaDoc exc) {
264                 ErrorManager.getDefault().notify(exc);
265             } finally {
266                 if (lock != null) {
267                     lock.releaseLock();
268                 }
269             }
270             if (!on) {
271                 handle.setAutosave(false);
272             }
273         }
274     }
275     
276     
277     public final class LayerMethodRefactoringElement extends LayerAbstractRefactoringElement {
278         
279         private String JavaDoc newAttrValue;
280         
281         public LayerMethodRefactoringElement(Method method,
282                 LayerUtils.LayerHandle handle,
283                 FileObject layerFile,
284                 String JavaDoc attributeName) {
285             super(handle, layerFile, attributeName);
286             // for methods the change can only be in the attribute value;
287
newAttrValue = oldAttrValue.replaceAll("\\." + method.getName() + "$", "." + rename.getNewName());
288         }
289         
290         
291         /** Returns text describing the refactoring formatted for display (using HTML tags).
292          * @return Formatted text.
293          */

294         public String JavaDoc getDisplayText() {
295             return NbBundle.getMessage(getClass(), "TXT_LayerMethodRename", oldAttrValue, rename.getNewName());
296         }
297         
298         
299         public void performExternalChange() {
300             doAttributeValueChange(newAttrValue, valueType);
301         }
302         
303         public void undoExternalChange() {
304             doAttributeValueChange(oldAttrValue, valueType);
305         }
306     }
307     
308     public final class LayerClassRefactoringElement extends LayerAbstractRefactoringElement {
309         
310         private JavaClass clazz;
311         private String JavaDoc newAttrName;
312         private String JavaDoc newAttrValue;
313         private String JavaDoc newFileName;
314         
315         public LayerClassRefactoringElement(JavaClass clzz,
316                 LayerUtils.LayerHandle handle,
317                 FileObject layerFile,
318                 String JavaDoc attributeName) {
319             super(handle, layerFile, attributeName);
320             this.clazz = clzz;
321             // for classes the change can be anywhere;
322
if (oldAttrName == null) {
323                 // no attribute -> it's a filename change. eg. org-milos-kleint-MyInstance.instance
324
newFileName = oldFileName.replaceAll("\\-" + clazz.getSimpleName() + "$", "-" + rename.getNewName());
325             } else {
326                 if (oldAttrName.indexOf(clazz.getName().replace('.','-') + ".instance") > 0) {
327                     //replacing the ordering attribute..
328
newAttrName = oldAttrName.replaceAll("-" + clazz.getSimpleName() + "\\.", "-" + rename.getNewName() + ".");
329                 } else {
330                     //replacing attr value probably in instanceCreate and similar
331
if (oldAttrValue != null) {
332                         String JavaDoc toReplacePattern = clazz.getSimpleName();
333                         newAttrValue = oldAttrValue.replaceAll(toReplacePattern, rename.getNewName());
334                     }
335                 }
336             }
337         }
338         
339         
340         /** Returns text describing the refactoring formatted for display (using HTML tags).
341          * @return Formatted text.
342          */

343         public String JavaDoc getDisplayText() {
344             if (newFileName != null) {
345                 return NbBundle.getMessage(getClass(), "TXT_LayerFileRename", oldFileName, rename.getNewName());
346             }
347             return NbBundle.getMessage(getClass(), "TXT_LayerMethodRename", oldAttrValue, rename.getNewName());
348         }
349         
350         
351         public void performExternalChange() {
352             if (newAttrValue != null) {
353                 doAttributeValueChange(newAttrValue, valueType);
354             }
355             if (newAttrName != null) {
356                 doAttributeMove(oldAttrName, newAttrName);
357             }
358             if (newFileName != null) {
359                 doFileMove(newFileName);
360             }
361         }
362         
363         public void undoExternalChange() {
364             if (newAttrValue != null) {
365                 doAttributeValueChange(oldAttrValue, valueType);
366             }
367             if (newAttrName != null) {
368                 doAttributeMove(newAttrName, oldAttrName);
369             }
370             if (newFileName != null) {
371                 doFileMove(oldFileName);
372             }
373         }
374         
375     }
376     
377     
378     public final class ManifestRenameRefactoringElement extends AbstractRefactoringElement implements ExternalChange {
379         
380         private JavaClass clazz;
381         private String JavaDoc attrName;
382         private String JavaDoc sectionName = null;
383         private String JavaDoc oldName;
384         private String JavaDoc oldContent;
385         private String JavaDoc newName;
386         public ManifestRenameRefactoringElement(JavaClass clazz, FileObject parentFile, String JavaDoc attributeValue, String JavaDoc attributeName) {
387             this.name = attributeValue;
388             this.clazz = clazz;
389             this.parentFile = parentFile;
390             attrName = attributeName;
391             oldName = clazz.getName();
392         }
393         public ManifestRenameRefactoringElement(JavaClass clazz, FileObject parentFile, String JavaDoc attributeValue, String JavaDoc attributeName, String JavaDoc secName) {
394             this(clazz, parentFile, attributeValue, attributeName);
395             sectionName = secName;
396         }
397         
398         
399         /** Returns text describing the refactoring formatted for display (using HTML tags).
400          * @return Formatted text.
401          */

402         public String JavaDoc getDisplayText() {
403             if (sectionName != null) {
404                 return NbBundle.getMessage(NbRenameRefactoringPlugin.class, "TXT_ManifestSectionRename", this.name, sectionName);
405             }
406             return NbBundle.getMessage(NbRenameRefactoringPlugin.class, "TXT_ManifestRename", this.name, attrName);
407         }
408         
409         public void performChange() {
410             JavaMetamodel.getManager().registerExtChange(this);
411         }
412         
413         public void performExternalChange() {
414             String JavaDoc content = Utility.readFileIntoString(parentFile);
415             oldContent = content;
416             if (content != null) {
417                 String JavaDoc longName = oldName;
418                 if (newName == null) {
419                     newName = clazz.getName();
420                     newName = newName.replace('.', '/') + ".class"; //NOI18N
421
clazz = null;
422                 }
423                 longName = longName.replace('.', '/') + ".class"; //NOI18N
424
content = content.replaceAll(longName, newName);
425                 Utility.writeFileFromString(parentFile, content);
426             }
427         }
428         
429         public void undoExternalChange() {
430             if (oldContent != null) {
431                 Utility.writeFileFromString(parentFile, oldContent);
432             }
433         }
434     }
435     
436     public final class ServicesRenameRefactoringElement extends AbstractRefactoringElement implements ExternalChange {
437         
438         private JavaClass clazz;
439         private String JavaDoc oldName;
440         private String JavaDoc oldContent;
441         private String JavaDoc newName;
442         /**
443          * Creates a new instance of ServicesRenameRefactoringElement
444          */

445         public ServicesRenameRefactoringElement(JavaClass clazz, FileObject file) {
446             this.name = clazz.getSimpleName();
447             parentFile = file;
448             this.clazz = clazz;
449             oldName = clazz.getName();
450         }
451         
452         /** Returns text describing the refactoring formatted for display (using HTML tags).
453          * @return Formatted text.
454          */

455         public String JavaDoc getDisplayText() {
456             return NbBundle.getMessage(NbRenameRefactoringPlugin.class, "TXT_ServicesRename", this.name);
457         }
458         
459         public void performChange() {
460             JavaMetamodel.getManager().registerExtChange(this);
461         }
462         
463         public void performExternalChange() {
464             String JavaDoc content = Utility.readFileIntoString(parentFile);
465             oldContent = content;
466             if (content != null) {
467                 String JavaDoc longName = oldName;
468                 if (newName == null) {
469                     newName = clazz.getName();
470                     clazz = null;
471                 }
472                 longName = longName.replaceAll("[.]", "\\."); // NOI18N
473
content = content.replaceAll("^" + longName + "[ \\\r\\\n]*", newName + System.getProperty("line.separator")); // NOI18N
474
Utility.writeFileFromString(parentFile, content);
475             }
476         }
477         
478         public void undoExternalChange() {
479             if (oldContent != null) {
480                 Utility.writeFileFromString(parentFile, oldContent);
481             }
482         }
483     }
484     
485     
486     public final class ServicesPackageRenameRefactoringElement extends AbstractRefactoringElement {
487         
488         private JavaPackage pack;
489         private String JavaDoc oldName;
490         /**
491          * Creates a new instance of ServicesRenameRefactoringElement
492          */

493         public ServicesPackageRenameRefactoringElement(JavaPackage pack, FileObject file) {
494             this.name = pack.getName();
495             parentFile = file;
496             this.pack = pack;
497             oldName = pack.getName();
498         }
499         
500         /** Returns text describing the refactoring formatted for display (using HTML tags).
501          * @return Formatted text.
502          */

503         public String JavaDoc getDisplayText() {
504             return NbBundle.getMessage(NbRenameRefactoringPlugin.class, "TXT_ServicesPackageRename", this.name);
505         }
506         
507         public void performChange() {
508             String JavaDoc content = Utility.readFileIntoString(parentFile);
509             if (content != null) {
510                 String JavaDoc longName = oldName;
511                 String JavaDoc newName = pack.getName();
512                 longName = longName.replaceAll("[.]", "\\."); // NOI18N
513
content = content.replaceAll("^" + longName, newName); // NOI18N
514
Utility.writeFileFromString(parentFile, content);
515             }
516         }
517     }
518
519 }
520
Popular Tags