New
authorMike Taylor <mike@indexdata.com>
Thu, 2 Feb 2006 18:22:47 +0000 (18:22 +0000)
committerMike Taylor <mike@indexdata.com>
Thu, 2 Feb 2006 18:22:47 +0000 (18:22 +0000)
doc/.cvsignore [new file with mode: 0644]
doc/Makefile.am [new file with mode: 0644]
doc/tkl.xsl.in [new file with mode: 0644]
doc/xml.dcl [new file with mode: 0644]
doc/yp2.xml.in [new file with mode: 0644]
doc/yp2html.dsl.in [new file with mode: 0644]
doc/yp2php.dsl.in [new file with mode: 0644]
doc/yp2print.dsl.in [new file with mode: 0644]

diff --git a/doc/.cvsignore b/doc/.cvsignore
new file mode 100644 (file)
index 0000000..b430ac7
--- /dev/null
@@ -0,0 +1,17 @@
+Makefile
+Makefile.in
+zebra.xml
+zebra.tex
+zebra.out
+zebra.log
+zebra.aux
+zebra.pdf
+manpage.links
+manpage.refs
+tkl.xsl
+*.8
+*.1
+*.html
+*.tkl
+*.dsl
+*.php
diff --git a/doc/Makefile.am b/doc/Makefile.am
new file mode 100644 (file)
index 0000000..82bb4e9
--- /dev/null
@@ -0,0 +1,62 @@
+## $Id: Makefile.am,v 1.1 2006-02-02 18:22:47 mike Exp $
+docdir=$(datadir)/doc/@PACKAGE@
+
+SUPPORTFILES = \
+ yp2html.dsl \
+ yp2php.dsl \
+ yp2print.dsl \
+ tkl.xsl \
+ xml.dcl
+
+XMLFILES = yp2.xml.in
+
+HTMLFILES = yp2.html 
+
+
+
+PNGFILES=
+EPSFILES=
+
+REFFILES= 
+
+doc_DATA = $(HTMLFILES) yp2.pdf $(PNGFILES)
+man_MANS = $(MANFILES)
+
+EXTRA_DIST = $(XMLFILES) $(SUPPORTFILES) $(REFFILES) \
+       $(doc_DATA) $(EPSFILES) $(man_MANS) $(REFFILES)
+
+$(HTMLFILES): $(XMLFILES)
+       jade -E14 -D $(srcdir) -d yp2html.dsl -t sgml $(srcdir)/xml.dcl yp2.xml
+
+yp2.php: $(XMLFILES)
+       jade -E14 -D $(srcdir) -d yp2php.dsl -t sgml $(srcdir)/xml.dcl yp2.xml
+
+yp2.pdf: $(XMLFILES)
+       for i in $(PNGFILES); do \
+               if test ! -f $$i; then ln -s $(srcdir)/$$i .; fi; \
+       done
+       jade -E14 -D $(srcdir) -d yp2print.dsl -t tex $(srcdir)/xml.dcl yp2.xml
+       pdfjadetex yp2.tex >/dev/null
+       pdfjadetex yp2.tex >/dev/null
+       pdfjadetex yp2.tex >/dev/null
+
+index.tkl: $(XMLFILES) tkl.xsl
+       xsltproc tkl.xsl yp2.xml
+
+clean-data-hook:
+       rm -f [0-9]* *.bak
+
+dist-hook:
+       for f in $(srcdir)/*.html; do \
+               found=0; \
+               b=`basename $$f`; \
+               for h in $(HTMLFILES); do \
+                       if test "$$h" = "$$b"; then \
+                               found=1; \
+                       fi \
+               done; \
+               if test "$$found" = "0"; then \
+                       echo "$$f not found in HTMLFILES"; \
+                       exit 1; \
+               fi \
+       done
diff --git a/doc/tkl.xsl.in b/doc/tkl.xsl.in
new file mode 100644 (file)
index 0000000..9265a0f
--- /dev/null
@@ -0,0 +1,47 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+               version="1.0">
+
+  <xsl:include href="@XSL_DIR@/xhtml/chunk.xsl"/>
+
+  <xsl:variable name="use.id.as.filename">1</xsl:variable>
+  <xsl:variable name="html.ext">.tkl</xsl:variable>
+  <xsl:variable name="navig.showtitles">0</xsl:variable>
+  <xsl:param name="chunker.output.omit-xml-declaration" select="'yes'"/> 
+
+<xsl:template name="chunk-element-content">
+  <xsl:param name="prev"/>
+  <xsl:param name="next"/>
+
+  <xsl:element name="document">
+    <title>
+       <xsl:apply-templates select="." mode="object.title.markup"/>
+    </title>
+    <nonews>1</nonews>
+    <body>
+      <xsl:call-template name="body.attributes"/>
+      <xsl:call-template name="user.header.navigation"/>
+
+      <xsl:call-template name="header.navigation">
+        <xsl:with-param name="prev" select="$prev"/>
+        <xsl:with-param name="next" select="$next"/>
+      </xsl:call-template>
+
+      <xsl:call-template name="user.header.content"/>
+
+      <xsl:apply-imports/>
+
+      <xsl:call-template name="user.footer.content"/>
+
+      <xsl:call-template name="footer.navigation">
+        <xsl:with-param name="prev" select="$prev"/>
+        <xsl:with-param name="next" select="$next"/>
+      </xsl:call-template>
+
+      <xsl:call-template name="user.footer.navigation"/>
+    </body>
+  </xsl:element>
+</xsl:template>
+
+</xsl:stylesheet>
+
+
diff --git a/doc/xml.dcl b/doc/xml.dcl
new file mode 100644 (file)
index 0000000..fed2103
--- /dev/null
@@ -0,0 +1,179 @@
+<!SGML -- SGML Declaration for valid XML documents --
+     "ISO 8879:1986 (WWW)"
+
+     CHARSET
+         BASESET
+             "ISO Registration Number 176//CHARSET
+             ISO/IEC 10646-1:1993 UCS-4 with implementation 
+             level 3//ESC 2/5 2/15 4/6"
+         DESCSET
+                0       9       UNUSED
+                9       2       9
+                11      2       UNUSED
+                13      1       13
+                14      18      UNUSED
+                32      95      32
+                127     1       UNUSED
+                128     32      UNUSED
+             -- use this instead of the official declaration because SP only
+                supports 16-bit characters --
+                160     65374   160
+                65534   2       UNUSED 
+             -- 55296   2048    UNUSED
+                57344   8190    57344
+                65534   2       UNUSED
+                65536   1048576 65536 --
+     CAPACITY NONE
+
+     SCOPE DOCUMENT
+
+     SYNTAX
+         SHUNCHAR NONE
+         BASESET "ISO Registration Number 176//CHARSET
+                 ISO/IEC 10646-1:1993 UCS-4 with implementation 
+                 level 3//ESC 2/5 2/15 4/6"
+         DESCSET
+             0 1114112 0
+         FUNCTION
+             RE    13
+             RS    10
+             SPACE 32
+             TAB   SEPCHAR 9
+
+         NAMING
+             LCNMSTRT ""
+             UCNMSTRT ""
+             NAMESTRT
+                 58 95 192-214 216-246 248-305 308-318 321-328
+                 330-382 384-451 461-496 500-501 506-535 592-680
+                 699-705 902 904-906 908 910-929 931-974 976-982
+                 986 988 990 992 994-1011 1025-1036 1038-1103
+                 1105-1116 1118-1153 1168-1220 1223-1224
+                 1227-1228 1232-1259 1262-1269 1272-1273
+                 1329-1366 1369 1377-1414 1488-1514 1520-1522
+                 1569-1594 1601-1610 1649-1719 1722-1726
+                 1728-1742 1744-1747 1749 1765-1766 2309-2361
+                 2365 2392-2401 2437-2444 2447-2448 2451-2472
+                 2474-2480 2482 2486-2489 2524-2525 2527-2529
+                 2544-2545 2565-2570 2575-2576 2579-2600
+                 2602-2608 2610-2611 2613-2614 2616-2617
+                 2649-2652 2654 2674-2676 2693-2699 2701
+                 2703-2705 2707-2728 2730-2736 2738-2739
+                 2741-2745 2749 2784 2821-2828 2831-2832
+                 2835-2856 2858-2864 2866-2867 2870-2873 2877
+                 2908-2909 2911-2913 2949-2954 2958-2960
+                 2962-2965 2969-2970 2972 2974-2975 2979-2980
+                 2984-2986 2990-2997 2999-3001 3077-3084
+                 3086-3088 3090-3112 3114-3123 3125-3129
+                 3168-3169 3205-3212 3214-3216 3218-3240
+                 3242-3251 3253-3257 3294 3296-3297 3333-3340
+                 3342-3344 3346-3368 3370-3385 3424-3425
+                 3585-3630 3632 3634-3635 3648-3653 3713-3714
+                 3716 3719-3720 3722 3725 3732-3735 3737-3743
+                 3745-3747 3749 3751 3754-3755 3757-3758 3760
+                 3762-3763 3773 3776-3780 3904-3911 3913-3945
+                 4256-4293 4304-4342 4352 4354-4355 4357-4359
+                 4361 4363-4364 4366-4370 4412 4414 4416 4428
+                 4430 4432 4436-4437 4441 4447-4449 4451 4453
+                 4455 4457 4461-4462 4466-4467 4469 4510 4520
+                 4523 4526-4527 4535-4536 4538 4540-4546 4587
+                 4592 4601 7680-7835 7840-7929 7936-7957
+                 7960-7965 7968-8005 8008-8013 8016-8023 8025
+                 8027 8029 8031-8061 8064-8116 8118-8124 8126
+                 8130-8132 8134-8140 8144-8147 8150-8155
+                 8160-8172 8178-8180 8182-8188 8486 8490-8491
+                 8494 8576-8578 12295 12321-12329 12353-12436
+                 12449-12538 12549-12588 19968-40869 44032-55203
+
+             LCNMCHAR ""
+             UCNMCHAR ""
+             NAMECHAR
+                 45-46 183 720-721 768-837 864-865 903 1155-1158
+                 1425-1441 1443-1465 1467-1469 1471 1473-1474
+                 1476 1600 1611-1618 1632-1641 1648 1750-1764
+                 1767-1768 1770-1773 1776-1785 2305-2307 2364
+                 2366-2381 2385-2388 2402-2403 2406-2415
+                 2433-2435 2492 2494-2500 2503-2504 2507-2509
+                 2519 2530-2531 2534-2543 2562 2620 2622-2626
+                 2631-2632 2635-2637 2662-2673 2689-2691 2748
+                 2750-2757 2759-2761 2763-2765 2790-2799
+                 2817-2819 2876 2878-2883 2887-2888 2891-2893
+                 2902-2903 2918-2927 2946-2947 3006-3010
+                 3014-3016 3018-3021 3031 3047-3055 3073-3075
+                 3134-3140 3142-3144 3146-3149 3157-3158
+                 3174-3183 3202-3203 3262-3268 3270-3272
+                 3274-3277 3285-3286 3302-3311 3330-3331
+                 3390-3395 3398-3400 3402-3405 3415 3430-3439
+                 3633 3636-3642 3654-3662 3664-3673 3761
+                 3764-3769 3771-3772 3782 3784-3789 3792-3801
+                 3864-3865 3872-3881 3893 3895 3897 3902-3903
+                 3953-3972 3974-3979 3984-3989 3991 3993-4013
+                 4017-4023 4025 8400-8412 8417 12293 12330-12335
+                 12337-12341 12441-12442 12445-12446 12540-12542
+
+             NAMECASE
+                 GENERAL NO
+                 ENTITY  NO
+
+         DELIM
+             GENERAL SGMLREF
+             HCRO "&#38;#x" -- 38 is the number for ampersand --
+             NESTC "/"
+             NET ">"
+             PIC "?>"
+             SHORTREF NONE
+
+         NAMES
+             SGMLREF
+
+         QUANTITY NONE
+
+         ENTITIES
+             "amp" 38
+             "lt" 60
+             "gt" 62
+             "quot" 34
+             "apos" 39
+
+     FEATURES
+         MINIMIZE
+             DATATAG NO
+             OMITTAG NO
+             RANK NO
+             SHORTTAG
+                 STARTTAG
+                     EMPTY NO
+                     UNCLOSED NO 
+                     NETENABL IMMEDNET
+                 ENDTAG
+                     EMPTY NO 
+                     UNCLOSED NO
+                 ATTRIB
+                     DEFAULT YES
+                     OMITNAME NO
+                     VALUE NO
+             EMPTYNRM YES
+             IMPLYDEF
+                 ATTLIST NO
+                 DOCTYPE NO
+                 ELEMENT NO
+                 ENTITY NO
+                 NOTATION NO
+         LINK
+             SIMPLE NO
+             IMPLICIT NO
+             EXPLICIT NO
+         OTHER
+             CONCUR NO
+             SUBDOC NO
+             FORMAL NO
+             URN NO
+             KEEPRSRE YES
+             VALIDITY TYPE
+             ENTITIES
+                 REF ANY
+                 INTEGRAL YES
+     APPINFO NONE
+     SEEALSO "ISO 8879:1986//NOTATION
+             Extensible Markup Language (XML) 1.0//EN"
+>
diff --git a/doc/yp2.xml.in b/doc/yp2.xml.in
new file mode 100644 (file)
index 0000000..e23efe5
--- /dev/null
@@ -0,0 +1,788 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+                    "@DTD_DIR@/docbookx.dtd" [
+        <!ENTITY oslash "&#x00F8;"> <!-- CIRCLED DIVISION SLASH -->
+]>
+<!-- $Id: yp2.xml.in,v 1.1 2006-02-02 18:22:47 mike Exp $ -->
+<book id="yp2">
+ <bookinfo>
+  <title>YP2 - User's Guide and Reference</title>
+  <author>
+   <firstname>Mike</firstname><surname>Taylor</surname>
+  </author>
+  <copyright>
+   <year>2006</year>
+   <holder>Index Data</holder>
+  </copyright>
+  <abstract>
+   <simpara>
+    ###
+    YP2 is ... in need of description :-)
+   </simpara>
+  </abstract>
+ </bookinfo>
+
+
+ <chapter id="introduction">
+  <title>Introduction</title>
+
+
+  <section>
+   <title>Overview</title>
+   <para>
+    <ulink url="http://indexdata.dk/yp2/">YP2</ulink>
+    is extremely cool.
+   </para>
+   <para>
+    ### We should probably consider saying a little more by way of
+    introduction.
+   </para>
+  </section>
+ </chapter>
+
+
+
+ <chapter id="filters">
+  <title>Filters</title>
+
+
+  <section>
+   <title>Introductory notes</title>
+   <para>
+    It's useful to think of YP2 as an interpreter providing a small
+    number of primitives and operations, but operating on a very
+    complex data type, namely the ``package''.
+   </para>
+   <para>
+    A package represents a Z39.50 or SRW/U request (whether for Init,
+    Search, Scan, etc.)  together with information about where it came
+    from.  Packages are created by front-end filters such as
+    <literal>frontend_net</literal> (see below), which reads them from
+    the network; other front-end filters are possible.  They then pass
+    along a route consisting of a sequence of filters, each of which
+    transforms the package and may also have side-effects such as
+    generating logging.  Eventually, the route will yield a response,
+    which is sent back to the origin.
+   </para>
+   <para>
+    There are many kinds of filter: some that are defined statically
+    as part of YP2, and other that may be provided by third parties
+    and dynamically loaded.  They all conform to the same simple API
+    of essentially two methods: <function>configure()</function> is
+    called at startup time, and is passed a DOM tree representing that
+    part of the configuration file that pertains to this filter
+    instance: it is expected to walk that tree extracting relevant
+    information; and <function>process()</function> is called every
+    time the filter has to processes a package.
+   </para>
+   <para>
+    While all filters provide the same API, there are different modes
+    of functionality.  Some filters are sources: they create
+    packages
+    (<literal>frontend_net</literal>);
+    others are sinks: they consume packages and return a result
+    (<literal>z3950_client</literal>,
+    <literal>backend_test</literal>,
+    <literal>http_file</literal>);
+    the others are true filters, that read, process and pass on the
+    packages they are fed
+    (<literal>auth_simple</literal>,
+    <literal>log</literal>,
+    <literal>multi</literal>,
+    <literal>session_shared</literal>,
+    <literal>template</literal>,
+    <literal>virt_db</literal>).
+   </para>
+  </section>
+
+
+  <section>
+   <title>Individual filters</title>
+   <para>
+    The filters are here named by the string that is used as the
+    <literal>type</literal> attribute of a
+    <literal>&lt;filter&gt;</literal> element in the configuration
+    file to request them, with the name of the class that implements
+    them in parentheses.
+   </para>
+
+   <section>
+    <title><literal>auth_simple</literal>
+       (yp2::filter::AuthSimple)</title>
+    <para>
+     Simple authentication and authorisation.  The configuration
+     specifies the name of a file that is the user register, which
+     lists <varname>username</varname>:<varname>password</varname>
+     pairs, one per line, colon separated. When a session begins, it
+     is rejected unless username and passsword are supplied, and match
+     a pair in the register.
+    </para>
+    <para>
+     ### discuss authorisation phase
+    </para>
+   </section>
+
+   <section>
+    <title><literal>backend_test</literal>
+       (yp2::filter::Backend_test)</title>
+    <para>
+     A sink that provides dummy responses in the manner of the
+     <literal>yaz-ztest</literal> Z39.50 server.  This is useful only
+     for testing.
+    </para>
+   </section>
+
+   <section>
+    <title><literal>frontend_net</literal>
+       (yp2::filter::FrontendNet)</title>
+    <para>
+     A source that accepts Z39.50 and SRW connections from a port
+     specified in the configuration, reads protocol units, and
+     feeds them into the next filter, eventually returning the
+     result to the origin.
+    </para>
+   </section>
+
+   <section>
+    <title><literal>http_file</literal>
+       (yp2::filter::HttpFile)</title>
+    <para>
+     A sink that returns the contents of files from the local
+     filesystem in response to HTTP requests.  (Yes, Virginia, this
+     does mean that YP2 is also a Web-server in its spare time.  So
+     far it does not contain either an email-reader or a Lisp
+     interpreter, but that day is surely coming.)
+    </para>
+   </section>
+
+   <section>
+    <title><literal>log</literal>
+       (yp2::filter::Log)</title>
+    <para>
+     Writes logging information to standard output, and passes on
+     the package unchanged.
+    </para>
+   </section>
+
+   <section>
+    <title><literal>multi</literal>
+       (yp2::filter::Multi)</title>
+    <para>
+     Performs multicast searching.  See the extended discussion of
+     multi-database searching below.
+    </para>
+   </section>
+
+   <section>
+    <title><literal>session_shared</literal>
+       (yp2::filter::SessionShared)</title>
+    <para>
+     When this is finished, it will implement global sharing of
+     result sets (i.e. between threads and therefore between
+     clients), but it's not yet done.
+    </para>
+   </section>
+
+   <section>
+    <title><literal>template</literal>
+       (yp2::filter::Template)</title>
+    <para>
+     Does nothing at all, merely passing the packet on.  (Maybe it
+     should be called <literal>nop</literal> or
+     <literal>passthrough</literal>?)  This exists not to be used, but
+     to be copied - to become the skeleton of new filters as they are
+     written.
+    </para>
+   </section>
+
+   <section>
+    <title><literal>virt_db</literal>
+       (yp2::filter::Virt_db)</title>
+    <para>
+     Performs virtual database selection.  See the extended discussion
+     of virtual databases below.
+    </para>
+   </section>
+
+   <section>
+    <title><literal>z3950_client</literal>
+       (yp2::filter::Z3950Client)</title>
+    <para>
+     Performs Z39.50 searching and retrieval by proxying the
+     packages that are passed to it.  Init requests are sent to the
+     address specified in the <literal>VAL_PROXY</literal> otherInfo
+     attached to the request: this may have been specified by client,
+     or generated by a <literal>virt_db</literal> filter earlier in
+     the route.  Subsequent requests are sent to the same address,
+     which is remembered at Init time in a Session object.
+    </para>
+   </section>
+  </section>
+
+
+  <section>
+   <title>Future directions</title>
+   <para>
+    Some other filters that do not yet exist, but which would be
+    useful, are briefly described.  These may be added in future
+    releases.
+   </para>
+
+   <variablelist>
+    <varlistentry>
+     <term><literal>frontend_cli</literal> (source)</term>
+     <listitem>
+      <para>
+       Command-line interface for generating requests.
+      </para>
+     </listitem>
+    </varlistentry>
+    <varlistentry>
+     <term><literal>srw2z3950</literal> (filter)</term>
+     <listitem>
+      <para>
+       Translate SRW requests into Z39.50 requests.
+      </para>
+     </listitem>
+    </varlistentry>
+    <varlistentry>
+     <term><literal>srw_client</literal> (sink)</term>
+     <listitem>
+      <para>
+       SRW searching and retrieval.
+      </para>
+     </listitem>
+    </varlistentry>
+    <varlistentry>
+     <term><literal>sru_client</literal> (sink)</term>
+     <listitem>
+      <para>
+       SRU searching and retrieval.
+      </para>
+     </listitem>
+    </varlistentry>
+    <varlistentry>
+     <term><literal>opensearch_client</literal> (sink)</term>
+     <listitem>
+      <para>
+       A9 OpenSearch searching and retrieval.
+      </para>
+     </listitem>
+    </varlistentry>
+   </variablelist>
+  </section>
+ </chapter>
+
+
+
+ <chapter id="configuration">
+  <title>Configuration: the YP2 configuration file format</title>
+
+
+  <section>
+   <title>Introductory notes</title>
+   <para>
+    If YP2 is an interpreter providing operations on packages, then
+    its configuration file can be thought of as a program for that
+    interpreter.  Configuration is by means of a single file, the name
+    of which is supplied as the sole command-line argument to the
+    <command>yp2</command> program.
+   </para>
+   <para>
+    The configuration files are written in XML.  (But that's just an
+    implementation detail - they could just as well have been written
+    in YAML or Lisp-like S-expressions, or in a custom syntax.)
+   </para>
+   <para>
+    Since XML has been chosen, an XML schema,
+    <filename>config.xsd</filename>, is provided for validating
+    configuration files.  This file is supplied in the
+    <filename>etc</filename> directory of the YP2 distribution.  It
+    can be used by (among other tools) the <command>xmllint</command>
+    program supplied as part of the <literal>libxml2</literal>
+    distribution:
+   </para>
+   <screen>
+       xmllint --noout --schema etc/config.xsd my-config-file.xml
+   </screen>
+   <para>
+    (A recent version of <literal>libxml2</literal> is required, as
+    support for XML Schemas is a relatively recent addition.)
+   </para>
+  </section>
+
+  <section>
+   <title>Overview of XML structure</title>
+   <para>
+    All elements and attributes are in the namespace
+    <ulink url="http://indexdata.dk/yp2/config/1"/>.
+    This is most easily achieved by setting the default namespace on
+    the top-level element, as here:
+   </para>
+   <screen>
+       &lt;yp2 xmlns="http://indexdata.dk/yp2/config/1"&gt;
+   </screen>
+   <para>
+    The top-level element is &lt;yp2&gt;.  This contains a
+    &lt;start&gt; element, a &lt;filters&gt; element and a
+    &lt;routes&gt; element, in that order.  &lt;filters&gt; is
+    optional; the other two are mandatory.  All three are
+    non-repeatable.
+   </para>
+   <para>
+    The &lt;start&gt; element is empty, but carries a
+    <literal>route</literal> attribute, whose value is the name of
+    route at which to start running - analogouse to the name of the
+    start production in a formal grammar.
+   </para>
+   <para>
+    If present, &lt;filters&gt; contains zero or more &lt;filter&gt;
+    elements; filters carry a <literal>type</literal> attribute and
+    contain various elements that provide suitable configuration for
+    filters of that type.  The filter-specific elements are described
+    below.  Filters defined in this part of the file must carry an
+    <literal>id</literal> attribute so that they can be referenced
+    from elsewhere.
+   </para>
+   <para>
+    &lt;routes&gt; contains one or more &lt;route&gt; elements, each
+    of which must carry an <literal>id</literal> element.  One of the
+    routes must have the ID value that was specified as the start
+    route in the &lt;start&gt; element's <literal>route</literal>
+    attribute.  Each route contains zero or more &lt;filter&gt;
+    elements.  These are of two types.  They may be empty, but carry a
+    <literal>refid</literal> attribute whose value is the same as the
+    <literal>id</literal> of a filter previously defined in the
+    &lt;filters&gt; section.  Alternatively, a route within a filter
+    may omit the <literal>refid</literal> attribute, but contain
+    configuration elements similar to those used for filters defined
+    in the &lt;filters&gt; section.
+   </para>
+  </section>
+
+
+  <section>
+   <title>Filter configuration</title>
+   <para>
+    All &lt;filter&gt; elements have in common that they must carry a
+    <literal>type</literal> attribute whose value is one of the
+    supported ones, listed in the schema file and discussed below.  In
+    additional, &lt;filters&gt;s occurring the &lt;filters&gt; section
+    must have an <literal>id</literal> attribute, and those occurring
+    within a route must have either a <literal>refid</literal>
+    attribute referencing a previously defined filter or contain its
+    own configuration information.
+   </para>
+   <para>
+    In general, each filter recognises different configuration
+    elements within its element, as each filter has different
+    functionality.  These are as follows:
+   </para>
+
+   <section>
+    <title><literal>auth_simple</literal></title>
+    <screen>
+       &lt;filter type="auth_simple"&gt;
+         &lt;userRegister&gt;../etc/example.simple-auth&lt;/userRegister&gt;
+       &lt;/filter&gt;
+    </screen>
+   </section>
+
+   <section>
+    <title><literal>backend_test</literal></title>
+    <screen>
+       &lt;filter type="backend_test"/&gt;
+    </screen>
+   </section>
+
+   <section>
+    <title><literal>frontend_net</literal></title>
+    <screen>
+       &lt;filter type="frontend_net"&gt;
+         &lt;threads&gt;10&lt;/threads&gt;
+         &lt;port&gt;@:9000&lt;/port&gt;
+       &lt;/filter&gt;
+    </screen>
+   </section>
+
+   <section>
+    <title><literal>http_file</literal></title>
+    <screen>
+       &lt;filter type="http_file"&gt;
+         &lt;mimetypes&gt;/etc/mime.types&lt;/mimetypes&gt;
+         &lt;area&gt;
+           &lt;documentroot&gt;.&lt;/documentroot&gt;
+           &lt;prefix&gt;/etc&lt;/prefix&gt;
+         &lt;/area&gt;
+       &lt;/filter&gt;
+    </screen>
+   </section>
+
+   <section>
+    <title><literal>log</literal></title>
+    <screen>
+       &lt;filter type="log"&gt;
+         &lt;message&gt;B&lt;/message&gt;
+       &lt;/filter&gt;
+    </screen>
+   </section>
+
+   <section>
+    <title><literal>multi</literal></title>
+    <screen>
+       &lt;filter type="multi"/&gt;
+    </screen>
+   </section>
+
+   <section>
+    <title><literal>session_shared</literal></title>
+    <screen>
+       &lt;filter type="session_shared"&gt;
+         ### Not yet defined
+       &lt;/filter&gt;
+    </screen>
+   </section>
+
+   <section>
+    <title><literal>template</literal></title>
+    <screen>
+       &lt;filter type="template"/&gt;
+    </screen>
+   </section>
+
+   <section>
+    <title><literal>virt_db</literal></title>
+    <screen>
+       &lt;filter type="virt_db"&gt;
+         &lt;virtual&gt;
+           &lt;database&gt;loc&lt;/database&gt;
+           &lt;target&gt;z3950.loc.gov:7090/voyager&lt;/target&gt;
+         &lt;/virtual&gt;
+         &lt;virtual&gt;
+           &lt;database&gt;idgils&lt;/database&gt;
+           &lt;target&gt;indexdata.dk/gils&lt;/target&gt;
+         &lt;/virtual&gt;
+       &lt;/filter&gt;
+    </screen>
+   </section>
+
+   <section>
+    <title><literal>z3950_client</literal></title>
+    <screen>
+       &lt;filter type="z3950_client"&gt;
+         &lt;timeout&gt;30&lt;/timeout&gt;
+       &lt;/filter&gt;
+    </screen>
+   </section>
+  </section>
+ </chapter>
+
+
+
+ <chapter id="multidb">
+  <title>Virtual database as multi-database searching</title>
+
+
+  <section>
+   <title>Introductory notes</title>
+   <para>
+    Two of YP2's filters are concerned with multiple-database
+    operations.  Of these, <literal>virt_db</literal> can work alone
+    to control the routing of searches to one of a number of servers,
+    while <literal>multi</literal> can work with the output of
+    <literal>virt_db</literal> to perform multicast searching, merging
+    the results into a unified result-set.  The interaction between
+    these two filters is necessarily complex, reflecting the real
+    complexity of multicast searching in a protocol such as Z39.50
+    that separates initialisation from searching, with the database to
+    search known only during the latter operation.
+   </para>
+   <para>
+    ### Much, much more to say!
+   </para>
+  </section>
+ </chapter>
+
+
+
+ <chapter id="classes">
+  <title>Classes in the YP2 source code</title>
+
+
+  <section>
+   <title>Introductory notes</title>
+   <para>
+    <emphasis>Stop!  Do not read this!</emphasis>
+    You won't enjoy it at all.
+   </para>
+   <para>
+    This chapter contains documentation of the YP2 source code, and is
+    of interest only to maintainers and developers.  If you need to
+    change YP2's behaviour or write a new filter, then you will most
+    likely find this chapter helpful.  Otherwise it's a waste of your
+    good time.  Seriously: go and watch a film or something.
+    <citetitle>This is Spinal Tap</citetitle> is particularly good.
+   </para>
+   <para>
+    Still here?  OK, let's continue.
+   </para>
+   <para>
+    In general, classes seem to be named big-endianly, so that
+    <literal>FactoryFilter</literal> is not a filter that filters
+    factories, but a factory that produces filters; and
+    <literal>FactoryStatic</literal> is a factory for the statically
+    registered filters (as opposed to those that are dynamically
+    loaded).
+   </para>
+  </section>
+
+  <section>
+   <title>Individual classes</title>
+   <para>
+    The classes making up the YP2 application are here listed by
+    class-name, with the names of the source files that define them in
+    parentheses.
+   </para>
+
+   <section>
+    <title><literal>yp::FactoryFilter</literal>
+       (<filename>factory_filter.cpp</filename>)</title>
+    <para>
+     A factory class that exists primarily to provide the
+     <literal>create()</literal> method, which takes the name of a
+     filter class as its argument and returns a new filter of that
+     type.  To enable this, the factory must first be populated by
+     calling <literal>add_creator()</literal> for static filters (this
+     is done by the <literal>FactoryStatic</literal> class, see below)
+     and <literal>add_creator_dyn()</literal> for filters loaded
+     dynamically.
+    </para>
+   </section>
+
+   <section>
+    <title><literal>yp2::FactoryStatic</literal>
+       (<filename>factory_static.cpp</filename>)</title>
+    <para>
+     A subclass of <literal>FactoryFilter</literal> which is
+     responsible for registering all the statically defined filter
+     types.  It does this by knowing about all those filters'
+     structures, which are listed in its constructor.  Merely
+     instantiating this class registers all the static classes.  It is
+     for the benefit of this class that <literal>struct
+     yp2_filter_struct</literal> exists, and that all the filter
+     classes provide a static object of that type.
+    </para>
+   </section>
+
+   <section>
+    <title><literal>yp2::filter::Base</literal>
+       (<filename>filter.cpp</filename>)</title>
+    <para>
+     The virtual base class of all filters.  The filter API is, on the
+     surface at least, extremely simple: two methods.
+     <literal>configure()</literal> is passed a DOM tree representing
+     that part of the configuration file that pertains to this filter
+     instance, and is expected to walk that tree extracting relevant
+     information.  And <literal>process()</literal> processes a
+     package (see below).  That surface simplicitly is a bit
+     misleading, as <literal>process()</literal> needs to know a lot
+     about the <literal>Package</literal> class in order to do
+     anything useful.
+    </para>
+   </section>
+
+   <section>
+    <title><literal>yp2::filter::AuthSimple</literal>,
+       <literal>Backend_test</literal>, etc.
+       (<filename>filter_auth_simple.cpp</filename>,
+        <filename>filter_backend_test.cpp</filename>, etc.)</title>
+    <para>
+     Individual filters.  Each of these is implemented by a header and
+     a source file, named <filename>filter_*.hpp</filename> and
+     <filename>filter_*.cpp</filename> respectively.  All the header
+     files should be pretty much identical, in that they declare the
+     class, including a private <literal>Rep</literal> class and a
+     member pointer to it, and the two public methods.  The only extra
+     information in any filter header is additional private types and
+     members (which should really all be in the <literal>Rep</literal>
+     anyway) and private methods (which should also remain known only
+     to the source file, but C++'s brain-damaged design requires this
+     dirty laundry to be exhibited in public.  Thanks, Bjarne!)
+    </para>
+    <para>
+     The source file for each filter needs to supply:
+    </para>
+    <itemizedlist>
+     <listitem>
+      <para>
+       A definition of the private <literal>Rep</literal> class.
+      </para>
+     </listitem>
+     <listitem>
+      <para>
+       Some boilerplate constructors and destructors.
+      </para>
+     </listitem>
+     <listitem>
+      <para>
+       A <literal>configure()</literal> method that uses the
+       appropriate XML fragment.
+      </para>
+     </listitem>
+     <listitem>
+      <para>
+       Most important, the <literal>process()</literal> method that
+       does all the actual work.
+      </para>
+     </listitem>
+    </itemizedlist>
+   </section>
+
+   <section>
+    <title><literal>yp2::Package</literal>
+       (<filename>package.cpp</filename>)</title>
+    <para>
+     Represents a package on its way through the series of filters
+     that make up a route.  This is essentially a Z39.50 or SRU APDU
+     together with information about where it came from, which is
+     modified as it passes through the various filters.
+    </para>
+   </section>
+
+   <section>
+    <title><literal>yp2::Pipe</literal>
+       (<filename>pipe.cpp</filename>)</title>
+    <para>
+     This class provides a compatibility layer so that we have an IPC
+     mechanism that works the same under Unix and Windows.  It's not
+     particularly exciting.
+    </para>
+   </section>
+
+   <section>
+    <title><literal>yp2::RouterChain</literal>
+       (<filename>router_chain.cpp</filename>)</title>
+    <para>
+     ###
+    </para>
+   </section>
+
+   <section>
+    <title><literal>yp2::RouterFleXML</literal>
+       (<filename>router_flexml.cpp</filename>)</title>
+    <para>
+     ###
+    </para>
+   </section>
+
+   <section>
+    <title><literal>yp2::Session</literal>
+       (<filename>session.cpp</filename>)</title>
+    <para>
+     ###
+    </para>
+   </section>
+
+   <section>
+    <title><literal>yp2::ThreadPoolSocketObserver</literal>
+       (<filename>thread_pool_observer.cpp</filename>)</title>
+    <para>
+     ###
+    </para>
+   </section>
+
+   <section>
+    <title><literal>yp2::util</literal>
+       (<filename>util.cpp</filename>)</title>
+    <para>
+     A namespace of various small utility functions and classes,
+     collected together for convenience.  Most importantly, includes
+     the <literal>yp2::util::odr</literal> class, a wrapper for YAZ's
+     ODR facilities.
+    </para>
+   </section>
+
+   <section>
+    <title><literal>yp2::xml</literal>
+       (<filename>xmlutil.cpp</filename>)</title>
+    <para>
+     A namespace of various XML utility functions and classes,
+     collected together for convenience.
+    </para>
+   </section>
+  </section>
+
+
+  <section>
+   <title>Other Source Files</title>
+   <para>
+    In addition to the YP2 source files that define the classes
+    described above, there are a few additional files which are
+    briefly described here:
+   </para>
+   <variablelist>
+    <varlistentry>
+     <term><literal>yp2_prog.cpp</literal></term>
+     <listitem>
+      <para>
+       The main function of the <command>yp2</command> program.
+      </para>
+     </listitem>
+    </varlistentry>
+    <varlistentry>
+     <term><literal>ex_router_flexml.cpp</literal></term>
+     <listitem>
+      <para>
+       Identical to <literal>yp2_prog.cpp</literal>: it's not clear why.
+      </para>
+     </listitem>
+    </varlistentry>
+    <varlistentry>
+     <term><literal>test_*.cpp</literal></term>
+     <listitem>
+      <para>
+       Unit-tests for various modules.
+      </para>
+     </listitem>
+    </varlistentry>
+   </variablelist>
+   <para>
+    ### Still to be described:
+    <literal>ex_filter_frontend_net.cpp</literal>,
+    <literal>filter_dl.cpp</literal>,
+    <literal>plainfile.cpp</literal>,
+    <literal>tstdl.cpp</literal>.
+   </para>
+
+
+   <!-- Epilogue -->
+   <para>
+    --
+   </para>
+   <screen>
+    <!-- This is just a lame way to get some vertical whitespace at
+       the end of the document -->
+
+
+
+
+   </screen>
+  </section>
+ </chapter>
+</book>
+
+<!-- Keep this comment at the end of the file
+Local variables:
+mode: sgml
+sgml-omittag:t
+sgml-shorttag:t
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:1
+sgml-indent-data:t
+sgml-parent-document:nil
+sgml-local-catalogs: nil
+sgml-namecase-general:t
+End:
+-->
diff --git a/doc/yp2html.dsl.in b/doc/yp2html.dsl.in
new file mode 100644 (file)
index 0000000..06df7c6
--- /dev/null
@@ -0,0 +1,26 @@
+<!DOCTYPE style-sheet PUBLIC "-//James Clark//DTD DSSSL Style Sheet//EN" [
+<!ENTITY docbook.dsl SYSTEM "@DSSSL_DIR@/html/docbook.dsl"
+  CDATA DSSSL>
+]>
+<!--
+  $Id: yp2html.dsl.in,v 1.1 2006-02-02 18:22:47 mike Exp $
+-->
+<style-sheet>
+<style-specification use="docbook">
+<style-specification-body>
+
+(define %use-id-as-filename% #t)
+(define %output-dir% "html")
+(define %html-ext% ".html")
+(define %shade-verbatim% #t)
+
+</style-specification-body>
+</style-specification>
+<external-specification id="docbook" document="docbook.dsl">
+</style-sheet>
+  
+<!--
+Local Variables:
+mode: scheme
+End:
+-->
diff --git a/doc/yp2php.dsl.in b/doc/yp2php.dsl.in
new file mode 100644 (file)
index 0000000..f50e336
--- /dev/null
@@ -0,0 +1,98 @@
+<!DOCTYPE style-sheet PUBLIC "-//James Clark//DTD DSSSL Style Sheet//EN" [
+<!ENTITY docbook.dsl SYSTEM "@DSSSL_DIR@/html/docbook.dsl"
+  CDATA DSSSL>
+]>
+<!--
+  $Id: yp2php.dsl.in,v 1.1 2006-02-02 18:22:47 mike Exp $
+-->
+<style-sheet>
+<style-specification use="docbook">
+<style-specification-body>
+
+(define %use-id-as-filename% #t)
+(define %output-dir% "php")
+(define %html-ext% ".php")
+(define %shade-verbatim% #t)
+
+(define newline "\U-000D")
+
+(define (html-document title-sosofo body-sosofo)
+  (let* (;; Let's look these up once, so that we can avoid calculating
+         ;; them over and over again.
+         (prev         (prev-chunk-element))
+         (next         (next-chunk-element))
+         (prevm        (prev-major-component-chunk-element))
+         (nextm        (next-major-component-chunk-element))
+         (navlist      (list prev next prevm nextm))
+        
+         ;; Let's make it possible to control the output even in the
+         ;; nochunks case. Note: in the nochunks case, (chunk?) will
+         ;; return #t for only the root element.
+         (make-entity? (and (or (not nochunks) rootchunk)
+                            (chunk?)))
+        
+         (make-head?   (or make-entity?
+                           (and nochunks
+                                (node-list=? (current-node)
+                                             (sgml-root-element)))))
+         (doc-sosofo 
+          (if make-head?
+             (make sequence
+               (make formatting-instruction data:
+                     (string-append "<" "?php "
+                                    newline
+                                    "require \"../../id_common.inc\";"
+                                    newline
+                                    "id_header(\""
+                                    )
+                     )
+               title-sosofo
+               (make formatting-instruction data:
+                     (string-append "\");"
+                                    newline
+                                    "?" ">"
+                                    )
+                     )
+               (header-navigation (current-node) navlist)
+               body-sosofo
+               (footer-navigation (current-node) navlist)
+               (make formatting-instruction data:
+                     (string-append "<" "?php id_footer() ?>")
+                     )
+               )
+             body-sosofo
+             )
+         )
+        )
+    (if make-entity?
+       (make entity
+         system-id: (html-entity-file (html-file))
+         (if %html-pubid%
+             (make document-type
+               name: "HTML"
+               public-id: %html-pubid%)
+             (empty-sosofo))
+         doc-sosofo)
+       (if (node-list=? (current-node) (sgml-root-element))
+           (make sequence
+             (if %html-pubid%
+                 (make document-type
+                   name: "HTML"
+                   public-id: %html-pubid%)
+                 (empty-sosofo))
+             doc-sosofo)
+           doc-sosofo)
+       )
+    )
+  )
+
+</style-specification-body>
+</style-specification>
+<external-specification id="docbook" document="docbook.dsl">
+</style-sheet>
+
+<!--
+Local Variables:
+mode: scheme
+End:
+-->
diff --git a/doc/yp2print.dsl.in b/doc/yp2print.dsl.in
new file mode 100644 (file)
index 0000000..50ee6dc
--- /dev/null
@@ -0,0 +1,21 @@
+<!DOCTYPE style-sheet PUBLIC "-//James Clark//DTD DSSSL Style Sheet//EN" [
+<!ENTITY docbook.dsl SYSTEM "@DSSSL_DIR@/print/docbook.dsl"
+  CDATA DSSSL>
+]>
+<!--
+  $Id: yp2print.dsl.in,v 1.1 2006-02-02 18:22:47 mike Exp $
+-->
+<style-sheet>
+<style-specification use="docbook">
+<style-specification-body>
+
+</style-specification-body>
+</style-specification>
+<external-specification id="docbook" document="docbook.dsl">
+</style-sheet>
+
+<!--
+Local Variables:
+mode: scheme
+End:
+-->