View Javadoc
1   /*
2    * Copyright (c) 2002, 2004, 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.InstanceKlass;
29  
30  import java.util.List;
31  import java.util.ArrayList;
32  import java.util.Map;
33  import java.util.Iterator;
34  import java.util.Collections;
35  import java.lang.ref.SoftReference;
36  
37  public class InterfaceTypeImpl extends ReferenceTypeImpl
38                                 implements InterfaceType {
39      private SoftReference superInterfacesCache = null;
40      private SoftReference subInterfacesCache = null;
41      private SoftReference implementorsCache = null;
42  
43      protected InterfaceTypeImpl(VirtualMachine aVm, InstanceKlass aRef) {
44          super(aVm, aRef);
45      }
46  
47      public List superinterfaces() throws ClassNotPreparedException {
48          List superinterfaces = (superInterfacesCache != null)? (List) superInterfacesCache.get() : null;
49          if (superinterfaces == null) {
50              checkPrepared();
51              superinterfaces = Collections.unmodifiableList(getInterfaces());
52              superInterfacesCache = new SoftReference(superinterfaces);
53          }
54          return superinterfaces;
55      }
56  
57      public List subinterfaces() {
58          List subinterfaces = (subInterfacesCache != null)? (List) subInterfacesCache.get() : null;
59          if (subinterfaces == null) {
60              List all = vm.allClasses();
61              subinterfaces = new ArrayList();
62              Iterator iter = all.iterator();
63              while (iter.hasNext()) {
64                  ReferenceType refType = (ReferenceType)iter.next();
65                  if (refType instanceof InterfaceType) {
66                      InterfaceType interfaze = (InterfaceType)refType;
67                      if (interfaze.isPrepared() && interfaze.superinterfaces().contains(this)) {
68                          subinterfaces.add(interfaze);
69                      }
70                 }
71              }
72              subinterfaces = Collections.unmodifiableList(subinterfaces);
73              subInterfacesCache = new SoftReference(subinterfaces);
74          }
75          return subinterfaces;
76      }
77  
78      public List implementors() {
79          List implementors = (implementorsCache != null)? (List) implementorsCache.get() : null;
80          if (implementors == null) {
81              List all = vm.allClasses();
82              implementors = new ArrayList();
83              Iterator iter = all.iterator();
84              while (iter.hasNext()) {
85                  ReferenceType refType = (ReferenceType)iter.next();
86                  if (refType instanceof ClassType) {
87                      ClassType clazz = (ClassType)refType;
88                      if (clazz.isPrepared() && clazz.interfaces().contains(this)) {
89                          implementors.add(clazz);
90                      }
91                  }
92              }
93              implementors = Collections.unmodifiableList(implementors);
94              implementorsCache = new SoftReference(implementors);
95          }
96          return implementors;
97      }
98  
99      void addVisibleMethods(Map methodMap) {
100         /*
101          * Add methods from
102          * parent types first, so that the methods in this class will
103          * overwrite them in the hash table
104          */
105         Iterator iter = superinterfaces().iterator();
106         while (iter.hasNext()) {
107             InterfaceTypeImpl interfaze = (InterfaceTypeImpl)iter.next();
108             interfaze.addVisibleMethods(methodMap);
109         }
110 
111         addToMethodMap(methodMap, methods());
112     }
113 
114     List getAllMethods() {
115         ArrayList list = new ArrayList(methods());
116         /*
117          * It's more efficient if don't do this
118          * recursively.
119          */
120         List interfaces = allSuperinterfaces();
121         Iterator iter = interfaces.iterator();
122         while (iter.hasNext()) {
123             InterfaceType interfaze = (InterfaceType)iter.next();
124             list.addAll(interfaze.methods());
125         }
126 
127         return list;
128     }
129 
130     List allSuperinterfaces() {
131         ArrayList list = new ArrayList();
132         addSuperinterfaces(list);
133         return list;
134     }
135 
136     void addSuperinterfaces(List list) {
137         /*
138          * This code is a little strange because it
139          * builds the list with a more suitable order than the
140          * depth-first approach a normal recursive solution would
141          * take. Instead, all direct superinterfaces precede all
142          * indirect ones.
143          */
144 
145         /*
146          * Get a list of direct superinterfaces that's not already in the
147          * list being built.
148          */
149         List immediate = new ArrayList(superinterfaces());
150         Iterator iter = immediate.iterator();
151         while (iter.hasNext()) {
152             InterfaceType interfaze = (InterfaceType)iter.next();
153             if (list.contains(interfaze)) {
154                 iter.remove();
155             }
156         }
157 
158         /*
159          * Add all new direct superinterfaces
160          */
161         list.addAll(immediate);
162 
163         /*
164          * Recurse for all new direct superinterfaces.
165          */
166         iter = immediate.iterator();
167         while (iter.hasNext()) {
168             InterfaceTypeImpl interfaze = (InterfaceTypeImpl)iter.next();
169             interfaze.addSuperinterfaces(list);
170         }
171     }
172 
173     boolean isAssignableTo(ReferenceType type) {
174 
175         // Exact match?
176         if (this.equals(type)) {
177             return true;
178         } else {
179             // Try superinterfaces.
180             List supers = superinterfaces();
181             Iterator iter = supers.iterator();
182             while (iter.hasNext()) {
183                 InterfaceTypeImpl interfaze = (InterfaceTypeImpl)iter.next();
184                 if (interfaze.isAssignableTo(type)) {
185                     return true;
186                 }
187             }
188 
189             return false;
190         }
191     }
192 
193     List inheritedTypes() {
194         return superinterfaces();
195     }
196 
197     public boolean isInitialized() {
198         return isPrepared();
199     }
200 
201     public String toString() {
202        return "interface " + name() + " (" + loaderString() + ")";
203     }
204 }