001 package org.mesopotamia.lang.java.ref; 002 003 import java.lang.ref.SoftReference; 004 import java.util.ArrayList; 005 import java.util.HashMap; 006 import java.util.List; 007 import java.util.Map; 008 import java.util.concurrent.ConcurrentHashMap; 009 010 /** 011 * Type info which caches resolved types, methods, and variables 012 * in soft references and other values in hard references. 013 * @author Pavel 014 * 015 */ 016 public abstract class SoftCachingTypeInfo implements TypeInfo { 017 018 private static final MethodInfo NO_METHOD_INFO = new MethodInfo() { 019 020 public List<TypeInfo> getExceptionTypes() { 021 throw new UnsupportedOperationException(); 022 } 023 024 public List<TypeSpecInfo> getParameterTypes() { 025 throw new UnsupportedOperationException(); 026 } 027 028 public TypeSpecInfo getReturnType() { 029 throw new UnsupportedOperationException(); 030 } 031 032 public TypeInfo getDeclaringType() { 033 throw new UnsupportedOperationException(); 034 } 035 036 public String getFcn() { 037 throw new UnsupportedOperationException(); 038 } 039 040 public List<String> getModifiers() { 041 throw new UnsupportedOperationException(); 042 } 043 044 public String getName() { 045 throw new UnsupportedOperationException(); 046 } 047 048 }; 049 050 private Map<List<String>, SoftReference<MethodInfo>> methodInfoCache = new ConcurrentHashMap<List<String>, SoftReference<MethodInfo>>(); 051 052 public MethodInfo findTypeMethod(String name, String[] parameterTypes) { 053 List<String> key = new ArrayList<String>(); 054 key.add(name); 055 if (parameterTypes!=null) { 056 for (String pt: parameterTypes) { 057 key.add(pt); 058 } 059 } 060 061 SoftReference<MethodInfo> ref = methodInfoCache.get(key); 062 MethodInfo ret = ref==null ? null : ref.get(); 063 if (ret == null) { 064 ret = findMethodInternal(name, parameterTypes); 065 if (ret == null) { 066 ret = NO_METHOD_INFO; 067 } 068 methodInfoCache.put(key, new SoftReference<MethodInfo>(ret)); 069 } 070 return ret==NO_METHOD_INFO ? null : ret; 071 } 072 073 private Map<List<String>, SoftReference<MethodInfo>> constructorInfoCache = new ConcurrentHashMap<List<String>, SoftReference<MethodInfo>>(); 074 075 public MethodInfo findConstructor(String[] parameterTypes) { 076 List<String> key = new ArrayList<String>(); 077 if (parameterTypes!=null) { 078 for (String pt: parameterTypes) { 079 key.add(pt); 080 } 081 } 082 083 SoftReference<MethodInfo> ref = constructorInfoCache.get(key); 084 MethodInfo ret = ref==null ? null : ref.get(); 085 if (ret == null) { 086 ret = findConstructorInternal(parameterTypes); 087 if (ret == null) { 088 ret = NO_METHOD_INFO; 089 } 090 constructorInfoCache.put(key, new SoftReference<MethodInfo>(ret)); 091 } 092 return ret==NO_METHOD_INFO ? null : ret; 093 } 094 095 protected abstract MethodInfo findConstructorInternal(String[] parameterTypes); 096 protected abstract MethodInfo findMethodInternal(String name, String[] parameterTypes); 097 098 private static final TypeInfo NO_TYPE_INFO = new TypeInfo() { 099 100 public MethodInfo findConstructor(String[] argumentTypes) { 101 throw new UnsupportedOperationException(); 102 } 103 104 public TypeInfo findNestedType(String name) { 105 throw new UnsupportedOperationException(); 106 } 107 108 public MethodInfo findTypeMethod(String name, String[] argumentTypes) { 109 throw new UnsupportedOperationException(); 110 } 111 112 public VariableInfo findTypeVariable(String name) { 113 throw new UnsupportedOperationException(); 114 } 115 116 public boolean isKindOf(String superFcn) { 117 throw new UnsupportedOperationException(); 118 } 119 120 public TypeInfo getDeclaringType() { 121 throw new UnsupportedOperationException(); 122 } 123 124 public String getFcn() { 125 throw new UnsupportedOperationException(); 126 } 127 128 public List<String> getModifiers() { 129 throw new UnsupportedOperationException(); 130 } 131 132 public String getName() { 133 throw new UnsupportedOperationException(); 134 } 135 136 }; 137 138 private Map<String, SoftReference<TypeInfo>> typeInfoCache = new ConcurrentHashMap<String, SoftReference<TypeInfo>>(); 139 140 public TypeInfo findNestedType(String name) { 141 SoftReference<TypeInfo> ref = typeInfoCache.get(name); 142 TypeInfo ret = ref==null ? null : ref.get(); 143 if (ret == null) { 144 ret = findNestedTypeInternal(name); 145 if (ret == null) { 146 ret = NO_TYPE_INFO; 147 } 148 typeInfoCache.put(name, new SoftReference<TypeInfo>(ret)); 149 } 150 return ret==NO_TYPE_INFO ? null : ret; 151 } 152 153 protected abstract TypeInfo findNestedTypeInternal(String name); 154 155 private static final VariableInfo NO_VARIABLE_INFO = new VariableInfo() { 156 157 public TypeSpecInfo getTypeSpecification() { 158 throw new UnsupportedOperationException(); 159 } 160 161 public TypeInfo getDeclaringType() { 162 throw new UnsupportedOperationException(); 163 } 164 165 public String getFcn() { 166 throw new UnsupportedOperationException(); 167 } 168 169 public List<String> getModifiers() { 170 throw new UnsupportedOperationException(); 171 } 172 173 public String getName() { 174 throw new UnsupportedOperationException(); 175 } 176 177 }; 178 179 private Map<String, SoftReference<VariableInfo>> variableInfoCache = new ConcurrentHashMap<String, SoftReference<VariableInfo>>(); 180 181 public VariableInfo findTypeVariable(String name) { 182 SoftReference<VariableInfo> ref = variableInfoCache.get(name); 183 VariableInfo ret = ref==null ? null : ref.get(); 184 if (ret == null) { 185 ret = findTypeVariableInternal(name); 186 if (ret == null) { 187 ret = NO_VARIABLE_INFO; 188 } 189 variableInfoCache.put(name, new SoftReference<VariableInfo>(ret)); 190 } 191 return ret==NO_VARIABLE_INFO ? null : ret; 192 } 193 194 protected abstract VariableInfo findTypeVariableInternal(String name); 195 196 private Map<String, Boolean> isKindOfMap = new HashMap<String, Boolean>(); 197 198 public boolean isKindOf(String superFcn) { 199 Boolean ret = isKindOfMap.get(superFcn); 200 if (ret==null) { 201 ret = isKindOfInternal(superFcn) ? Boolean.TRUE : Boolean.FALSE; 202 isKindOfMap.put(superFcn, ret); 203 } 204 return ret.booleanValue(); 205 } 206 207 protected abstract boolean isKindOfInternal(String superFcn); 208 209 private TypeInfo declaringType; 210 private boolean isDeclaringTypeRetrieved; 211 protected abstract TypeInfo getDeclaringTypeInternal(); 212 213 public TypeInfo getDeclaringType() { 214 if (!isDeclaringTypeRetrieved) { 215 declaringType = getDeclaringTypeInternal(); 216 isDeclaringTypeRetrieved = true; 217 } 218 return declaringType; 219 } 220 221 private String fcn; 222 private boolean isFcnRetrieved; 223 protected abstract String getFcnInternal(); 224 225 public String getFcn() { 226 if (!isFcnRetrieved) { 227 fcn = getFcnInternal(); 228 isFcnRetrieved = true; 229 } 230 return fcn; 231 } 232 233 private List<String> modifiers; 234 private boolean areModifiersRetrieved; 235 protected abstract List<String> getModifiersInternal(); 236 237 public List<String> getModifiers() { 238 if (!areModifiersRetrieved) { 239 modifiers = getModifiersInternal(); 240 areModifiersRetrieved = true; 241 } 242 return modifiers; 243 } 244 245 }