|
What this is
Other links
The source code/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is NetBeans. The Initial Developer of the Original * Code is Sun Microsystems, Inc. Portions Copyright 1997-2004 Sun * Microsystems, Inc. All Rights Reserved. */ /* * UsageFinder.java * * Created on 06 January 2004, 11:44 */ package org.netbeans.modules.javacore.jmiimpl.javamodel; import java.util.*; import org.netbeans.jmi.javamodel.*; import org.netbeans.modules.javacore.JMManager; import org.netbeans.modules.javacore.internalapi.JavaMetamodel; import org.netbeans.modules.javacore.internalapi.ProgressSupport; import org.openide.ErrorManager; import org.openide.util.Cancellable; /** * * @author Jan Becicka */ public class UsageFinder { private NamedElement what; private ElementNavigator navigator; private Collection usages; private static final int MAX_COUNT = 30; private Set declaringClasses; private boolean overriders = false; private boolean findUsages = true; /** Creates a new instance of UsageFinder */ public UsageFinder(NamedElement what) { if (what instanceof ParameterizedType) { this.what = convert(getRealClassDefinition((ParameterizedType) what)); } else { this.what = convert(what); } } private static List getParameters(CallableFeature f) { List params = new ArrayList(); for (Iterator i = f.getParameters().iterator(); i.hasNext(); params.add(convert(TypeClassImpl.getRealType(((Parameter)i.next()).getType())))); return params; } private static NamedElement convert(NamedElement what) { if (what instanceof TypeParameter) { return what; } if (what instanceof JavaClass) { return convert((JavaClass) what); } NamedElement convertedElement = null; if (what instanceof ClassMember) { ClassDefinition cls = ((ClassMember) what).getDeclaringClass(); if (cls instanceof JavaClass) { JavaClass clazz = (JavaClass) convert(cls); if (clazz.equals(cls)) { return what; } if (what instanceof Field) { convertedElement = clazz.getField(what.getName(), false); } else { if (what instanceof Method) { convertedElement = clazz.getMethod(what.getName(), getParameters((CallableFeature) what), false); } else if (what instanceof Constructor) { convertedElement = clazz.getConstructor(getParameters((CallableFeature) what), false); } } } } return convertedElement == null ? what:convertedElement ; } private static Type convert(Type clazz) { return JavaMetamodel.getManager().getDefaultExtent().getType().resolve(clazz.getName()); } /** * specific contructor for method * @param method method for search * @param findUsages find usages of methods * @param fromBaseClass find all occurrences including superclass * @param overriders get Overriding Methods */ public UsageFinder(CallableFeature method, boolean findUsages, boolean fromBaseClass, boolean overriders) { this(method); this.overriders = overriders; this.findUsages = findUsages; declaringClasses = new HashSet(); ClassDefinition clazz = method.getDeclaringClass(); declaringClasses.add(getRealClassDefinition(clazz)); List argTypes = new ArrayList(); for (Iterator i = method.getParameters().iterator(); i.hasNext(); argTypes.add(TypeClassImpl.getRealType(((Parameter)i.next()).getType()))); if (fromBaseClass) { LinkedList q = new LinkedList(); q.add(clazz); while (!q.isEmpty()) { clazz = (ClassDefinition) q.removeFirst(); CallableFeature callFeature = null; if (method instanceof Method) callFeature = clazz.getMethod(method.getName(), argTypes, false); else callFeature = clazz.getConstructor(argTypes, false); if (callFeature != null) { declaringClasses.add(getRealClassDefinition(clazz)); } q.addAll(clazz.getInterfaces()); clazz = clazz.getSuperClass(); if (clazz!=null) { q.add(clazz); } } } } private ClassDefinition getRealClassDefinition(ClassDefinition cls) { return (ClassDefinition) TypeClassImpl.getRealType(cls); } private Collection getUsers(MetadataElement where) { usages = new ArrayList(); List l = new ArrayList(1); l.add(where); getUsers(l); return usages; } public Collection getUsers(Resource res[]) { return new LazyCollection(res); } private void getUsers(Collection elements) { if (elements == null || elements.isEmpty()) return; for (Iterator iter = elements.iterator(); iter.hasNext();) { MetadataElement el = (MetadataElement) iter.next(); if ((el instanceof Resource) || navigator.containsIdentifierIn(el)) { if (isMatch(what, el)) { usages.add(el); } getUsers(el.getChildren()); } } } private boolean isMatch(Element what, Element r) { Element ref = r; if (findUsages) { if (ref instanceof ElementReference) { ref = ((ElementReference) r).getElement(); } else { if (!overriders) { return false; } } } if (!(what instanceof Method)) { if (ref instanceof ParameterizedType) { ref = getRealClassDefinition((ParameterizedType) ref); } return what.equals(ref); } // if (!overriders) { // if (ref instanceof Method) // return false; // } if (!(ref instanceof Method)) { return false; } if (!overriders && what.equals(ref)) { return true; } Method m = (Method) ref; if (m.signatureEquals((Method) what)) { ClassDefinition collectedClass, declaringClass = getRealClassDefinition(m.getDeclaringClass()); for (Iterator i = declaringClasses.iterator(); i.hasNext();) { collectedClass = (ClassDefinition) i.next(); if (declaringClass.isSubTypeOf(collectedClass)) { return true; } } } return false; } private class LazyCollection extends AbstractCollection { Resource res[]; public LazyCollection(Resource res[]) { this.res=res; } public Iterator iterator() { return new LazyIterator(res); } public int size() { int size = 0; for (Iterator i = iterator(); i.hasNext(); i.next(), size++ ); return size; } } private class LazyIterator implements Iterator, Cancellable { Resource res[]; Collection currentUsages = Collections.EMPTY_LIST; Iterator inner; int currentIndex; Object next; boolean hasNext; float step; int last; ProgressSupport progressSupport; private boolean cancelRequest; LazyIterator(Resource[] res) { this.res = res; inner = currentUsages.iterator(); currentIndex = -1; hasNext = true; step = 1; if (res.length > MAX_COUNT) { step = (float) MAX_COUNT / res.length; } last = 0; progressSupport = org.netbeans.modules.javacore.internalapi.JavaMetamodel.getManager().getProgressSupport(); } public void remove() { throw new UnsupportedOperationException(); } public Object next() { if (next==null) { findNext(); } Object result = next; next = null; return result; } private void findNext() { if (!hasNext) { throw new NoSuchElementException(); } while (next==null && hasNext == true) { if (!inner.hasNext()) { if (cancelRequest) return; currentIndex++; if (currentIndex == 0) { progressSupport.fireProgressListenerStart(0, Math.min(res.length,MAX_COUNT)); } if (currentIndex < res.length) { try { if (!res[currentIndex].getName().endsWith("class")) { navigator = new ElementNavigator(res[currentIndex], what); currentUsages = getUsers((MetadataElement) res[currentIndex]); inner = currentUsages.iterator(); } } catch (IllegalArgumentException e) { JMManager.getLog().notify(ErrorManager.INFORMATIONAL, new Exception("Resource " + res[currentIndex].getName() + " is not parsable: " + e.getMessage())); } if (currentIndex*step >= last) { progressSupport.fireProgressListenerStep(); last++; } } else { hasNext = false; progressSupport.fireProgressListenerStop(); } } if (inner.hasNext()) { next = inner.next(); } } } public boolean hasNext() { findNext(); if (cancelRequest) return false; return hasNext; } public boolean cancel() { cancelRequest = true; return true; } } } |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.