PageRenderTime 28ms CodeModel.GetById 12ms app.highlight 12ms RepoModel.GetById 1ms app.codeStats 0ms

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

http://ambienttalk.googlecode.com/
Java | 365 lines | 187 code | 55 blank | 123 comment | 12 complexity | 83d8110736600047caee64ef9775cc66 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.eval.Evaluator;
 32import edu.vub.at.exceptions.InterpreterException;
 33import edu.vub.at.exceptions.XArityMismatch;
 34import edu.vub.at.exceptions.XIllegalArgument;
 35import edu.vub.at.exceptions.XSerializationError;
 36import edu.vub.at.objects.ATBoolean;
 37import edu.vub.at.objects.ATClosure;
 38import edu.vub.at.objects.ATContext;
 39import edu.vub.at.objects.ATField;
 40import edu.vub.at.objects.ATMethod;
 41import edu.vub.at.objects.ATMethodInvocation;
 42import edu.vub.at.objects.ATMirrorRoot;
 43import edu.vub.at.objects.ATNil;
 44import edu.vub.at.objects.ATObject;
 45import edu.vub.at.objects.ATTable;
 46import edu.vub.at.objects.ATTypeTag;
 47import edu.vub.at.objects.coercion.NativeTypeTags;
 48import edu.vub.at.objects.grammar.ATSymbol;
 49import edu.vub.at.objects.natives.NATByRef;
 50import edu.vub.at.objects.natives.NATTable;
 51import edu.vub.at.objects.natives.NATText;
 52import edu.vub.at.objects.natives.grammar.AGSymbol;
 53import edu.vub.at.util.logging.Logging;
 54
 55import java.io.IOException;
 56import java.util.HashMap;
 57
 58/**
 59 * This class denotes the root node of the intercessive mirrors delegation hierarchy.
 60 * 
 61 * Intercessive mirrors are always tied to a particular 'base' object.
 62 * The default intercessive mirror is named 'mirrorroot' and is an object
 63 * that understands all meta_* operations, implementing them using default semantics.
 64 * It can be thought of as being defined as follows:
 65 * 
 66 * def mirrorroot := object: {
 67 *   def base := object: { nil } mirroredBy: self // base of the mirror root is an empty mirage
 68 *   def init(b) {
 69 *     base := b
 70 *   }
 71 *   def invoke(@args) { <default native invocation behaviour on base> }
 72 *   def select(@args) { <default native selection behaviour on base> }
 73 *   ...
 74 * } taggedAs: [ Mirror ]
 75 * 
 76 * This object can then simply be extended / composed by other objects to deviate from the default semantics.
 77 * Note that the default semantics is applied to 'base' and *not* 'self.base', in other words:
 78 * although child mirrors can define their own 'base' field, it is not taken into consideration
 79 * by the mirror root. This also ensures that the mirror root is not abused to enact upon a mirage
 80 * for which it was not assigned to be the mirror.
 81 * 
 82 * Hence, 'mirrors' are simply objects with the same interface as this mirrorroot object: they should be
 83 * able to respond to all meta_* messages and have a 'base' field.
 84 * 
 85 * @author tvcutsem, smostinc
 86 */
 87public final class NATMirrorRoot extends NATByRef implements ATMirrorRoot {
 88
 89	// The name of the field that points to the base_level representation of a custom mirror
 90	public static final AGSymbol _BASE_NAME_ = AGSymbol.jAlloc("base");
 91	
 92	// the native read-only 'base' field of the mirror root
 93	private NATMirage base_;
 94	
 95	private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
 96		try {
 97			in.defaultReadObject();
 98		} catch(IOException e) {
 99			Logging.Actor_LOG.fatal("Failed to reconstruct an OBJMirrorRoot", e);
100			throw e;
101		}
102	}
103	
104	/**
105	 * Constructor used to initialize the initial mirror root prototype.
106	 */
107	public NATMirrorRoot() {
108		base_ = new NATMirage(this);
109	};
110
111	/**
112	 * Constructor used for cloning: creates a shallow copy of the mirror root.
113	 * @param base the base field value of the original mirror root from which
114	 * this new one will be cloned.
115	 */
116	protected NATMirrorRoot(NATMirage base) {
117		base_ = base;
118	};
119
120	/**
121	 * OBJMirrorRoot's primitive 'init method, in pseudo-code:
122	 * 
123	 * def init(newBase) {
124	 *   base := newBase
125	 * }
126	 */
127	public ATObject base_init(ATObject[] initargs) throws InterpreterException {
128		if (initargs.length != 1) {
129			throw new XArityMismatch("init", 1, initargs.length);
130		}
131		
132		NATMirage newBase = initargs[0].asMirage();
133		// check whether the passed base field does not have a mirror assigned to it yet
134		if (newBase.getMirror() == Evaluator.getNil()) {
135			base_ = newBase;
136			return newBase;
137		} else {
138			throw new XIllegalArgument("mirror root's init method requires an uninitialized mirage, found: " + newBase);
139		}
140	}
141
142	/**
143	 * This implementation is actually an ad hoc modification of the NATObject implementation
144	 * of instance creation, dedicated for the mirror root. Using the NATObject implementation
145	 * would work perfectly, but this one is more efficient.
146	 */
147	public ATObject meta_newInstance(ATTable initargs) throws InterpreterException {
148		ATObject[] initargz = initargs.asNativeTable().elements_;
149		if (initargz.length != 1) {
150			throw new XArityMismatch("newInstance", 1, initargz.length);
151		}
152		NATMirage newBase = initargz[0].asMirage();
153		// check whether the passed base field does not have a mirror assigned to it yet
154		if (newBase.getMirror() == Evaluator.getNil()) {
155			return new NATMirrorRoot(newBase);
156		} else {
157			throw new XIllegalArgument("mirror root's init method requires an uninitialized mirage, found: " + newBase);
158		}
159	}
160	
161	/* ------------------------------------
162	 * -- Extension and cloning protocol --
163	 * ------------------------------------ */
164	
165	/**
166	 * The mirror root is cloned but the base field is only shallow-copied, i.e. it is shared
167	 * between the clones! Normally, mirrors are instantiated rather than cloned when assigned
168	 * to a new object, such that this new base field will be re-assigned to another mirage
169	 * (in {@link NATMirrorRoot#base_init(ATObject[])}).
170	 */
171	public ATObject meta_clone() throws InterpreterException {
172		return new NATMirrorRoot(base_);
173	}
174	
175    public ATTable meta_typeTags() throws InterpreterException {
176    	return NATTable.of(NativeTypeTags._MIRROR_);
177    }
178    
179    public NATText meta_print() throws InterpreterException {
180    	return NATText.atValue("<mirror on: "+base_+">");
181    }
182    
183    public ATObject meta_pass() throws InterpreterException {
184    	if ((base_.meta_isTaggedAs(NativeTypeTags._ISOLATE_)).asNativeBoolean().javaValue) {
185    		return this;
186    	} else {
187    		return super.meta_pass();
188    	}
189    }
190    
191	public ATObject meta_resolve() throws InterpreterException {
192		return this;
193	}
194	
195	/**
196	 * The read-only field containing the mirror's base-level mirage.
197	 */
198	public NATMirage base_base() throws InterpreterException {
199		return base_;
200	}
201	
202    
203	/* ------------------------------------------
204	 * -- Slot accessing and mutating protocol --
205	 * ------------------------------------------ */
206
207	/*
208	 * <p>The effect of selecting fields or methods on a mirror (through meta_select) 
209	 * consists of checking whether the requested selector matches a field of the 
210	 * principal wrapped by this mirror. If this is the case, the principal's 
211	 * ('meta_get' + selector) method will be invoked. Else the selector might 
212	 * identify one of the principal's meta-operations. If this is the case, then
213	 * an AmbientTalk representation of the Java method ('meta_' + selector) will 
214	 * be returned. </p>
215	 *  
216	 * <p>Because an explicit AmbientTalk method invocation must be converted into 
217	 * an implicit Java method invocation, the invocation must be deified ('upped').
218	 * To uphold stratification of the mirror architecture, the result of this 
219	 * operation should be a mirror on the result of the Java method invocation.</p>
220	 * 
221	 * <p>Note that only when the principal does not have a matching meta_level field 
222	 * or method the mirror itself will be tested for a corresponding base_level 
223	 * behaviour (e.g. for its base field or for operators such as ==). In the 
224	 * latter case, stratification is not enforced. This is due to the fact that 
225	 * the said fields and methods are not meta-level behaviour, rather they are 
226	 * base-level operations which happen to be applicable on a mirror. An added 
227	 * advantage of this technique is that it permits a mirror to have a field 
228	 * referring to its principal.</p>
229	 */
230	
231	/* ========================================================================
232	 * OBJMirrorRoot has a base_x method for each meta_x method defined in ATObject.
233	 * Each base_x method invokes NATObject's default behaviour on the base_ NATMirage
234	 * via that mirage's magic_x methods.
235	 * ======================================================================== */
236
237	public ATObject base_clone() throws InterpreterException {
238		return base_base().magic_clone();
239	}
240	
241    public ATTable base_typeTags() throws InterpreterException {
242		return base_base().magic_typeTags();
243    }
244    
245    public NATText base_print() throws InterpreterException {
246		return base_base().magic_print();
247    }
248    
249    public NATText base_asCode() throws InterpreterException {
250		return base_base().magic_asCode();
251    }
252	
253	public ATObject base_pass() throws InterpreterException {
254		return base_base().magic_pass();
255	}
256
257	public ATObject base_resolve() throws InterpreterException {
258		return base_base().magic_resolve();
259	}
260
261	public ATNil base_addField(ATField field) throws InterpreterException {
262		return base_base().magic_addField(field);
263	}
264
265	public ATNil base_addMethod(ATMethod method) throws InterpreterException {
266		return base_base().magic_addMethod(method);
267	}
268	
269	public ATNil base_addSlot(ATMethod slot) throws InterpreterException {
270		return base_base().magic_addSlot(slot);
271	}
272
273	public ATNil base_defineField(ATSymbol name, ATObject value) throws InterpreterException {
274		return base_base().magic_defineField(name, value);
275	}
276
277	public ATClosure base_doesNotUnderstand(ATSymbol selector) throws InterpreterException {
278		return base_base().magic_doesNotUnderstand(selector);
279	}
280
281	public ATObject base_eval(ATContext ctx) throws InterpreterException {
282		return base_base().magic_eval(ctx);
283	}
284
285	public ATBoolean base_isExtensionOfParent() throws InterpreterException {
286		return base_base().magic_isExtensionOfParent();
287	}
288
289	public ATObject base_invokeField(ATObject rcv, ATSymbol sym) throws InterpreterException {
290		return base_base().magic_invokeField(rcv, sym);
291	}
292
293	public ATField base_grabField(ATSymbol fieldName) throws InterpreterException {
294		return base_base().magic_grabField(fieldName);
295	}
296
297	public ATMethod base_grabMethod(ATSymbol methodName) throws InterpreterException {
298		return base_base().magic_grabMethod(methodName);
299	}
300	
301	public ATMethod base_grabSlot(ATSymbol methodName) throws InterpreterException {
302		return base_base().magic_grabSlot(methodName);
303	}
304
305    public ATObject meta_removeSlot(ATSymbol selector) throws InterpreterException {
306    	return base_base().magic_removeSlot(selector);
307    }
308	
309	public ATObject base_invoke(ATObject receiver, ATMethodInvocation inv) throws InterpreterException {
310		return base_base().magic_invoke(receiver, inv);
311	}
312
313	public ATBoolean base_isCloneOf(ATObject original) throws InterpreterException {
314		return base_base().magic_isCloneOf(original);
315	}
316
317	public ATBoolean base_isRelatedTo(ATObject object) throws InterpreterException {
318		return base_base().magic_isRelatedTo(object);
319	}
320
321	public ATBoolean base_isTaggedAs(ATTypeTag type) throws InterpreterException {
322		return base_base().magic_isTaggedAs(type);
323	}
324
325	public ATTable base_listFields() throws InterpreterException {
326		return base_base().magic_listFields();
327	}
328
329	public ATTable base_listMethods() throws InterpreterException {
330		return base_base().magic_listMethods();
331	}
332	
333	public ATTable base_listSlots() throws InterpreterException {
334		return base_base().magic_listSlots();
335	}
336	
337	public ATObject base_removeSlot(ATSymbol selector) throws InterpreterException {
338		return base_base().magic_removeSlot(selector);
339	}
340
341	public ATObject base_newInstance(ATTable initargs) throws InterpreterException {
342		return base_base().magic_newInstance(initargs);
343	}
344
345	public ATObject base_quote(ATContext ctx) throws InterpreterException {
346		return base_base().magic_quote(ctx);
347	}
348
349	public ATObject base_receive(ATAsyncMessage message) throws InterpreterException {
350		return base_base().magic_receive(message);
351	}
352
353	public ATBoolean base_respondsTo(ATSymbol atSelector) throws InterpreterException {
354		return base_base().magic_respondsTo(atSelector);
355	}
356
357	public ATClosure base_select(ATObject receiver, ATSymbol selector) throws InterpreterException {
358		return base_base().magic_select(receiver, selector);
359	}
360
361	public ATObject base_send(ATObject receiver, ATAsyncMessage message) throws InterpreterException {
362		return base_base().magic_send(receiver, message);
363	}
364	
365}