001: // Copyright (c) 2004 Per M.A. Bothner.
002: // This is free software; for terms and warranty disclaimer see ./COPYING.
003:
004: package gnu.mapping;
005:
006: /** A Location that can be used as an entry in an Environment. */
007:
008: public abstract class NamedLocation extends IndirectableLocation
009: implements
010: /* #ifdef JAVA2 */
011: java.util.Map.Entry /* <EnvironmentKey, Object> */,
012: /* #endif */
013: EnvironmentKey {
014: NamedLocation next;
015:
016: public boolean entered() {
017: return next != null;
018: }
019:
020: public Environment getEnvironment() {
021: for (NamedLocation loc = this ; loc != null; loc = loc.next) {
022: if (loc.name == null) {
023: Environment env = (Environment) loc.value;
024: if (env != null)
025: return env;
026: }
027: }
028: return super .getEnvironment();
029: }
030:
031: final Symbol name;
032: final Object property;
033:
034: public NamedLocation(NamedLocation loc) {
035: name = loc.name;
036: property = loc.property;
037: }
038:
039: public NamedLocation(Symbol name, Object property) {
040: this .name = name;
041: this .property = property;
042: }
043:
044: public final Symbol getKeySymbol() {
045: return name;
046: }
047:
048: public final Object getKeyProperty() {
049: return property;
050: }
051:
052: public final boolean matches(EnvironmentKey key) {
053: return Symbol.equals(key.getKeySymbol(), this .name)
054: && key.getKeyProperty() == this .property;
055: }
056:
057: public final boolean matches(Symbol symbol, Object property) {
058: return Symbol.equals(symbol, this .name)
059: && property == this .property;
060: }
061:
062: public final Object /*<EnvironmentKey>*/getKey() {
063: if (property == null)
064: return name;
065: else
066: return this ;
067: }
068:
069: public boolean equals(Object x) {
070: if (!(x instanceof NamedLocation))
071: return false;
072: NamedLocation e2 = (NamedLocation) x;
073: if (name == null ? e2.name != null : !name.equals(e2.name))
074: return false;
075: if (property != e2.property)
076: return false;
077: Object val1 = getValue();
078: Object val2 = e2.getValue();
079: if (val1 == val2)
080: return true;
081: if (val1 == null || val2 == null)
082: return false;
083: return val1.equals(val2);
084: }
085:
086: public int hashCode() {
087: int h = name.hashCode() ^ System.identityHashCode(property);
088: Object val = getValue();
089: if (val != null)
090: h ^= val.hashCode();
091: return h;
092: }
093:
094: public synchronized Object setWithSave(Object newValue,
095: CallContext ctx) {
096: Object old;
097: if (base != null) {
098: if (value == INDIRECT_FLUIDS)
099: return base.setWithSave(newValue, ctx);
100: old = base;
101: base = null;
102: } else {
103: old = value;
104: }
105: value = newValue;
106: ctx.pushFluid(this );
107: return old;
108: }
109:
110: public synchronized void setRestore(Object oldValue, CallContext ctx) {
111: if (value == INDIRECT_FLUIDS)
112: base.setRestore(oldValue, ctx);
113: else {
114: if (oldValue instanceof Location) {
115: value = null;
116: base = (Location) oldValue;
117: } else {
118: value = oldValue;
119: base = null;
120: }
121: ctx.popFluid();
122: }
123: }
124: }
|