X-Git-Url: http://git.kpe.io/?a=blobdiff_plain;f=hyperobject.lisp;h=2479712a0dd855e57cf1ca52067186f5c58f4bfe;hb=18558405db4d6d5ca2a47aac32fb13958430b189;hp=cedfa5e82452c1292e9c6daf9d07b2aace52db37;hpb=52b71f23b37b79d9f23bd1ab1d8b39e42c7c18d9;p=hyperobject.git diff --git a/hyperobject.lisp b/hyperobject.lisp index cedfa5e..2479712 100644 --- a/hyperobject.lisp +++ b/hyperobject.lisp @@ -11,7 +11,7 @@ ;;;; in Text, HTML, and XML formats. This includes hyperlinking ;;;; capability and sub-objects. ;;;; -;;;; $Id: hyperobject.lisp,v 1.9 2002/11/22 19:48:49 kevin Exp $ +;;;; $Id: hyperobject.lisp,v 1.13 2002/11/25 02:10:38 kevin Exp $ ;;;; ;;;; This file is Copyright (c) 2000-2002 by Kevin M. Rosenberg ;;;; @@ -22,69 +22,74 @@ (eval-when (:compile-toplevel :execute) (declaim (optimize (speed 3) (safety 1) (compilation-speed 0) (debug 3)))) +(eval-when (:compile-toplevel :load-toplevel :execute) + (shadowing-import + #+allegro + `(mop::class-slots mop::slot-definition-name mop:finalize-inheritance + mop::standard-direct-slot-definition mop::standard-effective-slot-definition + mop:direct-slot-definition-class mop:compute-effective-slot-definition + excl::compute-effective-slot-definition-initargs) + #+lispworks + `(clos:class-slots clos::slot-definition-name clos:finalize-inheritance + clos::standard-direct-slot-definition clos::standard-effective-slot-definition + clos:direct-slot-definition-class clos:compute-effective-slot-definition + clos::compute-effective-slot-definition-initargs) + #+sbcl + `(sb-pcl:class-of sb-pcl:class-name sb-pcl:class-slots sb-pcl::standard-class + sb-pcl::slot-definition-name sb-pcl:finalize-inheritance + sb-pcl::standard-direct-slot-definition + sb-pcl::standard-effective-slot-definition sb-pcl::validate-superclass + sb-pcl:direct-slot-definition-class sb-pcl:compute-effective-slot-definition + sb-pcl::compute-effective-slot-definition-initargs) + #+cmu + `(pcl:class-of pcl:class-name pcl:class-slots pcl::standard-class + pcl::slot-definition-name pcl:finalize-inheritance + pcl::standard-direct-slot-definition pcl::standard-effective-slot-definition + pcl::validate-superclass pcl:direct-slot-definition-class + pcl:compute-effective-slot-definition + pcl::compute-effective-slot-definition-initargs) + + :hyperobject)) -(shadowing-import - #+allegro - `(mop::class-slots mop::slot-definition-name mop:finalize-inheritance - mop::standard-direct-slot-definition mop::standard-effective-slot-definition - mop:direct-slot-definition-class mop:compute-effective-slot-definition - excl::compute-effective-slot-definition-initargs) - #+lispworks - `(clos:class-slots clos::slot-definition-name clos:finalize-inheritance - clos::standard-direct-slot-definition clos::standard-effective-slot-definition - clos:direct-slot-definition-class clos:compute-effective-slot-definition - clos::compute-effective-slot-definition-initargs) - #+sbcl - `(sb-pcl:class-of sb-pcl:class-name sb-pcl:class-slots sb-pcl::standard-class - sb-pcl::slot-definition-name sb-pcl:finalize-inheritance - sb-pcl::standard-direct-slot-definition - sb-pcl::standard-effective-slot-definition sb-pcl::validate-superclass - sb-pcl:direct-slot-definition-class sb-pcl:compute-effective-slot-definition - sb-pcl::compute-effective-slot-definition-initargs) -#+(or cmu scl) -`(pcl:class-of pcl:class-name pcl:class-slots pcl::standard-class - pcl::slot-definition-name pcl:finalize-inheritance - pcl::standard-direct-slot-definition pcl::standard-effective-slot-definition - pcl::validate-superclass pcl:direct-slot-definition-class - pcl:compute-effective-slot-definition - pcl::compute-effective-slot-definition-initargs) - :hyperobject) ;; Slot definitions (defclass hyperobject-dsd (standard-direct-slot-definition) - ((ho-type :initarg :ho-type :initform nil :accessor dsd-ho-type) - (format-func :initarg :format-func :initform nil :accessor dsd-format-func) - (subobject :initarg :subobject :initform nil :accessor dsd-subobject) - (reference :initarg :reference :initform nil :accessor dsd-reference) + ((ho-type :initarg :ho-type :initform nil) + (print-formatter :initarg :print-formatter :initform nil) + (subobject :initarg :subobject :initform nil) + (reference :initarg :reference :initform nil) + (description :initarg :description :initform nil) )) (defclass hyperobject-esd (standard-effective-slot-definition) ((ho-type :initarg :ho-type :initform nil :accessor esd-ho-type) - (format-func :initarg :format-func :initform nil :accessor esd-format-func) + (print-formatter :initarg :print-formatter :initform nil :accessor esd-print-formatter) (subobject :initarg :subobject :initform nil :accessor esd-subobject) (reference :initarg :reference :initform nil :accessor esd-reference) + (description :initarg :description :initform nil :accessor esd-description) )) ;; Main class (defclass hyperobject-class (standard-class) - ((title :initarg :title :type string :initform nil + ( ;; slots initialized in defclass + (title :initarg :title :type string :initform nil :documentation "Print Title for class") (print-slots :initarg :print-slots :type list :initform nil - :documentation "List of slots to print") - (subobjects - :initarg :subobjects :initform nil - :documentation "List of fields that contain a list of subobjects objects.") - (references - :initarg :references :type list :initform nil - :documentation - "List of fields that can be referred to by browsers. -Format is ((field-name field-lookup-func other-link-params) ...)") - + :documentation "List of slots to print") + (description :initarg :description :initform nil + :documentation "Class description") + ;;; The remainder of these fields are calculated one time ;;; in finalize-inheritence. + + (subobjects :initform nil :documentation + "List of fields that contain a list of subobjects objects.") + (references :type list :initform nil :documentation + "List of fields that have references") + (value-func :initform nil :type function) (xmlvalue-func :initform nil :type function) (fmtstr-text :initform nil :type string) @@ -127,44 +132,45 @@ Format is ((field-name field-lookup-func other-link-params) ...)") ;; Slot definitions (defmethod direct-slot-definition-class ((cl hyperobject-class) - &rest iargs) + #+allegro &rest + iargs) (find-class 'hyperobject-dsd)) +(defmacro define-class-slot (slot-name &optional required) + #+lispworks + `(defmethod clos:process-a-class-option ((class hyperobject-class) + (name (eql ,slot-name)) + value) + (when (and ,required (null value)) + (error "hyperobject class slot ~A must have a value" name)) + (if (null (cdr value)) + (list name (car value)) + (list name `',value))) + #+(or allegro sbcl cmu scl) + (declare (ignore slot-name required)) + ) +(define-class-slot :title) +(define-class-slot :print-slots) +(define-class-slot :description) -#+lispworks -(defmethod clos:process-a-class-option ((class hyperobject-class) - (name (eql :title)) - value) - (unless value - (error "hyperobject-class title must have a value")) - (if (null (cdr value)) - (list name (car value)) - (list name `',value))) - -#+lispworks -(defmethod clos:process-a-class-option ((class hyperobject-class) - (name (eql :print-slots)) - value) - (if (null (cdr value)) - (list name (car value)) - (list name `',value))) (defmethod compute-effective-slot-definition :around - ((cl hyperobject-class) #+(or allegro lispworks) slot dsds) - (declare (ignorable slot)) + ((cl hyperobject-class) #+(or allegro lispworks) name dsds) + #+allergo (declare (ignore name)) (let* ((dsd (car dsds)) (ho-type (slot-value dsd 'type))) (setf (slot-value dsd 'ho-type) ho-type) (setf (slot-value dsd 'type) (convert-ho-type ho-type)) (let ((ia (compute-effective-slot-definition-initargs - cl #+lispworks slot dsds))) + cl #+lispworks name dsds))) (apply #'make-instance 'hyperobject-esd :ho-type ho-type - :format-func (slot-value dsd 'format-func) + :print-formatter (slot-value dsd 'print-formatter) :subobject (slot-value dsd 'subobject) :reference (slot-value dsd 'reference) + :description (slot-value dsd 'description) ia))) ) @@ -190,75 +196,98 @@ Format is ((field-name field-lookup-func other-link-params) ...)") (defun find-slot-by-name (cl name) (find name (class-slots cl) :key #'slot-definition-name)) - -(defun init-hyperobject-class (cl) - (let ((fmtstr-text "") - (fmtstr-html "") - (fmtstr-xml "") - (fmtstr-text-labels "") - (fmtstr-html-labels "") - (fmtstr-xml-labels "") - (fmtstr-html-ref "") - (fmtstr-xml-ref "") - (fmtstr-html-ref-labels "") - (fmtstr-xml-ref-labels "") - (first-field t) - (value-func '()) - (xmlvalue-func '()) - (classname (class-name cl)) - (package (symbol-package (class-name cl))) - (references nil) - (subobjects nil)) - (declare (ignore classname)) + + +(defun process-subobjects (cl) + "Process class subobjects slot" + (setf (slot-value cl 'subobjects) + (let ((subobjects '())) (dolist (slot (class-slots cl)) (when (slot-value slot 'subobject) (push (make-instance 'subobject :name (slot-definition-name slot) :reader (if (eq t (esd-subobject slot)) (slot-definition-name slot) - (esd-subobject slot))) + (esd-subobject slot))) subobjects))) - (setf (slot-value cl 'subobjects) subobjects) - (dolist (slot-name (slot-value cl 'print-slots)) - (let ((slot (find-slot-by-name cl slot-name))) - (unless slot - (error "Slot ~A is not found in class ~S" slot-name cl)) - (let ((name (slot-definition-name slot)) - (namestr (symbol-name (slot-definition-name slot))) - (namestr-lower (string-downcase (symbol-name (slot-definition-name slot)))) - (type (slot-value slot 'ho-type)) - (formatter (slot-value slot 'format-func)) - (value-fmt "~a") - (plain-value-func nil) - html-str xml-str html-label-str xml-label-str) - - (when (or (eql type :integer) (eql type :fixnum)) - (setq value-fmt "~d")) - - (when (eql type :commainteger) - (setq value-fmt "~:d")) - - (when (eql type :boolean) - (setq value-fmt "~a")) - - (if first-field - (setq first-field nil) - (progn - (string-append fmtstr-text " ") - (string-append fmtstr-html " ") - (string-append fmtstr-xml " ") - (string-append fmtstr-text-labels " ") - (string-append fmtstr-html-labels " ") - (string-append fmtstr-xml-labels " ") - (string-append fmtstr-html-ref " ") - (string-append fmtstr-xml-ref " ") - (string-append fmtstr-html-ref-labels " ") - (string-append fmtstr-xml-ref-labels " "))) - - (setq html-str (concatenate 'string "" value-fmt "")) - (setq xml-str (concatenate 'string "<" namestr-lower ">" value-fmt "")) - (setq html-label-str (concatenate 'string "" namestr-lower " " value-fmt "")) - (setq xml-label-str (concatenate 'string " <" namestr-lower ">" value-fmt "")) - + subobjects))) + +(defun process-documentation (cl) + "Calculate class documentation slot" + (awhen (slot-value cl 'title) + (setf (slot-value cl 'title) (car it))) + (awhen (slot-value cl 'description) + (setf (slot-value cl 'description) (car it))) + + (let ((*print-circle* nil)) + (setf (documentation (class-name cl) 'class) + (format nil "Hyperobject~A~A~A~A" + (aif (slot-value cl 'title) + (format nil ": ~A" it "")) + (aif (slot-value cl 'description) + (format nil "~%Class description: ~A" it) "") + (aif (slot-value cl 'subobjects) + (format nil "~%Subobjects:~{ ~A~}" (mapcar #'name it)) "") + (aif (slot-value cl 'print-slots) + (format nil "~%Print-slots:~{ ~A~}" it) "") + )))) + +(defun process-views (cl) + "Calculate all view slots for a hyperobject class" + (let ((fmtstr-text "") + (fmtstr-html "") + (fmtstr-xml "") + (fmtstr-text-labels "") + (fmtstr-html-labels "") + (fmtstr-xml-labels "") + (fmtstr-html-ref "") + (fmtstr-xml-ref "") + (fmtstr-html-ref-labels "") + (fmtstr-xml-ref-labels "") + (first-field t) + (value-func '()) + (xmlvalue-func '()) + (classname (class-name cl)) + (package (symbol-package (class-name cl))) + (references nil)) + (declare (ignore classname)) + (dolist (slot-name (slot-value cl 'print-slots)) + (let ((slot (find-slot-by-name cl slot-name))) + (unless slot + (error "Slot ~A is not found in class ~S" slot-name cl)) + (let ((name (slot-definition-name slot)) + (namestr (symbol-name (slot-definition-name slot))) + (namestr-lower (string-downcase (symbol-name (slot-definition-name slot)))) + (type (slot-value slot 'ho-type)) + (print-formatter (slot-value slot 'print-formatter)) + (value-fmt "~a") + (plain-value-func nil) + html-str xml-str html-label-str xml-label-str) + + (when (or (eql type :integer) (eql type :fixnum)) + (setq value-fmt "~d")) + + (when (eql type :boolean) + (setq value-fmt "~a")) + + (if first-field + (setq first-field nil) + (progn + (string-append fmtstr-text " ") + (string-append fmtstr-html " ") + (string-append fmtstr-xml " ") + (string-append fmtstr-text-labels " ") + (string-append fmtstr-html-labels " ") + (string-append fmtstr-xml-labels " ") + (string-append fmtstr-html-ref " ") + (string-append fmtstr-xml-ref " ") + (string-append fmtstr-html-ref-labels " ") + (string-append fmtstr-xml-ref-labels " "))) + + (setq html-str (concatenate 'string "" value-fmt "")) + (setq xml-str (concatenate 'string "<" namestr-lower ">" value-fmt "")) + (setq html-label-str (concatenate 'string "" namestr-lower " " value-fmt "")) + (setq xml-label-str (concatenate 'string " <" namestr-lower ">" value-fmt "")) + (string-append fmtstr-text value-fmt) (string-append fmtstr-html html-str) (string-append fmtstr-xml xml-str) @@ -280,9 +309,9 @@ Format is ((field-name field-lookup-func other-link-params) ...)") (string-append fmtstr-html-ref-labels html-label-str) (string-append fmtstr-xml-ref-labels xml-label-str))) - (if formatter + (if print-formatter (setq plain-value-func - (list `(,formatter (,(intern namestr package) x)))) + (list `(,print-formatter (,(intern namestr package) x)))) (setq plain-value-func (list `(,(intern namestr package) x)))) (setq value-func (append value-func plain-value-func)) @@ -291,33 +320,38 @@ Format is ((field-name field-lookup-func other-link-params) ...)") (setq xmlvalue-func (append xmlvalue-func (list `(xml-cdata ,@plain-value-func)))) (setq xmlvalue-func (append xmlvalue-func plain-value-func))) ))) - - (setf (slot-value cl 'references) references) - - (if value-func - (setq value-func `(lambda (x) (values ,@value-func))) + + (setf (slot-value cl 'references) references) + + (if value-func + (setq value-func `(lambda (x) (values ,@value-func))) (setq value-func `(lambda () (values)))) - (setq value-func (compile nil (eval value-func))) - - (if xmlvalue-func - (setq xmlvalue-func `(lambda (x) (values ,@xmlvalue-func))) + (setq value-func (compile nil (eval value-func))) + + (if xmlvalue-func + (setq xmlvalue-func `(lambda (x) (values ,@xmlvalue-func))) (setq xmlvalue-func `(lambda () (values)))) - (setq xmlvalue-func (compile nil (eval xmlvalue-func))) - - (setf (slot-value cl 'fmtstr-text) fmtstr-text) - (setf (slot-value cl 'fmtstr-html) fmtstr-html) - (setf (slot-value cl 'fmtstr-xml) fmtstr-xml) - (setf (slot-value cl 'fmtstr-text-labels) fmtstr-text-labels) - (setf (slot-value cl 'fmtstr-html-labels) fmtstr-html-labels) - (setf (slot-value cl 'fmtstr-xml-labels) fmtstr-xml-labels) - (setf (slot-value cl 'fmtstr-html-ref) fmtstr-html-ref) - (setf (slot-value cl 'fmtstr-xml-ref) fmtstr-xml-ref) - (setf (slot-value cl 'fmtstr-html-ref-labels) fmtstr-html-ref-labels) - (setf (slot-value cl 'fmtstr-xml-ref-labels) fmtstr-xml-ref-labels) - (setf (slot-value cl 'value-func) value-func) - (setf (slot-value cl 'xmlvalue-func) xmlvalue-func)) - (values)) + (setq xmlvalue-func (compile nil (eval xmlvalue-func))) + + (setf (slot-value cl 'fmtstr-text) fmtstr-text) + (setf (slot-value cl 'fmtstr-html) fmtstr-html) + (setf (slot-value cl 'fmtstr-xml) fmtstr-xml) + (setf (slot-value cl 'fmtstr-text-labels) fmtstr-text-labels) + (setf (slot-value cl 'fmtstr-html-labels) fmtstr-html-labels) + (setf (slot-value cl 'fmtstr-xml-labels) fmtstr-xml-labels) + (setf (slot-value cl 'fmtstr-html-ref) fmtstr-html-ref) + (setf (slot-value cl 'fmtstr-xml-ref) fmtstr-xml-ref) + (setf (slot-value cl 'fmtstr-html-ref-labels) fmtstr-html-ref-labels) + (setf (slot-value cl 'fmtstr-xml-ref-labels) fmtstr-xml-ref-labels) + (setf (slot-value cl 'value-func) value-func) + (setf (slot-value cl 'xmlvalue-func) xmlvalue-func)) + (values)) +(defun init-hyperobject-class (cl) + "Initialize a hyperobject class. Calculates all class slots" + (process-subobjects cl) + (process-views cl) + (process-documentation cl)) (defun hyperobject-class-fmtstr-text (obj) (slot-value (class-of obj) 'fmtstr-text)) @@ -804,17 +838,3 @@ Format is ((field-name field-lookup-func other-link-params) ...)") (fmt-file-end fmt os))) objs) - -(defclass hyperobject () - () - (:metaclass hyperobject-class)) - - -(defmethod print-object ((obj hyperobject) (s stream)) - (print-unreadable-object (obj s :type t :identity t) - (let ((fmt (make-instance 'hyperobject::textformat))) - (apply #'format - s (funcall (obj-data-fmtstr fmt) obj) - (multiple-value-list - (funcall (funcall (obj-data-value-func fmt) obj) obj)))))) -