/interpreter/tags/at_build150307/src/edu/vub/at/objects/mirrors/OBJMirrorRoot.java

http://ambienttalk.googlecode.com/ · Java · 318 lines · 146 code · 49 blank · 123 comment · 5 complexity · f07289b9b8fb848707a5eb84ad545404 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. */
  28. package edu.vub.at.objects.mirrors;
  29. import edu.vub.at.actors.ATAsyncMessage;
  30. import edu.vub.at.exceptions.InterpreterException;
  31. import edu.vub.at.exceptions.XArityMismatch;
  32. import edu.vub.at.exceptions.XIllegalArgument;
  33. import edu.vub.at.objects.ATBoolean;
  34. import edu.vub.at.objects.ATContext;
  35. import edu.vub.at.objects.ATField;
  36. import edu.vub.at.objects.ATMethod;
  37. import edu.vub.at.objects.ATNil;
  38. import edu.vub.at.objects.ATObject;
  39. import edu.vub.at.objects.ATStripe;
  40. import edu.vub.at.objects.ATTable;
  41. import edu.vub.at.objects.coercion.NativeStripes;
  42. import edu.vub.at.objects.grammar.ATSymbol;
  43. import edu.vub.at.objects.natives.NATByCopy;
  44. import edu.vub.at.objects.natives.NATNil;
  45. import edu.vub.at.objects.natives.NATTable;
  46. import edu.vub.at.objects.natives.NATText;
  47. import edu.vub.at.objects.natives.grammar.AGSymbol;
  48. /**
  49. * OBJMirrorRoot denotes the root node of the intercessive mirrors delegation hierarchy.
  50. *
  51. * Intercessive mirrors are always tied to a particular 'base' object.
  52. * The default intercessive mirror is named 'mirrorroot' and is an object
  53. * that understands all meta_* operations, implementing them using default semantics.
  54. * It can be thought of as being defined as follows:
  55. *
  56. * def mirrorroot := object: {
  57. * def base := object: { nil } mirroredBy: self // base of the mirror root is an empty mirage
  58. * def init(b) {
  59. * base := b
  60. * }
  61. * def invoke(@args) { <default native invocation behaviour on base> }
  62. * def select(@args) { <default native selection behaviour on base> }
  63. * ...
  64. * } stripedWith: [ Mirror ]
  65. *
  66. * This object can then simply be extended / composed by other objects to deviate from the default semantics.
  67. * Note that the default semantics is applied to 'base' and *not* 'self.base', in other words:
  68. * although child mirrors can define their own 'base' field, it is not taken into consideration
  69. * by the mirror root. This also ensures that the mirror root is not abused to enact upon a mirage
  70. * for which it was not assigned to be the mirror.
  71. *
  72. * Hence, 'mirrors' are simply objects with the same interface as this mirrorroot object: they should be
  73. * able to respond to all meta_* messages and have a 'base' field.
  74. *
  75. * @author smostinc
  76. * @author tvcutsem
  77. */
  78. public final class OBJMirrorRoot extends NATByCopy implements ATObject {
  79. // The name of the field that points to the base_level representation of a custom mirror
  80. public static final AGSymbol _BASE_NAME_ = AGSymbol.jAlloc("base");
  81. // the native read-only 'base' field of the mirror root
  82. private NATMirage base_;
  83. /**
  84. * Constructor used to initialize the initial mirror root prototype.
  85. */
  86. public OBJMirrorRoot() {
  87. base_ = new NATMirage(this);
  88. };
  89. /**
  90. * Constructor used for cloning: creates a shallow copy of the mirror root.
  91. * @param base the base field value of the original mirror root from which
  92. * this new one will be cloned.
  93. */
  94. private OBJMirrorRoot(NATMirage base) {
  95. base_ = base;
  96. };
  97. /**
  98. * OBJMirrorRoot's primitive 'init method, in pseudo-code:
  99. *
  100. * def init(newBase) {
  101. * base := newBase
  102. * }
  103. */
  104. public ATObject base_init(ATObject[] initargs) throws InterpreterException {
  105. if (initargs.length != 1) {
  106. throw new XArityMismatch("init", 1, initargs.length);
  107. }
  108. NATMirage newBase = initargs[0].asMirage();
  109. // check whether the passed base field does not have a mirror assigned to it yet
  110. if (newBase.getMirror() == NATNil._INSTANCE_) {
  111. base_ = newBase;
  112. return newBase;
  113. } else {
  114. throw new XIllegalArgument("mirror root's init method requires an uninitialized mirage, found: " + newBase);
  115. }
  116. }
  117. /**
  118. * This implementation is actually an ad hoc modification of the NATObject implementation
  119. * of instance creation, dedicated for OBJMirrorRoot. Using the NATObject implementation
  120. * would work perfectly, but this one is more efficient.
  121. */
  122. public ATObject meta_newInstance(ATTable initargs) throws InterpreterException {
  123. OBJMirrorRoot clone = new OBJMirrorRoot(base_); // same as this.meta_clone()
  124. clone.base_init(initargs.asNativeTable().elements_);
  125. return clone;
  126. }
  127. /* ------------------------------------
  128. * -- Extension and cloning protocol --
  129. * ------------------------------------ */
  130. /**
  131. * The mirror root is cloned but the base field is only shallow-copied, i.e. it is shared
  132. * between the clones! Normally, mirrors are instantiated rather than cloned when assigned
  133. * to a new object, such that this new base field will be re-assigned to another mirage
  134. * (in OBJMirrorRoot's primitive 'init' method.
  135. */
  136. public ATObject meta_clone() throws InterpreterException {
  137. return new OBJMirrorRoot(base_);
  138. }
  139. public ATTable meta_getStripes() throws InterpreterException {
  140. return NATTable.of(NativeStripes._MIRROR_);
  141. }
  142. public NATText meta_print() throws InterpreterException {
  143. return NATText.atValue("<mirror on: "+base_+">");
  144. }
  145. /**
  146. * The read-only field containing the mirror's base-level mirage.
  147. */
  148. public NATMirage base_getBase() throws InterpreterException {
  149. return base_;
  150. }
  151. /* ------------------------------------------
  152. * -- Slot accessing and mutating protocol --
  153. * ------------------------------------------ */
  154. /*
  155. * <p>The effect of selecting fields or methods on a mirror (through meta_select)
  156. * consists of checking whether the requested selector matches a field of the
  157. * principal wrapped by this mirror. If this is the case, the principal's
  158. * ('meta_get' + selector) method will be invoked. Else the selector might
  159. * identify one of the principal's meta-operations. If this is the case, then
  160. * an AmbientTalk representation of the Java method ('meta_' + selector) will
  161. * be returned. </p>
  162. *
  163. * <p>Because an explicit AmbientTalk method invocation must be converted into
  164. * an implicit Java method invocation, the invocation must be deified ('upped').
  165. * To uphold stratification of the mirror architecture, the result of this
  166. * operation should be a mirror on the result of the Java method invocation.</p>
  167. *
  168. * <p>Note that only when the principal does not have a matching meta_level field
  169. * or method the mirror itself will be tested for a corresponding base_level
  170. * behaviour (e.g. for its base field or for operators such as ==). In the
  171. * latter case, stratification is not enforced. This is due to the fact that
  172. * the said fields and methods are not meta-level behaviour, rather they are
  173. * base-level operations which happen to be applicable on a mirror. An added
  174. * advantage of this technique is that it permits a mirror to have a field
  175. * referring to its principal.</p>
  176. */
  177. /* ========================================================================
  178. * OBJMirrorRoot has a base_x method for each meta_x method defined in ATObject.
  179. * Each base_x method invokes NATObject's default behaviour on the base_ NATMirage
  180. * via that mirage's magic_x methods.
  181. * ======================================================================== */
  182. public ATObject base_clone() throws InterpreterException {
  183. return base_getBase().magic_clone();
  184. }
  185. public ATTable base_getStripes() throws InterpreterException {
  186. return base_getBase().magic_getStripes();
  187. }
  188. public NATText base_print() throws InterpreterException {
  189. return base_getBase().magic_print();
  190. }
  191. public ATObject base_pass() throws InterpreterException {
  192. return base_getBase().magic_pass();
  193. }
  194. public ATObject base_resolve() throws InterpreterException {
  195. return base_getBase().magic_resolve();
  196. }
  197. public ATNil base_addField(ATField field) throws InterpreterException {
  198. return base_getBase().magic_addField(field);
  199. }
  200. public ATNil base_addMethod(ATMethod method) throws InterpreterException {
  201. return base_getBase().magic_addMethod(method);
  202. }
  203. public ATNil base_assignField(ATObject receiver, ATSymbol name, ATObject value) throws InterpreterException {
  204. return base_getBase().magic_assignField(receiver, name, value);
  205. }
  206. public ATNil base_assignVariable(ATSymbol name, ATObject value) throws InterpreterException {
  207. return base_getBase().magic_assignVariable(name, value);
  208. }
  209. public ATNil base_defineField(ATSymbol name, ATObject value) throws InterpreterException {
  210. return base_getBase().magic_defineField(name, value);
  211. }
  212. public ATObject base_doesNotUnderstand(ATSymbol selector) throws InterpreterException {
  213. return base_getBase().magic_doesNotUnderstand(selector);
  214. }
  215. public ATObject base_eval(ATContext ctx) throws InterpreterException {
  216. return base_getBase().magic_eval(ctx);
  217. }
  218. public ATBoolean base_isExtensionOfParent() throws InterpreterException {
  219. return base_getBase().magic_isExtensionOfParent();
  220. }
  221. public ATObject base_getLexicalParent() throws InterpreterException {
  222. return base_getBase().magic_getLexicalParent();
  223. }
  224. public ATField base_grabField(ATSymbol fieldName) throws InterpreterException {
  225. return base_getBase().magic_grabField(fieldName);
  226. }
  227. public ATMethod base_grabMethod(ATSymbol methodName) throws InterpreterException {
  228. return base_getBase().magic_grabMethod(methodName);
  229. }
  230. public ATObject base_invoke(ATObject receiver, ATSymbol atSelector, ATTable arguments) throws InterpreterException {
  231. return base_getBase().magic_invoke(receiver, atSelector, arguments);
  232. }
  233. public ATBoolean base_isCloneOf(ATObject original) throws InterpreterException {
  234. return base_getBase().magic_isCloneOf(original);
  235. }
  236. public ATBoolean base_isRelatedTo(ATObject object) throws InterpreterException {
  237. return base_getBase().magic_isRelatedTo(object);
  238. }
  239. public ATBoolean base_isStripedWith(ATStripe stripe) throws InterpreterException {
  240. return base_getBase().magic_isStripedWith(stripe);
  241. }
  242. public ATTable base_listFields() throws InterpreterException {
  243. return base_getBase().magic_listFields();
  244. }
  245. public ATTable base_listMethods() throws InterpreterException {
  246. return base_getBase().magic_listMethods();
  247. }
  248. public ATObject base_lookup(ATSymbol selector) throws InterpreterException {
  249. return base_getBase().magic_lookup(selector);
  250. }
  251. public ATObject base_newInstance(ATTable initargs) throws InterpreterException {
  252. return base_getBase().magic_newInstance(initargs);
  253. }
  254. public ATObject base_quote(ATContext ctx) throws InterpreterException {
  255. return base_getBase().magic_quote(ctx);
  256. }
  257. public ATObject base_receive(ATAsyncMessage message) throws InterpreterException {
  258. return base_getBase().magic_receive(message);
  259. }
  260. public ATBoolean base_respondsTo(ATSymbol atSelector) throws InterpreterException {
  261. return base_getBase().magic_respondsTo(atSelector);
  262. }
  263. public ATObject base_select(ATObject receiver, ATSymbol selector) throws InterpreterException {
  264. return base_getBase().magic_select(receiver, selector);
  265. }
  266. public ATObject base_send(ATAsyncMessage message) throws InterpreterException {
  267. return base_getBase().magic_send(message);
  268. }
  269. }