KickJava   Java API By Example, From Geeks To Geeks.

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


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.File JavaDoc;
23 import java.io.FileNotFoundException JavaDoc;
24 import java.io.IOException JavaDoc;
25 import java.io.InputStream JavaDoc;
26 import java.io.OutputStream JavaDoc;
27 import java.util.StringTokenizer JavaDoc;
28 import java.util.regex.Pattern JavaDoc;
29 import org.netbeans.api.project.FileOwnerQuery;
30 import org.netbeans.api.project.Project;
31 import org.netbeans.jmi.javamodel.Constructor;
32 import org.netbeans.jmi.javamodel.Element;
33 import org.netbeans.jmi.javamodel.JavaClass;
34 import org.netbeans.jmi.javamodel.Method;
35 import org.netbeans.jmi.javamodel.Resource;
36 import org.netbeans.modules.apisupport.project.EditableManifest;
37 import org.netbeans.modules.apisupport.project.NbModuleProject;
38 import org.netbeans.modules.apisupport.project.layers.LayerUtils;
39 import org.netbeans.modules.javacore.api.JavaModel;
40 import org.netbeans.modules.javacore.internalapi.ExternalChange;
41 import org.netbeans.modules.javacore.internalapi.JavaMetamodel;
42 import org.netbeans.modules.refactoring.api.AbstractRefactoring;
43 import org.netbeans.modules.refactoring.api.Problem;
44 import org.netbeans.modules.refactoring.api.SafeDeleteRefactoring;
45 import org.netbeans.modules.refactoring.spi.RefactoringElementImplementation;
46 import org.netbeans.modules.refactoring.spi.RefactoringElementsBag;
47 import org.openide.ErrorManager;
48 import org.openide.filesystems.FileLock;
49 import org.openide.filesystems.FileObject;
50 import org.openide.filesystems.FileUtil;
51 import org.openide.util.NbBundle;
52
53 /**
54  *
55  * @author Milos Kleint - inspired by j2eerefactoring
56  */

57 public class NbSafeDeleteRefactoringPlugin extends AbstractRefactoringPlugin {
58     
59     /** This one is important creature - makes sure that cycles between plugins won't appear */
60     private static ThreadLocal JavaDoc semafor = new ThreadLocal JavaDoc();
61     
62     /**
63      * Creates a new instance of NbRenameRefactoringPlugin
64      */

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

83     public Problem prepare(RefactoringElementsBag refactoringElements) {
84         if (semafor.get() != null) {
85             return null;
86         }
87         semafor.set(new Object JavaDoc());
88         try {
89             SafeDeleteRefactoring delete = (SafeDeleteRefactoring)refactoring;
90             Problem problem = null;
91             Element[] elements = delete.getElementsToDelete();
92             for (int i = 0 ; i < elements.length; i++) {
93                 if (elements[i] instanceof JavaClass) {
94                     JavaClass clzz = (JavaClass)elements[i];
95                     Resource res = clzz.getResource();
96                     FileObject fo = JavaModel.getFileObject(res);
97                     Project project = FileOwnerQuery.getOwner(fo);
98                     if (project != null && project instanceof NbModuleProject) {
99                         checkMetaInfServices(project, clzz, refactoringElements);
100                         checkManifest((NbModuleProject)project, clzz, refactoringElements);
101                         checkLayer((NbModuleProject)project, clzz, refactoringElements);
102                     }
103                 }
104             }
105             err.log("Gonna return problem: " + problem);
106             return problem;
107         } finally {
108             semafor.set(null);
109         }
110     }
111     
112     protected RefactoringElementImplementation createManifestRefactoring(JavaClass clazz,
113             FileObject manifestFile,
114             String JavaDoc attributeKey,
115             String JavaDoc attributeValue,
116             String JavaDoc section) {
117         return new ManifestSafeDeleteRefactoringElement(manifestFile, attributeValue,
118                 attributeKey, section);
119     }
120     
121     protected RefactoringElementImplementation createMetaInfServicesRefactoring(JavaClass clazz, FileObject serviceFile, int line) {
122         return new ServicesSafeDeleteRefactoringElement(clazz, serviceFile);
123     }
124
125     protected RefactoringElementImplementation createLayerRefactoring(
126             Constructor constructor,
127             LayerUtils.LayerHandle handle,
128             FileObject layerFileObject,
129             String JavaDoc layerAttribute) {
130         return new LayerSafeDeleteRefactoringElement(constructor.getName(), handle, layerFileObject);
131             
132     }
133
134     protected RefactoringElementImplementation createLayerRefactoring(
135             JavaClass clazz,
136             LayerUtils.LayerHandle handle,
137             FileObject layerFileObject,
138             String JavaDoc layerAttribute) {
139         return new LayerSafeDeleteRefactoringElement(clazz.getSimpleName(), handle, layerFileObject, layerAttribute);
140     
141     }
142
143     protected RefactoringElementImplementation createLayerRefactoring(
144             Method method,
145             LayerUtils.LayerHandle handle,
146             FileObject layerFileObject,
147             String JavaDoc layerAttribute) {
148         return new LayerSafeDeleteRefactoringElement(method.getName(), handle, layerFileObject);
149     }
150     
151     
152     public final class ManifestSafeDeleteRefactoringElement extends AbstractRefactoringElement implements ExternalChange {
153         
154         private String JavaDoc attrName;
155         private String JavaDoc sectionName = null;
156         private String JavaDoc oldContent;
157         
158         public ManifestSafeDeleteRefactoringElement(FileObject parentFile, String JavaDoc attributeValue, String JavaDoc attributeName) {
159             this.name = attributeValue;
160             this.parentFile = parentFile;
161             attrName = attributeName;
162             // read old content here. in the unprobable case when 2 classes are to be removed
163
// and both are placed in same services file, we need the true original content
164
oldContent = Utility.readFileIntoString(parentFile);
165         }
166         public ManifestSafeDeleteRefactoringElement(FileObject parentFile, String JavaDoc attributeValue, String JavaDoc attributeName, String JavaDoc secName) {
167             this(parentFile, attributeValue, attributeName);
168             sectionName = secName;
169         }
170         
171         /** Returns text describing the refactoring formatted for display (using HTML tags).
172          * @return Formatted text.
173          */

174         public String JavaDoc getDisplayText() {
175             if (sectionName != null) {
176                 return NbBundle.getMessage(NbSafeDeleteRefactoringPlugin.class, "TXT_ManifestSectionDelete", this.name, sectionName);
177             }
178             return NbBundle.getMessage(NbSafeDeleteRefactoringPlugin.class, "TXT_ManifestDelete", this.name, attrName);
179         }
180         
181         public void performChange() {
182             JavaMetamodel.getManager().registerExtChange(this);
183         }
184         
185         public void performExternalChange() {
186             FileLock lock = null;
187             OutputStream JavaDoc stream = null;
188             InputStream JavaDoc instream = null;
189             
190             try {
191                 instream = parentFile.getInputStream();
192                 EditableManifest manifest = new EditableManifest(instream);
193                 instream.close();
194                 instream = null;
195                 if (sectionName != null) {
196                     manifest.removeSection(name);
197                 } else {
198                     manifest.removeAttribute(attrName, null);
199                 }
200                 lock = parentFile.lock();
201                 stream = parentFile.getOutputStream(lock);
202                 manifest.write(stream);
203             } catch (FileNotFoundException JavaDoc ex) {
204                 //TODO
205
err.notify(ex);
206             } catch (IOException JavaDoc exc) {
207                 //TODO
208
err.notify(exc);
209             } finally {
210                 if (instream != null) {
211                     try {
212                         instream.close();
213                     } catch (IOException JavaDoc ex) {
214                         err.notify(ex);
215                     }
216                 }
217                 if (stream != null) {
218                     try {
219                         stream.close();
220                     } catch (IOException JavaDoc ex) {
221                         err.notify(ex);
222                     }
223                 }
224                 if (lock != null) {
225                     lock.releaseLock();
226                 }
227             }
228         }
229         
230         public void undoExternalChange() {
231             if (oldContent != null) {
232                 Utility.writeFileFromString(parentFile, oldContent);
233             }
234         }
235         
236     }
237     
238     public final class ServicesSafeDeleteRefactoringElement extends AbstractRefactoringElement implements ExternalChange {
239         
240         private String JavaDoc oldName;
241         private String JavaDoc oldContent;
242         private File JavaDoc parent;
243         /**
244          * Creates a new instance of ServicesRenameRefactoringElement
245          */

246         public ServicesSafeDeleteRefactoringElement(JavaClass clazz, FileObject file) {
247             this.name = clazz.getSimpleName();
248             parentFile = file;
249             oldName = clazz.getName();
250             // read old content here. in the unprobable case when 2 classes are to be removed
251
// and both are placed in same services file, we need the true original content
252
oldContent = Utility.readFileIntoString(parentFile);
253             parent = FileUtil.toFile(parentFile);
254         }
255         
256         /** Returns text describing the refactoring formatted for display (using HTML tags).
257          * @return Formatted text.
258          */

259         public String JavaDoc getDisplayText() {
260             return NbBundle.getMessage(NbSafeDeleteRefactoringPlugin.class, "TXT_ServicesDelete", this.name);
261         }
262         
263         public void performChange() {
264             JavaMetamodel.getManager().registerExtChange(this);
265         }
266         
267         public void performExternalChange() {
268             String JavaDoc content = Utility.readFileIntoString(parentFile);
269             if (content != null) {
270                 String JavaDoc longName = oldName;
271                 longName = longName.replaceAll("[.]", "\\."); //NOI18N
272
content = content.replaceAll("^" + longName + "[ \\\n]?", ""); //NOI18N
273
// now check if there's more entries in the file..
274
boolean hasMoreThanComments = false;
275                 StringTokenizer JavaDoc tok = new StringTokenizer JavaDoc(content, "\n"); //NOI18N
276
while (tok.hasMoreTokens()) {
277                     String JavaDoc token = tok.nextToken().trim();
278                     if (token.length() > 0 && (! Pattern.matches("^[#].*", token))) { //NOI18N
279
hasMoreThanComments = true;
280                         break;
281                     }
282                 }
283                 if (hasMoreThanComments) {
284                     Utility.writeFileFromString(parentFile, content);
285                 } else {
286                     try {
287                         parentFile.delete();
288                     } catch (IOException JavaDoc exc) {
289                         err.notify(exc);
290                     }
291                 }
292             }
293         }
294         
295         public void undoExternalChange() {
296             try {
297                 if (oldContent != null) {
298                     if (!parent.exists()) {
299                         FileObject fo = FileUtil.toFileObject(parent.getParentFile());
300                         if (fo != null) {
301                             parentFile = fo.createData(parent.getName());
302                         }
303                     }
304                     Utility.writeFileFromString(parentFile, oldContent);
305                 }
306             } catch (IOException JavaDoc exc) {
307                 err.notify(exc);
308             }
309         }
310         
311     }
312     
313     public final class LayerSafeDeleteRefactoringElement extends AbstractRefactoringElement implements ExternalChange {
314         
315         private FileObject layerFO;
316         private LayerUtils.LayerHandle handle;
317
318         private String JavaDoc attribute;
319         /**
320          * Creates a new instance of LayerRenameRefactoringElement
321          */

322         public LayerSafeDeleteRefactoringElement(String JavaDoc name, LayerUtils.LayerHandle handle, FileObject layerFO, String JavaDoc attr) {
323             this(name, handle, layerFO);
324             attribute = attr;
325         }
326         
327         public LayerSafeDeleteRefactoringElement(String JavaDoc name, LayerUtils.LayerHandle handle, FileObject layerFO) {
328             this.name = name;
329             this.handle = handle;
330             parentFile = handle.getLayerFile();
331             this.layerFO = layerFO;
332         }
333         
334         /** Returns text describing the refactoring formatted for display (using HTML tags).
335          * @return Formatted text.
336          */

337         public String JavaDoc getDisplayText() {
338             return NbBundle.getMessage(NbSafeDeleteRefactoringPlugin.class, "TXT_LayerDelete", layerFO.getNameExt());
339         }
340         
341         public void performChange() {
342             JavaMetamodel.getManager().registerExtChange(this);
343         }
344         
345         public void performExternalChange() {
346             boolean on = handle.isAutosave();
347             if (!on) {
348                 //TODO is this a hack or not?
349
handle.setAutosave(true);
350             }
351             try {
352                 if (attribute != null) {
353                     layerFO.setAttribute(attribute, null);
354                     if ("originalFile".equals(attribute)) {
355                         layerFO.delete();
356                     }
357                 } else {
358                     layerFO.delete();
359                 }
360                 deleteEmptyParent(layerFO.getParent());
361             } catch (IOException JavaDoc exc) {
362                 ErrorManager.getDefault().notify(exc);
363             }
364             if (!on) {
365                 handle.setAutosave(false);
366             }
367             
368         }
369
370         private void deleteEmptyParent(FileObject parent) throws IOException JavaDoc {
371             if (parent != null) {
372                 if (!parent.getChildren(true).hasMoreElements() &&
373                         !parent.getAttributes().hasMoreElements()) {
374                     FileObject parentToDel = parent.getParent();
375                     parent.delete();
376                     deleteEmptyParent(parentToDel);
377                 }
378             }
379         }
380         
381         public void undoExternalChange() {
382         }
383         
384     }
385
386 }
387
Popular Tags