1 /* 2 * Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 package sun.jvm.hotspot.jdi; 26 27 import com.sun.jdi.*; 28 import sun.jvm.hotspot.oops.Klass; 29 import sun.jvm.hotspot.oops.InstanceKlass; 30 31 import java.util.*; 32 import java.lang.ref.SoftReference; 33 34 public class ClassTypeImpl extends ReferenceTypeImpl 35 implements ClassType 36 { 37 private SoftReference interfacesCache = null; 38 private SoftReference allInterfacesCache = null; 39 private SoftReference subclassesCache = null; 40 41 protected ClassTypeImpl(VirtualMachine aVm, InstanceKlass aRef) { 42 super(aVm, aRef); 43 } 44 45 public ClassType superclass() { 46 InstanceKlass kk = (InstanceKlass)ref().getSuper(); 47 if (kk == null) { 48 return null; 49 } 50 return (ClassType) vm.referenceType(kk); 51 } 52 53 public List interfaces() { 54 List interfaces = (interfacesCache != null)? (List) interfacesCache.get() : null; 55 if (interfaces == null) { 56 checkPrepared(); 57 interfaces = Collections.unmodifiableList(getInterfaces()); 58 interfacesCache = new SoftReference(interfaces); 59 } 60 return interfaces; 61 } 62 63 void addInterfaces(List list) { 64 List immediate = interfaces(); 65 66 HashSet hashList = new HashSet(list); 67 hashList.addAll(immediate); 68 list.clear(); 69 list.addAll(hashList); 70 71 Iterator iter = immediate.iterator(); 72 while (iter.hasNext()) { 73 InterfaceTypeImpl interfaze = (InterfaceTypeImpl)iter.next(); 74 interfaze.addSuperinterfaces(list); 75 } 76 77 ClassTypeImpl superclass = (ClassTypeImpl)superclass(); 78 if (superclass != null) { 79 superclass.addInterfaces(list); 80 } 81 } 82 83 public List allInterfaces() { 84 List allinterfaces = (allInterfacesCache != null)? (List) allInterfacesCache.get() : null; 85 if (allinterfaces == null) { 86 checkPrepared(); 87 allinterfaces = new ArrayList(); 88 addInterfaces(allinterfaces); 89 allinterfaces = Collections.unmodifiableList(allinterfaces); 90 allInterfacesCache = new SoftReference(allinterfaces); 91 } 92 return allinterfaces; 93 } 94 95 public List subclasses() { 96 List subclasses = (subclassesCache != null)? (List) subclassesCache.get() : null; 97 if (subclasses == null) { 98 List all = vm.allClasses(); 99 subclasses = new ArrayList(0); 100 Iterator iter = all.iterator(); 101 while (iter.hasNext()) { 102 ReferenceType refType = (ReferenceType)iter.next(); 103 if (refType instanceof ClassType) { 104 ClassType clazz = (ClassType)refType; 105 ClassType superclass = clazz.superclass(); 106 if ((superclass != null) && superclass.equals(this)) { 107 subclasses.add(refType); 108 } 109 } 110 } 111 subclasses = Collections.unmodifiableList(subclasses); 112 subclassesCache = new SoftReference(subclasses); 113 } 114 return subclasses; 115 } 116 117 public Method concreteMethodByName(String name, String signature) { 118 checkPrepared(); 119 List methods = visibleMethods(); 120 Method method = null; 121 Iterator iter = methods.iterator(); 122 while (iter.hasNext()) { 123 Method candidate = (Method)iter.next(); 124 if (candidate.name().equals(name) && 125 candidate.signature().equals(signature) && 126 !candidate.isAbstract()) { 127 128 method = candidate; 129 break; 130 } 131 } 132 return method; 133 } 134 135 List getAllMethods() { 136 ArrayList list = new ArrayList(methods()); 137 ClassType clazz = superclass(); 138 while (clazz != null) { 139 list.addAll(clazz.methods()); 140 clazz = clazz.superclass(); 141 } 142 /* 143 * Avoid duplicate checking on each method by iterating through 144 * duplicate-free allInterfaces() rather than recursing 145 */ 146 Iterator iter = allInterfaces().iterator(); 147 while (iter.hasNext()) { 148 InterfaceType interfaze = (InterfaceType)iter.next(); 149 list.addAll(interfaze.methods()); 150 } 151 return list; 152 } 153 154 List inheritedTypes() { 155 List inherited = new ArrayList(interfaces()); 156 if (superclass() != null) { 157 inherited.add(0, superclass()); /* insert at front */ 158 } 159 return inherited; 160 } 161 162 public boolean isEnum() { 163 ClassTypeImpl superclass = (ClassTypeImpl) superclass(); 164 if (superclass != null) { 165 return superclass.typeNameAsSymbol().equals(vm.javaLangEnum()); 166 } else { 167 return false; 168 } 169 } 170 171 public void setValue(Field field, Value value) 172 throws InvalidTypeException, ClassNotLoadedException { 173 vm.throwNotReadOnlyException("ClassType.setValue(...)"); 174 } 175 176 177 public Value invokeMethod(ThreadReference threadIntf, Method methodIntf, 178 List arguments, int options) 179 throws InvalidTypeException, 180 ClassNotLoadedException, 181 IncompatibleThreadStateException, 182 InvocationException { 183 vm.throwNotReadOnlyException("ClassType.invokeMethod(...)"); 184 return null; 185 } 186 187 public ObjectReference newInstance(ThreadReference threadIntf, 188 Method methodIntf, 189 List arguments, int options) 190 throws InvalidTypeException, 191 ClassNotLoadedException, 192 IncompatibleThreadStateException, 193 InvocationException { 194 vm.throwNotReadOnlyException("ClassType.newInstance(...)"); 195 return null; 196 } 197 198 void addVisibleMethods(Map methodMap) { 199 /* 200 * Add methods from 201 * parent types first, so that the methods in this class will 202 * overwrite them in the hash table 203 */ 204 205 Iterator iter = interfaces().iterator(); 206 while (iter.hasNext()) { 207 InterfaceTypeImpl interfaze = (InterfaceTypeImpl)iter.next(); 208 interfaze.addVisibleMethods(methodMap); 209 } 210 211 ClassTypeImpl clazz = (ClassTypeImpl)superclass(); 212 if (clazz != null) { 213 clazz.addVisibleMethods(methodMap); 214 } 215 216 addToMethodMap(methodMap, methods()); 217 } 218 219 boolean isAssignableTo(ReferenceType type) { 220 ClassTypeImpl superclazz = (ClassTypeImpl)superclass(); 221 if (this.equals(type)) { 222 return true; 223 } else if ((superclazz != null) && superclazz.isAssignableTo(type)) { 224 return true; 225 } else { 226 List interfaces = interfaces(); 227 Iterator iter = interfaces.iterator(); 228 while (iter.hasNext()) { 229 InterfaceTypeImpl interfaze = (InterfaceTypeImpl)iter.next(); 230 if (interfaze.isAssignableTo(type)) { 231 return true; 232 } 233 } 234 return false; 235 } 236 } 237 238 public String toString() { 239 return "class " + name() + "(" + loaderString() + ")"; 240 } 241 }