Preparing for release.
[simpleserver-moved-to-github.git] / GRS1.pm
diff --git a/GRS1.pm b/GRS1.pm
index 2f322ac..9862193 100644 (file)
--- a/GRS1.pm
+++ b/GRS1.pm
@@ -1,5 +1,32 @@
 package Net::Z3950::GRS1;
 
+##  $Id: GRS1.pm,v 1.6 2004-05-28 20:14:28 sondberg Exp $
+##
+##  Copyright (c) 2000-2004, Index Data.
+##
+##  Permission to use, copy, modify, distribute, and sell this software and
+##  its documentation, in whole or in part, for any purpose, is hereby granted,
+##  provided that:
+##
+##  1. This copyright and permission notice appear in all copies of the
+##  software and its documentation. Notices of copyright or attribution
+##  which appear at the beginning of any file must remain unchanged.
+##
+##  2. The name of Index Data or the individual authors may not be used to
+##  endorse or promote products derived from this software without specific
+##  prior written permission.
+##
+##  THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTY OF ANY KIND,
+##  EXPRESS, IMPLIED, OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+##  WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+##  IN NO EVENT SHALL INDEX DATA BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+##  INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES
+##  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR
+##  NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+##  LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+##  OF THIS SOFTWARE.
+##
+
 use strict;
 use IO::Handle;
 use Carp;
@@ -16,9 +43,9 @@ sub new {
        bless $self, $class;
        if (defined($href) && ref($href) eq 'HASH') {
                if (!defined($map)) {
-                       croak "Usage: new Net::Z3950::GRS1($href, $map);";
+                       croak 'Usage: new Net::Z3950::GRS1($href, $map);';
                }       
-               $self->Hash2grs($href);
+               $self->Hash2grs($href, $map);
        }
 
        return $self;
@@ -30,25 +57,37 @@ sub Hash2grs {
        my $key;
        my $content;
        my $aref;
+       my $issue;
 
        $mapping = defined($mapping) ? $mapping : $self->{MAP};
+       $self->{MAP} = $mapping;
        foreach $key (keys %$href) {
                $content = $href->{$key};
+               next unless defined($content);
                if (!defined($aref = $mapping->{$key})) {
                        print STDERR "Hash2grs: Unmapped key: '$key'\n";
                        next;
                }
                if (ref($content) eq 'HASH') {                                  ## Subtree?
-                       my $subtree = new Net::Z3950::GRS1($content);
+                       my $subtree = new Net::Z3950::GRS1($content, $mapping);
                        $self->AddElement($aref->[0], $aref->[1], &Net::Z3950::GRS1::ElementData::Subtree, $subtree);
-               } elsif (ref($content) eq '') {                                 ## Regular string?
+               } elsif (!ref($content)) {                                      ## Regular string?
                        $self->AddElement($aref->[0], $aref->[1], &Net::Z3950::GRS1::ElementData::String, $content);
+               } elsif (ref($content) eq 'ARRAY') {
+                       my $issues = new Net::Z3950::GRS1;
+                       foreach $issue (@$content) {
+                               my $entry = new Net::Z3950::GRS1($issue, $mapping);
+                               $issues->AddElement(5, 1, &Net::Z3950::GRS1::ElementData::Subtree, $entry);
+                       }
+                       $self->AddElement($aref->[0], $aref->[1], &Net::Z3950::GRS1::ElementData::Subtree, $issues);
                } else {
                        print STDERR "Hash2grs: Unsupported content type\n";
                        next;
                }
        }
 }
+
+
 sub GetElementList {
        my $self = shift;
 
@@ -267,7 +306,7 @@ $content should be some kind of scalar. If on the other hand,
 
 $content should be a GRS1 object.
 
-=head3 Render
+=head2 Render
 
 This method digs through the GRS-1 data structure and renders the record. You call it
 this way,
@@ -289,6 +328,28 @@ When no file name is specified, you can choose to stream the rendered record, fo
   $grs1->Render(HANDLE => *STDERR);            ## or
   $grs1->Render(HANDLE => *MY_HANDLE);
 
+=head2 Hash2grs
+
+This method converts a hash into a GRS-1 object. Scalar entries within the hash are converted
+into GRS-1 string elements. A hash entry can itself be a reference to another hash. In this case,
+the new referenced hash will be converted into a GRS-1 subtree. The method is called this way,
+
+  $grs1->Hash2grs($href, $mapping);
+
+where $href is the hash to be converted and $mapping is referenced hash specifying the mapping
+between keys in $href and (type, value) pairs in the $grs1 object. The $mapping hash could
+for instance look like this,
+
+  my $mapping =        {
+                       title   =>      [2, 1],
+                       author  =>      [1, 1],
+                       issn    =>      [3, 1]
+               };
+
+If the $grs1 object contains data prior to the invocation of Hash2grs, the new data represented
+by the hash is simply added.
+
+
 =head1 APPENDIX A
 
 These element data types are specified in the Z39.50 protocol:
@@ -320,15 +381,3 @@ Index Data ApS, Copenhagen, Denmark.
 Specification of the GRS-1 standard, for instance in the Z39.50 protocol specification.
 
 =cut
-
-#$Log: GRS1.pm,v $
-#Revision 1.3  2001-05-17 13:43:04  sondberg
-#Added method Hash2grs into GRS1 module.
-#
-#Revision 1.2  2001/03/13 14:53:15  sondberg
-#Added a few lines of documentation into GRS1.pm.
-#
-#Revision 1.1  2001/03/13 14:17:15  sondberg
-#Added support for GRS-1.
-#
-