blob: 755889d7c68a1f66439e1f8932d3dcf4e52573c4 [file] [log] [blame]
/*
* Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.jdi;
import com.sun.jdi.*;
import sun.jvm.hotspot.oops.Klass;
import sun.jvm.hotspot.oops.InstanceKlass;
import java.util.*;
import java.lang.ref.SoftReference;
public class ClassTypeImpl extends ReferenceTypeImpl
implements ClassType
{
private SoftReference interfacesCache = null;
private SoftReference allInterfacesCache = null;
private SoftReference subclassesCache = null;
protected ClassTypeImpl(VirtualMachine aVm, InstanceKlass aRef) {
super(aVm, aRef);
}
public ClassType superclass() {
InstanceKlass kk = (InstanceKlass)ref().getSuper();
if (kk == null) {
return null;
}
return (ClassType) vm.referenceType(kk);
}
public List interfaces() {
List interfaces = (interfacesCache != null)? (List) interfacesCache.get() : null;
if (interfaces == null) {
checkPrepared();
interfaces = Collections.unmodifiableList(getInterfaces());
interfacesCache = new SoftReference(interfaces);
}
return interfaces;
}
void addInterfaces(List list) {
List immediate = interfaces();
HashSet hashList = new HashSet(list);
hashList.addAll(immediate);
list.clear();
list.addAll(hashList);
Iterator iter = immediate.iterator();
while (iter.hasNext()) {
InterfaceTypeImpl interfaze = (InterfaceTypeImpl)iter.next();
interfaze.addSuperinterfaces(list);
}
ClassTypeImpl superclass = (ClassTypeImpl)superclass();
if (superclass != null) {
superclass.addInterfaces(list);
}
}
public List allInterfaces() {
List allinterfaces = (allInterfacesCache != null)? (List) allInterfacesCache.get() : null;
if (allinterfaces == null) {
checkPrepared();
allinterfaces = new ArrayList();
addInterfaces(allinterfaces);
allinterfaces = Collections.unmodifiableList(allinterfaces);
allInterfacesCache = new SoftReference(allinterfaces);
}
return allinterfaces;
}
public List subclasses() {
List subclasses = (subclassesCache != null)? (List) subclassesCache.get() : null;
if (subclasses == null) {
List all = vm.allClasses();
subclasses = new ArrayList(0);
Iterator iter = all.iterator();
while (iter.hasNext()) {
ReferenceType refType = (ReferenceType)iter.next();
if (refType instanceof ClassType) {
ClassType clazz = (ClassType)refType;
ClassType superclass = clazz.superclass();
if ((superclass != null) && superclass.equals(this)) {
subclasses.add(refType);
}
}
}
subclasses = Collections.unmodifiableList(subclasses);
subclassesCache = new SoftReference(subclasses);
}
return subclasses;
}
public Method concreteMethodByName(String name, String signature) {
checkPrepared();
List methods = visibleMethods();
Method method = null;
Iterator iter = methods.iterator();
while (iter.hasNext()) {
Method candidate = (Method)iter.next();
if (candidate.name().equals(name) &&
candidate.signature().equals(signature) &&
!candidate.isAbstract()) {
method = candidate;
break;
}
}
return method;
}
List getAllMethods() {
ArrayList list = new ArrayList(methods());
ClassType clazz = superclass();
while (clazz != null) {
list.addAll(clazz.methods());
clazz = clazz.superclass();
}
/*
* Avoid duplicate checking on each method by iterating through
* duplicate-free allInterfaces() rather than recursing
*/
Iterator iter = allInterfaces().iterator();
while (iter.hasNext()) {
InterfaceType interfaze = (InterfaceType)iter.next();
list.addAll(interfaze.methods());
}
return list;
}
List inheritedTypes() {
List inherited = new ArrayList(interfaces());
if (superclass() != null) {
inherited.add(0, superclass()); /* insert at front */
}
return inherited;
}
public boolean isEnum() {
ClassTypeImpl superclass = (ClassTypeImpl) superclass();
if (superclass != null) {
return superclass.typeNameAsSymbol().equals(vm.javaLangEnum());
} else {
return false;
}
}
public void setValue(Field field, Value value)
throws InvalidTypeException, ClassNotLoadedException {
vm.throwNotReadOnlyException("ClassType.setValue(...)");
}
public Value invokeMethod(ThreadReference threadIntf, Method methodIntf,
List arguments, int options)
throws InvalidTypeException,
ClassNotLoadedException,
IncompatibleThreadStateException,
InvocationException {
vm.throwNotReadOnlyException("ClassType.invokeMethod(...)");
return null;
}
public ObjectReference newInstance(ThreadReference threadIntf,
Method methodIntf,
List arguments, int options)
throws InvalidTypeException,
ClassNotLoadedException,
IncompatibleThreadStateException,
InvocationException {
vm.throwNotReadOnlyException("ClassType.newInstance(...)");
return null;
}
void addVisibleMethods(Map methodMap) {
/*
* Add methods from
* parent types first, so that the methods in this class will
* overwrite them in the hash table
*/
Iterator iter = interfaces().iterator();
while (iter.hasNext()) {
InterfaceTypeImpl interfaze = (InterfaceTypeImpl)iter.next();
interfaze.addVisibleMethods(methodMap);
}
ClassTypeImpl clazz = (ClassTypeImpl)superclass();
if (clazz != null) {
clazz.addVisibleMethods(methodMap);
}
addToMethodMap(methodMap, methods());
}
boolean isAssignableTo(ReferenceType type) {
ClassTypeImpl superclazz = (ClassTypeImpl)superclass();
if (this.equals(type)) {
return true;
} else if ((superclazz != null) && superclazz.isAssignableTo(type)) {
return true;
} else {
List interfaces = interfaces();
Iterator iter = interfaces.iterator();
while (iter.hasNext()) {
InterfaceTypeImpl interfaze = (InterfaceTypeImpl)iter.next();
if (interfaze.isAssignableTo(type)) {
return true;
}
}
return false;
}
}
public String toString() {
return "class " + name() + "(" + loaderString() + ")";
}
}