[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