1 19 20 25 26 package org.netbeans.modules.javacore.jmiimpl.javamodel; 27 28 import java.util.*; 29 import org.netbeans.jmi.javamodel.*; 30 import org.netbeans.mdr.NBMDRepositoryImpl; 31 import org.netbeans.mdr.persistence.MOFID; 32 import org.netbeans.modules.javacore.JMManager; 33 import org.netbeans.modules.javacore.internalapi.JavaMetamodel; 34 import org.netbeans.modules.javacore.internalapi.ProgressSupport; 35 import org.openide.ErrorManager; 36 import org.openide.util.Cancellable; 37 38 42 public class UsageFinder { 43 44 private NamedElement what; 45 private ElementNavigator navigator; 46 private Collection usages; 47 private static final int MAX_COUNT = 30; 48 private Set declaringClasses; 49 private boolean overriders = false; 50 private boolean findUsages = true; 51 52 53 public UsageFinder(NamedElement what) { 54 if (what instanceof ParameterizedType) { 55 this.what = convert(getRealClassDefinition((ParameterizedType) what)); 56 } else { 57 this.what = convert(what); 58 } 59 } 60 61 private static List getParameters(CallableFeature f) { 62 List params = new ArrayList(); 63 for (Iterator i = f.getParameters().iterator(); i.hasNext(); params.add(convert(TypeClassImpl.getRawType(((Parameter)i.next()).getType())))); 64 return params; 65 } 66 67 private static NamedElement convert(NamedElement what) { 68 if (what instanceof TypeParameter) { 69 return what; 70 } 71 if (what instanceof JavaClass) { 72 return convert((JavaClass) what); 73 } 74 75 NamedElement convertedElement = null; 76 77 if (what instanceof ClassMember) { 78 ClassDefinition cls = ((ClassMember) what).getDeclaringClass(); 79 if (cls instanceof JavaClass) { 80 JavaClass clazz = (JavaClass) convert(cls); 81 if (clazz.equals(cls)) { 82 return what; 83 } 84 85 if (what instanceof Field) { 86 convertedElement = clazz.getField(what.getName(), false); 87 } else { 88 if (what instanceof Method) { 89 convertedElement = clazz.getMethod(what.getName(), getParameters((CallableFeature) what), false); 90 } else if (what instanceof Constructor) { 91 convertedElement = clazz.getConstructor(getParameters((CallableFeature) what), false); 92 } 93 } 94 } 95 } 96 return convertedElement == null ? what:convertedElement ; 97 } 98 99 private static Type convert(Type clazz) { 100 if (clazz instanceof JavaClassImpl && ((JavaClassImpl)clazz).isTransient()) return clazz; 102 return JavaMetamodel.getManager().getDefaultExtent().getType().resolve(clazz.getName()); 103 } 104 105 112 public UsageFinder(CallableFeature method, boolean findUsages, boolean fromBaseClass, boolean overriders) { 113 this(method); 114 this.overriders = overriders; 115 this.findUsages = findUsages; 116 declaringClasses = new HashSet(); 117 ClassDefinition clazz = method.getDeclaringClass(); 118 declaringClasses.add(getRealClassDefinition(clazz)); 119 List argTypes = new ArrayList(); 120 for (Iterator i = method.getParameters().iterator(); i.hasNext(); argTypes.add(TypeClassImpl.getRawType(((Parameter)i.next()).getType()))); 121 122 if (fromBaseClass) { 123 LinkedList q = new LinkedList(); 124 q.add(clazz); 125 HashSet visited = new HashSet(); 126 while (!q.isEmpty()) { 127 clazz = (ClassDefinition) q.removeFirst(); 128 if (visited.add(clazz)) { 129 CallableFeature callFeature = null; 130 if (method instanceof Method) 131 callFeature = clazz.getMethod(method.getName(), argTypes, false); 132 else 133 callFeature = clazz.getConstructor(argTypes, false); 134 if (callFeature != null) { 135 declaringClasses.add(getRealClassDefinition(clazz)); 136 } 137 q.addAll(clazz.getInterfaces()); 138 clazz = clazz.getSuperClass(); 139 if (clazz!=null) { 140 q.add(clazz); 141 } 142 } 143 } 144 } 145 } 146 147 private ClassDefinition getRealClassDefinition(ClassDefinition cls) { 148 return (ClassDefinition) TypeClassImpl.getRawType(cls); 149 } 150 151 private Collection getUsers(MetadataElement where) { 152 usages = new ArrayList(); 153 List l = new ArrayList(1); 154 l.add(where); 155 getUsers(l); 156 return usages; 157 } 158 159 public Collection getUsers(Resource res[]) { 160 return new LazyCollection(res); 161 } 162 163 private void getUsers(Collection elements) { 164 if (elements == null || elements.isEmpty()) 165 return; 166 167 for (Iterator iter = elements.iterator(); iter.hasNext();) { 168 MetadataElement el = (MetadataElement) iter.next(); 169 if ((el instanceof Resource) || navigator.containsIdentifierIn(el)) { 170 if (isMatch(what, el)) { 171 usages.add(el); 172 } 173 getUsers(el.getChildren()); 174 } 175 } 176 } 177 178 private boolean isMatch(Element what, Element r) { 179 if (what.equals(r)) 181 return false; 182 183 Element ref = r; 184 if (findUsages) { 185 if (ref instanceof ElementReference) { 186 ref = ((ElementReference) r).getElement(); 187 } else { 188 if (!overriders) { 189 return false; 190 } 191 } 192 } 193 194 if (!(what instanceof Method)) { 195 if (ref instanceof ParameterizedType) { 196 ref = getRealClassDefinition((ParameterizedType) ref); 197 } 198 return what.equals(ref); 199 } 200 201 206 if (!(ref instanceof Method)) { 207 return false; 208 } 209 210 if (!overriders && what.equals(ref)) { 211 return true; 212 } 213 214 Method m = (Method) ref; 215 if (m.signatureEquals((Method) what)) { 216 ClassDefinition collectedClass, declaringClass = getRealClassDefinition(m.getDeclaringClass()); 217 for (Iterator i = declaringClasses.iterator(); i.hasNext();) { 218 collectedClass = (ClassDefinition) i.next(); 219 if (declaringClass.isSubTypeOf(collectedClass)) { 220 return true; 221 } 222 } 223 } 224 return false; 225 } 226 227 private void lock() { 228 JavaMetamodel.getDefaultRepository().beginTrans(false); 229 } 230 231 private void unlock() { 232 JavaMetamodel.getDefaultRepository().endTrans(false); 233 } 234 235 private class LazyCollection extends AbstractCollection { 236 MOFID res[]; 237 238 public LazyCollection(Resource res[]) { 239 this.res = new MOFID[res.length]; 240 for (int i = 0; i < res.length; i++) { 241 this.res[i] = ((MetadataElement) res[i])._getMofId(); 242 } 243 } 244 245 public Iterator iterator() { 246 return new LazyIterator(res); 247 } 248 249 public int size() { 250 lock(); 251 try { 252 int size = 0; 253 for (Iterator i = iterator(); i.hasNext(); i.next(), size++ ); 254 return size; 255 } finally { 256 unlock(); 257 } 258 } 259 260 public boolean isEmpty() { 261 lock(); 262 try { 263 return !iterator().hasNext(); 264 } finally { 265 unlock(); 266 } 267 } 268 } 269 270 private class LazyIterator implements Iterator, Cancellable { 271 272 MOFID res[]; 273 Collection currentUsages = Collections.EMPTY_LIST; 274 Iterator inner; 275 int currentIndex; 276 Object next; 277 boolean hasNext; 278 float step; 279 int last; 280 ProgressSupport progressSupport; 281 private boolean cancelRequest; 282 283 LazyIterator(MOFID[] res) { 284 this.res = res; 285 inner = currentUsages.iterator(); 286 currentIndex = -1; 287 hasNext = true; 288 289 step = 1; 290 if (res.length > MAX_COUNT) { 291 step = (float) MAX_COUNT / res.length; 292 } 293 last = 0; 294 295 progressSupport = JavaMetamodel.getManager().getProgressSupport(); 296 } 297 298 public void remove() { 299 throw new UnsupportedOperationException (); 300 } 301 302 public Object next() { 303 lock(); 304 try { 305 if (next==null) { 306 findNext(); 307 } 308 Object result = next; 309 next = null; 310 return result; 311 } finally { 312 unlock(); 313 } 314 } 315 316 private void findNext() { 317 if (!hasNext) { 318 throw new NoSuchElementException(); 319 } 320 while (next==null && hasNext == true) { 321 if (!inner.hasNext()) { 322 if (cancelRequest) 323 return; 324 currentIndex++; 325 if (currentIndex == 0) { 326 progressSupport.fireProgressListenerStart(0, Math.min(res.length,MAX_COUNT)); 327 } 328 if (currentIndex < res.length) { 329 MOFID mofId = res[currentIndex]; 330 if (mofId != null) { 331 ResourceImpl resource = (ResourceImpl) ((NBMDRepositoryImpl) JMManager.getDefaultRepository()).getByMofId(mofId); 332 try { 333 if (resource != null && !resource.getName().endsWith("class")) { navigator = new ElementNavigator(resource, what); 335 currentUsages = getUsers(resource); 336 inner = currentUsages.iterator(); 337 if (!inner.hasNext()) { 338 res[currentIndex] = null; 339 } 340 } else { 341 res[currentIndex] = null; 342 } 343 } catch (IllegalArgumentException e) { 344 JMManager.getLog().notify(ErrorManager.INFORMATIONAL, new Exception ("Resource " + resource == null ? null : resource.getName() + " is not parsable.", e)); } 346 } 347 348 if (currentIndex*step >= last) { 349 progressSupport.fireProgressListenerStep(); 350 last++; 351 } 352 353 } else { 354 hasNext = false; 355 progressSupport.fireProgressListenerStop(); 356 } 357 } 358 if (inner.hasNext()) { 359 next = inner.next(); 360 } 361 } 362 } 363 364 public boolean hasNext() { 365 lock(); 366 try { 367 findNext(); 368 if (cancelRequest) 369 return false; 370 return hasNext; 371 } finally { 372 unlock(); 373 } 374 } 375 376 public boolean cancel() { 377 cancelRequest = true; 378 return true; 379 } 380 } 381 } 382 | Popular Tags |