1 4 package gnu.mapping; 5 6 public class InheritingEnvironment extends SimpleEnvironment 7 { 8 int numInherited; 9 Environment[] inherited; 10 Namespace[] namespaceMap; 11 Object [] propertyMap; 12 int baseTimestamp; 13 14 public InheritingEnvironment (String name, Environment parent) 15 { 16 super(name); 17 addParent(parent); 18 if (parent instanceof SimpleEnvironment) 19 { 20 int timestamp = ++((SimpleEnvironment) parent).currentTimestamp; 21 baseTimestamp = timestamp; 22 currentTimestamp = timestamp; 23 } 24 } 25 26 public final int getNumParents () { return numInherited; } 27 public final Environment getParent (int index) { return inherited[index]; } 28 29 public void addParent (Environment env) 30 { 31 if (numInherited == 0) 32 inherited = new Environment[4]; 33 else if (numInherited <= inherited.length) 34 { 35 Environment[] newInherited 36 = new Environment[2 * numInherited]; 37 System.arraycopy(inherited, 0, newInherited, 0, numInherited); 38 inherited = newInherited; 39 } 40 inherited[numInherited] = env; 41 numInherited++; 42 } 43 44 public NamedLocation lookupInherited (Symbol name, Object property, int hash) 45 { 46 for (int i = 0; i < numInherited; i++) 47 { 48 Symbol sym = name; 49 Object prop = property; 50 if (namespaceMap != null && namespaceMap.length > 2*i) 51 { 52 Object srcNamespace = namespaceMap[2*i]; 53 Object dstNamespace = namespaceMap[2*i+1]; 54 if (srcNamespace != null || dstNamespace != null) 55 { 56 if (name.getNamespace() != dstNamespace) 57 continue; 58 sym = Symbol.make(srcNamespace, name.getName()); 59 } 60 } 61 if (propertyMap != null && propertyMap.length > 2*i) 62 { 63 Object srcProperty = propertyMap[2*i]; 64 Object dstProperty = propertyMap[2*i+1]; 65 if (srcProperty != null || dstProperty != null) 66 { 67 if (property != dstProperty) 68 continue; 69 prop = srcProperty; 70 } 71 } 72 NamedLocation loc = inherited[i].lookup(sym, prop, hash); 73 if (loc != null && loc.isBound()) 74 { 75 if (! (loc instanceof SharedLocation) 76 || ((SharedLocation) loc).timestamp < baseTimestamp) 77 return loc; 78 } 79 } 80 return null; 81 } 82 83 public NamedLocation lookup (Symbol name, Object property, int hash) 84 { 85 NamedLocation loc = super.lookup(name, property, hash); 86 if (loc != null && loc.isBound()) 87 return loc; 88 return lookupInherited(name, property, hash); 89 } 90 91 public synchronized NamedLocation 92 getLocation (Symbol name, Object property, int hash, boolean create) 93 { 94 NamedLocation loc = lookupDirect(name, property, hash); 95 if (loc != null && (create || loc.isBound())) 96 return loc; 97 if ((flags & INDIRECT_DEFINES) != 0 && create) 98 loc = inherited[0].getLocation(name, property, hash, true); 99 else 100 loc = lookupInherited(name, property, hash); 101 102 if (loc != null) 103 { 104 if (create ) 105 { 106 NamedLocation xloc = addUnboundLocation(name, property, hash); 107 if ((flags & CAN_DEFINE) == 0 && loc.isBound()) 108 redefineError(name, property, xloc); 109 xloc.base = loc; 110 if (loc.value == IndirectableLocation.INDIRECT_FLUIDS) 111 xloc.value = loc.value; 112 else if ((flags & DIRECT_INHERITED_ON_SET) != 0) 113 xloc.value = IndirectableLocation.DIRECT_ON_SET; 114 else 115 xloc.value = null; 116 if (xloc instanceof SharedLocation) 117 ((SharedLocation) xloc).timestamp = baseTimestamp; 118 return xloc; 119 } 120 else 121 return loc; 122 } 123 return create ? addUnboundLocation(name, property, hash) : null; 124 } 125 126 public LocationEnumeration enumerateAllLocations() 127 { 128 LocationEnumeration it = new LocationEnumeration(table, 1 << log2Size); 129 it.env = this; 130 if (inherited != null && inherited.length > 0) 131 { 132 it.inherited = inherited[0].enumerateAllLocations(); 133 it.index = 0; 134 } 135 return it; 136 } 137 138 protected boolean hasMoreElements (LocationEnumeration it) 139 { 140 if (it.inherited != null) 141 { 142 for (;;) 143 { 144 NamedLocation loc = it.curLoc; 145 for (;;) 146 { 147 it.inherited.curLoc = loc; 148 if (! it.inherited.hasMoreElements()) 149 { 150 it.curLoc = it.inherited.curLoc; 151 break; 152 } 153 loc = it.inherited.curLoc; 154 if (lookup(loc.name, loc.property) == loc) 155 { 156 it.curLoc = loc; 157 return true; 158 } 159 loc = loc.next; 160 } 161 if (++it.index == numInherited) 162 break; 163 it.inherited = inherited[it.index].enumerateAllLocations(); 164 } 165 it.inherited = null; 166 it.bindings = table; 167 it.index = 1 << log2Size; 168 } 169 return super.hasMoreElements(it); 170 } 171 172 protected void toStringBase (StringBuffer sbuf) 173 { 174 sbuf.append(" baseTs:"); 175 sbuf.append(baseTimestamp); 176 for (int i = 0; i < numInherited; i++) 177 { 178 sbuf.append(" base:"); 179 sbuf.append(inherited[i].toStringVerbose()); 180 } 181 } 182 } 183 | Popular Tags |