1 19 20 package org.netbeans.modules.apisupport.refactoring; 21 22 import java.io.IOException ; 23 import java.io.StringReader ; 24 import javax.jmi.reflect.RefObject; 25 import javax.swing.text.Document ; 26 import javax.xml.parsers.SAXParser ; 27 import javax.xml.parsers.SAXParserFactory ; 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 ; 49 import org.xml.sax.InputSource ; 50 import org.xml.sax.Locator ; 51 import org.xml.sax.SAXException ; 52 import org.xml.sax.helpers.DefaultHandler ; 53 54 58 public class NbWhereUsedRefactoringPlugin extends AbstractRefactoringPlugin { 59 60 61 private static ThreadLocal semafor = new ThreadLocal (); 62 63 public void cancelRequest() { 64 65 } 66 67 public Problem fastCheckParameters() { 68 return null; 69 } 70 71 72 75 public NbWhereUsedRefactoringPlugin(AbstractRefactoring refactoring) { 76 super(refactoring); 77 } 78 79 80 86 public Problem prepare(RefactoringElementsBag refactoringElements) { 87 if (semafor.get() != null) { 88 return null; 89 } 90 semafor.set(new Object ()); 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 attributeKey, 129 String attributeValue, 130 String 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 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 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 layerAttribute) { 158 return new LayerWhereUsedRefactoringElement(handle.getLayerFile(), layerFileObject, layerAttribute); 159 } 160 161 public final class LayerWhereUsedRefactoringElement extends AbstractRefactoringElement { 162 private String attr; 163 private String path; 164 private String attrValue; 165 public LayerWhereUsedRefactoringElement(FileObject fo, FileObject layerFo, String attribute) { 166 parentFile = fo; 167 attr = attribute; 168 this.path = layerFo.getPath(); 169 if (attr != null) { 170 Object vl = layerFo.getAttribute("literal:" + attr); if (vl instanceof String ) { 172 attrValue = ((String ) vl).replaceFirst("^(new|method):", ""); } 174 } 175 } 176 public String 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 doc = ec.openDocument(); 190 String text = doc.getText(0, doc.getLength()); 191 assert text.indexOf('\r') == -1; InputSource in = new InputSource (new StringReader (text)); 193 in.setSystemId(parentFile.getURL().toExternalForm()); 194 SAXParserFactory factory = SAXParserFactory.newInstance(); 195 SAXParser parser = factory.newSAXParser(); 196 final int[] lineAndColStartAndEnd = new int[4]; 197 class Halt extends SAXException { 198 public Halt() { 199 super((String ) null); 200 } 201 } 202 class Handler extends DefaultHandler { 203 private int state = -1; private Locator locator; 205 private String runningPath = ""; 206 public void setDocumentLocator(Locator l) { 207 locator = l; 208 } 209 public void startElement(String uri, String localname, String qname, Attributes attr) throws SAXException { 210 if (qname.equals("file") || qname.equals("folder")) { String name = attr.getValue("name"); 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 uri, String localname, String qname) throws SAXException { 228 if (qname.equals("file") || qname.equals("folder")) { 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 resolveEntity(String publicId, String systemId) throws SAXException { 241 try { 242 return EntityCatalog.getDefault().resolveEntity(publicId, systemId); 243 } catch (IOException e) { 244 throw new SAXException (e); 245 } 246 } 247 } 248 try { 249 parser.parse(in, new Handler ()); 250 } catch (Halt h) { 251 } 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 startAndEnd[0] = Math.max(text.lastIndexOf('<', startAndEnd[0]), 0); 276 if (startAndEnd[1] == 0) { 277 startAndEnd[1] = Math.max(text.indexOf('>', startAndEnd[0]), startAndEnd[0]); 279 } 280 String 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 return new int[] {loc, loc + match.length()}; 291 } else { 292 return startAndEnd; 294 } 295 } catch (Exception 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 attrName; 306 private String sectionName = null; 307 public ManifestWhereUsedRefactoringElement(String name, FileObject parentFile, String attributeName) { 308 this.name = name; 309 this.parentFile = parentFile; 310 attrName = attributeName; 311 } 312 public ManifestWhereUsedRefactoringElement(String name, FileObject parentFile, String attributeName, String secName) { 313 this(name, parentFile, attributeName); 314 sectionName = secName; 315 } 316 317 public String 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 doc = ec.openDocument(); 329 String text = doc.getText(0, doc.getLength()); 330 assert text.indexOf('\r') == -1; 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 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 name, FileObject file, int line) { 350 this.name = name; 351 parentFile = file; 352 this.line = line; 353 } 354 355 public String 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 doc = ec.openDocument(); 364 String text = doc.getText(0, doc.getLength()); 365 assert text.indexOf('\r') == -1; 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 e) { 385 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); 386 return new int[] {0, 0}; 387 } 388 } 389 390 } 391 392 } 393 | Popular Tags |