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

/interpreter/tags/at_build150307/src/edu/vub/at/actors/natives/NATFarReference.java

http://ambienttalk.googlecode.com/
Java | 344 lines | 158 code | 42 blank | 144 comment | 3 complexity | 56fc08016ea7c261c35855a9554810f6 MD5 | raw file
  1/**
  2 * AmbientTalk/2 Project
  3 * NATFarReference.java created on Dec 6, 2006 at 9:53:20 AM
  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.actors.natives;
 29
 30import edu.vub.at.actors.ATAsyncMessage;
 31import edu.vub.at.actors.ATFarReference;
 32import edu.vub.at.actors.id.ATObjectID;
 33import edu.vub.at.exceptions.InterpreterException;
 34import edu.vub.at.exceptions.XIllegalOperation;
 35import edu.vub.at.exceptions.XSelectorNotFound;
 36import edu.vub.at.exceptions.XTypeMismatch;
 37import edu.vub.at.objects.ATBoolean;
 38import edu.vub.at.objects.ATClosure;
 39import edu.vub.at.objects.ATField;
 40import edu.vub.at.objects.ATMethod;
 41import edu.vub.at.objects.ATNil;
 42import edu.vub.at.objects.ATObject;
 43import edu.vub.at.objects.ATStripe;
 44import edu.vub.at.objects.ATTable;
 45import edu.vub.at.objects.grammar.ATSymbol;
 46import edu.vub.at.objects.mirrors.NativeClosure;
 47import edu.vub.at.objects.natives.NATBoolean;
 48import edu.vub.at.objects.natives.NATByCopy;
 49import edu.vub.at.objects.natives.NATNil;
 50import edu.vub.at.objects.natives.NATObject;
 51import edu.vub.at.objects.natives.NATTable;
 52import edu.vub.at.objects.natives.NATText;
 53import edu.vub.at.objects.natives.grammar.AGSymbol;
 54
 55/**
 56 * 
 57 * NATFarReference is the root of the native classes that represent native far references.
 58 * The AmbientTalk/2 implementation distinguishes between two kinds of far references:
 59 * local and remote far references. The former denote far references to objects hosted by
 60 * actors on the same virtual machine. The latter ones denote far references to remote objects
 61 * that are hosted on a separate virtual (and usually even physical) machine.
 62 * 
 63 * This abstract superclass encapsulates all of the code that these two kinds of far references
 64 * have in common. The variabilities are delegated to the subclasses. Subclasses should implement
 65 * an abstract method (transmit) which is invoked by this class when the far reference receives
 66 * a message to be forwarded to the remote principal.
 67 * 
 68 * Note that far references are pass by copy and resolve to either a near or a new
 69 * actor-local far reference.
 70 * 
 71 * Far references encapsulate the same stripes as the remote object they represent.
 72 * As such it becomes possible to perform a stripe test on a far reference as if it
 73 * was performed on the local object itself!
 74 * 
 75 * @author tvcutsem
 76 * @author smostinc
 77 */
 78public abstract class NATFarReference extends NATByCopy implements ATFarReference {
 79	
 80	// encodes the identity of the far object pointed at
 81	private final ATObjectID objectId_;
 82	
 83	// the stripes with which the remote object is tagged
 84	private final ATStripe[] stripes_;
 85
 86	protected NATFarReference(ATObjectID objectId, ATStripe[] stripes) {
 87		objectId_ = objectId;
 88		stripes_ = stripes;
 89	}
 90	
 91	public ATObjectID getObjectId() {
 92		return objectId_;
 93	}
 94	
 95	public NATFarReference asNativeFarReference() throws XTypeMismatch {
 96		return this;
 97	}
 98	
 99	/**
100	 * After deserialization, ensure that only one unique remote reference exists for
101	 * my target.
102	 */
103	public ATObject meta_resolve() throws InterpreterException {
104		// it may be that the once local target object is now remote!
105		return ELActor.currentActor().resolve(getObjectId(), stripes_);
106	}
107
108	/* ------------------------------
109     * -- Message Sending Protocol --
110     * ------------------------------ */
111
112	public ATObject meta_receive(ATAsyncMessage message) throws InterpreterException {
113		return this.transmit(message);
114	}
115	
116	protected abstract ATObject transmit(ATAsyncMessage passedMessage) throws InterpreterException;
117
118	/**
119	 * @throws XIllegalOperation Cannot synchronously invoke a method on a far reference
120	 */
121	public ATObject meta_invoke(ATObject receiver, ATSymbol atSelector, ATTable arguments) throws InterpreterException {
122		throw new XIllegalOperation("Cannot invoke " + atSelector + " on far reference " + this);
123	}
124
125	/**
126	 * @return true if and only if the far object is queried for responses to basic operations such as ==
127	 */
128	public ATBoolean meta_respondsTo(ATSymbol atSelector) throws InterpreterException {
129		return super.meta_respondsTo(atSelector);
130	}
131
132	/**
133	 * @throws XSelectorNotFound to ensure proper semantics should the interpreter be
134	 * extended such that it allows extending a far reference in the future.
135	 */
136	public ATObject meta_doesNotUnderstand(ATSymbol selector) throws InterpreterException {
137		return super.meta_doesNotUnderstand(selector);
138	}
139
140	/* ------------------------------------
141     * -- Extension and cloning protocol --
142     * ------------------------------------ */
143
144	/**
145	 * References to objects hosted by another actor are forced to be unique. Therefore
146	 * cloning them throws an XIllegalOperation to avoid inconsistencies by performing
147	 * state updates (through sent messages) after a clone operation. 
148	 * 
149	 * TODO(discuss) clone: farObject may create a clone on the other actor.
150	 */
151	public ATObject meta_clone() throws InterpreterException {
152		throw new XIllegalOperation("Cannot clone far reference " + this);
153	}
154
155	/**
156	 * Cannot create a new instance using a farObject, this should be done either by 
157	 * sending rather than invoking new(args) such that the correct method is triggered
158	 * or by invoking newInstance on a farMirror, which will send the call as well. 
159	 */
160	public ATObject meta_newInstance(ATTable initargs) throws InterpreterException {
161		throw new XIllegalOperation("Cannot create new instance of far reference " + this);
162	}
163	
164	/* ------------------------------------------
165     * -- Slot accessing and mutating protocol --
166     * ------------------------------------------ */
167	
168	/**
169	 * @throws XIllegalOperation - cannot select in objects hosted by another actor.
170	 */
171	public ATObject meta_select(ATObject receiver, ATSymbol selector) throws InterpreterException {
172		throw new XIllegalOperation("Cannot select " + selector + " from far reference " + this);
173	}
174
175	/**
176	 * @throws XIllegalOperation - cannot lookup in objects hosted by another actor.
177	 */
178	public ATObject meta_lookup(ATSymbol selector) throws InterpreterException {
179		throw new XIllegalOperation("Cannot lookup " + selector + " from far reference " + this);
180	}
181
182	/**
183	 * @throws XIllegalOperation - cannot define in objects hosted by another actor.
184	 */
185	public ATNil meta_defineField(ATSymbol name, ATObject value) throws InterpreterException {
186		throw new XIllegalOperation("Cannot define field " + name + " in far reference " + this);
187	}
188
189	/**
190	 * @throws XIllegalOperation - cannot assign in objects hosted by another actor.
191	 */
192	public ATNil meta_assignField(ATObject receiver, ATSymbol name, ATObject value) throws InterpreterException {
193		throw new XIllegalOperation("Cannot assign field " + name + " in far reference " + this);
194	}
195
196	/**
197	 * @throws XIllegalOperation - cannot assign in objects hosted by another actor.
198	 */
199	public ATNil meta_assignVariable(ATSymbol name, ATObject value) throws InterpreterException {
200		throw new XIllegalOperation("Cannot assign variable " + name + " in far reference " + this);
201	}
202
203    /* ----------------------------------------
204     * -- Object Relation Testing Protocol   --
205     * ---------------------------------------- */
206
207    /**
208     * @return false unless this == original
209     */
210	public ATBoolean meta_isCloneOf(ATObject original) throws InterpreterException {
211		return NATBoolean.atValue(this == original);
212	}
213
214    /**
215     * @return false unless this == original
216     */
217	public ATBoolean meta_isRelatedTo(ATObject object) throws InterpreterException {
218		return this.meta_isCloneOf(object);
219	}
220
221    /* ---------------------------------
222     * -- Structural Access Protocol  --
223     * --------------------------------- */
224	
225	/**
226	 * @throws XIllegalOperation - cannot add fields to an object in another actor.
227	 */
228	public ATNil meta_addField(ATField field) throws InterpreterException {
229		return super.meta_addField(field);
230	}
231
232	/**
233	 * @throws XIllegalOperation - cannot add methods to an object in another actor.
234	 */
235	public ATNil meta_addMethod(ATMethod method) throws InterpreterException {
236		return super.meta_addMethod(method);
237	}
238
239	/**
240	 * @throws XSelectorNotFound - as the far object has no fields of its own
241	 */
242	public ATField meta_grabField(ATSymbol fieldName) throws InterpreterException {
243		return super.meta_grabField(fieldName);
244	}
245
246	/**
247	 * @return a method if and only if the requested selector is a default operator such as == 
248	 * @throws XSelectorNotFound otherwise
249	 */
250	public ATMethod meta_grabMethod(ATSymbol methodName) throws InterpreterException {
251		return super.meta_grabMethod(methodName);
252	}
253
254	/**
255	 * @return an empty table
256	 */
257	public ATTable meta_listFields() throws InterpreterException {
258		return super.meta_listFields();
259	}
260
261	/**
262	 * @return a table of default methods
263	 */
264	public ATTable meta_listMethods() throws InterpreterException {
265		return super.meta_listMethods();
266	}
267
268    /* ----------------------
269     * -- Output Protocol  --
270     * ---------------------- */
271	
272	public NATText meta_print() throws InterpreterException {
273		return NATText.atValue("<far ref:"+objectId_+">");
274	}
275	
276    /* --------------------
277     * -- Mirror Fields  --
278     * -------------------- */
279	
280	/**
281	 * The stripes of a far reference are the stripes of the remote object
282	 * it points to, plus the FarReference stripe.
283	 */
284    public ATTable meta_getStripes() throws InterpreterException {
285    	return NATTable.atValue(stripes_);
286    }
287	
288	public boolean isFarReference() {
289		return true;
290	}
291
292    public ATFarReference asFarReference() throws XTypeMismatch {
293  	    return this;
294  	}
295    
296	public static class NATDisconnectionSubscription extends NATObject {
297		private static final AGSymbol _REFERENCE_ = AGSymbol.jAlloc("reference");
298		private static final AGSymbol _HANDLER_ = AGSymbol.jAlloc("handler");
299		private static final AGSymbol _CANCEL_ = AGSymbol.jAlloc("cancel");
300		public NATDisconnectionSubscription(final NATFarReference reference, ATClosure handler) throws InterpreterException {
301			this.meta_defineField(_REFERENCE_, reference);
302			this.meta_defineField(_HANDLER_, handler);
303			this.meta_defineField(_CANCEL_, 	new NativeClosure(this) {
304				public ATObject base_apply(ATTable args) throws InterpreterException {
305					NATFarReference reference = scope_.meta_select(scope_, _REFERENCE_).asNativeFarReference();
306					if(reference instanceof NATRemoteFarRef) {
307						NATRemoteFarRef remote = (NATRemoteFarRef)reference;
308						ATObject handler = scope_.meta_select(scope_, _HANDLER_);
309						remote.removeDisconnectionListener(handler);
310					}
311					return NATNil._INSTANCE_;
312				}
313			});
314		}
315		public NATText meta_print() throws InterpreterException {
316			return NATText.atValue("<disconnection subscription:"+ this.meta_select(this, _REFERENCE_)+">");
317		}
318	}
319	
320	public static class NATReconnectionSubscription extends NATObject {
321		private static final AGSymbol _REFERENCE_ = AGSymbol.jAlloc("reference");
322		private static final AGSymbol _HANDLER_ = AGSymbol.jAlloc("handler");
323		private static final AGSymbol _CANCEL_ = AGSymbol.jAlloc("cancel");
324		public NATReconnectionSubscription(final NATFarReference reference, ATClosure handler) throws InterpreterException {
325			this.meta_defineField(_REFERENCE_, reference);
326			this.meta_defineField(_HANDLER_, handler);
327			this.meta_defineField(_CANCEL_, 	new NativeClosure(this) {
328				public ATObject base_apply(ATTable args) throws InterpreterException {
329					NATFarReference reference = scope_.meta_select(scope_, _REFERENCE_).asNativeFarReference();
330					if(reference instanceof NATRemoteFarRef) {
331						NATRemoteFarRef remote = (NATRemoteFarRef)reference;
332						ATObject handler = scope_.meta_select(scope_, _HANDLER_);
333						remote.removeReconnectionListener(handler);
334					}
335					return NATNil._INSTANCE_;
336				}
337			});
338		}
339		public NATText meta_print() throws InterpreterException {
340			return NATText.atValue("<reconnection subscription:"+ this.meta_select(this, _REFERENCE_)+">");
341		}
342	}
343	
344}