[bknr-cvs] r2516 - branches/trunk-reorg/bknr/web/src/web

hhubner at common-lisp.net hhubner at common-lisp.net
Sat Feb 16 20:00:18 UTC 2008


Author: hhubner
Date: Sat Feb 16 15:00:17 2008
New Revision: 2516

Modified:
   branches/trunk-reorg/bknr/web/src/web/handlers.lisp
Log:
Docstrings


Modified: branches/trunk-reorg/bknr/web/src/web/handlers.lisp
==============================================================================
--- branches/trunk-reorg/bknr/web/src/web/handlers.lisp	(original)
+++ branches/trunk-reorg/bknr/web/src/web/handlers.lisp	Sat Feb 16 15:00:17 2008
@@ -66,7 +66,11 @@
     :import-spool-directory #p"/home/bknr/spool/"
     :template-base-directory nil
     :template-command-packages nil
-    :rss-feed-url nil))
+    :rss-feed-url nil)
+  (:documentation "Class to hold all information on a web server that
+is served within BKNR.  Currently, this is a singleton object, and
+*WEBSITE* will point to the only instance.  Eventually, multiple
+WEBSITE instances for virtual hosts may be supported."))
 
 (defmethod initialize-instance :after ((website website) &key &allow-other-keys)
   (when *website*
@@ -86,9 +90,20 @@
 (defmethod website-make-path ((website website) path)
   (format nil "~A~A" (website-base-href website) (relative path)))
 
-(defgeneric publish-handler (website handler))
-(defgeneric handler-matches (handler))
-(defgeneric publish-site (website))
+(defgeneric publish-handler (website handler)
+  (:documentation "Publish HANDLER on WEBSITE, thereby adding it to
+the chain of handlers that is searched to handle an incoming
+request."))
+
+(defgeneric handler-matches-p (handler)
+  (:documentation "Determine whether HANDLER is willing to handle the
+current request.  Returns non-NIL if the HANDLER wants to handle the request
+NIL otherwise."))
+
+(defgeneric publish-site (website)
+  (:documentation "Publish all handlers defined in WEBSITE.
+
+XXX When is this called?"))
 
 (defun handler-definition-name (handler-definition)
   (first handler-definition))
@@ -191,9 +206,21 @@
   (print-unreadable-object (handler stream :type t)
     (format stream "~A" (page-handler-prefix handler))))
 
-(defgeneric handle (page-handler))
-(defgeneric authorized-p (page-handler))
-(defgeneric page-handler-url (page-handler))
+(defgeneric handle (page-handler)
+  (:documentation "Handle an incoming HTTP request, returning either a
+string or an (array (unsigned-byte 8) (*)) with the response
+contents.  Alternatively, the handler may call (SEND-HEADERS) to
+get access to the response stream and output the data to it."))
+
+(defgeneric authorized-p (page-handler)
+  (:documentation "Return non-nil if the request is authorized to be
+executed on PAGE-HANDLER
+
+XXX wouldn't it be better if handler-matches-p checked
+authorization?"))
+
+(defgeneric page-handler-url (page-handler)
+  (:documentation "Return the full base URL for PAGE-HANDLER."))
 
 (defmethod handler-path ((handler page-handler))
   (subseq (script-name)
@@ -266,7 +293,7 @@
 
 (defun bknr-dispatch (request)
   (declare (ignore request))
-  (let ((handler (find-if #'handler-matches (website-handlers *website*))))
+  (let ((handler (find-if #'handler-matches-p (website-handlers *website*))))
     (cond
       (handler
        (start-session)
@@ -279,7 +306,7 @@
 (defmethod publish-handler ((website website) (handler page-handler))
   (setf *handlers* (append *handlers* (list handler))))
 
-(defmethod handler-matches ((handler page-handler))
+(defmethod handler-matches-p ((handler page-handler))
   (string-equal (page-handler-prefix handler)
 		(script-name)))
 
@@ -296,7 +323,10 @@
   (redirect (random-elt (redirect-handler-to page-handler))))
 
 (defclass form-handler (page-handler)
-  ())
+  ()
+  (:documentation "A FORM-HANDLER is a handler that processes form
+submissions.  The handler generic function for FORM-HANDLER subclasses
+is called HANDLE-FORM."))
 
 (define-condition form-condition (condition)
   ((reason :initarg :reason
@@ -315,7 +345,12 @@
     (signal (make-condition 'form-field-missing-condition
 	     :field ',field-name))))
 
-(defgeneric handle-form (page-handler action))
+(defgeneric handle-form (page-handler action)
+  (:documentation "Handle form submission for PAGE-HANDLER.  The
+form variable \"action\" will be parsed into a keyword and passwd to
+the invocation of this generic function as ACTION.  Methods are meant
+to specialize on individual keywords to handle different actions that
+the form supports."))
 
 (defmethod handle ((page-handler form-handler))
   (let* ((form (query-param "action"))
@@ -323,7 +358,11 @@
     (handle-form page-handler form-keyword)))
 
 (defclass prefix-handler (page-handler)
-  ())
+  ()
+  (:documentation "A PREFIX-HANDLER is a handler that is invoked for
+URLs with a certain prefix, as determined by the :PREFIX
+initialization argument.  It is used as a mixin class and only
+provides for a HANDLER-MATCHES-P method."))
 
 #+(or)
 (defmethod initialize-instance :after ((handler prefix-handler) &key)
@@ -331,7 +370,7 @@
                          (1- (length (page-handler-prefix handler)))))
     (warn "prefix handler ~A does not have prefix ending with / - may match unexpectedly" handler)))
 
-(defmethod handler-matches ((handler prefix-handler))
+(defmethod handler-matches-p ((handler prefix-handler))
   (and (>= (length (script-name))
 	   (length (page-handler-prefix handler)))
        (string-equal (page-handler-prefix handler)
@@ -340,20 +379,26 @@
 
 (defclass directory-handler (prefix-handler)
   ((destination :initarg :destination
-		:reader page-handler-destination)))
+		:reader page-handler-destination))
+  (:documentation
+   "Handler for a directory in the file system.  Publishes all files
+in the directory DESTINATION under their relative path name."))
+
+(defgeneric request-relative-pathname (directory-handler)
+  (:documentation "Return the relative pathname for the current
+request as determined by DIRECTORY-HANDLER.")
+  (:method ((handler directory-handler))
+    (or (aux-request-value 'request-relative-pathname)
+        (setf (aux-request-value 'request-relative-pathname)
+              (pathname (subseq (script-name) (1+ (length (page-handler-prefix handler)))))))))
 
-(defmethod request-pathname ((handler directory-handler))
-  (or (aux-request-value 'request-pathname)
-      (setf (aux-request-value 'request-pathname)
-	    (subseq (script-name) (1+ (length (page-handler-prefix handler)))))))
-
-(defmethod handler-matches ((handler directory-handler))
+(defmethod handler-matches-p ((handler directory-handler))
   (and (call-next-method)
-       (probe-file (merge-pathnames (request-pathname handler)
+       (probe-file (merge-pathnames (request-relative-pathname handler)
 				    (page-handler-destination handler)))))
 
 (defmethod handle ((handler directory-handler))
-  (handle-static-file (merge-pathnames (request-pathname handler)
+  (handle-static-file (merge-pathnames (request-relative-pathname handler)
 				       (page-handler-destination handler))))
 
 (defclass file-handler (page-handler)
@@ -361,34 +406,64 @@
 		:reader page-handler-destination)
    (content-type :initarg :content-type
 		 :reader page-handler-content-type))
-  (:default-initargs :content-type "text/plain"))
+  (:default-initargs :content-type "text/plain")
+  (:documentation "A FILE-HANDLER is used to publish a single file
+under an URL.  :DESTINATION is the pathname of the file to publish,
+:CONTENT-TYPE is the content type to use."))
 
 (defmethod handle ((handler file-handler))
-  (handle-static-file (page-handler-destination handler)))
+  (handle-static-file (page-handler-destination handler) (page-handler-content-type handler)))
 
 (defclass object-handler (prefix-handler)
   ((query-function :initarg :query-function :reader object-handler-query-function)
    (object-class :initarg :object-class :reader object-handler-object-class))
-  (:default-initargs :object-class t :query-function nil))
-
-(defgeneric object-handler-get-object (object-handler))
-(defgeneric handle-object (object-handler object))
-
-(defmethod object-handler-get-object ((handler object-handler))
-  (let ((id (parse-url)))
-    (when id
-      (find-store-object id
-			 :class (object-handler-object-class handler)
-			 :query-function (object-handler-query-function handler)))))
+  (:default-initargs :object-class t :query-function nil)
+  (:documentation "An OBJECT-HANDLER handles requests for a persistent
+object in the BKNR datastore.  The first component of the relative
+path of the request is used as the key to locate the object.  The
+object is looked up using the OBJECT-HANDLER-GET-OBJECT generic
+function, which will, by default, call FIND-STORE-OBJECT with the key
+as argument.
+
+The :QUERY-FUNCTION initarg may be supplied to set up a query function
+that maps from the key to an object.  It is typically used to
+implement lookup by name.
+
+The :OBJECT-CLASS initarg may be supplied to restrict the handler to
+operate on objects of that class or its subclass.  If the key
+specifies the ID of an object that has a different class or if the
+QUERY-FUNCTION returns an object of a different class, a run-time
+error is signaled."))
+
+(defgeneric object-handler-get-object (object-handler)
+  (:documentation "Implement object lookup.  Methods return the object
+that the current request should operate upon.  The default method for
+the OBJECT handler class performs a lookup using FIND-STORE-OBJECT.")
+  (:method ((handler object-handler))
+    (let ((id (parse-url)))
+      (when id
+        (find-store-object id
+                           :class (object-handler-object-class handler)
+                           :query-function (object-handler-query-function handler))))))
+
+(defgeneric handle-object (object-handler object)
+  (:documentation "Handle the current to the OBJECT-HANDLER.  OBJECT
+is the object as looked up by OBJECT-HANDLER-GET-OBJECT."))
 
 (defmethod handle ((handler object-handler))
   (let ((object (object-handler-get-object handler)))
     (handle-object handler object)))
 
 (defclass edit-object-handler (form-handler object-handler)
-  ())
-
-(defgeneric handle-object-form (handler action object))
+  ()
+  (:documentation "Combined FORM-HANDLER and OBJECT-HANDLER class that
+is used as a base class for handlers that edit an object using a HTML
+form."))
+
+(defgeneric handle-object-form (handler action object)
+  (:documentation "Perform ACTION, a keyword that has been determined by
+parsing the \"action\" input element of the current HTML form, on
+OBJECT, which is parsed using the mechanism of an OBJECT-HANDLER."))
 
 (defmethod handle-form ((handler edit-object-handler) action)
   (let ((object (object-handler-get-object handler)))



More information about the Bknr-cvs mailing list