OPAC record support for ZOOM
authorAdam Dickmeiss <adam@indexdata.dk>
Mon, 14 Jul 2003 12:59:22 +0000 (12:59 +0000)
committerAdam Dickmeiss <adam@indexdata.dk>
Mon, 14 Jul 2003 12:59:22 +0000 (12:59 +0000)
CHANGELOG
client/client.c
doc/zoom.xml
include/yaz/proto.h
util/marcdisp.c
zoom/zoomsh.c
zutil/opacdisp.c
zutil/zoom-c.c
zutil/zoom-p.h

index 66a644d..4d01a8b 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,8 @@
 Possible compatibility problems with earlier versions marked with '*'.
 
+OPAC support ZOOM. ZOOM_record_get returns OPAC info (as XML) if
+type is "opac".
+
 Add three new utility functions for translating OIDs between various
 formats -- symbolic name such as "Usmarc", minus-1-terminated int
 arrays and dotted strings such as "1.2.840.10003.9.5.1":
index c7c6e1b..a833835 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (c) 1995-2003, Index Data
  * See the file LICENSE for details.
  *
- * $Id: client.c,v 1.201 2003-06-19 21:10:03 adam Exp $
+ * $Id: client.c,v 1.202 2003-07-14 12:59:23 adam Exp $
  */
 
 #include <stdio.h>
@@ -808,6 +808,107 @@ static void display_record(Z_External *r)
         puts (wrbuf_buf(w));
         wrbuf_free(w, 1);
     }
+    else if ( /* OPAC display not complete yet .. */
+            ent && ent->value == VAL_OPAC)
+    {
+       int i;
+       if (r->u.opac->bibliographicRecord)
+           display_record(r->u.opac->bibliographicRecord);
+       for (i = 0; i<r->u.opac->num_holdingsData; i++)
+       {
+           Z_HoldingsRecord *h = r->u.opac->holdingsData[i];
+           if (h->which == Z_HoldingsRecord_marcHoldingsRecord)
+           {
+               printf ("MARC holdings %d\n", i);
+               display_record(h->u.marcHoldingsRecord);
+           }
+           else if (h->which == Z_HoldingsRecord_holdingsAndCirc)
+           {
+               int j;
+
+               Z_HoldingsAndCircData *data = h->u.holdingsAndCirc;
+
+               printf ("Data holdings %d\n", i);
+               if (data->typeOfRecord)
+                   printf ("typeOfRecord: %s\n", data->typeOfRecord);
+               if (data->encodingLevel)
+                   printf ("encodingLevel: %s\n", data->encodingLevel);
+               if (data->receiptAcqStatus)
+                   printf ("receiptAcqStatus: %s\n", data->receiptAcqStatus);
+               if (data->generalRetention)
+                   printf ("generalRetention: %s\n", data->generalRetention);
+               if (data->completeness)
+                   printf ("completeness: %s\n", data->completeness);
+               if (data->dateOfReport)
+                   printf ("dateOfReport: %s\n", data->dateOfReport);
+               if (data->nucCode)
+                   printf ("nucCode: %s\n", data->nucCode);
+               if (data->localLocation)
+                   printf ("localLocation: %s\n", data->localLocation);
+               if (data->shelvingLocation)
+                   printf ("shelvingLocation: %s\n", data->shelvingLocation);
+               if (data->callNumber)
+                   printf ("callNumber: %s\n", data->callNumber);
+               if (data->copyNumber)
+                   printf ("copyNumber: %s\n", data->copyNumber);
+               if (data->publicNote)
+                   printf ("publicNote: %s\n", data->publicNote);
+               if (data->reproductionNote)
+                   printf ("reproductionNote: %s\n", data->reproductionNote);
+               if (data->termsUseRepro)
+                   printf ("termsUseRepro: %s\n", data->termsUseRepro);
+               if (data->enumAndChron)
+                   printf ("enumAndChron: %s\n", data->enumAndChron);
+               for (j = 0; j<data->num_volumes; j++)
+               {
+                   printf ("volume %d\n", j);
+                   if (data->volumes[j]->enumeration)
+                       printf (" enumeration: %s\n",
+                               data->volumes[j]->enumeration);
+                   if (data->volumes[j]->chronology)
+                       printf (" chronology: %s\n",
+                               data->volumes[j]->chronology);
+                   if (data->volumes[j]->enumAndChron)
+                       printf (" enumAndChron: %s\n",
+                               data->volumes[j]->enumAndChron);
+               }
+               for (j = 0; j<data->num_circulationData; j++)
+               {
+                   printf ("circulation %d\n", j);
+                   if (data->circulationData[j]->availableNow)
+                       printf (" availableNow: %d\n",
+                               *data->circulationData[j]->availableNow);
+                   if (data->circulationData[j]->availablityDate)
+                       printf (" availabiltyDate: %s\n",
+                               data->circulationData[j]->availablityDate);
+                   if (data->circulationData[j]->availableThru)
+                       printf (" availableThru: %s\n",
+                               data->circulationData[j]->availableThru);
+                   if (data->circulationData[j]->restrictions)
+                       printf (" restrictions: %s\n",
+                               data->circulationData[j]->restrictions);
+                   if (data->circulationData[j]->itemId)
+                       printf (" itemId: %s\n",
+                               data->circulationData[j]->itemId);
+                   if (data->circulationData[j]->renewable)
+                       printf (" renewable: %d\n",
+                               *data->circulationData[j]->renewable);
+                   if (data->circulationData[j]->onHold)
+                       printf (" onHold: %d\n",
+                               *data->circulationData[j]->onHold);
+                   if (data->circulationData[j]->enumAndChron)
+                       printf (" enumAndChron: %s\n",
+                               data->circulationData[j]->enumAndChron);
+                   if (data->circulationData[j]->midspine)
+                       printf (" midspine: %s\n",
+                               data->circulationData[j]->midspine);
+                   if (data->circulationData[j]->temporaryLocation)
+                       printf (" temporaryLocation: %s\n",
+                               data->circulationData[j]->temporaryLocation);
+               }
+           }
+       }
+    }
     else 
     {
         printf("Unknown record representation.\n");
index 0ca1c8c..da40e9d 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $Id: zoom.xml,v 1.31 2003-07-09 22:38:12 mike Exp $ -->
+<!-- $Id: zoom.xml,v 1.32 2003-07-14 12:59:23 adam Exp $ -->
  <chapter id="zoom"><title>ZOOM</title>
   <para>
     &zoom; is an acronym for 'Z39.50 Object-Orientation Model' and is
         <literal>*len</literal>.
        </para></listitem>
      </varlistentry>
+     <varlistentry><term><literal>opac</literal></term>
+      <listitem><para>OPAC for record is returned in XML.
+       </para></listitem>
+     </varlistentry>
     </variablelist>
    </para>
    <para>
index 0d0ea5a..cf01f36 100644 (file)
@@ -3,7 +3,7 @@
  * See the file LICENSE for details.
  * Sebastian Hammer, Adam Dickmeiss
  *
- * $Id: proto.h,v 1.9 2003-02-21 12:08:58 adam Exp $
+ * $Id: proto.h,v 1.10 2003-07-14 12:59:23 adam Exp $
  */
 #ifndef Z_PROTO_H
 #define Z_PROTO_H
@@ -111,6 +111,7 @@ YAZ_EXPORT const char* yaz_z3950_oid_value_to_str(oid_value ov, oid_class oc);
 
 YAZ_EXPORT void yaz_display_grs1(WRBUF wrbuf, Z_GenericRecord *r, int flags);
 
+YAZ_EXPORT void yaz_display_OPAC(WRBUF wrbuf, Z_OPACRecord *r, int flags);
 
 YAZ_END_CDECL
 
index 9156281..b728872 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (c) 1995-2003, Index Data
  * See the file LICENSE for details.
  *
- * $Id: marcdisp.c,v 1.29 2003-02-12 22:02:47 adam Exp $
+ * $Id: marcdisp.c,v 1.30 2003-07-14 12:59:23 adam Exp $
  */
 
 #if HAVE_CONFIG_H
@@ -56,6 +56,12 @@ static void marc_cdata (yaz_marc_t mt, const char *buf, size_t len, WRBUF wr)
             case '&':
                 wrbuf_puts(wr, "&amp;");
                 break;
+           case '"':
+               wrbuf_puts(wr, "&quot;");
+               break;
+           case '\'':
+               wrbuf_puts(wr, "&apos;");
+               break;
             default:
                 wrbuf_putc(wr, buf[i]);
             }
index c6b29ae..aaf6899 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: zoomsh.c,v 1.22 2003-07-10 11:50:32 mike Exp $
+ * $Id: zoomsh.c,v 1.23 2003-07-14 12:59:23 adam Exp $
  *
  * ZOOM-C Shell
  */
@@ -153,8 +153,9 @@ static void display_records (ZOOM_connection c,
        int pos = i + start;
         ZOOM_record rec = ZOOM_resultset_record (r, pos);
        const char *db = ZOOM_record_get (rec, "database", 0);
-       int len;
+       int len, opac_len;
        const char *render = ZOOM_record_get (rec, "render", &len);
+       const char *opac_render = ZOOM_record_get (rec, "opac", &opac_len);
        const char *syntax = ZOOM_record_get (rec, "syntax", 0);
        /* if rec is non-null, we got a record for display */
        if (rec)
@@ -166,7 +167,10 @@ static void display_records (ZOOM_connection c,
            if (render)
                fwrite (render, 1, len, stdout);
            printf ("\n");
+           if (opac_render)
+               fwrite (opac_render, 1, opac_len, stdout);
        }
+           
     }
 }
 
index e18b7b9..aefe98d 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (c) 2003, Index Data.
  * See the file LICENSE for details.
  *
- * $Id: opacdisp.c,v 1.1 2003-04-23 12:31:07 adam Exp $
+ * $Id: opacdisp.c,v 1.2 2003-07-14 12:59:23 adam Exp $
  */
 
 #include <stdio.h>
 
 #include <yaz/proto.h>
 
+static void opac_element_str(WRBUF wrbuf, int l, const char *elem,
+                            const char *data)
+{
+    if (data)
+    {
+       while (--l >= 0)
+           wrbuf_puts(wrbuf, " ");
+       wrbuf_puts(wrbuf, "<");
+       wrbuf_puts(wrbuf, elem);
+       wrbuf_puts(wrbuf, ">");
+       wrbuf_xmlputs(wrbuf, data);
+       wrbuf_puts(wrbuf, "</");
+       wrbuf_puts(wrbuf, elem);
+       wrbuf_puts(wrbuf, ">\n");
+    }
+}
+
+static void opac_element_bool(WRBUF wrbuf, int l, const char *elem, int *data)
+{
+    if (data && *data)
+    {
+       while (--l >= 0)
+           wrbuf_puts(wrbuf, " ");
+       wrbuf_puts(wrbuf, "<");
+       wrbuf_puts(wrbuf, elem);
+       wrbuf_puts(wrbuf, "/>\n");
+    }
+}
+
 void yaz_display_OPAC(WRBUF wrbuf, Z_OPACRecord *r, int flags)
 {
+    int i;
+    wrbuf_puts(wrbuf, "<holdings>\n");
 
+    for (i = 0; i < r->num_holdingsData; i++)
+    {
+       Z_HoldingsRecord *h = r->holdingsData[i];
+       wrbuf_puts(wrbuf, " <holding>\n");
 
+       if (h->which == Z_HoldingsRecord_marcHoldingsRecord)
+       {
+           wrbuf_puts (wrbuf, "  <marc/>\n");
+       /*  h->u.marcHoldingsRecord) */
+       }
+       else if (h->which == Z_HoldingsRecord_holdingsAndCirc)
+       {
+           int j;
+           
+           Z_HoldingsAndCircData *d = h->u.holdingsAndCirc;
+       
+           opac_element_str(wrbuf, 2, "typeOfRecord", d->typeOfRecord);
+           opac_element_str(wrbuf, 2, "encodingLevel", d->encodingLevel);
+           opac_element_str(wrbuf, 2, "encodingLevel", d->encodingLevel);
+           opac_element_str(wrbuf, 2, "receiptAcqStatus", d->receiptAcqStatus);
+           opac_element_str (wrbuf, 2, "generalRetention", d->generalRetention);
+           opac_element_str (wrbuf, 2, "completeness", d->completeness);
+           opac_element_str (wrbuf, 2, "dateOfReport", d->dateOfReport);
+           opac_element_str (wrbuf, 2, "nucCode", d->nucCode);
+           opac_element_str (wrbuf, 2, "localLocation", d->localLocation);
+           opac_element_str (wrbuf, 2, "shelvingLocation", d->shelvingLocation);
+           opac_element_str (wrbuf, 2, "callNumber", d->callNumber);
+           opac_element_str (wrbuf, 2, "copyNumber", d->copyNumber);
+           opac_element_str (wrbuf, 2, "publicNote", d->publicNote);
+           opac_element_str (wrbuf, 2, "reproductionNote", d->reproductionNote);
+           opac_element_str (wrbuf, 2, "termsUseRepro", d->termsUseRepro);
+           opac_element_str (wrbuf, 2, "enumAndChron", d->enumAndChron);
+           if (d->num_volumes)
+           {
+               wrbuf_puts (wrbuf, "  <volumes>\n");
+               for (j = 0; j<d->num_volumes; j++)
+               {
+                   wrbuf_puts (wrbuf, "   <volume>\n");
+                   opac_element_str (wrbuf, 4, "enumeration",
+                                     d->volumes[j]->enumeration);
+                   opac_element_str (wrbuf, 4, "chronology",
+                                     d->volumes[j]->chronology);
+                   opac_element_str (wrbuf, 4, "enumAndChron",
+                                     d->volumes[j]->enumAndChron);
+                   wrbuf_puts (wrbuf, "   </volume>\n");
+               }
+               wrbuf_puts (wrbuf, "  </volumes>\n");
+           }
+           if (d->num_circulationData)
+           {
+               wrbuf_puts (wrbuf, "  <circulations>\n");
+               for (j = 0; j<d->num_circulationData; j++)
+               {
+                   wrbuf_puts (wrbuf,"   <circulation>\n");
+                   opac_element_bool (wrbuf, 4, "availableNow",
+                                      d->circulationData[j]->availableNow);
+                   opac_element_str (wrbuf, 4, "availabiltyDate",
+                                     d->circulationData[j]->availablityDate);
+                   opac_element_str (wrbuf, 4, "availableThru",
+                                     d->circulationData[j]->availableThru);
+                   opac_element_str (wrbuf, 4, "restrictions",
+                                     d->circulationData[j]->restrictions);
+                   opac_element_str (wrbuf, 4, "itemId",
+                                     d->circulationData[j]->itemId);
+                   opac_element_bool (wrbuf, 4, "renewable: %d\n",
+                                      d->circulationData[j]->renewable);
+                   opac_element_bool (wrbuf, 4, "onHold: %d\n",
+                                      d->circulationData[j]->onHold);
+                   opac_element_str (wrbuf, 4, "enumAndChron",
+                                     d->circulationData[j]->enumAndChron);
+                   opac_element_str (wrbuf, 4, "midspine",
+                                     d->circulationData[j]->midspine);
+                   opac_element_str (wrbuf, 4, "temporaryLocation",
+                                     d->circulationData[j]->temporaryLocation);
+                   wrbuf_puts (wrbuf, "   </circulation>\n");
+               }
+               wrbuf_puts (wrbuf, "  </circulations>\n");
+           }
+       }
+       wrbuf_puts(wrbuf, " </holding>\n");
+    }
+    wrbuf_puts(wrbuf, "</holdings>\n");
 }
index d67461a..648fba2 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (c) 2000-2003, Index Data
  * See the file LICENSE for details.
  *
- * $Id: zoom-c.c,v 1.38 2003-06-03 13:59:28 adam Exp $
+ * $Id: zoom-c.c,v 1.39 2003-07-14 12:59:23 adam Exp $
  *
  * ZOOM layer for C, connections, result sets, queries.
  */
@@ -604,6 +604,8 @@ ZOOM_resultset_destroy(ZOOM_resultset r)
                 wrbuf_free (rc->rec.wrbuf_marc, 1);
             if (rc->rec.wrbuf_iconv)
                 wrbuf_free (rc->rec.wrbuf_iconv, 1);
+            if (rc->rec.wrbuf_opac)
+                wrbuf_free (rc->rec.wrbuf_opac, 1);
        }
        if (r->connection)
        {
@@ -1304,6 +1306,7 @@ ZOOM_record_clone (ZOOM_record srec)
     nrec->odr = odr_createmem(ODR_DECODE);
     nrec->wrbuf_marc = 0;
     nrec->wrbuf_iconv = 0;
+    nrec->wrbuf_opac = 0;
     odr_setbuf (nrec->odr, buf, size, 0);
     z_NamePlusRecord (nrec->odr, &nrec->npr, 0, 0);
     
@@ -1337,6 +1340,10 @@ ZOOM_record_destroy (ZOOM_record rec)
        return;
     if (rec->wrbuf_marc)
        wrbuf_free (rec->wrbuf_marc, 1);
+    if (rec->wrbuf_iconv)
+       wrbuf_free (rec->wrbuf_iconv, 1);
+    if (rec->wrbuf_opac)
+       wrbuf_free (rec->wrbuf_opac, 1);
     odr_destroy (rec->odr);
     xfree (rec);
 }
@@ -1478,7 +1485,15 @@ ZOOM_record_get (ZOOM_record rec, const char *type_spec, int *len)
     {
         Z_External *r = (Z_External *) npr->u.databaseRecord;
         oident *ent = oid_getentbyoid(r->direct_reference);
-        
+
+       /* render bibliographic record .. */
+       if (r->which == Z_External_OPAC)
+       {
+           r = r->u.opac->bibliographicRecord;
+           if (!r)
+               return 0;
+           ent = oid_getentbyoid(r->direct_reference);
+       }
         if (r->which == Z_External_sutrs)
            return record_iconv_return(rec, len,
                                       r->u.sutrs->buf, r->u.sutrs->len,
@@ -1537,6 +1552,15 @@ ZOOM_record_get (ZOOM_record rec, const char *type_spec, int *len)
     {
         Z_External *r = (Z_External *) npr->u.databaseRecord;
         oident *ent = oid_getentbyoid(r->direct_reference);
+
+       /* render bibliographic record .. */
+       if (r->which == Z_External_OPAC)
+       {
+           r = r->u.opac->bibliographicRecord;
+           if (!r)
+               return 0;
+           ent = oid_getentbyoid(r->direct_reference);
+       }
         
         if (r->which == Z_External_sutrs)
            return record_iconv_return(rec, len,
@@ -1589,11 +1613,6 @@ ZOOM_record_get (ZOOM_record rec, const char *type_spec, int *len)
             if (len) *len = 5;
             return "GRS-1";
         }
-       else if (r->which == Z_External_OPAC)
-        {
-            if (len) *len = 4;
-            return "OPAC";
-        }
        return 0;
     }
     else if (!strcmp (type, "raw"))
@@ -1612,7 +1631,7 @@ ZOOM_record_get (ZOOM_record rec, const char *type_spec, int *len)
                if (len) *len = r->u.octet_aligned->len;
                return (const char *) r->u.octet_aligned->buf;
            }
-           else /* grs-1, explain, ... */
+           else /* grs-1, explain, OPAC, ... */
            {
                if (len) *len = -1;
                 return (const char *) npr->u.databaseRecord;
@@ -1626,6 +1645,23 @@ ZOOM_record_get (ZOOM_record rec, const char *type_spec, int *len)
             return (const char *) npr->u.databaseRecord;
        return 0;
     }
+    else if (npr->which == Z_NamePlusRecord_databaseRecord &&
+             !strcmp (type, "opac"))
+            
+    {
+       Z_External *r = (Z_External *) npr->u.databaseRecord;
+       if (r->which == Z_External_OPAC)
+       {
+           if (!rec->wrbuf_opac)
+               rec->wrbuf_opac = wrbuf_alloc();
+           wrbuf_rewind (rec->wrbuf_opac);
+           yaz_display_OPAC(rec->wrbuf_opac, r->u.opac, 0);
+           return record_iconv_return(rec, len,
+                                      wrbuf_buf(rec->wrbuf_opac),
+                                      wrbuf_len(rec->wrbuf_opac),
+                                      charset);
+       }
+    }
     return 0;
 }
 
@@ -1671,6 +1707,7 @@ static void record_cache_add (ZOOM_resultset r, Z_NamePlusRecord *npr,
     rc->rec.odr = 0;
     rc->rec.wrbuf_marc = 0;
     rc->rec.wrbuf_iconv = 0;
+    rc->rec.wrbuf_opac = 0;
     if (elementSetName)
        rc->elementSetName = odr_strdup (r->odr, elementSetName);
     else
index 1871801..0e136ee 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Private C header for ZOOM C.
- * $Id: zoom-p.h,v 1.9 2003-06-02 12:53:28 adam Exp $
+ * $Id: zoom-p.h,v 1.10 2003-07-14 12:59:23 adam Exp $
  */
 
 #if HAVE_XSLT
@@ -102,6 +102,7 @@ struct ZOOM_record_p {
     ODR odr;
     WRBUF wrbuf_marc;
     WRBUF wrbuf_iconv;
+    WRBUF wrbuf_opac;
     Z_NamePlusRecord *npr;
 };