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