1# -*- Mode: Perl -*-
2#
3# Parser.pm - Redland Perl RDF Parser module
4#
5# Copyright (C) 2000-2005 David Beckett - http://www.dajobe.org/
6# Copyright (C) 2000-2005 University of Bristol - http://www.bristol.ac.uk/
7#
8# This package is Free Software and part of Redland http://librdf.org/
9#
10# It is licensed under the following three licenses as alternatives:
11#   1. GNU Lesser General Public License (LGPL) V2.1 or any newer version
12#   2. GNU General Public License (GPL) V2 or any newer version
13#   3. Apache License, V2.0 or any newer version
14#
15# You may not use this file except in compliance with at least one of
16# the above three licenses.
17#
18# See LICENSE.html or LICENSE.txt at the top of this package for the
19# full license terms.
20#
21#
22#
23
24package RDF::Redland::Parser;
25
26use strict;
27
28use RDF::Redland::Stream;
29
30=pod
31
32=head1 NAME
33
34RDF::Redland::Parser - Redland RDF Syntax Parsers Class
35
36=head1 SYNOPSIS
37
38  use RDF::Redland;
39
40  ...
41  my $parser=new RDF::Redland::Parser("rdfxml");
42  my $parser2=new RDF::Redland::Parser(undef, "application/rdf+xml);
43
44  # Return as an RDF::Redland::Stream
45  my $stream=$parser->parse_as_stream($source_uri, $base_uri);
46
47  # Store in an RDF::Redland::Model
48  $parser->parse_into_model($source_uri, $base_uri, $model);
49
50=head1 DESCRIPTION
51
52This class represents parsers of various syntaxes that can deliver a
53RDF model either as a RDF::Redland::Stream of RDF::Redland::Statement objects or
54directly into an RDF::Redland::Model object.
55
56=cut
57
58######################################################################
59
60=pod
61
62=head1 CONSTRUCTORS
63
64=over
65
66=item new [NAME [MIME_TYPE [URI]]]
67
68Create a new RDF::Redland::Parser object for a syntax parser named I<NAME>,
69with MIME Type I<MIME_TYPE> and/or URI I<URI>.  Any field can be undef
70or omitted; if all are omitted, a parser that provides MIME Type
71application/rdf+xml will be requested.
72
73=cut
74
75# CONSTRUCTOR
76# (main)
77sub new ($;$$$) {
78  my($proto,$name,$mime_type,$uri)=@_;
79  my $class = ref($proto) || $proto;
80  my $self  = {};
81  my $reduri = undef;
82
83  if(defined $uri) {
84    $reduri=$uri->{URI};
85  }
86
87  $self->{PARSER}=&RDF::Redland::CORE::librdf_new_parser($RDF::Redland::World->{WORLD},$name,$mime_type,$reduri);
88  return undef if !$self->{PARSER};
89
90  bless ($self, $class);
91  return $self;
92}
93
94=pod
95
96=back
97
98=cut
99
100sub DESTROY ($) {
101  warn "RDF::Redland::Parser DESTROY\n" if $RDF::Redland::Debug;
102  &RDF::Redland::CORE::librdf_free_parser(shift->{PARSER});
103}
104
105=head1 METHODS
106
107=over
108
109=item parse_as_stream SOURCE_URI BASE_URI
110
111Parse the syntax at the RDF::Redland::URI I<SOURCE_URI> with optional base
112RDF::Redland::URI I<BASE_URI>.  If the base URI is given then the content is
113parsed as if it was at the base URI rather than the source URI.
114
115Returns an RDF::Redland::Stream of RDF::Redland::Statement objects or
116undef on failure.
117
118=cut
119
120sub parse_as_stream ($$$) {
121  my($self,$uri,$base_uri)=@_;
122  my $rbase_uri=$base_uri ? $base_uri->{URI} : undef;
123  my $stream=&RDF::Redland::CORE::librdf_parser_parse_as_stream($self->{PARSER},$uri->{URI}, $rbase_uri);
124  return undef if !$stream;
125  return new RDF::Redland::Stream($stream,$self);
126}
127
128=item parse_into_model SOURCE_URI BASE_URI MODEL [HANDLER]
129
130Parse the syntax at the RDF::Redland::URI I<SOURCE_URI> with optional base
131RDF::Redland::URI I<BASE_URI> into RDF::Redland::Model I<MODEL>.  If the base URI is
132given then the content is parsed as if it was at the base URI rather
133than the source URI.
134
135If the optional I<HANDLER> is given, it is a reference to a sub with the signature
136  sub handler($$$$$$$$$) {
137    my($code, $level, $facility, $message, $line, $column, $byte, $file, $uri)=@_;
138    ...
139  }
140that receives errors in parsing.
141
142=cut
143
144sub parse_into_model ($$$$;$) {
145  my($self,$uri,$base_uri,$model,$handler)=@_;
146  if($handler) {
147    &RDF::Redland::set_log_handler($handler);
148  }
149  my $rbase_uri=$base_uri ? $base_uri->{URI} : undef;
150  my $rc=&RDF::Redland::CORE::librdf_parser_parse_into_model($self->{PARSER},$uri->{URI},$rbase_uri,$model->{MODEL});
151  if($handler) {
152    &RDF::Redland::reset_log_handler();
153  }
154  return $rc;
155}
156
157=item parse_string_as_stream STRING BASE_URI
158
159Parse the syntax in I<STRING> with required base
160RDF::Redland::URI I<BASE_URI>.
161
162Returns an RDF::Redland::Stream of RDF::Redland::Statement objects or
163undef on failure.
164
165=cut
166
167sub parse_string_as_stream ($$$) {
168  my($self,$string,$base_uri)=@_;
169  my $rbase_uri=$base_uri ? $base_uri->{URI} : undef;
170  my $stream=&RDF::Redland::CORE::librdf_parser_parse_string_as_stream($self->{PARSER},$string, $rbase_uri);
171  return undef if !$stream;
172  return new RDF::Redland::Stream($stream,$self);
173}
174
175=item parse_string_into_model STRING BASE_URI MODEL [HANDLER]
176
177Parse the syntax in I<STRING> with required base
178RDF::Redland::URI I<BASE_URI> into RDF::Redfland::Model I<MODEL>.
179
180If the optional I<HANDLER> is given, it is a reference to a sub with the signature
181  sub handler($$$$$$$$$) {
182    my($code, $level, $facility, $message, $line, $column, $byte, $file, $uri)=@_;
183    ...
184  }
185that receives errors in parsing.
186
187=cut
188
189sub parse_string_into_model ($$$$;$) {
190  my($self,$string,$base_uri,$model,$handler)=@_;
191  if($handler) {
192    &RDF::Redland::set_log_handler($handler);
193  }
194  my $rbase_uri=$base_uri ? $base_uri->{URI} : undef;
195  my $rc=&RDF::Redland::CORE::librdf_parser_parse_string_into_model($self->{PARSER},$string,$rbase_uri,$model->{MODEL});
196  if($handler) {
197    &RDF::Redland::reset_log_handler();
198  }
199  return $rc;
200}
201
202=item feature URI [VALUE]
203
204Get/set a parser feature.  The feature is named via RDF::Redland::URI
205I<URI> and the value is a RDF::Redland::Node.  If I<VALUE> is given,
206the feature is set to that value, otherwise the current value is
207returned.
208
209=cut
210
211sub feature ($$;$) {
212  my($self,$uri,$value)=@_;
213
214  warn "RDF::Redland::Parser->feature('$uri', '$value')\n"
215    if $RDF::Redland::Debug;
216  $uri=RDF::Redland::URI->new($uri)
217    unless ref $uri;
218
219  if(!defined $value) {
220    $value=&RDF::Redland::CORE::librdf_parser_get_feature($self->{PARSER},
221							  $uri->{URI});
222    return $value ? RDF::Redland::Node->_new_from_object($value,1) : undef;
223  }
224
225  $value=RDF::Redland::LiteralNode->new($value)
226    unless ref $value;
227
228  return &RDF::Redland::CORE::librdf_parser_set_feature($self->{PARSER},
229							$uri->{URI},
230							$value->{NODE})
231
232}
233
234
235=item namespaces_seen
236
237Get the set of namespace declarations seen during parsing as a
238hash of key:prefix string (may be ''), value: RDF::Redland::URI objects.
239
240=cut
241
242sub namespaces_seen($) {
243  my $self=shift;
244
245  my $count=&RDF::Redland::CORE::librdf_parser_get_namespaces_seen_count($self->{PARSER});
246  my(%namespaces)=();
247  for (my $offset=0; $offset < $count; $offset++) {
248    my $prefix=&RDF::Redland::CORE::librdf_parser_get_namespaces_seen_prefix($self->{PARSER}, $offset);
249    $prefix ||= '';
250    my $uri=&RDF::Redland::CORE::librdf_parser_get_namespaces_seen_uri($self->{PARSER}, $offset);
251    my $ruri=$uri ?  RDF::Redland::URI->_new_from_object($uri) : undef;
252    $namespaces{$prefix}=$ruri;
253    }
254  return %namespaces;
255}
256
257
258=pod
259
260=back
261
262=head1 SEE ALSO
263
264L<RDF::Redland::URI>
265
266=head1 AUTHOR
267
268Dave Beckett - http://www.dajobe.org/
269
270=cut
271
2721;
273