ovidiu 02/02/12 17:51:20 Modified: src/scratchpad/schecoon/scheme sitemap.scm Log: Add support for defining external flow script files to be included in the sitemap. Revision Changes Path 1.10 +121 -52 xml-cocoon2/src/scratchpad/schecoon/scheme/sitemap.scm Index: sitemap.scm =================================================================== RCS file: /home/cvs/xml-cocoon2/src/scratchpad/schecoon/scheme/sitemap.scm,v retrieving revision 1.9 retrieving revision 1.10 diff -u -r1.9 -r1.10 --- sitemap.scm 9 Feb 2002 00:19:13 -0000 1.9 +++ sitemap.scm 13 Feb 2002 01:51:20 -0000 1.10 @@ -7,6 +7,7 @@ (load-module "sisc.modules.Regexp") (load-module "sisc.modules.J2S") (load-module "org.apache.cocoon.scheme.sitemap.SchemeSitemapFunctions") +(load-module "org.apache.cocoon.scheme.sitemap.SchemeEnvironmentFunctions") (load-module "org.apache.cocoon.scheme.sitemap.ContinuationsManager") ;; A Cocoon XML sitemap description is processed by the Scheme code in @@ -125,6 +126,9 @@ ((symbol? name) (name->resource (symbol->string name))) (else #f))) +;; The global scope. +(define top-level (interaction-environment)) + ;; The main function to process an SXML representation of the sitemap, ;; and generate a function which is the executable version of the ;; sitemap. @@ -137,7 +141,7 @@ ;; The side effect of executing this returned function is the ;; processing of the input HTTP request as defined by the sitemap. ;; -(define (process-sitemap sitemap) +(define (process-sitemap sitemap xsxml) (let ((exit #f) ;; Regular expressions for matching various types of arguments (res-arg-regexp (regexp "/({[^0-9].*})/")) @@ -516,8 +520,40 @@ (match-match pipeline #t))) ))) - ;; This function is called by the `apply-templates' function below - ;; to process SXML nodes corresponding to <map:resource>. + ;; This function is called to process <map:script> elements + ;; embedded inside <map:resource> elements that have a type="flow" + ;; attribute. + ;; + ;; As opposed to the rest of the process- functions, this function + ;; doesn't generate any code. Instead it has the side-effect of + ;; reading, and possibly translating the script file, into the + ;; running Scheme engine. + (define (process-script node) + (let ((resource (sxml:attr node 'src)) + (lang (or (sxml:attr node 'language) "scheme"))) + (if (not resource) + (xml-error node "required 'src' attribute for <script> is not present")) + (cond ((string-ci=? lang "scheme") + (call-with-failure-continuation + (lambda () + (let* ((content (sitemap:read-resource sitemap resource)) + (port (open-input-string content))) + (let loop () + (let ((form (read port))) + (if (not (eof-object? form)) + (begin + (eval form (interaction-environment)) + (loop))))))) + (lambda (message error-continuation parent-fk) + (xml-error + node + (format "Error parsing ~s: ~s~%" resource message))))) + + (else + (xml-error node "unknown script language '~s'~%" lang))) + )) + + ;; Handle pipeline definitions defined using <map:resource name="..."> ;; ;; For each named resource we create a function whose name is ;; r_<resource-name>, which contains the definition of the @@ -543,52 +579,82 @@ ;; `function' macro, instead of the normal Scheme `define'. This ;; allows for named parameters to be passed to the function at ;; runtime. + (define (define-pipeline node) + (let* ((resname (sxml:attr node 'name)) + (funname (name->resource resname)) + ;; Check to see if a similar resource has already + ;; been defined. + (_ (if (lookup-resource funname) + (xml-error node "A resource named ~s already defined" + funname))) + (attributes (map (lambda (x) (cadr x)) + ((sxpath '(// @ (*))) node))) + (source-arguments + (filter (lambda (x) + (if (and (string? x) + (regexp-match res-arg-regexp-match x)) + x + #f)) + attributes)) + ;; `source-arguments' contains all the attributes + ;; that contain named parameters. We need to + ;; extract the names from within curly braces + (arguments + (flatten + (map + (lambda (x) + (let* ((v (regexp-split/delimiter arg-regexp-split x)) + (len (vector-length v))) + (let loop ((i 1) (acc '())) + (if (>= i len) + acc + (loop (+ i 2) (cons (vector-ref v i) acc)))) + )) + source-arguments))) + (argument-symbols + (map (lambda (x) (string->symbol x)) arguments)) + (funsig `(,funname ,@argument-symbols)) + (funbody + `(function (,funname sitemap env ,@argument-symbols) + ,(generate-function-body + (reverse (sxml:child-elements node)) #f)))) + (add-resource funsig funbody) + (pretty-print funbody) (newline) + (eval funbody (interaction-environment)) + )) + + + ;; This function is called by the `apply-templates' function below + ;; to process SXML nodes corresponding to <map:resource>. + ;; + ;; Resources can be either pipeline definitions or flow scripts + ;; references. This function calls the appropriate function that + ;; does the work for each case. (define (process-resource node) - (let ((resname (sxml:attr node 'name))) - (if (not resname) - (xml-error node "Resource must be named, use a 'name' attribute") - (let* ((funname (name->resource resname)) - ;; Check to see if a similar resource has already - ;; been defined. - (_ (if (lookup-resource funname) - (xml-error node "A resource named ~s already defined" - funname))) - (attributes (map (lambda (x) (cadr x)) - ((sxpath '(// @ (*))) node))) - (source-arguments - (filter (lambda (x) - (if (and (string? x) - (regexp-match res-arg-regexp-match x)) - x - #f)) - attributes)) - ;; `source-arguments' contains all the attributes - ;; that contain named parameters. We need to - ;; extract the names from within curly braces - (arguments - (flatten - (map - (lambda (x) - (let* ((v (regexp-split/delimiter arg-regexp-split x)) - (len (vector-length v))) - (let loop ((i 1) (acc '())) - (if (>= i len) - acc - (loop (+ i 2) (cons (vector-ref v i) acc)))) - )) - source-arguments))) - (argument-symbols - (map (lambda (x) (string->symbol x)) arguments)) - (funsig `(,funname ,@argument-symbols)) - (funbody - `(function (,funname sitemap env ,@argument-symbols) - ,(generate-function-body - (reverse (sxml:child-elements node)) #f)))) - (add-resource funsig funbody) - (pretty-print funbody) (newline) - (eval funbody (interaction-environment)) - )))) + (cond ((sxml:attr node 'name) + ;; + ;; A named pipeline definition + ;; + (define-pipeline node)) + + ((equal? (sxml:attr node 'type) "flow") + ;; + ;; Flow script definitions. Include all the flow scripts + ;; defined using <map:script>. + ;; + (apply-templates + node + `((script . ,(lambda (node) (process-script node)))))) + + ;; + ;; Anything else is an error + ;; + (else + (xml-error node "Resource must define either a named pipeline, using the 'name' attribute, or flow scripts, using the 'type' attribute")) + )) + ;; This is the main of process-sitemap. + ;; ;; Process the SXML representation of the sitemap. This is done by ;; invoking the apply-templates function on the SXML representation ;; of the sitemap. @@ -601,7 +667,7 @@ (set! pcount 0) ;; Compute the available resources first. (apply-templates - sitemap + xsxml `((resources resource . ,(lambda (node) (process-resource node))))) ;; `matchers' will contain a list of (regexp . matcher-function) @@ -609,7 +675,7 @@ ;; represents the sitemap. (let* ((matchers (apply-templates - sitemap + xsxml `((pipelines pipeline match . ,(lambda (node) (process-match node)))))) (sitemap-code @@ -671,16 +737,19 @@ ;; SchemeSitemap#process method will invoke the main function, usually ;; defined as `main'. This will simply call the function stored in ;; `the-sitemap'. -(define (sitemap-parse! manager source) +(define (sitemap-parse! sitemap manager source) (let* ((sxml (sitemap:parse manager source)) - (xsxml (process-sitemap sxml))) + (xsxml (process-sitemap sitemap sxml))) (if (not (eq? xsxml 'error)) (set! the-sitemap xsxml)))) ;; This is the main entry point in the Scheme Cocoon sitemap. This ;; function is invoked from the SchemeSitemap#process method. (define (main url sitemap environment) - (the-sitemap url sitemap environment)) + (call/cc + (lambda (k) + (environ:set-attr environment "suicide" k) + (the-sitemap url sitemap environment)))) (define test-sitemap '(sitemap (@ (*line* 3))
---------------------------------------------------------------------- In case of troubles, e-mail: [EMAIL PROTECTED] To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]