PageRenderTime 19ms CodeModel.GetById 1ms app.highlight 13ms RepoModel.GetById 1ms app.codeStats 1ms

/interpreter/tags/at2dist130208/src/edu/vub/at/objects/mirrors/NATMirrorRoot.java

http://ambienttalk.googlecode.com/
Java | 317 lines | 147 code | 48 blank | 122 comment | 5 complexity | aa1b6b171473a037968db1e141c9e746 MD5 | raw file
  1/**
  2 * AmbientTalk/2 Project
  3 * OBJMirrorRoot.java created on Oct 3, 2006 at 3:26:08 PM
  4 * (c) Programming Technology Lab, 2006 - 2007
  5 * Authors: Tom Van Cutsem & Stijn Mostinckx
  6 * 
  7 * Permission is hereby granted, free of charge, to any person
  8 * obtaining a copy of this software and associated documentation
  9 * files (the "Software"), to deal in the Software without
 10 * restriction, including without limitation the rights to use,
 11 * copy, modify, merge, publish, distribute, sublicense, and/or
 12 * sell copies of the Software, and to permit persons to whom the
 13 * Software is furnished to do so, subject to the following
 14 * conditions:
 15 *
 16 * The above copyright notice and this permission notice shall be
 17 * included in all copies or substantial portions of the Software.
 18 *
 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 20 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 21 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 22 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 23 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 24 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 25 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 26 * OTHER DEALINGS IN THE SOFTWARE.
 27 */
 28package edu.vub.at.objects.mirrors;
 29
 30import edu.vub.at.actors.ATAsyncMessage;
 31import edu.vub.at.exceptions.InterpreterException;
 32import edu.vub.at.exceptions.XArityMismatch;
 33import edu.vub.at.exceptions.XIllegalArgument;
 34import edu.vub.at.objects.ATBoolean;
 35import edu.vub.at.objects.ATContext;
 36import edu.vub.at.objects.ATField;
 37import edu.vub.at.objects.ATMethod;
 38import edu.vub.at.objects.ATNil;
 39import edu.vub.at.objects.ATObject;
 40import edu.vub.at.objects.ATTable;
 41import edu.vub.at.objects.ATTypeTag;
 42import edu.vub.at.objects.coercion.NativeTypeTags;
 43import edu.vub.at.objects.grammar.ATSymbol;
 44import edu.vub.at.objects.natives.NATByCopy;
 45import edu.vub.at.objects.natives.NATTable;
 46import edu.vub.at.objects.natives.NATText;
 47import edu.vub.at.objects.natives.OBJNil;
 48import edu.vub.at.objects.natives.grammar.AGSymbol;
 49import edu.vub.at.util.logging.Logging;
 50
 51import java.io.IOException;
 52
 53/**
 54 * This class denotes the root node of the intercessive mirrors delegation hierarchy.
 55 * 
 56 * Intercessive mirrors are always tied to a particular 'base' object.
 57 * The default intercessive mirror is named 'mirrorroot' and is an object
 58 * that understands all meta_* operations, implementing them using default semantics.
 59 * It can be thought of as being defined as follows:
 60 * 
 61 * def mirrorroot := object: {
 62 *   def base := object: { nil } mirroredBy: self // base of the mirror root is an empty mirage
 63 *   def init(b) {
 64 *     base := b
 65 *   }
 66 *   def invoke(@args) { <default native invocation behaviour on base> }
 67 *   def select(@args) { <default native selection behaviour on base> }
 68 *   ...
 69 * } taggedAs: [ Mirror ]
 70 * 
 71 * This object can then simply be extended / composed by other objects to deviate from the default semantics.
 72 * Note that the default semantics is applied to 'base' and *not* 'self.base', in other words:
 73 * although child mirrors can define their own 'base' field, it is not taken into consideration
 74 * by the mirror root. This also ensures that the mirror root is not abused to enact upon a mirage
 75 * for which it was not assigned to be the mirror.
 76 * 
 77 * Hence, 'mirrors' are simply objects with the same interface as this mirrorroot object: they should be
 78 * able to respond to all meta_* messages and have a 'base' field.
 79 * 
 80 * @author tvcutsem, smostinc
 81 */
 82public final class NATMirrorRoot extends NATByCopy implements ATObject {
 83	
 84	// The name of the field that points to the base_level representation of a custom mirror
 85	public static final AGSymbol _BASE_NAME_ = AGSymbol.jAlloc("base");
 86	
 87	// the native read-only 'base' field of the mirror root
 88	private NATMirage base_;
 89	
 90	private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
 91		try {
 92			in.defaultReadObject();
 93		} catch(IOException e) {
 94			Logging.Actor_LOG.fatal("Failed to reconstruct an OBJMirrorRoot", e);
 95			throw e;
 96		}
 97	}
 98	
 99	/**
100	 * Constructor used to initialize the initial mirror root prototype.
101	 */
102	public NATMirrorRoot() {
103		base_ = new NATMirage(this);
104	};
105
106	/**
107	 * Constructor used for cloning: creates a shallow copy of the mirror root.
108	 * @param base the base field value of the original mirror root from which
109	 * this new one will be cloned.
110	 */
111	private NATMirrorRoot(NATMirage base) {
112		base_ = base;
113	};
114
115	/**
116	 * OBJMirrorRoot's primitive 'init method, in pseudo-code:
117	 * 
118	 * def init(newBase) {
119	 *   base := newBase
120	 * }
121	 */
122	public ATObject base_init(ATObject[] initargs) throws InterpreterException {
123		if (initargs.length != 1) {
124			throw new XArityMismatch("init", 1, initargs.length);
125		}
126		
127		NATMirage newBase = initargs[0].asMirage();
128		// check whether the passed base field does not have a mirror assigned to it yet
129		if (newBase.getMirror() == OBJNil._INSTANCE_) {
130			base_ = newBase;
131			return newBase;
132		} else {
133			throw new XIllegalArgument("mirror root's init method requires an uninitialized mirage, found: " + newBase);
134		}
135	}
136
137	/**
138	 * This implementation is actually an ad hoc modification of the NATObject implementation
139	 * of instance creation, dedicated for OBJMirrorRoot. Using the NATObject implementation
140	 * would work perfectly, but this one is more efficient.
141	 */
142	public ATObject meta_newInstance(ATTable initargs) throws InterpreterException {
143		NATMirrorRoot clone = new NATMirrorRoot(base_); // same as this.meta_clone()
144		clone.base_init(initargs.asNativeTable().elements_);
145		return clone;
146	}
147	
148	/* ------------------------------------
149	 * -- Extension and cloning protocol --
150	 * ------------------------------------ */
151	
152	/**
153	 * The mirror root is cloned but the base field is only shallow-copied, i.e. it is shared
154	 * between the clones! Normally, mirrors are instantiated rather than cloned when assigned
155	 * to a new object, such that this new base field will be re-assigned to another mirage
156	 * (in OBJMirrorRoot's primitive 'init' method).
157	 */
158	public ATObject meta_clone() throws InterpreterException {
159		return new NATMirrorRoot(base_);
160	}
161	
162    public ATTable meta_typeTags() throws InterpreterException {
163    	return NATTable.of(NativeTypeTags._MIRROR_);
164    }
165    
166    public NATText meta_print() throws InterpreterException {
167    	return NATText.atValue("<mirror on: "+base_+">");
168    }
169    
170	
171	/**
172	 * The read-only field containing the mirror's base-level mirage.
173	 */
174	public NATMirage base_base() throws InterpreterException {
175		return base_;
176	}
177	
178    
179	/* ------------------------------------------
180	 * -- Slot accessing and mutating protocol --
181	 * ------------------------------------------ */
182
183	/*
184	 * <p>The effect of selecting fields or methods on a mirror (through meta_select) 
185	 * consists of checking whether the requested selector matches a field of the 
186	 * principal wrapped by this mirror. If this is the case, the principal's 
187	 * ('meta_get' + selector) method will be invoked. Else the selector might 
188	 * identify one of the principal's meta-operations. If this is the case, then
189	 * an AmbientTalk representation of the Java method ('meta_' + selector) will 
190	 * be returned. </p>
191	 *  
192	 * <p>Because an explicit AmbientTalk method invocation must be converted into 
193	 * an implicit Java method invocation, the invocation must be deified ('upped').
194	 * To uphold stratification of the mirror architecture, the result of this 
195	 * operation should be a mirror on the result of the Java method invocation.</p>
196	 * 
197	 * <p>Note that only when the principal does not have a matching meta_level field 
198	 * or method the mirror itself will be tested for a corresponding base_level 
199	 * behaviour (e.g. for its base field or for operators such as ==). In the 
200	 * latter case, stratification is not enforced. This is due to the fact that 
201	 * the said fields and methods are not meta-level behaviour, rather they are 
202	 * base-level operations which happen to be applicable on a mirror. An added 
203	 * advantage of this technique is that it permits a mirror to have a field 
204	 * referring to its principal.</p>
205	 */
206	
207	/* ========================================================================
208	 * OBJMirrorRoot has a base_x method for each meta_x method defined in ATObject.
209	 * Each base_x method invokes NATObject's default behaviour on the base_ NATMirage
210	 * via that mirage's magic_x methods.
211	 * ======================================================================== */
212
213	public ATObject base_clone() throws InterpreterException {
214		return base_base().magic_clone();
215	}
216	
217    public ATTable base_typeTags() throws InterpreterException {
218		return base_base().magic_typeTags();
219    }
220    
221    public NATText base_print() throws InterpreterException {
222		return base_base().magic_print();
223    }
224	
225	public ATObject base_pass() throws InterpreterException {
226		return base_base().magic_pass();
227	}
228
229	public ATObject base_resolve() throws InterpreterException {
230		return base_base().magic_resolve();
231	}
232
233	public ATNil base_addField(ATField field) throws InterpreterException {
234		return base_base().magic_addField(field);
235	}
236
237	public ATNil base_addMethod(ATMethod method) throws InterpreterException {
238		return base_base().magic_addMethod(method);
239	}
240
241	public ATNil base_defineField(ATSymbol name, ATObject value) throws InterpreterException {
242		return base_base().magic_defineField(name, value);
243	}
244
245	public ATObject base_doesNotUnderstand(ATSymbol selector) throws InterpreterException {
246		return base_base().magic_doesNotUnderstand(selector);
247	}
248
249	public ATObject base_eval(ATContext ctx) throws InterpreterException {
250		return base_base().magic_eval(ctx);
251	}
252
253	public ATBoolean base_isExtensionOfParent() throws InterpreterException {
254		return base_base().magic_isExtensionOfParent();
255	}
256
257	public ATObject base_invokeField(ATObject rcv, ATSymbol sym) throws InterpreterException {
258		return base_base().magic_invokeField(rcv, sym);
259	}
260
261	public ATField base_grabField(ATSymbol fieldName) throws InterpreterException {
262		return base_base().magic_grabField(fieldName);
263	}
264
265	public ATMethod base_grabMethod(ATSymbol methodName) throws InterpreterException {
266		return base_base().magic_grabMethod(methodName);
267	}
268
269	public ATObject base_invoke(ATObject receiver, ATSymbol atSelector, ATTable arguments) throws InterpreterException {
270		return base_base().magic_invoke(receiver, atSelector, arguments);
271	}
272
273	public ATBoolean base_isCloneOf(ATObject original) throws InterpreterException {
274		return base_base().magic_isCloneOf(original);
275	}
276
277	public ATBoolean base_isRelatedTo(ATObject object) throws InterpreterException {
278		return base_base().magic_isRelatedTo(object);
279	}
280
281	public ATBoolean base_isTaggedAs(ATTypeTag type) throws InterpreterException {
282		return base_base().magic_isTaggedAs(type);
283	}
284
285	public ATTable base_listFields() throws InterpreterException {
286		return base_base().magic_listFields();
287	}
288
289	public ATTable base_listMethods() throws InterpreterException {
290		return base_base().magic_listMethods();
291	}
292
293	public ATObject base_newInstance(ATTable initargs) throws InterpreterException {
294		return base_base().magic_newInstance(initargs);
295	}
296
297	public ATObject base_quote(ATContext ctx) throws InterpreterException {
298		return base_base().magic_quote(ctx);
299	}
300
301	public ATObject base_receive(ATAsyncMessage message) throws InterpreterException {
302		return base_base().magic_receive(message);
303	}
304
305	public ATBoolean base_respondsTo(ATSymbol atSelector) throws InterpreterException {
306		return base_base().magic_respondsTo(atSelector);
307	}
308
309	public ATObject base_select(ATObject receiver, ATSymbol selector) throws InterpreterException {
310		return base_base().magic_select(receiver, selector);
311	}
312
313	public ATObject base_send(ATObject receiver, ATAsyncMessage message) throws InterpreterException {
314		return base_base().magic_send(receiver, message);
315	}
316	
317}