215 lines
7.4 KiB
Plaintext
215 lines
7.4 KiB
Plaintext
{ (define LIBNAME "Simplified Scheme Web Servlets")
|
|
(include "head.tinc") }
|
|
|
|
<p>This teachpack provides a simplified API for PLT Scheme servlets. The
|
|
teachpack does not require any understanding of HTML and higher-order
|
|
functions. It uses structures and lists, and is therefore well-suited for
|
|
use with an HtDP course.
|
|
|
|
<hr>
|
|
<h3>Interface</h3>
|
|
|
|
<pre>
|
|
; Data Constructors -------------------------------------------------------
|
|
{(idx make-password)} ; asking for a password
|
|
{(idx make-number)} ; asking for a number
|
|
{(idx make-yes-no)} ; asking for a Yes-No style answer
|
|
{(idx make-boolean)} ; asking for a true-false style answer
|
|
{(idx make-radio)} ; requesting one choice from some mutually exclusive choices
|
|
|
|
#| Data Definitions --------------------------------------------------------
|
|
|
|
Forms ----------------------------------------------------------------------
|
|
Query = (union String
|
|
(make-password String)
|
|
(make-number String)
|
|
(make-boolean String)
|
|
(make-yes-no String String String)
|
|
(make-radio String (cons String (listof String))))
|
|
FormItem = (list Symbol Query)
|
|
Form = (cons FormItem (listof FormItem))
|
|
|
|
Table -------------------------------------------------------------------
|
|
Response = (union String Number Boolean)
|
|
Table = (listof (list Symbol Response))
|
|
|#
|
|
|
|
; Functions ----------------------------------------------------------------
|
|
|
|
{(idx form?)} ; TST -> Boolean
|
|
; checking the structure of forms
|
|
|
|
{(idx form-element?)} ; TST -> Boolean
|
|
; checking the structure of form-elements
|
|
|
|
{(idx single-query)} ; Query -> Response
|
|
; posing a single question
|
|
|
|
{(idx queries)} ; (listof Query) -> (listof Response)
|
|
; posing a list of questions
|
|
|
|
{(idx echo-answers)} ; (listof Response) -> true
|
|
; echoing the answers from a list of questions to a Web page (development)
|
|
|
|
{(idx form-query)} ; Form -> Table
|
|
; posing a list of questions with tag
|
|
|
|
{(idx extract/single)} ; Symbol Table -> Response
|
|
; extracting the answer for a given tag from a response; the tag must
|
|
; occur exactly once.
|
|
|
|
{(idx extract)} ; Symbol Table -> (listof Response)
|
|
; extracting all the answers for a given tag from a response; the list
|
|
; is empty if there is no such tag.
|
|
|
|
{(idx echo-response)} ; Table -> true
|
|
; echoing the response from a form to a Web page (development)
|
|
|
|
{(idx inform)} ; String String *-> true
|
|
; posting some information on a Web page, wait for continue signal
|
|
|
|
{(idx final-page)} ; String String *-> true
|
|
; posting some information on a Web page,
|
|
; killing the script and all associated backtrack/clone points
|
|
|
|
</pre>
|
|
<hr>
|
|
<h3>Pragmatics</h3>
|
|
|
|
<p>The following table specifies what kind of answer each form of query
|
|
produces:
|
|
|
|
<pre>
|
|
Query GUI Item Response
|
|
________________________________________________________________________________
|
|
String text field String
|
|
(make-password String) password field String
|
|
(make-number String) text field Number
|
|
(make-boolean String) check box Boolean
|
|
(make-yes-no String String1 String2) 2-pronged radio String1 or String2
|
|
(make-radio String loString) radio button one of loString
|
|
(make-button String0) submit button String0
|
|
</pre>
|
|
|
|
<p>The functions play the following role:
|
|
<ul>
|
|
<li>
|
|
<code>form?</code> and <code>form-element?</code> enable programmers to
|
|
check the well-formedness of their queries.
|
|
|
|
<li>
|
|
<code>single-query</code> poses a question and waits for a answer from
|
|
the consumer.
|
|
|
|
<li>
|
|
<code>queries</code> poses a list of questions and waits for the
|
|
submission of answers; it produces a list of answers that is as
|
|
long as the list of given questions.
|
|
|
|
<li>
|
|
<code>echo-answers</code> echoes a list of answers to a Web page; this
|
|
function is useful for testing Web form designs.
|
|
|
|
<li>
|
|
<code>form-query</code> poses a form with queries and waits for the
|
|
submission of answers; it produces a list of tagged or labeled answers
|
|
that is as long as the list of given questions.
|
|
|
|
<li>
|
|
<code>echo-response</code> echoes a response to a Web page as a table.
|
|
|
|
<li>
|
|
<code>inform</code> posts some information on a Web page and wait for a
|
|
continue signal (a link) from the consumer; the first string plays the
|
|
role of a title and the rest form a paragraph.
|
|
|
|
<li>
|
|
<code>final-page</code> posts some information on a Web page and
|
|
shuts down the script and all associated backtrack/clone points.
|
|
</ul>
|
|
|
|
|
|
<h3>Example</h3>
|
|
|
|
<p>The following example illustrates how the library enables programs to
|
|
interact with the consumer. In particular, note the properly recursive
|
|
calls to <code>login</code> in <code>inform-error</code>. Also note how the
|
|
primitives <code>make-password</code> and <code>make-number</code> deliver
|
|
strings and numbers, respectively.
|
|
|
|
<pre>
|
|
#| Login Site -----------------------------------------------------------------
|
|
Author: Matthias Felleisen
|
|
Language: Intermediate
|
|
Teachpack: servlet2.ss
|
|
|
|
Login Web Site:
|
|
|
|
A login site consists of three pages:
|
|
1. login: request user information: name, password, year-of-birth
|
|
- if correct, respond with greeting for name
|
|
- if incorrect, go to error page
|
|
2. error: inform user of error, continue goes back to login page
|
|
3. greetings: say hello to name
|
|
The second and third are generated from user input, the first is
|
|
generated by the program alone.
|
|
|
|
|#
|
|
|
|
;; Login Page -----------------------------------------------------------------
|
|
|
|
; ask three questions: one plain, one password, one numeric
|
|
(define login-page
|
|
(list
|
|
(list 'name "User Name")
|
|
(list 'pass (make-password "Password"))
|
|
(list 'yofb (make-number "Year-of-birth"))))
|
|
|
|
; Table -> true
|
|
; process the response for login-page
|
|
(define (login r)
|
|
(let ([name (extract/single 'name r)])
|
|
(if (string=? (lookup-password name) (extract/single 'pass r))
|
|
(if (= (lookup-yofb name) (extract/single 'yofb r))
|
|
(greetings name)
|
|
(inform-error "bad data"))
|
|
(inform-error "bad match"))))
|
|
|
|
; String -> (union false String)
|
|
; lookup the password for name in DB
|
|
(define (lookup-password name)
|
|
(local ([define (x=? x) (string=? name x)]
|
|
[define r (assf x=? DB)])
|
|
(if (boolean? r) false (second r))))
|
|
|
|
; String -> (union false Number)
|
|
; lookup the year-of-birth for name in DB
|
|
(define (lookup-yofb name)
|
|
(local ([define (x=? x) (string=? name x)]
|
|
[define r (assf x=? DB)])
|
|
(if (boolean? r) false (third r))))
|
|
|
|
(define DB
|
|
'(("matthias" "okay" 1958)))
|
|
|
|
;; Error Page -----------------------------------------------------------------
|
|
|
|
; String -> true
|
|
; consume error message, print and enable return to login page
|
|
(define (inform-error s)
|
|
(let ([_ (inform "Error" s)])
|
|
(login (form-query login-page))))
|
|
|
|
;; Greetings Page -------------------------------------------------------------
|
|
|
|
; String -> true
|
|
; consume name and display good bye message
|
|
(define (greetings name)
|
|
(inform "Welcome" "Welcome " name " and good bye."))
|
|
|
|
;; RUN ------------------------------------------------------------------------
|
|
(login (form-query login-page))
|
|
</pre>
|
|
|
|
{(include "foot.tinc")}
|