1a36216595d7856c8112c9c672e01f4e61da6e60
[idzebra-moved-to-github.git] / perl / lib / IDZebra / Data1.pm
1 #!/usr/bin/perl
2 # ============================================================================
3 # Zebra perl API header
4 # =============================================================================
5 use strict;
6 use Carp;
7 # =============================================================================
8 package IDZebra::Data1;
9 use IDZebra;
10 1;
11
12 # -----------------------------------------------------------------------------
13 # Class constructors and destructor
14 # -----------------------------------------------------------------------------
15 sub get {
16     my ($proto, $handle, $mem) = @_;
17     my $class = ref($proto) || $proto;
18     my $self = {};
19     bless ($self,$class);
20     
21     $self->{dh} = $handle;
22     $self->{mem} = $mem;
23     # data1_destroy is not going to be called, when object is released
24     $self->{dflag} = 0;  
25     
26     return ($self);
27 }
28
29 sub new {
30     my ($proto, $mem, $flag) = @_;
31     my $class = ref($proto) || $proto;
32     my $self = {};
33
34     bless ($self,$class);
35
36     unless ($self->{dh} = IDZebra::data1_createx($flag)) {
37         croak ("Cannot create data1 handle");
38     }
39
40     # data1_destroy going to be called, when object is released
41     $self->{dflag} = 1;
42
43     unless ($self->{mem} = $mem) {
44         croak ("Missing NMEM handle");
45     }
46
47     return ($self);
48 }
49
50 sub DESTROY {
51     my $self = shift;
52     if ($self->{dh}) {
53         if ($self->{dflag}) { IDZebra::data1_destroy($self->{dh}) }
54         $self->{dh} = undef;
55     }
56 }
57
58 # -----------------------------------------------------------------------------
59 # Profile information
60 # -----------------------------------------------------------------------------
61 # Not usable...
62 sub path_fopen {
63     my ($self, $file, $mode) = @_;
64     return (IDZebra::data1_path_fopen ($self->{dh}, $file, $mode));
65 }
66
67 sub tabpath {
68     my ($self, $path) = @_;
69     if (defined($path)) { IDZebra::data1_set_tabpath($self->{dh}, $path); }
70     return (IDZebra::data1_get_tabpath($self->{dh}));
71 }
72
73 sub tabroot {
74     my ($self, $path) = @_;
75     if (defined($path)) { IDZebra::data1_set_tabroot($self->{dh}, $path); }
76     return (IDZebra::data1_get_tabroot($self->{dh}));
77 }
78
79 # -----------------------------------------------------------------------------
80 # D1 Structure manipulation
81 # -----------------------------------------------------------------------------
82 sub mk_root {
83     my ($self, $name) = @_;
84     return (IDZebra::data1_mk_root($self->{dh}, $self->{mem}, $name));
85 }
86
87 sub set_root {
88     my ($self, $node, $name) = @_;
89     IDZebra::data1_set_root($self->{dh}, $node, $self->{mem}, $name);
90 }
91
92 sub mk_tag {
93     my ($self, $parent, $tag, @attributes) = @_;
94     return (IDZebra::data1_mk_tag($self->{dh}, $self->{mem},
95                                   $tag, \@attributes, $parent)); 
96 }
97
98 sub tag_add_attr {
99     my ($self, $node, @attributes) = @_;
100     IDZebra::data1_tag_add_attr ($self->{dh}, $self->{mem},
101                                  $node, \@attributes);
102 }
103
104 sub mk_text {
105     my ($self, $parent, $text) = @_;
106     $text = "" unless defined ($text);
107     return (IDZebra::data1_mk_text($self->{dh}, $self->{mem},
108                                    $text, $parent)); 
109 }
110
111 sub mk_comment {
112     my ($self, $parent, $text) = @_;
113     return (IDZebra::data1_mk_comment($self->{dh}, $self->{mem},
114                                    $text, $parent)); 
115 }
116
117 sub mk_preprocess {
118     my ($self, $parent, $target, @attributes) = @_;
119     return (IDZebra::data1_mk_preprocess($self->{dh}, $self->{mem},
120                                          $target, \@attributes, $parent)); 
121 }
122
123
124 sub pr_tree {
125     my ($self, $node) = @_;
126     IDZebra::data1_print_tree($self->{dh}, $node);
127 }
128
129 sub free_tree {
130     my ($self, $node) = @_;
131     IDZebra::data1_free_tree($self->{dh}, $node);
132
133
134 # =============================================================================
135
136 __END__
137
138 =head1 NAME
139
140 IDZebra::Data1 - OO Aproach interface for data1 structures
141
142 =head1 SYNOPSIS
143
144    use IDZebra::Data1;
145
146    my $m = IDZebra::nmem_create();
147    my $d1=IDZebra::Data1->new($m,$IDZebra::DATA1_FLAG_XML);
148    my $root = $d1->mk_root('ostriches');
149    my $tag  = $d1->mk_tag($root,'emu',('speed'  => 120,
150                                        'height' => 110));
151    $d1->pr_tree($root);
152
153 =head1 DESCRIPTION
154
155 I never managed to understand data1 entirely. Probably Adam, or someone else from IndexData could write a more deep introduction here. However here are some ideas:
156
157 Data1 structures are used in zebra to represent structured data. You can map an xml structure, a marc record, or anything in D1. These structures are built by different filters - this is called "extraction" in zebra's code. 
158
159 When zebra asks a filter to extract a file, it provides a data1 handle, which can be used to
160
161   - reach profile information, provided in zebra.cfg, and other refered 
162     configuration files, (like tab path).
163
164   - build data1 structures
165
166 In one word, a data1 handle is a kind of context in the d1 API. This handle is represented here as a IDZebra::Data1 object. When you implement a filter, you'll get this object ready for use, otherwise, you'll have to prepare an NMEM handle, and call the constructor:
167
168    my $m = IDZebra::nmem_create();
169    my $dh = IDZebra::Data1->new($m,$IDZebra::DATA1_FLAG_XML);
170
171 What is FLAG_XML? I don't know exactly. You don't have to worry about it, it's already set, if you implement a filter. 
172
173 =head1 PROFILE INFORMATION
174
175 =item $d1->tabpath([$path])
176
177 Set and/or get the tab path. This is a colon separated list of directories, where different configuration files can be found.
178
179 =item $d1->tabroot([$path])
180
181 Set and/or get the tab root.
182
183 =head1 BUILDING DATA STRUCTURES
184
185 It's obvious, that first of all you have to create a root node:
186
187    my $r1 = $d1->mk_root('pod');    
188
189 This is going to initialize the abstract syntax "pod" (trying to open and parse pod.abs). I don't know why exactly, but then, you'll have to create a root tag as well, under the same name.
190
191    my $root=$d1->mk_tag($r1,'pod');
192
193 Then just continue, to add child nodes, as tags, text nodes... to your structure. 
194
195 =item $d1->mk_root($name)
196
197 Create a root node, with the given name. (name is type in d1 terminology?)
198
199 =item $d1->set_root($node, $name)
200
201 Makes an existing node into root node, under the given name
202
203 =item $d1->mk_tag($parent, $name, [@attributes])
204
205 Add a tag to the parent node, with the given name and attributes. For example:
206
207    my $tag  = $d1->mk_tag($root,'emu',('speed'  => 120,
208                                        'height' => 110));
209
210 =item $d1->tag_add_attr($node, @attributes)
211
212 Add attributes to an existing node
213
214 =item $d1->mk_text($parent, $text)
215
216 Add a text node to the given parent
217
218 =item $d1->mk_comment($parent, $text)
219
220 Add a comment node to the given parent
221
222 =item $d1->mk_preprocess($parent, $target, $attributes)
223
224 ???
225
226 =item $d1->pr_tree($node)
227
228 Prints data1 tree on STDOUT;
229
230 =item $d1->free_tree($node)
231
232 Destroys a data1 node structure;
233
234 =head1 COPYRIGHT
235
236 Fill in
237
238 =head1 AUTHOR
239
240 Peter Popovics, pop@technomat.hu
241
242 =head1 SEE ALSO
243
244 IDZebra, Zebra documentation
245
246 =cut