001 package org.mesopotamia.lang.java.ref; 002 003 import java.lang.ref.SoftReference; 004 import java.util.ArrayList; 005 import java.util.List; 006 import java.util.Map; 007 import java.util.concurrent.ConcurrentHashMap; 008 009 /** 010 * Scope which caches resolved types, variables and methods 011 * using soft references. 012 * @author Pavel 013 */ 014 public abstract class SoftCachingScope implements Scope { 015 016 private static final MethodInfo NO_METHOD_INFO = new MethodInfo() { 017 018 public List<TypeInfo> getExceptionTypes() { 019 throw new UnsupportedOperationException(); 020 } 021 022 public List<TypeSpecInfo> getParameterTypes() { 023 throw new UnsupportedOperationException(); 024 } 025 026 public TypeSpecInfo getReturnType() { 027 throw new UnsupportedOperationException(); 028 } 029 030 public TypeInfo getDeclaringType() { 031 throw new UnsupportedOperationException(); 032 } 033 034 public String getFcn() { 035 throw new UnsupportedOperationException(); 036 } 037 038 public List<String> getModifiers() { 039 throw new UnsupportedOperationException(); 040 } 041 042 public String getName() { 043 throw new UnsupportedOperationException(); 044 } 045 046 }; 047 048 private Map<List<String>, SoftReference<MethodInfo>> methodInfoCache = new ConcurrentHashMap<List<String>, SoftReference<MethodInfo>>(); 049 050 public MethodInfo findMethod(String name, String[] parameterTypes) { 051 List<String> key = new ArrayList<String>(); 052 key.add(name); 053 if (parameterTypes!=null) { 054 for (String pt: parameterTypes) { 055 key.add(pt); 056 } 057 } 058 059 SoftReference<MethodInfo> ref = methodInfoCache.get(key); 060 MethodInfo ret = ref==null ? null : ref.get(); 061 if (ret == null) { 062 ret = findMethodInternal(name, parameterTypes); 063 if (ret == null) { 064 ret = NO_METHOD_INFO; 065 } 066 methodInfoCache.put(key, new SoftReference<MethodInfo>(ret)); 067 } 068 return ret==NO_METHOD_INFO ? null : ret; 069 } 070 071 protected abstract MethodInfo findMethodInternal(String name, String[] parameterTypes); 072 073 private static final TypeInfo NO_TYPE_INFO = new TypeInfo() { 074 075 public MethodInfo findConstructor(String[] argumentTypes) { 076 throw new UnsupportedOperationException(); 077 } 078 079 public TypeInfo findNestedType(String name) { 080 throw new UnsupportedOperationException(); 081 } 082 083 public MethodInfo findTypeMethod(String name, String[] argumentTypes) { 084 throw new UnsupportedOperationException(); 085 } 086 087 public VariableInfo findTypeVariable(String name) { 088 throw new UnsupportedOperationException(); 089 } 090 091 public boolean isKindOf(String superFcn) { 092 throw new UnsupportedOperationException(); 093 } 094 095 public TypeInfo getDeclaringType() { 096 throw new UnsupportedOperationException(); 097 } 098 099 public String getFcn() { 100 throw new UnsupportedOperationException(); 101 } 102 103 public List<String> getModifiers() { 104 throw new UnsupportedOperationException(); 105 } 106 107 public String getName() { 108 throw new UnsupportedOperationException(); 109 } 110 111 }; 112 113 private Map<String, SoftReference<TypeInfo>> typeInfoCache = new ConcurrentHashMap<String, SoftReference<TypeInfo>>(); 114 115 public TypeInfo findType(String name) { 116 SoftReference<TypeInfo> ref = typeInfoCache.get(name); 117 TypeInfo ret = ref==null ? null : ref.get(); 118 if (ret == null) { 119 ret = findTypeInternal(name); 120 if (ret == null) { 121 ret = NO_TYPE_INFO; 122 } 123 typeInfoCache.put(name, new SoftReference<TypeInfo>(ret)); 124 } 125 return ret==NO_TYPE_INFO ? null : ret; 126 } 127 128 protected abstract TypeInfo findTypeInternal(String name); 129 130 private static final VariableInfo NO_VARIABLE_INFO = new VariableInfo() { 131 132 public TypeSpecInfo getTypeSpecification() { 133 throw new UnsupportedOperationException(); 134 } 135 136 public TypeInfo getDeclaringType() { 137 throw new UnsupportedOperationException(); 138 } 139 140 public String getFcn() { 141 throw new UnsupportedOperationException(); 142 } 143 144 public List<String> getModifiers() { 145 throw new UnsupportedOperationException(); 146 } 147 148 public String getName() { 149 throw new UnsupportedOperationException(); 150 } 151 152 }; 153 154 private Map<String, SoftReference<VariableInfo>> variableInfoCache = new ConcurrentHashMap<String, SoftReference<VariableInfo>>(); 155 156 public VariableInfo findVariable(String name) { 157 SoftReference<VariableInfo> ref = variableInfoCache.get(name); 158 VariableInfo ret = ref==null ? null : ref.get(); 159 if (ret == null) { 160 ret = findVariableInternal(name); 161 if (ret == null) { 162 ret = NO_VARIABLE_INFO; 163 } 164 variableInfoCache.put(name, new SoftReference<VariableInfo>(ret)); 165 } 166 return ret==NO_VARIABLE_INFO ? null : ret; 167 } 168 169 protected abstract VariableInfo findVariableInternal(String name); 170 171 }