r5304: *** empty log message ***
[hyperobject.git] / mop.lisp
index 4ea60683b33184e8e93e2d66b54380639512baf1..e42ee8bfbc991b33ceca85ea3eccd4015a405c54 100644 (file)
--- a/mop.lisp
+++ b/mop.lisp
@@ -11,7 +11,7 @@
 ;;;; in Text, HTML, and XML formats. This includes hyperlinking\r
 ;;;; capability and sub-objects.\r
 ;;;;\r
-;;;; $Id: mop.lisp,v 1.83 2003/07/11 18:02:41 kevin Exp $\r
+;;;; $Id: mop.lisp,v 1.84 2003/07/14 04:10:02 kevin Exp $\r
 ;;;;\r
 ;;;; This file is Copyright (c) 2000-2003 by Kevin M. Rosenberg\r
 ;;;; *************************************************************************\r
   (:documentation "Metaclass for Markup Language classes."))\r
 \r
 (defclass subobject ()\r
-  ((name-class :type symbol :initform nil :initarg :name-class :reader name-class)\r
-   (name-slot :type symbol :initform nil :initarg :name-slot :reader name-slot)\r
-   (lookup :type (or function symbol) :initform nil :initarg :lookup :reader lookup)\r
-   (lookup-keys :type list :initform nil :initarg :lookup-keys\r
-               :reader lookup-keys))\r
-  (:documentation "Contains subobject information"))\r
+  ((name-class :type symbol :initarg :name-class :reader name-class)\r
+   (name-slot :type symbol :initarg :name-slot :reader name-slot)\r
+   (subobj-class :type symbol :initarg :subobj-class :reader subobj-class)\r
+   (lookup :type (or function symbol) :initarg :lookup :reader lookup)\r
+   (lookup-keys :type list :initarg :lookup-keys :reader lookup-keys))\r
+  (:documentation "subobject information")\r
+  (:default-initargs :name-class nil :name-slot nil :subobj-class nil\r
+                    :lookup nil :lookup-keys nil))\r
 \r
 \r
 (defmethod print-object ((obj subobject) (s stream))\r
@@ -344,89 +346,37 @@ SQL name"
 \r
 ;;;; Class initialization function\r
 \r
-;; defines a slot-unbound method for class and slot-name, fills\r
-;; the slot by calling reader function with the slot values of\r
-;; the instance's reader-keys\r
-(defmacro def-lazy-reader (class slot-name reader &rest reader-keys)\r
-  (let* ((the-slot-name (gensym))\r
-        (the-class (gensym))\r
-        (the-instance (gensym))\r
-        (keys '()))\r
-    (dolist (key reader-keys)\r
-      (push (list 'slot-value the-instance (list 'quote key)) keys))\r
-    (setq keys (nreverse keys))\r
-    `(defmethod slot-unbound (,the-class (,the-instance ,class)\r
-                             (,the-slot-name (eql ',slot-name)))\r
-      (declare (ignore ,the-class))\r
-      (setf (slot-value ,the-instance ,the-slot-name) (,reader ,@keys)))))\r
-\r
-\r
-#+lispworks\r
-(defun intern-eql-specializer (slot)\r
-  `(eql ,slot))\r
-\r
-#+(or sbcl cmu lispworks)\r
-(defun ensure-lazy-reader (class-name slot-name reader &rest reader-keys)\r
-  (let ((keys nil)\r
-       (gf (ensure-generic-function 'slot-unbound)))\r
-    (dolist (key reader-keys)\r
-      (push (list 'slot-value 'the-instance (list 'quote key)) keys))\r
-    (setq keys (nreverse keys))\r
-    (multiple-value-bind (method-lambda init-args-values)\r
-       (make-method-lambda\r
-        gf\r
-        (class-prototype (generic-function-method-class gf))\r
-        #-lispworks\r
-        `(lambda (the-class the-instance the-slot-name)\r
-          (declare (ignore the-class))\r
-          (setf (slot-value the-instance the-slot-name) (,reader ,@keys)))\r
-        #+lispworks\r
-        '(the-class the-instance the-slot-name)\r
-        #+lispworks\r
-        nil\r
-        #+lispworks\r
-        `(setf (slot-value the-instance the-slot-name) (,reader ,@keys))\r
-        nil)\r
-      (add-method gf\r
-                 (apply\r
-                  #'make-instance (generic-function-method-class gf)\r
-                  ':specializers (list (class-of (find-class class-name))\r
-                                       (find-class class-name)\r
-                                       (intern-eql-specializer slot-name))\r
-                  ':lambda-list '(the-class the-instance the-slot-name)\r
-                  ':function (compile nil method-lambda)\r
-                  init-args-values)))))\r
-\r
-#+(or allegro scl openmcl)\r
-(progn\r
-  ;; One entry for each class with lazy readers defined.  The value is a plist mapping\r
-  ;; slot-name to a lazy reader, each of which is a list of a function and slot-names.\r
-  (defvar *lazy-readers* (make-hash-table))\r
+;; One entry for each class with lazy readers defined.  The value is a plist mapping\r
+;; slot-name to a lazy reader, each of which is a list of a function and slot-names.\r
+(defvar *lazy-readers* (make-hash-table))\r
 \r
 (defmethod slot-unbound :around ((class hyperobject-class) instance slot-name)\r
   (let ((lazy-reader (loop for super in (class-precedence-list class)\r
-                          as lazy-reader = (getf (gethash super *lazy-readers*) slot-name)\r
-                          when lazy-reader return it)))\r
+                        as lazy-reader = (getf (gethash super *lazy-readers*) slot-name)\r
+                        when lazy-reader return it)))\r
     (if lazy-reader\r
        (setf (slot-value instance slot-name)\r
-             (apply (car lazy-reader)\r
-                    (loop for arg-slot-name in (cdr lazy-reader)\r
-                          collect (slot-value instance arg-slot-name))))\r
-       ;; No lazy reader -- defer to regular slot-unbound handling.\r
-       (call-next-method))))\r
-\r
-  ;; The reader is a function and the reader-keys are slot names.  The slot is lazily set to\r
-  ;; the result of applying the function to the slot-values of those slots, and that value\r
-  ;; is also returned.\r
-  (defun ensure-lazy-reader (class-name slot-name reader &rest reader-keys)\r
-    (setf (getf (gethash (find-class class-name) *lazy-readers*) slot-name)\r
-         (list* reader (copy-list reader-keys))))\r
-\r
-  (defun remove-lazy-reader (class-name slot-name)\r
-    (setf (getf (gethash (find-class class-name) *lazy-readers*) slot-name)\r
-         nil))\r
-  \r
-  ) ;; #+(or allegro sc openmcll)\r
+         (if (atom lazy-reader)\r
+             (make-instance lazy-reader)\r
+           (apply (car lazy-reader)\r
+                  (loop for arg-slot-name in (cdr lazy-reader)\r
+                      collect (slot-value instance arg-slot-name)))))\r
+      ;; No lazy reader -- defer to regular slot-unbound handling.\r
+      (call-next-method))))\r
+\r
+;; The reader is a function and the reader-keys are slot names.  The slot is lazily set to\r
+;; the result of applying the function to the slot-values of those slots, and that value\r
+;; is also returned.\r
+(defun ensure-lazy-reader (class-name slot-name subobj-class reader \r
+                          &rest reader-keys)\r
+  (setf (getf (gethash (find-class class-name) *lazy-readers*) slot-name)\r
+    (aif subobj-class\r
+        it\r
+        (list* reader (copy-list reader-keys)))))\r
+\r
+(defun remove-lazy-reader (class-name slot-name)\r
+  (setf (getf (gethash (find-class class-name) *lazy-readers*) slot-name)\r
+    nil))\r
 \r
 \r
 (defun finalize-subobjects (cl)\r
@@ -440,30 +390,24 @@ SQL name"
                    (make-instance 'subobject\r
                                   :name-class (class-name cl)\r
                                   :name-slot (slot-definition-name slot)\r
-                                  :lookup (if (atom subobj-def)\r
-                                              subobj-def\r
-                                              (car subobj-def))\r
-                                  :lookup-keys (if (atom subobj-def)\r
-                                                   nil\r
-                                                   (cdr subobj-def)))))\r
+                                  :subobj-class (when (atom subobj-def)\r
+                                                  subobj-def)\r
+                                  :lookup (when (listp subobj-def)\r
+                                            (car subobj-def))\r
+                                  :lookup-keys (when (listp subobj-def)\r
+                                                 (cdr subobj-def)))))\r
               (unless (eq (lookup subobject) t)\r
-                #+ignore ;; #-(or sbcl cmu lispworks)\r
-                (eval\r
-                 `(hyperobject::def-lazy-reader ,(name-class subobject)\r
-                   ,(name-slot subobject) ,(lookup subobject)\r
-                   ,@(lookup-keys subobject)))\r
-                #+(or sbcl cmu lispworks allegro scl openmcl)\r
                 (apply #'ensure-lazy-reader \r
                        (name-class subobject) (name-slot subobject)\r
-                       (lookup subobject) (lookup-keys subobject)))\r
-              (push subobject subobjects))))\r
+                       (subobj-class subobject)\r
+                       (lookup subobject) (lookup-keys subobject))\r
+                (push subobject subobjects)))))\r
          ;; sbcl/cmu reverse class-slots compared to the defclass form\r
          ;; so re-reverse on cmu/sbcl\r
          #+(or cmu sbcl) subobjects\r
          #-(or cmu sbcl) (nreverse subobjects)\r
          )))\r
 \r
-\r
 (defun finalize-class-slots (cl)\r
   "Make sure all class slots have an expected value"\r
   (unless (user-name cl)\r
@@ -477,13 +421,12 @@ SQL name"
                                   (user-name cl))\r
                    2)))\r
 \r
-  (dolist (name '(user-name description version guid sql-name\r
-                 direct-views direct-rules))\r
+  (dolist (name '(user-name description version guid sql-name))\r
     (awhen (slot-value cl name)\r
           (setf (slot-value cl name)\r
-                (etypecase (slot-value cl name)\r
-                  (cons (car it))\r
-                  ((or string symbol) it)))))\r
+            (if (listp it)\r
+                (car it)\r
+              it))))\r
   \r
   (unless (sql-name cl)\r
     (setf (sql-name cl) (lisp-name-to-sql-name (class-name cl))))\r