1 19 20 package org.netbeans.modules.apisupport.refactoring; 21 22 import java.io.File ; 23 import java.io.FileNotFoundException ; 24 import java.io.IOException ; 25 import java.io.InputStream ; 26 import java.io.OutputStream ; 27 import java.util.StringTokenizer ; 28 import java.util.regex.Pattern ; 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 57 public class NbSafeDeleteRefactoringPlugin extends AbstractRefactoringPlugin { 58 59 60 private static ThreadLocal semafor = new ThreadLocal (); 61 62 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 83 public Problem prepare(RefactoringElementsBag refactoringElements) { 84 if (semafor.get() != null) { 85 return null; 86 } 87 semafor.set(new Object ()); 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 attributeKey, 115 String attributeValue, 116 String 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 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 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 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 attrName; 155 private String sectionName = null; 156 private String oldContent; 157 158 public ManifestSafeDeleteRefactoringElement(FileObject parentFile, String attributeValue, String attributeName) { 159 this.name = attributeValue; 160 this.parentFile = parentFile; 161 attrName = attributeName; 162 oldContent = Utility.readFileIntoString(parentFile); 165 } 166 public ManifestSafeDeleteRefactoringElement(FileObject parentFile, String attributeValue, String attributeName, String secName) { 167 this(parentFile, attributeValue, attributeName); 168 sectionName = secName; 169 } 170 171 174 public String 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 stream = null; 188 InputStream 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 ex) { 204 err.notify(ex); 206 } catch (IOException exc) { 207 err.notify(exc); 209 } finally { 210 if (instream != null) { 211 try { 212 instream.close(); 213 } catch (IOException ex) { 214 err.notify(ex); 215 } 216 } 217 if (stream != null) { 218 try { 219 stream.close(); 220 } catch (IOException 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 oldName; 241 private String oldContent; 242 private File parent; 243 246 public ServicesSafeDeleteRefactoringElement(JavaClass clazz, FileObject file) { 247 this.name = clazz.getSimpleName(); 248 parentFile = file; 249 oldName = clazz.getName(); 250 oldContent = Utility.readFileIntoString(parentFile); 253 parent = FileUtil.toFile(parentFile); 254 } 255 256 259 public String 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 content = Utility.readFileIntoString(parentFile); 269 if (content != null) { 270 String longName = oldName; 271 longName = longName.replaceAll("[.]", "\\."); content = content.replaceAll("^" + longName + "[ \\\n]?", ""); boolean hasMoreThanComments = false; 275 StringTokenizer tok = new StringTokenizer (content, "\n"); while (tok.hasMoreTokens()) { 277 String token = tok.nextToken().trim(); 278 if (token.length() > 0 && (! Pattern.matches("^[#].*", token))) { hasMoreThanComments = true; 280 break; 281 } 282 } 283 if (hasMoreThanComments) { 284 Utility.writeFileFromString(parentFile, content); 285 } else { 286 try { 287 parentFile.delete(); 288 } catch (IOException 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 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 attribute; 319 322 public LayerSafeDeleteRefactoringElement(String name, LayerUtils.LayerHandle handle, FileObject layerFO, String attr) { 323 this(name, handle, layerFO); 324 attribute = attr; 325 } 326 327 public LayerSafeDeleteRefactoringElement(String 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 337 public String 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 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 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 { 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 |