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