View Javadoc
1   /*
2    * Copyright (c) 1998, 2011, 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.  Oracle designates this
8    * particular file as subject to the "Classpath" exception as provided
9    * by Oracle in the LICENSE file that accompanied this code.
10   *
11   * This code is distributed in the hope that it will be useful, but WITHOUT
12   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14   * version 2 for more details (a copy is included in the LICENSE file that
15   * accompanied this code).
16   *
17   * You should have received a copy of the GNU General Public License version
18   * 2 along with this work; if not, write to the Free Software Foundation,
19   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20   *
21   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22   * or visit www.oracle.com if you need additional information or have any
23   * questions.
24   */
25  
26  package com.sun.tools.jdi;
27  
28  import com.sun.jdi.*;
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  
40      private SoftReference<List<InterfaceType>> superinterfacesRef = null;
41  
42      protected InterfaceTypeImpl(VirtualMachine aVm,long aRef) {
43          super(aVm, aRef);
44      }
45  
46      public List<InterfaceType> superinterfaces() {
47          List<InterfaceType> superinterfaces = (superinterfacesRef == null) ? null :
48                                       superinterfacesRef.get();
49          if (superinterfaces == null) {
50              superinterfaces = getInterfaces();
51              superinterfaces = Collections.unmodifiableList(superinterfaces);
52              superinterfacesRef = new SoftReference<List<InterfaceType>>(superinterfaces);
53          }
54          return superinterfaces;
55      }
56  
57      public List<InterfaceType> subinterfaces() {
58          List<InterfaceType> subs = new ArrayList<InterfaceType>();
59          for (ReferenceType refType : vm.allClasses()) {
60              if (refType instanceof InterfaceType) {
61                  InterfaceType interfaze = (InterfaceType)refType;
62                  if (interfaze.isPrepared() && interfaze.superinterfaces().contains(this)) {
63                      subs.add(interfaze);
64                  }
65              }
66          }
67          return subs;
68      }
69  
70      public List<ClassType> implementors() {
71          List<ClassType> implementors = new ArrayList<ClassType>();
72          for (ReferenceType refType : vm.allClasses()) {
73              if (refType instanceof ClassType) {
74                  ClassType clazz = (ClassType)refType;
75                  if (clazz.isPrepared() && clazz.interfaces().contains(this)) {
76                      implementors.add(clazz);
77                  }
78              }
79          }
80          return implementors;
81      }
82  
83      void addVisibleMethods(Map<String, Method> methodMap) {
84          /*
85           * Add methods from
86           * parent types first, so that the methods in this class will
87           * overwrite them in the hash table
88           */
89  
90          for (InterfaceType interfaze : superinterfaces()) {
91              ((InterfaceTypeImpl)interfaze).addVisibleMethods(methodMap);
92          }
93  
94          addToMethodMap(methodMap, methods());
95      }
96  
97      public List<Method> allMethods() {
98          ArrayList<Method> list = new ArrayList<Method>(methods());
99  
100         /*
101          * It's more efficient if don't do this
102          * recursively.
103          */
104         for (InterfaceType interfaze : allSuperinterfaces()) {
105             list.addAll(interfaze.methods());
106         }
107 
108         return list;
109     }
110 
111     List<InterfaceType> allSuperinterfaces() {
112         ArrayList<InterfaceType> list = new ArrayList<InterfaceType>();
113         addSuperinterfaces(list);
114         return list;
115     }
116 
117     void addSuperinterfaces(List<InterfaceType> list) {
118         /*
119          * This code is a little strange because it
120          * builds the list with a more suitable order than the
121          * depth-first approach a normal recursive solution would
122          * take. Instead, all direct superinterfaces precede all
123          * indirect ones.
124          */
125 
126         /*
127          * Get a list of direct superinterfaces that's not already in the
128          * list being built.
129          */
130         List<InterfaceType> immediate = new ArrayList<InterfaceType>(superinterfaces());
131         Iterator<InterfaceType> iter = immediate.iterator();
132         while (iter.hasNext()) {
133             InterfaceType interfaze = iter.next();
134             if (list.contains(interfaze)) {
135                 iter.remove();
136             }
137         }
138 
139         /*
140          * Add all new direct superinterfaces
141          */
142         list.addAll(immediate);
143 
144         /*
145          * Recurse for all new direct superinterfaces.
146          */
147         iter = immediate.iterator();
148         while (iter.hasNext()) {
149             InterfaceTypeImpl interfaze = (InterfaceTypeImpl)iter.next();
150             interfaze.addSuperinterfaces(list);
151         }
152     }
153 
154     boolean isAssignableTo(ReferenceType type) {
155 
156         // Exact match?
157         if (this.equals(type)) {
158             return true;
159         } else {
160             // Try superinterfaces.
161             for (InterfaceType interfaze : superinterfaces()) {
162                 if (((InterfaceTypeImpl)interfaze).isAssignableTo(type)) {
163                     return true;
164                 }
165             }
166 
167             return false;
168         }
169     }
170 
171     List<InterfaceType> inheritedTypes() {
172         return superinterfaces();
173     }
174 
175     public boolean isInitialized() {
176         return isPrepared();
177     }
178 
179     public String toString() {
180        return "interface " + name() + " (" + loaderString() + ")";
181     }
182 }