1#
2# RDF.py - Redland Python RDF module
3#
4# Copyright (C) 2000-2011 David Beckett - http://www.dajobe.org/
5# Copyright (C) 2000-2005 University of Bristol - http://www.bristol.ac.uk/
6#
7# This package is Free Software and part of Redland http://librdf.org/
8#
9# It is licensed under the following three licenses as alternatives:
10#   1. GNU Lesser General Public License (LGPL) V2.1 or any newer version
11#   2. GNU General Public License (GPL) V2 or any newer version
12#   3. Apache License, V2.0 or any newer version
13#
14# This one file RDF.py is also available under the following license:
15#
16#   4. BSD License without advertising (aka MIT license)
17#      from http://www.opensource.org/licenses/mit-license.html
18#
19#      -------------------------------------------------------------------
20#      Permission is hereby granted, free of charge, to any person
21#      obtaining a copy of this software and associated documentation
22#      files (the "Software"), to deal in the Software without
23#      restriction, including without limitation the rights to use, copy,
24#      modify, merge, publish, distribute, sublicense, and/or sell copies
25#      of the Software, and to permit persons to whom the Software is
26#      furnished to do so, subject to the following conditions:
27#
28#      The above copyright notice and this permission notice shall be
29#      included in all copies or substantial portions of the Software.
30#
31#      THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
32#      EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
33#      MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
34#      NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
35#      BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
36#      ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
37#      CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
38#      SOFTWARE.
39#     --------------------------------------------------------------------
40#
41# You may not use this file except in compliance with at least one of
42# the above four licenses.
43#
44# See LICENSE.html or LICENSE.txt at the top of this package for the
45# full license terms.
46#
47#
48
49from __future__ import generators
50
51# TODO:
52# * express failure conditions with Exceptions -- create a class hierarchy
53#   of exceptions for Redland
54# * rename modules: Redland as _Redland, RDF as Redland
55
56
57"""Redland Python API
58
59  import RDF
60
61  storage=RDF.Storage(...)
62  model=RDF.Model(storage)
63
64  ... do stuff
65
66The Python interface to the Redland RDF library.  See
67  http://librdf.org/
68for full details.
69
70The main class that is used is Model which represents the RDF graph
71formed from triples or Statements.  These statements consist of
72three Node objects for resource or literals and can be stored in
73a Storage (persistent or in-memory) as well as serialized to/from
74syntaxes via the Serializer or Parser classes.  The Query class
75provides a way to use a query language with a Model, returning
76answers in QueryResults objects.
77
78"""
79
80import sys
81import string
82
83__all__ = [ "Node",
84            "Statement",
85            "Model",
86            "Iterator",
87            "Serializer",
88            "NTriplesSerializer",
89            "RDFXMLSerializer",
90            "Stream",
91            "Storage",
92            "MemoryStorage",
93            "HashStorage",
94            "Uri",
95            "Parser",
96            "TurtleParser",
97            "NTriplesParser",
98            "NS",
99            "Query",
100            "RDQLQuery",
101            "SPARQLQuery",
102            "debug"]
103
104__version__ = "1.1"
105
106# For pydoc
107__date__ = '$Date$'
108__author__ = 'Dave Beckett - http://www.dajobe.org/, Edd Dumbill <edd@usefulinc.com> and Matt Biddulph <mb@picdiary.com>'
109
110# Package variables [globals]
111#   Python style says to use _ to prevent exporting
112#   Use two underscores "(class-private names,
113#     enforced by Python 1.4) in those cases where it is important
114#     that only the current class accesses an attribute"
115#      -- http://python.sourceforge.net/peps/pep-0008.html
116
117_debug = 0
118_world = None
119
120_node_types={
121    'NODE_TYPE_UNKNOWN'   : 0,
122    'NODE_TYPE_RESOURCE'  : 1,
123    'NODE_TYPE_LITERAL'   : 2,
124    'NODE_TYPE_BLANK'     : 4}
125
126import Redland
127
128if sys.version_info >= (3,0,0):
129  PY3 = True
130  def unicode(s, enc=None):
131    if not isinstance(s, str):
132      return str(s)
133    else:
134      return s
135else:
136  PY3 = False
137
138class RedlandError(Exception):
139  """Redland Runtime errors"""
140  def __init__(self, value):
141    self.value = value
142
143  def __str__(self):
144    return repr(self.value)
145
146class NodeTypeError(RedlandError):
147  pass
148
149class RedlandWarning(Warning):
150  pass
151
152def node_type(name):
153  """Return the Redland node type of a node name"""
154  if name in _node_types:
155    return _node_types[name]
156  else:
157    raise NodeTypeError('Unknown node type %s' % name)
158
159def node_type_name(num):
160  """Return the name of a Redland node type"""
161  for n in list(_node_types.keys()):
162    if num==_node_types[n]:
163      return n
164  raise NodeTypeError('Unknown node type number %d' % num)
165
166def message_handler (type, message):
167  raise RedlandError("Obsolete method")
168
169def set_message_handler(handler):
170  raise RedlandError("Obsolete method")
171
172class World(object):
173  """Redland Initialisation class.
174
175  There are no user methods (can only be constructed).
176
177  """
178
179  def __init__(self,digest_name="",uri_hash=None):
180    """Create new RDF World object (constructor)"""
181    #trick to ensure function exists during module cleanup
182    self._cleanup = Redland.librdf_free_world
183
184    self._world = None
185
186    self._world = Redland.librdf_new_world()
187    Redland.librdf_world_open(self._world)
188
189    Redland.librdf_python_world_init(self._world)
190
191  def __del__(self):
192    """Destroy RDF World object (destructor)."""
193    global _debug
194    if self._world:
195      if _debug:
196        print("Destroying RDF.World")
197      self._cleanup(self._world)
198
199# end class World
200
201
202def debug(value = None):
203  """Get/set Redland debugging output status.
204
205  RDF.debug (1)   # enable debugging
206  if RDF.debug(): # test for debug mode
207  """
208  global _debug
209  if value is not None:
210      _debug = value
211  else:
212      return _debug
213
214
215class Node(object):
216  """Redland Node (RDF Resource, Property, Literal) Class
217
218    import RDF
219
220    node1=RDF.Node()
221
222    node2=RDF.Node(RDF.Uri("http://example.com/"))
223    node3=RDF.Node("Hello, World!")
224
225    node4=RDF.Node(uri_string="http://example.com/")
226    node5=RDF.Node(literal="<tag>content</tag>", is_wf_xml=1)
227    node6=RDF.Node(blank="abc")
228    node7=RDF.Node(node5)
229  ...
230
231    print node2
232    if node7.is_resource():
233      print "Resource with URI", node7.uri
234
235    if node5.is_blank():
236      print "Resource with blank node name ", node5.blank_identifier
237
238  """
239
240  def __init__(self, arg = None, **args):
241    """Create an RDF Node (constructor).
242
243    Resource or Property node creation:
244
245      n1 = Node(Uri("http://example.com/foo"))
246
247    String literal node creation (see below for more complex
248    ways of building literals.)
249
250      n2 = Node("foo")
251
252    Node copying:
253
254      n3 = Node(n1)
255
256    Or create a new RDF Node using the following named parameters:
257
258      uri_string  - create a resource node from a string URI
259      uri         - create a resource node from a URI object
260      literal     - create a literal node from a literal string
261        datatype     - the datatype URI
262        is_wf_xml    - the literal is XML (alternative to datatype)
263        language     - the literal XML language
264      blank       - create a resource node from with a blank node identiifer
265      node        - copy a node
266    """
267
268    global _world
269    global _debug
270    if _debug:
271      print("Creating RDF.Node args=",args)
272    self._node=None
273
274    if arg is not None:
275      if isinstance(arg, str):
276        args['literal'] = arg
277      elif not PY3 and isinstance(arg, unicode):
278        import Redland_python
279        args['literal'] = Redland_python.unicode_to_bytes(arg)
280      elif isinstance(arg, Uri):
281        args['uri'] = arg
282      elif isinstance(arg, Node):
283        args['node'] = arg
284
285    if not PY3 and 'literal' in args and isinstance(args['literal'], unicode):
286        import Redland_python
287        args['literal'] = Redland_python.unicode_to_bytes(args['literal'])
288
289    if 'uri_string' in args:
290      self._node=Redland.librdf_new_node_from_uri_string(_world._world,
291        args['uri_string'])
292
293    elif 'uri' in args:
294      # no need to copy the underlying uri as the redland C api does
295      # this on node construction
296      self._node = Redland.librdf_new_node_from_uri(_world._world,
297              args['uri']._reduri)
298
299    elif 'literal' in args:
300      if 'xml_language' in args:
301        xml_language=args['xml_language']
302      elif 'language' in args:
303        xml_language=args['language']
304      else:
305        xml_language=None
306      if 'is_wf_xml' in args:
307        is_wf_xml=args['is_wf_xml']
308      else:
309        is_wf_xml=0
310      if 'datatype' in args:
311        datatype=args['datatype']
312        self._node=Redland.librdf_new_node_from_typed_literal(_world._world,
313          args['literal'], xml_language, datatype._reduri)
314      else:
315        self._node=Redland.librdf_new_node_from_literal(_world._world,
316          args['literal'], xml_language, is_wf_xml)
317
318    elif 'node' in args:
319      self._node=Redland.librdf_new_node_from_node(args['node']._node)
320
321    elif 'blank' in args:
322      self._node=Redland.librdf_new_node_from_blank_identifier(_world._world, args['blank'])
323
324    elif 'from_object' in args:
325      if 'do_not_copy' in args:
326        self._node=args['from_object']
327      else:
328        self._node=Redland.librdf_new_node_from_node(args['from_object'])
329    else:
330      self._node=Redland.librdf_new_node(_world._world)
331
332    if self._node is None:
333        raise RedlandError("Node construction failed")
334
335  def __del__(self):
336    """Free an RDF Node (destructor)."""
337    global _debug
338    if _debug:
339      print("Destroying RDF.Node")
340    if self._node:
341      if _debug:
342        print("Deleting Redland node object")
343      Redland.librdf_free_node(self._node)
344
345  def _get_uri(self):
346    # we return a copy of our internal uri
347    if self.is_resource():
348      return Uri(from_object=Redland.librdf_node_get_uri(self._node))
349    else:
350      raise NodeTypeError("Can't get URI for node type %s (%d)" % \
351                          (node_type_name(self.type), self.type))
352
353  def _get_type(self):
354    return Redland.librdf_node_get_type(self._node)
355
356  uri = property(_get_uri, doc = "The URI of a resource node")
357  type = property(_get_type, doc = "The node type, an integer")
358
359  def _get_literal (self):
360    if not self.is_literal():
361      raise NodeTypeError("Can't get literal value for node type %s (%d)" % \
362            (node_type_name(self.type), self.type))
363
364    dt_uri = Redland.librdf_node_get_literal_value_datatype_uri(self._node)
365
366    if dt_uri:
367      dt_uri = Uri(string=Redland.librdf_uri_to_string(dt_uri))
368
369    return (unicode(Redland.librdf_node_get_literal_value(self._node), 'utf-8'),
370            Redland.librdf_node_get_literal_value_language(self._node),
371            dt_uri)
372
373  def _get_literal_value (self):
374    if not self.is_literal():
375      raise NodeTypeError("Can't get literal value for node type %s (%d)" % \
376            (node_type_name(self.type), self.type))
377
378    dt_uri = Redland.librdf_node_get_literal_value_datatype_uri(self._node)
379
380    if dt_uri:
381      dt_uri = Uri(string=Redland.librdf_uri_to_string(dt_uri))
382
383    val={
384        'string': unicode(Redland.librdf_node_get_literal_value(self._node), 'utf-8'),
385        'language': Redland.librdf_node_get_literal_value_language(self._node),
386        'datatype': dt_uri
387        }
388    return val
389
390  literal = property(_get_literal,
391          doc = "A tuple of the string, language and datatype values of the node")
392
393  literal_value = property(_get_literal_value,
394          doc = "A dictionary containing the value of the node literal with keys string, language and datatype")
395
396  def _get_blank_identifier(self):
397    if not self.is_blank():
398      raise NodeTypeError("Can't get blank identifier for node type %s (%d)" % \
399            (node_type_name(self.type), self.type))
400    else:
401      return unicode(Redland.librdf_node_get_blank_identifier(self._node), 'utf-8')
402
403  blank = property(_get_blank_identifier,
404          doc = "The blank node identifier")
405
406  blank_identifier = property(_get_blank_identifier,
407          doc = "The node identifier of a blank node")
408
409  def __str__(self):
410    """Get a string representation of an RDF Node."""
411    value = self.__unicode__()
412    if PY3:
413      return value
414    else:
415      return value.encode('utf-8')
416
417  def __unicode__(self):
418    """Get a Unicode string representation of an RDF Node."""
419    if self._node is None:
420      raise RedlandError("Node is invalid")
421    elif self.is_literal():
422      return unicode(Redland.librdf_node_get_literal_value(self._node), 'utf-8')
423    elif self.is_blank():
424      return self._get_blank_identifier()
425    else:
426      return unicode(self.uri)
427
428  def __eq__(self,other):
429    """Equality of an RDF Node compared to another RDF Node."""
430    if not isinstance(other, self.__class__):
431      return False
432    return (Redland.librdf_node_equals(self._node, other._node) != 0)
433
434  def __ne__(self,other):
435    """Inequality of an RDF Node compared to another RDF Node."""
436    return not self == other
437
438  def __hash__(self):
439    return hash(unicode(self))
440
441  def is_resource(self):
442    """Return true if node is a resource  with a URI"""
443    return (Redland.librdf_node_is_resource(self._node) != 0)
444
445  def is_literal(self):
446    """Return true if node is a literal"""
447    return (Redland.librdf_node_is_literal(self._node) != 0)
448
449  def is_blank(self):
450    """Return true if node is a blank node"""
451    return (Redland.librdf_node_is_blank(self._node) != 0)
452
453# end class Node
454
455
456class Statement(object):
457  """Redland Statement (triple) class.  The main means of manipulating
458  statements is by the subject, predicate and object properties.
459
460    import RDF
461    statement1 = RDF.Statement(node1, node2, node3)
462    statement2 = RDF.Statement(statement = statement1)
463
464    if statement2.subject.is_resource():
465      print "statement2 subject is URI ",statement2.subject.uri
466
467    statement.object = Node("hello, world")
468  """
469
470  def __init__(self, subject = None, predicate = None,
471          object = None, **args):
472    """Constructor for Statement.
473
474    Create a Statement from three Node objects.
475
476        s1 = RDF.Statement(subjnode, prednode, objnode)
477
478    A Node argument can be replaced with Uri or string to
479    shortcut Node creation.
480
481        s2 = RDF.Statement(Uri("http://foo"), Uri("http://bar"), "baz")
482
483    Copy an existing Statement s1.
484
485        s3 = RDF.Statement(statement=s1)
486    """
487    global _world
488    global _debug
489    if _debug:
490      print("Creating RDF.Statement subject=",subject,"predicate=",predicate,"object=",object,"args=",args)
491
492    self._statement = None
493
494    if 'statement' in args:
495      self._statement=Redland.librdf_new_statement_from_statement(
496          args['statement']._statement)
497
498    elif 'from_object' in args:
499      self._statement = Redland.librdf_new_statement_from_statement(
500          args['from_object'])
501
502    else:
503      if subject is None:
504        s = None
505      else:
506        if isinstance(subject, Uri) or isinstance(subject, str):
507          subject = Node(subject)
508        elif not PY3 and isinstance(subject, unicode):
509          import Redland_python
510          subject = Node(Redland_python.unicode_to_bytes(subject))
511        s = Redland.librdf_new_node_from_node(subject._node)
512
513      if predicate is None:
514        p = None
515      else:
516        if isinstance(predicate, Uri) or isinstance(predicate, str):
517          predicate = Node(predicate)
518        elif not PY3 and isinstance(predicate, unicode):
519          import Redland_python
520          predicate = Node(Redland_python.unicode_to_bytes(predicate))
521        p = Redland.librdf_new_node_from_node(predicate._node)
522
523      if object is None:
524        o = None
525      else:
526        if isinstance(object, Uri) or isinstance(object, str):
527          object = Node(object)
528        elif not PY3 and isinstance(object, unicode):
529          import Redland_python
530          object = Node(Redland_python.unicode_to_bytes(object))
531        o = Redland.librdf_new_node_from_node(object._node)
532
533      self._statement=Redland.librdf_new_statement_from_nodes(
534          _world._world, s, p, o)
535
536    if self._statement is None:
537        raise RedlandError("Statement construction failed")
538
539  def __del__(self):
540    global _debug
541    if _debug:
542      print("Destroying RDF.Statement")
543    if self._statement:
544      if _debug:
545        print("Deleting Redland statement object")
546      Redland.librdf_free_statement(self._statement)
547
548  def _wrap_node(self, rednode):
549    if rednode is None:
550      return None
551    return Node(from_object=rednode)
552
553  def _get_subject(self):
554    return self._wrap_node(
555      Redland.librdf_statement_get_subject(self._statement))
556
557  def _get_object(self):
558    return self._wrap_node(
559      Redland.librdf_statement_get_object(self._statement))
560
561  def _get_predicate(self):
562    return self._wrap_node(
563      Redland.librdf_statement_get_predicate(self._statement))
564
565  def _set_subject(self, value):
566    if value is None:
567      Redland.librdf_statement_set_subject(self._statement, None)
568    else:
569      Redland.librdf_statement_set_subject(self._statement,
570          Redland.librdf_new_node_from_node(value._node))
571
572  def _set_object(self, value):
573    if value is None:
574      Redland.librdf_statement_set_object(self._statement, None)
575    else:
576      Redland.librdf_statement_set_object(self._statement,
577          Redland.librdf_new_node_from_node(value._node))
578
579  def _set_predicate(self, value):
580    if value is None:
581      Redland.librdf_statement_set_predicate(self._statement, None)
582    else:
583      Redland.librdf_statement_set_predicate(self._statement,
584          Redland.librdf_new_node_from_node(value._node))
585
586  object = property(_get_object, _set_object,
587          doc = "The object node of the statement.")
588  subject = property(_get_subject, _set_subject,
589          doc = "The subject node of the statement.")
590  predicate = property(_get_predicate, _set_predicate,
591          doc = "The predicate node of the statement.")
592
593  def __str__(self):
594    if self._statement is None:
595      raise RedlandError("Statement is invalid")
596    else:
597      return Redland.librdf_statement_to_string(self._statement)
598
599  def __unicode__(self):
600    if self._statement is None:
601      raise RedlandError("Statement is invalid")
602    else:
603      return unicode(Redland.librdf_statement_to_string(self._statement), 'utf-8')
604
605  def __eq__(self,other):
606    """Equality of an RDF Statement compared to another RDF Statement."""
607    if not isinstance(other, self.__class__):
608      return False
609    return (Redland.librdf_statement_equals(self._statement, other._statement) != 0)
610
611  def __ne__(self,other):
612    """Inequality of an RDF Statement compared to another RDF Statement."""
613    return not self == other
614
615  def matches(self,other):
616    """Comparison of this potentially incomplete RDF Statement compared to another RDF Statement."""
617    if other is None:
618      return (self is None)
619    return (Redland.librdf_statement_match(other._statement, self._statement) != 0)
620
621# end class Statement
622
623
624class Model(object):
625  """Redland Graph class
626
627    import RDF
628    model = RDF.Model(storage)
629
630  The main interface to the Redland RDF graph (formed from triples, or
631  RDF statements).  There are many methods for adding, removing, querying
632  statements and serializing them to/from syntaxes using the Serializer
633  or Parser classes.
634
635  Models can also be used as Python sequences to give every triple in the
636  model:
637
638    for statement in model:
639      print statement
640
641  Models have other aspects of sequence types.  The following also works:
642
643    if statement in model:            # do whatever
644    if (statement, context) in model: # do whatever
645
646    del model[statement]              # remove statement from model
647    del model[statement, context]     # ditto for context-aware model
648
649    model.append(statement)           # append a statement
650    model.append(statement, context)  # append statement with context
651
652    num_items = len(model) # get number of statements in the model
653                           # works only with countable storages
654
655
656  """
657
658  def __init__(self, storage = None, **args):
659    """Create an RDF Model (constructor).
660
661Create a Model from an existing Storage (most common use).
662
663Optional parameters:
664
665  options_string - A string of options for the Model
666  options_hash   - A Hash of options for the Model
667
668  m1 = RDF.Model(s1)
669  m1 = RDF.Model(storage = s1)
670
671Copy an existing model m1, copying the underlying Storage of m1
672
673  m2 = RDF.Model(model = m1)
674
675Create a model using an in-memory storage.
676
677  m3 = RDF.Model()
678    """
679    global _world
680    global _debug
681    if _debug:
682      print("Creating RDF.Model args=",args)
683    self._model=None
684    self._storage=None
685
686    if storage is None:
687      storage = MemoryStorage()
688
689    if 'options_string' in args:
690      self._model=Redland.librdf_new_model(_world._world, storage._storage,
691        args['options_string'])
692    elif 'options_hash' in args:
693      self._model=Redland.librdf_new_model_with_options( _world._world,
694        storage._storage, args['options_hash'].hash)
695    elif 'model' in args:
696      self._model=Redland.librdf_new_model_from_model(storage._storage,
697                                                     args['model']._model)
698    else:
699      self._model=Redland.librdf_new_model(_world._world, storage._storage, "")
700
701    if self._model is None or self._model == "NULL":
702      self._model=None
703      raise RedlandError("Creating new Model failed")
704    else:
705      # keep a reference around so storage object is destroyed after this
706      self._storage=storage
707
708  def __iter__(self):
709    return self.as_stream().__iter__()
710
711  def __del__(self):
712    global _debug
713    if _debug:
714      print("Destroying RDF.Model")
715    if self._model:
716      Redland.librdf_free_model(self._model)
717
718  def __len__(self):
719    s = self.size()
720    if s < 0:
721      raise RedlandError("Attempt to get size when using non-countable storage.")
722    return s
723
724  def size(self):
725    """Return the size of the Model in number of statements.
726       Returns a value < 0 if number of statements not countable."""
727    return Redland.librdf_model_size(self._model)
728
729  def add(self,subject,predicate,object):
730    """Add the statement (subject,predicate,object) to the model.
731    DEPRECATED. Use Model.append(Statement(s,p,o)) instead."""
732    # the reason to deprecate this method is that the Node constructors
733    # will do a lot more checking.  This wanton calling of underlying
734    # C methods is a recipe for unexplained core dumps if any of the
735    # nodes are null or invalid.
736    return Redland.librdf_model_add(self._model,
737        Redland.librdf_new_node_from_node(subject._node),
738        Redland.librdf_new_node_from_node(predicate._node),
739        Redland.librdf_new_node_from_node(object._node))
740
741  def add_typed_literal_statement(self,subject,predicate,
742                                  string,xml_language=None,datatype=None):
743    """Add the Statement (subject,predicate, typed literal) to the Model
744       where the typed literal is constructed from the
745       literal string, optional XML language and optional datatype URI.
746       DEPRECATED. Use Model.append(Statement(s,p,o)) instead."""
747    # the reason to deprecate this method is that the Node constructors
748    # will do a lot more checking.  This wanton calling of underlying
749    # C methods is a recipe for unexplained core dumps if any of the
750    # nodes are null or invalid.
751    if datatype is not None:
752      rdatatype = datatype._reduri
753    else:
754      rdatatype = None
755    subject_copy = Redland.librdf_new_node_from_node(subject._node)
756    predicate_copy = Redland.librdf_new_node_from_node(predicate._node)
757    return Redland.librdf_model_add_typed_literal_statement(self._model,
758        subject_copy, predicate_copy, string, xml_language, rdatatype)
759
760  def add_statement(self,statement,context=None):
761    """Add the Statement to the Model with optional context Node.
762    For Python idiom you should use Model.append() instead, which does
763    the same thing."""
764    # adding a statement means it gets *copied* into the model
765    # we are free to re-use the statement after adding it
766    if context is not None:
767      rc = Redland.librdf_model_context_add_statement(self._model,
768              context._node, statement._statement)
769    else:
770      rc = Redland.librdf_model_add_statement(self._model,
771                                                statement._statement)
772    if rc != 0:
773      raise RedlandError("Adding statement failed")
774
775  def add_statements(self,statement_stream,context=None):
776    """Add the Stream of Statements to the Model with the optional
777    context Node"""
778    if context is not None:
779      return Redland.librdf_model_context_add_statements(self._model,
780              context._node, statement_stream._stream)
781    else:
782      return Redland.librdf_model_add_statements(self._model,
783                                                 statement_stream._stream)
784
785  def append(self, statement, context = None):
786      """Append a Statement to the Model, with optional context Node.
787
788        model.append(Statement(s, p, o)"""
789      self.add_statement(statement, context)
790
791  def remove_statement(self, statement, context = None):
792    """Remove the Statement from the Model with the optional context Node.
793    This is used by the __delitem__ method.  Preferred way of removing a
794    Statement is:
795
796        del model[statement]
797        del model[statement, context]
798    """
799    if context is not None:
800      return Redland.librdf_model_context_remove_statement(self._model,
801              context._node, statement._statement)
802    else:
803      return Redland.librdf_model_remove_statement(self._model,
804                                                   statement._statement)
805
806  def __delitem__(self, arg):
807    if isinstance(arg, tuple):
808      try:
809        (s, c) = arg
810        self.remove_statement(s, c)
811      except ValueError:
812        raise TypeError("can only del statement or (statement,context) tuple")
813    else:
814        self.remove_statement(arg)
815
816  def remove_statements_with_context(self, context):
817    """Remove all Statements from the Model with the given context Node"""
818    return Redland.librdf_model_context_remove_statements(self._model,
819                                                          context._node)
820
821  context_remove_statements = remove_statements_with_context
822
823  def contains_statement(self, statement):
824    """Return true if the Statement is in the Model"""
825    return Redland.librdf_model_contains_statement(self._model,
826        statement._statement)
827
828  def contains_statement_context(self, statement, context):
829    """Return true if the Statement is in the Model with the specified
830    context.  Note that the implementation is pretty inefficient."""
831    for (s, c) in self.find_statements_context(statement):
832      if c == context:
833        return 1
834    return 0
835
836  def __contains__(self, arg):
837    # provided here for efficiency, otherwise Python
838    # would iterate through the contents of the model
839    if isinstance(arg, tuple):
840      try:
841        (s, c) = arg
842        return self.contains_statement_context(s, c)
843      except ValueError:
844        raise TypeError("requires statement or (statement,context) tuple")
845    else:
846      return self.contains_statement(arg)
847
848
849  def as_stream(self, context = None):
850    """Return the Model as a Stream of Statements.  No need to use
851    this explicitly, instead do:
852
853        for statement in model:
854            # process statement
855    """
856    if context is None:
857      my_stream = Redland.librdf_model_as_stream(self._model)
858    else:
859      my_stream = Redland.librdf_model_context_as_stream(self._model,
860                                                         context._node)
861    return Stream(my_stream, self)
862
863  serialise = as_stream
864
865  def as_stream_context(self, context = None):
866    """Return the Model as a Stream of (statement, context) tuples.
867
868        for (s, c) in model.as_stream_context():
869            # do whatever
870
871       Specify the optional argument context if you want to hardwire
872       the stream's context.
873    """
874    return StreamWithContextIter(self.as_stream(context))
875
876  def find_statements(self,statement, context = None):
877    """Return a Stream of Statements matching the given Statement --
878       any nodes with value None of the statement match any Node in
879       the Model.
880
881       Specify the optional argument context if you want to search
882       only in one context.
883
884       qs = RDF.Statement(subject = None,
885           predicate = RDF.Node(uri_string = "http://example.com/pred"),
886           object = None)
887       for statement in model.find_statements(qs):
888           # do whatever
889
890    """
891    if context is None:
892      my_stream = Redland.librdf_model_find_statements(self._model,
893                                                     statement._statement)
894    else:
895      my_stream = Redland.librdf_model_find_statements_in_context(self._model,
896                                                                  statement._statement,
897                                                                  context._node)
898    return Stream(my_stream, self)
899
900  def find_statements_context(self,statement):
901    """Return a Stream of Statements with context, matching the given
902       Statement -- any nodes with value None of the statement match
903       any Node in the Model.
904
905       qs = RDF.Statement(subject = None,
906           predicate = RDF.Node(uri_string = "http://example.com/pred"),
907           object = None)
908       for (statement, context) in model.find_statements_context(qs):
909           # do whatever
910     """
911    return StreamWithContextIter(self.find_statements(statement))
912
913  def get_sources(self, predicate, target):
914    """Return a sequence of Node s that are the source
915       of Statements in the Model matching (?, predicate, target).
916
917       Instead of specifying a Node for predicate, you can shortcut with
918       a Uri, and with a Uri or string for target.
919
920       e.g.
921         model.get_sources(Uri("http://example.com/name"), "Fred")
922    """
923    if isinstance(predicate, Uri):
924      predicate = Node(predicate)
925    if isinstance(target, Uri) or isinstance(target, str):
926      target = Node(target)
927    elif isinstance(target, str):
928      import Redland_python
929      target = Node(Redland_python.unicode_to_bytes(target))
930
931    my_iterator = Redland.librdf_model_get_sources(self._model,
932                                                   predicate._node,
933                                                   target._node)
934    if my_iterator is None:
935      raise RedlandError("Unable to create iterator")
936
937    return Iterator(my_iterator, self, predicate, target)
938
939  sources = get_sources
940
941  def get_sources_context(self, predicate, target):
942    """As for Model.get_sources but returns a list of
943    (statement, context) tuples."""
944    return IteratorWithContextIter(self.get_sources(predicate, target))
945
946  def get_predicates(self,source,target):
947    """Return a sequence of Nodes that are the predicates
948       of Statements in the Model matching (source, ?, target).
949
950       Instead of specifying a Node for source, you can shortcut with
951       a Uri, and with a Uri or string for target.
952
953       e.g.
954         model.get_predicates(Uri("http://example.com/me"), "Fred")
955    """
956    if isinstance(source, Uri):
957      source = Node(source)
958    if isinstance(target, Uri) or isinstance(target, str):
959      target = Node(target)
960    elif isinstance(target, str):
961      import Redland_python
962      target = Node(Redland_python.unicode_to_bytes(target))
963
964    my_iterator=Redland.librdf_model_get_arcs(self._model, source._node,
965                                              target._node)
966    if my_iterator is None:
967      raise RedlandError("Unable to create iterator")
968
969    return Iterator(my_iterator,self,source,target)
970
971  arcs = get_predicates
972  get_arcs = get_predicates
973  predicates = get_predicates
974
975  def get_predicates_context(self, source, target):
976    """As for Model.get_predicates but returns a list of
977    (statement, context) tuples."""
978    return IteratorWithContextIter(self.get_predicates(source, target))
979
980  def get_targets(self, source, predicate):
981    """Return a sequence of Nodes that are the targets
982       of Statements in the Model matching (source, predicate, ?).
983
984       Instead of specifying a Node for source or predicate, you
985       can shortcut with a Uri.
986
987       e.g.
988
989         model.get_targets(Uri("http://example.com/me"), prednode)
990    """
991    if isinstance(source, Uri):
992      source = Node(source)
993    if isinstance(predicate, Uri):
994      predicate = Node(predicate)
995
996    my_iterator = Redland.librdf_model_get_targets(self._model, source._node,
997                                                   predicate._node)
998    if my_iterator is None:
999      raise RedlandError("Unable to create iterator")
1000
1001    return Iterator(my_iterator,self,source,predicate)
1002
1003  targets = get_targets
1004
1005  def get_targets_context(self, source, predicate):
1006    """As for Model.get_targets but returns a list of
1007    (statement, context) tuples."""
1008    return IteratorWithContextIter(self.get_targets(source, predicate))
1009
1010  def get_source(self, predicate, target):
1011    """Return one Node in the Model matching (?, predicate, target).
1012    The predicate can be a Node or Uri, the target a Node, Uri or string."""
1013    if isinstance(predicate, Uri):
1014      predicate = Node(predicate)
1015    if isinstance(target, Uri) or isinstance(target, str):
1016      target = Node(target)
1017    elif isinstance(target, str):
1018      import Redland_python
1019      target = Node(Redland_python.unicode_to_bytes(target))
1020
1021    my_node=Redland.librdf_model_get_source(self._model, predicate._node,
1022                                            target._node)
1023    if not my_node:
1024      return None
1025    else:
1026      return Node(from_object=my_node, do_not_copy=1)
1027
1028  def get_predicate(self,source,target):
1029    """Return one Node in the Model matching (source, ?, target).
1030    The source can be a Node or Uri, the target a Node, Uri or string."""
1031    if isinstance(source, Uri):
1032      source = Node(source)
1033    if isinstance(target, Uri) or isinstance(target, str):
1034      target = Node(target)
1035    elif isinstance(target, str):
1036      import Redland_python
1037      target = Node(Redland_python.unicode_to_bytes(target))
1038
1039    my_node=Redland.librdf_model_get_arc(self._model, source._node,
1040                                         target._node)
1041    if not my_node:
1042      return None
1043    else:
1044      return Node(from_object=my_node, do_not_copy=1)
1045
1046  get_arc = get_predicate
1047
1048  def get_target(self, source, predicate):
1049    """Return one Node in the Model matching (source, predicate, ?).
1050    The source and predicate can be a Node or Uri."""
1051    if isinstance(source, Uri):
1052      source = Node(source)
1053    if isinstance(predicate, Uri):
1054      predicate = Node(predicate)
1055
1056    my_node=Redland.librdf_model_get_target(self._model, source._node,
1057                                            predicate._node)
1058    if not my_node:
1059      return None
1060    else:
1061      return Node(from_object=my_node, do_not_copy=1)
1062
1063  def sync(self):
1064    """Synchronise the Model with the underlying Storage."""
1065    Redland.librdf_model_sync(self._model)
1066
1067  def get_contexts(self):
1068    """Return a sequence of context Nodes in the Model."""
1069
1070    my_iterator = Redland.librdf_model_get_contexts(self._model)
1071    if my_iterator is None:
1072      raise RedlandError("Unable to create iterator")
1073
1074    return Iterator(my_iterator,self)
1075
1076  def get_feature(self, uri):
1077    """Return the Node value of Model feature URI uri"""
1078    if not isinstance(uri, Uri):
1079      uri=Uri(string=uri)
1080
1081    value=Redland.librdf_model_get_feature(self._model,uri._reduri)
1082    if value == "NULL" or value == None:
1083      return None
1084    return Node(from_object=value)
1085
1086  def set_feature(self, uri, value):
1087    """Set the Node value of Model feature URI uri."""
1088    if not isinstance(uri, Uri):
1089      uri=Uri(string=uri)
1090    if not isinstance(value, Node):
1091      value=Node(literal=value)
1092    Redland.librdf_model_set_feature(self._model,uri._reduri,value._node)
1093
1094  def load(self, uri, name="", mime_type="", type_uri=None, handler=None):
1095    """Load triples into the Model from a URI in a syntax.
1096       Returns a boolean success or failure.
1097
1098       If no parser name is given, the parser to use is guessed.
1099
1100       If handler is given, an error handler with the signature
1101         def handler(code, level, facility, message, line, column, byte, file, uri)
1102       is called.
1103   """
1104    if isinstance(uri, str):
1105      uri = Uri(string=uri)
1106    elif not PY3 and isinstance(uri, unicode):
1107      import Redland_python
1108      uri = Uri(string=Redland_python.unicode_to_bytes(uri))
1109    if uri is None:
1110      raise TypeError("uri must be a string or RDF.Uri")
1111    ruri = uri._reduri
1112
1113    if isinstance(type_uri, str):
1114      type_uri = Uri(string=type_uri)
1115    elif not PY3 and isinstance(type_uri, unicode):
1116      import Redland_python
1117      type_uri = Uri(string=Redland_python.unicode_to_bytes(type_uri))
1118    if type_uri is not None:
1119      rtype_uri = type_uri._reduri
1120    else:
1121      rtype_uri = None
1122
1123    if handler is not None:
1124      import Redland_python
1125      Redland_python.set_callback(handler)
1126
1127    rc=Redland.librdf_model_load(self._model, ruri, name, mime_type, rtype_uri)
1128
1129    if handler is not None:
1130      import Redland_python
1131      Redland_python.reset_callback()
1132
1133    return (rc != None)
1134
1135  def to_string(self, base_uri=None, name="", mime_type="", type_uri=None):
1136    """Serialize the Model to a syntax.
1137
1138       print model.to_string(base_uri="http://example.org/base")
1139
1140       If no serializer name is given, the default serializer RDF/XML is used.
1141   """
1142    if isinstance(base_uri, str):
1143      base_uri = Uri(string=base_uri)
1144    elif not PY3 and isinstance(base_uri, unicode):
1145      import Redland_python
1146      base_uri = Uri(string=Redland_python.unicode_to_bytes(base_uri))
1147    if base_uri is not None:
1148      rbase_uri = base_uri._reduri
1149    else:
1150      rbase_uri = None
1151    if isinstance(type_uri, str):
1152      type_uri = Uri(string=type_uri)
1153    elif not PY3 and isinstance(type_uri, unicode):
1154      import Redland_python
1155      type_uri = Uri(string=Redland_python.unicode_to_bytes(type_uri))
1156    if type_uri is not None:
1157      rtype_uri = type_uri._reduri
1158    else:
1159      rtype_uri = None
1160    return Redland.librdf_model_to_string(self._model, rbase_uri, name, mime_type, rtype_uri)
1161
1162  def __str__(self):
1163    return self.to_string()
1164
1165  def __unicode__(self):
1166    return unicode(self.to_string(), 'utf-8')
1167
1168  def execute(self,query):
1169    results = Redland.librdf_model_query_execute(self._model,query._query)
1170    if results is not None:
1171      return QueryResults(query._query,results)
1172    else:
1173      return None
1174
1175  def run_as_statements(self,query):
1176    results = Redland.librdf_model_query_execute(self._model,query._query)
1177    if results is not None:
1178      s=Redland.librdf_query_results_as_stream(results)
1179      return Stream(s,results)
1180    else:
1181      return None
1182
1183
1184# end class Model
1185
1186
1187class Iterator(object):
1188  """Redland Node Iterator class
1189
1190     A class for iterating over a sequence of Node s such as
1191     those returned from a Model query.  Some methods return
1192     Iterator s or Python sequences.  If this is used, it works
1193     as follows:
1194
1195       iterator=model.get_targets_iterator(source, arc)
1196       while not iterator.end():
1197         # get the current Node
1198         node=iterator.current()
1199         # do something with it
1200         # (it is shared; you must copy it you want to keep it)
1201         ...
1202         iterator.next()
1203       iterator=None
1204
1205  """
1206
1207  def __init__(self,object,creator1=None,creator2=None,creator3=None):
1208    """Create an RDF Iterator (constructor)."""
1209    global _debug
1210    if _debug:
1211      print("Creating RDF.Iterator object=",object,"creator=",creator1)
1212
1213    self._iterator=object
1214    # keep references to the things we're iterating over so they
1215    # don't get destroyed before we're done with them.
1216    self._creator1=creator1
1217    self._creator2=creator2
1218    self._creator3=creator3
1219
1220  def __iter__(self):
1221    return IteratorIter(self)
1222
1223  def __del__(self):
1224    global _debug
1225    if _debug:
1226      print("Destroying RDF.Iterator")
1227    if self._iterator:
1228      Redland.librdf_free_iterator(self._iterator)
1229
1230  def end(self):
1231    """Return true if the iterator is exhausted"""
1232    return Redland.librdf_iterator_end(self._iterator)
1233
1234  def have_elements(self):
1235    print("""RDF.Iterator method have_elements is deprecated,
1236please use 'not iterator.end' instead.""")
1237    return Redland.librdf_iterator_have_elements(self._iterator)
1238
1239  def current(self):
1240    """Return the current object on the Iterator"""
1241    my_node=Redland.librdf_iterator_get_object(self._iterator)
1242    if my_node == "NULL" or my_node == None:
1243      return None
1244
1245    return Node(from_object=my_node)
1246
1247  def __next__(self):
1248    """Move to the next object on the Iterator"""
1249    Redland.librdf_iterator_next(self._iterator)
1250  next = __next__
1251
1252  def context(self):
1253    """Return the context Node of the current object on the Iterator"""
1254    my_node=Redland.librdf_iterator_get_context(self._iterator)
1255    if my_node == "NULL" or my_node == None:
1256      return None
1257
1258    return Node(from_object=my_node)
1259
1260# end class Iterator
1261
1262class StreamWithContextIter(object):
1263  def __init__(self,stream):
1264    global _debug
1265    if _debug:
1266      print("Creating StreamWithContextIter for Stream "+repr(stream))
1267    self.stream = stream
1268    self.first = 1
1269
1270  def __iter__(self):
1271    return self
1272
1273  def __next__(self):
1274    if self.first:
1275      self.first = 0
1276    else:
1277      next(self.stream)
1278    if self.stream is None or self.stream.end():
1279      raise StopIteration
1280    return (self.stream.current(), self.stream.context())
1281  next = __next__
1282
1283class IteratorWithContextIter(object):
1284  def __init__(self,iterator):
1285    global _debug
1286    if _debug:
1287      print("Creating IteratorWithContextIter for Iterator "+repr(iterator))
1288    self.iterator = iterator
1289    self.first = 1
1290
1291  def __iter__(self):
1292    return self
1293
1294  def __next__(self):
1295    if self.first:
1296      self.first = 0
1297    else:
1298      next(self.iterator)
1299    if self.iterator is None or self.iterator.end():
1300      raise StopIteration
1301    try:
1302      return (self.iterator.current(), self.iterator.context())
1303    except AttributeError:
1304      return (self.iterator.current(), None)
1305  next = __next__
1306
1307class IteratorIter(object):
1308  def __init__(self,iterator):
1309    global _debug
1310    if _debug:
1311      print("Creating IteratorIter for Iterator "+repr(iterator))
1312    self.iterator = iterator
1313    self.first = 1
1314
1315  def __iter__(self):
1316    return self
1317
1318  def __next__(self):
1319    if self.first:
1320      self.first = 0
1321    else:
1322      next(self.iterator)
1323    if self.iterator is None or self.iterator.end():
1324      raise StopIteration
1325    return self.iterator.current()
1326  next = __next__
1327
1328class StreamIter:
1329  def __init__(self,stream):
1330    global _debug
1331    if _debug:
1332      print("Creating StreamIter for Stream "+repr(stream))
1333    self.stream = stream
1334    self.first = 1
1335
1336  def __iter__(self):
1337    return self
1338
1339  def __next__(self):
1340    if self.first:
1341      self.first = 0
1342    else:
1343      next(self.stream)
1344    if self.stream is None or self.stream.end():
1345      raise StopIteration
1346    return self.stream.current()
1347  next = __next__
1348
1349class Stream(object):
1350  """Redland Statement Stream class
1351
1352     A class encapsulating a sequence of Statements, such as
1353     those returned from a Model query.  Can be used as a Python
1354     sequence.
1355
1356     stream = model.find_statements(query_statement)
1357     for statement in stream:
1358        # do whatever with 'statement'
1359        # note it is shared and will go out of scope, so you must
1360        # copy it if you want it to stay around
1361
1362     You should not normally find yourself needing to use this
1363     class explicitly.
1364   """
1365
1366  def __init__(self, object, creator):
1367    """Create an RDF Stream (constructor)."""
1368    global _debug
1369    if _debug:
1370      print("Creating RDF.Stream for object",object, "creator",creator)
1371
1372    self._stream=object
1373
1374    # Keep around a reference to the object that created the stream
1375    # so that Python does not destroy them before us.
1376    self.creator=creator
1377
1378  def context_iter(self):
1379    """Return an iterator over this stream that
1380       returns (stream, context) tuples each time it is iterated.
1381       DEPRECATED.  Instead use the context-aware method appropriate,
1382       e.g.  Model.find_statements_context() or Model.as_stream_context()
1383       """
1384    return StreamWithContextIter(self)
1385
1386  def __iter__(self):
1387    return StreamIter(self)
1388
1389  def __del__(self):
1390    global _debug
1391    if _debug:
1392      print("Destroying RDF.Stream")
1393    if self._stream:
1394      Redland.librdf_free_stream(self._stream)
1395
1396  def end(self):
1397    """Return true if the stream is exhausted"""
1398    if not self._stream:
1399      return 1
1400    return Redland.librdf_stream_end(self._stream)
1401
1402  def current(self):
1403    """Return the current Statement on the Stream"""
1404    if not self._stream:
1405      return None
1406
1407    my_statement=Redland.librdf_stream_get_object(self._stream)
1408    if my_statement == "NULL" or my_statement == None:
1409      return None
1410    return Statement(from_object=my_statement)
1411
1412  def __next__(self):
1413    """Move to the next Statement on the Stream"""
1414    if not self._stream:
1415      return 1
1416
1417    return Redland.librdf_stream_next(self._stream)
1418  next = __next__
1419
1420  def context(self):
1421    """Return the context Node of the current object on the Stream"""
1422    if not self._stream:
1423      return 1
1424
1425    my_node=Redland.librdf_stream_get_context(self._stream)
1426    if my_node == "NULL" or my_node == None:
1427      return None
1428
1429    return Node(from_object=my_node)
1430
1431# end class Stream
1432
1433
1434class Storage(object):
1435
1436  """Redland Statement Storage class
1437
1438     import RDF
1439     storage=RDF.Storage(storage_name="memory")
1440
1441  The Redland abstraction for storing RDF graphs as Statements.
1442
1443  There are no user methods (can only be constructed).
1444
1445  You should normally use a specialized class such as MemoryStorage or
1446  HashStorage in preference to this class.
1447
1448  """
1449
1450  def __init__(self, **args):
1451    """Create an RDF Storage (constructor).
1452
1453    Create a new RDF Storage using any of these forms
1454
1455  s1=RDF.Storage(storage_name="name",options_string="")
1456
1457Create a Storage of the given type.  Currently the built in storage
1458names that are always present are 'memory', 'hashes', 'file' and
1459'uri'.  'bdb' is available when Sleepycat / BerkeleyDB is compiled
1460in, 'mysql' when MySQL is compiled in, and 'sqlite' when SQLite is
1461compiled in.  If storage_name is omitted, it defaults to 'memory'.
1462
1463The argument 'name' can be used when the storage needs a name
1464to operate, such as used for a filename or URI:
1465
1466  s1=RDF.Storage(storage_name="file", name='/filename',options_string="")
1467
1468  s2=RDF.Storage(storage_name="uri", name='http://rdf.example.org/',options_string="")
1469
1470
1471The required argument options_string allows additional store-specific
1472options to be given, some of which are required by certain stores.
1473This uses the following form:
1474
1475  s3=RDF.Storage(storage_name="name", name='abc',
1476                 options_string="key1='value1', key2='value2', ...")
1477
1478for multiple key/value option pairs, option values are always
1479surrounded by single quotes.
1480
1481The common options are:
1482  new - optional and takes a boolean value (default false)
1483    If true, it deletes any existing store and creates a new one
1484    otherwise if false (default) open an existing store.
1485
1486  write - optional and takes a boolean value (default true)
1487    If true (default) the Storage is opened read-write otherwise
1488    if false the storage is opened read-only and for file-based
1489    Storages or those with locks, may be opened with shared-readers.
1490
1491Some storage types have additional options:
1492
1493storage_name 'hashes' has options:
1494  hash-type -  the name of any hash type supported.
1495    'memory' (default), 'file' hash types are always present. 'bdb' is
1496    available when BerkeleyDB is compiled in,
1497  dir - the directory name to create the files in (default '.')
1498  mode - the file creation mode (default 0644 octal)
1499
1500storage_name 'mysql' has options:
1501  host - required MySQL database hostname
1502  port - optional MySQL database port (defaults to 3306)
1503  database - required MySQL database name
1504  user - required MySQL database user
1505  password - required MySQL database password
1506
1507stoage name 'sqlite' has options:
1508  synchronous - optional value off, normal or full
1509
1510The other form is:
1511  s4=RDF.Storage(storage=s1)
1512Copy an existing Storage s1.
1513
1514
1515Note: there are convience classes to create a memory storage
1516  s5=RDF.MemoryStorage()
1517
1518and Hash storage:
1519  # memory hash
1520  s6=RDF.HashStorage('abc')
1521
1522  # specified bdb hash stored in files named 'def'*
1523  s7=RDF.HashStorage('def', options="hash-type='bdb'")
1524
1525    """
1526    global _world
1527    global _debug
1528    if _debug:
1529      print("Creating RDF.Storage args=",args)
1530    self._storage=None
1531
1532    if ('storage_name' in args and
1533        'name' in args and
1534        'options_string' in args):
1535      self._storage=Redland.librdf_new_storage(_world._world,
1536          args['storage_name'], args['name'], args['options_string'])
1537    elif 'storage' in args:
1538      self._storage=Redland.librdf_new_storage_from_storage(
1539          args['storage']._storage)
1540    else:
1541      raise RedlandError("Creating Storage failed - missing storage_name, name or options_string arguments")
1542
1543    if self._storage == "NULL" or self._storage == None:
1544      self._storage=None
1545      raise RedlandError("Creating Storage failed")
1546
1547  def __del__(self):
1548    global _debug
1549    if _debug:
1550      print("Destroying RDF.Storage")
1551    if self._storage:
1552      Redland.librdf_free_storage(self._storage)
1553
1554# end class Storage
1555
1556
1557class HashStorage(Storage):
1558  """Redland Hashed Storage class
1559
1560     import RDF
1561     h1=RDF.HashStorage("abc", options="hash-type='memory'")
1562
1563     # Creating a storage with contexts enabled
1564     s=RDF.HashStorage("def", options="contexts='yes'")
1565
1566  Class of hashed Storage for a particular type of hash (typically
1567  hash-type is "memory" or "bdb") and any other options.
1568  """
1569  def __init__(self, hash_name, options=""):
1570    Storage.__init__(self, name = hash_name, storage_name = "hashes",
1571                     options_string = options)
1572
1573
1574class MemoryStorage(Storage):
1575  """Redland memory Storage class
1576
1577     import RDF
1578     h1=RDF.MemoryStorage()
1579     h1=RDF.MemoryStorage("abc")
1580     h2=RDF.MemoryStorage("abc", "write='no'")
1581
1582     # Creating a storage with contexts enabled
1583     s = RDF.MemoryStorage(options_string="contexts='yes'")
1584
1585  Class of memory Storage with optional name, additional options.
1586  """
1587  def __init__(self, mem_name = "", options_string = ""):
1588    Storage.__init__(self, name = mem_name, storage_name = "memory",
1589                     options_string = options_string)
1590
1591
1592class FileStorage(Storage):
1593  """Redland file Storage class
1594
1595     import RDF
1596     s=RDF.FileStorage("abc")
1597
1598  Class of file Storage with required name, additional options.
1599  """
1600  def __init__(self, mem_name, options_string = ""):
1601    Storage.__init__(self, name = mem_name, storage_name = "file",
1602                     options_string = options_string)
1603
1604
1605class Uri(object):
1606  """Redland URI Class
1607
1608  import RDF
1609  uri1 = RDF.Uri("http://example.com/")
1610  uri2 = RDF.Uri(uri1)
1611
1612  """
1613
1614  def __init__(self, arg = None, **args):
1615    """Create an RDF URI (constructor).
1616
1617Creates a new RDF URI from either of the following forms:
1618
1619  uri1 = RDF.Uri("http://example.com/")
1620
1621Create a URI from the given string.
1622
1623  uri2 = RDF.Uri(uri1)
1624
1625Copy an existing URI uri1.
1626    """
1627    global _world
1628    global _debug
1629    if _debug:
1630      print("Creating RDF.Uri arg,args=",arg,args)
1631    self._reduri=None
1632
1633    if arg is not None:
1634      if isinstance(arg, str):
1635        args['string'] = arg
1636      elif not PY3 and isinstance(arg, unicode):
1637        import Redland_python
1638        args['string'] = Redland_python.unicode_to_bytes(arg)
1639      elif isinstance(arg, Uri):
1640        args['uri'] = arg
1641
1642    if 'string' in args and args['string'] is not None:
1643      self._reduri=Redland.librdf_new_uri(_world._world, args['string'])
1644    elif 'uri' in args:
1645      self._reduri=Redland.librdf_new_uri_from_uri(args['uri']._reduri)
1646    elif 'from_object' in args:
1647      if args['from_object']!=None:
1648        self._reduri=Redland.librdf_new_uri_from_uri(args['from_object'])
1649      else:
1650        raise RedlandError("Attempt to create new URI from null URI")
1651
1652    if self._reduri is None:
1653      raise RedlandError("Uri construction failed")
1654
1655  def __del__(self):
1656    global _debug
1657    if _debug:
1658      print("Destroying RDF.Uri")
1659    if self._reduri:
1660      if _debug:
1661        print("Deleting Redland uri object")
1662      Redland.librdf_free_uri(self._reduri)
1663
1664  def __str__(self):
1665    """Get a string representation of an RDF URI."""
1666    return Redland.librdf_uri_to_string(self._reduri)
1667
1668  def __unicode__(self):
1669    """Get a Unicode string representation of an RDF URI."""
1670    return unicode(Redland.librdf_uri_to_string(self._reduri), 'utf-8')
1671
1672  def __hash__(self):
1673    return hash(unicode(self))
1674
1675  def __eq__(self,other):
1676    """Equality of RDF URI to another RDF URI."""
1677    if not isinstance(other, self.__class__):
1678      return False
1679    return (Redland.librdf_uri_equals(self._reduri, other._reduri) != 0)
1680
1681  def __ne__(self,other):
1682    """Inequality of RDF URI to another RDF URI."""
1683    return not self == other
1684
1685# end class Uri
1686
1687class Parser(object):
1688  """Redland Syntax Parser Class
1689
1690  import RDF
1691  parser1=RDF.Parser()
1692  parser2=RDF.Parser(name="rdfxml")
1693  parser3=RDF.Parser(mime_type="application/rdf+xml")
1694
1695  stream=parser2.parse_as_stream("file://dir/file.rdf")
1696  parser3.parse_into_model(model, "file://dir/file.rdf", "http://example.org/")
1697
1698  The default parser type if not given explicitly is raptor,
1699  for the RDF/XML syntax.
1700  """
1701
1702  def __init__(self, name=None, mime_type=None, uri=None):
1703    """Create an RDF Parser (constructor).
1704
1705Create a new RDF Parser for a particular syntax.  The parser is
1706chosen by the fields given to the constructor, all of which are
1707optional.  When any are given, they must all match.  The default
1708parser is chosen if none are given, which is RDF/XML in the
1709standard configuration of Raptor.
1710
1711  name      - parser syntax name
1712  mime_type - syntax mime type
1713  uri       - URI identifying the syntax
1714    """
1715    #"
1716    global _world
1717    global _debug
1718    if _debug:
1719      print("Creating RDF.Parser name=",name,"mime_type=",mime_type, "uri=",uri)
1720
1721    self._parser = None
1722
1723    if uri is not None:
1724      ruri=uri._reduri
1725    else:
1726      ruri=None
1727
1728    self._parser=Redland.librdf_new_parser(_world._world, name, mime_type, ruri)
1729    if self._parser is None:
1730      raise RedlandError("Parser construction failed")
1731
1732  def __del__(self):
1733    global _debug
1734    if _debug:
1735      print("Destroying RDF.Parser")
1736    if self._parser:
1737      Redland.librdf_free_parser(self._parser)
1738
1739  def parse_as_stream(self, uri, base_uri=None):
1740    """Return a Stream of Statements from parsing the content at
1741        a URI for the optional base URI or None if the parsing fails.
1742
1743        (This depends on what URI support raptor provides to redland)
1744
1745          for statement in parser.parse_as_stream("http://localhost/r.rdf"):
1746              print statement
1747    """
1748    if isinstance(uri, str):
1749      uri = Uri(string=uri)
1750    elif not PY3 and isinstance(uri, unicode):
1751      import Redland_python
1752      uri = Uri(string=Redland_python.unicode_to_bytes(uri))
1753    if base_uri is None:
1754      base_uri=uri
1755    my_stream=Redland.librdf_parser_parse_as_stream(self._parser,
1756        uri._reduri, base_uri._reduri)
1757    if my_stream is None:
1758      return None
1759    return Stream(my_stream, self)
1760
1761  def parse_string_as_stream(self, string, base_uri):
1762    """Return a Stream of Statements from parsing the content in
1763        string with the required base URI or None if the parsing fails.
1764
1765          for statement in parser.parse_string_as_stream(rdfstring, base_uri):
1766              print statement
1767    """
1768    if isinstance(base_uri, str):
1769      base_uri = Uri(string=base_uri)
1770    elif not PY3 and isinstance(base_uri, unicode):
1771      import Redland_python
1772      base_uri = Uri(string=Redland_python.unicode_to_bytes(base_uri))
1773    if base_uri is None:
1774      raise RedlandError("A base URI is required when parsing a string")
1775
1776    if not PY3 and isinstance(string, unicode):
1777      import Redland_python
1778      string=Redland_python.unicode_to_bytes(string)
1779
1780    my_stream=Redland.librdf_parser_parse_string_as_stream(self._parser,
1781      string, base_uri._reduri)
1782    if my_stream==None:
1783      return None
1784    return Stream(my_stream, self)
1785
1786  def parse_into_model(self, model, uri, base_uri=None, handler=None):
1787    """Parse into the Model model from the content at the URI, for
1788       the optional base URI.  Returns a boolean success or failure.
1789
1790       If handler is given, an error handler with the signature
1791         def handler(code, level, facility, message, line, column, byte, file, uri)
1792       is called.
1793
1794       parser.parse_into_model(model, "file:./foo.rdf",
1795                               "http://example.com/foo.rdf")
1796    """
1797
1798    if isinstance(uri, str):
1799      uri = Uri(string = uri)
1800    elif not PY3 and isinstance(uri, unicode):
1801      import Redland_python
1802      uri = Uri(string=Redland_python.unicode_to_bytes(uri))
1803    if isinstance(base_uri, str):
1804      base_uri = Uri(string = base_uri)
1805    elif not PY3 and isinstance(base_uri, unicode):
1806      import Redland_python
1807      base_uri = Uri(string=Redland_python.unicode_to_bytes(base_uri))
1808    if base_uri is None:
1809      base_uri = uri
1810
1811    if handler is not None:
1812      import Redland_python
1813      Redland_python.set_callback(handler)
1814
1815    try:
1816      rc = Redland.librdf_parser_parse_into_model(self._parser,
1817        uri._reduri, base_uri._reduri, model._model)
1818    except RedlandError as err:
1819      print("Caught error",err)
1820      raise err
1821
1822    if handler is not None:
1823      import Redland_python
1824      Redland_python.reset_callback()
1825
1826    return (rc != None)
1827
1828  def parse_string_into_model(self, model, string, base_uri, handler = None):
1829    """Parse into the Model model from the content string
1830        with the required base URI.  Returns a boolean success or failure.
1831
1832       If handler is given, an error handler with the signature
1833         def handler(code, level, facility, message, line, column, byte, file, uri)
1834       is called.
1835
1836    """
1837    if isinstance(base_uri, str):
1838      base_uri = Uri(string = base_uri)
1839    elif not PY3 and isinstance(base_uri, unicode):
1840      import Redland_python
1841      base_uri = Uri(string=Redland_python.unicode_to_bytes(base_uri))
1842    if base_uri is None:
1843      raise RedlandError("A base URI is required when parsing a string")
1844
1845    if handler is not None:
1846      import Redland_python
1847      Redland_python.set_callback(handler)
1848
1849    if not PY3 and isinstance(string, unicode):
1850      import Redland_python
1851      string=Redland_python.unicode_to_bytes(string)
1852
1853    rc=Redland.librdf_parser_parse_string_into_model(self._parser, string,
1854                                           base_uri._reduri, model._model)
1855
1856    if handler is not None:
1857      import Redland_python
1858      Redland_python.reset_callback()
1859
1860    return (rc != None)
1861
1862  def get_feature(self, uri):
1863    """Return the Node value of Parser feature URI uri"""
1864    if not isinstance(uri, Uri):
1865      uri=Uri(string=uri)
1866
1867    value=Redland.librdf_parser_get_feature(self._parser,uri._reduri)
1868    if value == "NULL" or value == None:
1869      return None
1870    return Node(from_object=value)
1871
1872  def set_feature(self, uri, value):
1873    """Set the Node value of Parser feature URI uri."""
1874    if not isinstance(uri, Uri):
1875      uri=Uri(string=uri)
1876    if not isinstance(value, Node):
1877      value=Node(literal=value)
1878    Redland.librdf_parser_set_feature(self._parser,uri._reduri,value._node)
1879
1880  def set_uri_filter(self, filter):
1881    """Set a function for rejecting retrieval of URIs seen during parsing.
1882
1883   Return False or 0 to not reject the URI
1884
1885   def reject(uri):
1886     if "bad" == uri:
1887       return True
1888     return False
1889
1890   parser.set_uri_filter(reject)
1891"""
1892    import Redland_python
1893    Redland_python.set_parser_uri_filter(self._parser, filter)
1894
1895  def namespaces_seen(self):
1896    """Get a dictionary of prefix/URI pairs for namespaces seen during parsing.
1897"""
1898    count = Redland.librdf_parser_get_namespaces_seen_count(self._parser)
1899    nspaces={}
1900    for index in range(0, count-1):
1901      prefix=Redland.librdf_parser_get_namespaces_seen_prefix(self._parser, index)
1902      uri_obj=Redland.librdf_parser_get_namespaces_seen_uri(self._parser, index)
1903      if uri_obj is None:
1904        uri=None
1905      else:
1906        uri=Uri(from_object=uri_obj)
1907      nspaces[prefix]=uri
1908    return nspaces
1909
1910# end class Parser
1911
1912class RDFXMLParser(Parser):
1913  """Redland RDF/XML Parser class
1914
1915     import RDF
1916     parser=RDF.RDFXMLParser()
1917  """
1918  def __init__(self):
1919    Parser.__init__(self, name = "rdfxml")
1920
1921class NTriplesParser(Parser):
1922  """Redland N-Triples Parser class
1923
1924     import RDF
1925     parser=RDF.NTriplesParser()
1926  """
1927  def __init__(self):
1928    Parser.__init__(self, name = "ntriples")
1929
1930class TurtleParser(Parser):
1931  """Redland Turtle Parser class
1932
1933     import RDF
1934     parser=RDF.TurtleParser()
1935  """
1936  def __init__(self):
1937    Parser.__init__(self, name = "turtle")
1938
1939class RSSTagSoupParser(Parser):
1940  """Redland RSS Tag Soup Parser class
1941
1942     import RDF
1943     parser=RDF.RSSTagSoupParser()
1944  """
1945  def __init__(self):
1946    Parser.__init__(self, name = "rss-tag-soup")
1947
1948class GRDDLParser(Parser):
1949  """Redland GRDDL Parser class
1950
1951     import RDF
1952     parser=RDF.GRDDLParser()
1953  """
1954  def __init__(self):
1955    Parser.__init__(self, name = "grddl")
1956
1957
1958class Query(object):
1959  """Redland Query interface class
1960
1961  import RDF
1962
1963  q1 = RDF.Query("SELECT ?a ?c WHERE (?a dc:title ?c) USING dc FOR <http://purl.org/dc/elements/1.1/>")
1964  q2 = RDF.Query("- - -", query_language="triples")
1965  q3 = RDF.Query("select $a where ...", query_language="sparql")
1966
1967  results=q1.execute(model)
1968  for result in results:
1969    print result['a']
1970    print result['c']
1971
1972  for statement in q2.execute().as_stream(model):
1973    print statement
1974
1975  """
1976  def __init__(self, querystring, base_uri=None, query_language="sparql", query_uri=None):
1977    self._query = None
1978
1979    if querystring is None:
1980      raise RedlandError("No query string given")
1981
1982    if not PY3 and isinstance(querystring, unicode):
1983      querystring = querystring.encode('utf-8')
1984
1985    if query_uri is not None:
1986      ruri = query_uri._reduri
1987    else:
1988      ruri = None
1989
1990    if base_uri is not None:
1991      rbase_uri = base_uri._reduri
1992    else:
1993      rbase_uri = None
1994
1995    global _world
1996    global _debug
1997    if _debug:
1998      print("Creating query for language '"+query_language+"', base '"+unicode(rbase_uri)+"': "+querystring)
1999
2000    self._query = Redland.librdf_new_query(_world._world, query_language, ruri, querystring, rbase_uri)
2001    self.result_stream = None
2002
2003    if self._query is None:
2004      raise RedlandError("Query construction failed")
2005
2006  def __del__(self):
2007    global _debug
2008    if _debug:
2009      print("Destroying RDF.Query")
2010    if self._query:
2011      Redland.librdf_free_query(self._query)
2012
2013  def execute(self,model):
2014    results = Redland.librdf_query_execute(self._query,model._model)
2015    if results is not None:
2016      return QueryResults(self._query,results)
2017    else:
2018      return None
2019
2020  def get_limit(self):
2021    return Redland.librdf_query_get_limit(self._query)
2022
2023  def set_limit(self,limit):
2024    rc = Redland.librdf_query_set_limit(self._query,limit)
2025    if rc != 0:
2026      raise RedlandError("Couldn't set query results limit")
2027
2028  def get_offset(self):
2029    return Redland.librdf_query_get_offset(self._query)
2030
2031  def set_offset(self,offset):
2032    rc = Redland.librdf_query_set_offset(self._query,offset)
2033    if rc != 0:
2034      raise RedlandError("Couldn't set query results offset")
2035
2036# end class Query
2037
2038
2039class RDQLQuery(Query):
2040  """Redland RDQL Query class"""
2041  def __init__(self, querystring, base_uri=None):
2042    Query.__init__(self, querystring = querystring, base_uri = base_uri,
2043                   query_language = "rdql")
2044
2045class SPARQLQuery(Query):
2046  """Redland SPARQL Query class"""
2047  def __init__(self, querystring, base_uri=None):
2048    Query.__init__(self, querystring = querystring, base_uri = base_uri,
2049                   query_language = "sparql")
2050
2051
2052class QueryResults(object):
2053  """Redland Query results class
2054
2055
2056  """
2057  def __init__(self,query,results):
2058    global _debug
2059    if _debug:
2060      print("Creating QueryResults")
2061    self._query = query
2062    self._results = results
2063    self.first = True
2064
2065  def is_bindings(self):
2066    """Test if the query results format is variable bindings"""
2067    return (Redland.librdf_query_results_is_bindings(self._results) != 0)
2068
2069  def is_boolean(self):
2070    """Test if the query results format is a boolean"""
2071    return (Redland.librdf_query_results_is_boolean(self._results) != 0)
2072
2073  def is_graph(self):
2074    """Test if the query results format is an RDF graph"""
2075    return (Redland.librdf_query_results_is_graph(self._results) != 0)
2076
2077  def __iter__(self):
2078    return self
2079
2080  def __len__(self):
2081    """Returns an exception since len() of an iterable is undefined."""
2082    raise ValueError("Cannot take the length of iterable query results")
2083
2084  # Iterator method
2085  def __next__(self):
2086    """Get the next variable binding result"""
2087    if not self.is_bindings():
2088      raise RedlandError("Query result is not in variable bindings format")
2089    if self.first:
2090      self.first = False
2091    else:
2092      Redland.librdf_query_results_next(self._results)
2093    if Redland.librdf_query_results_finished(self._results):
2094      raise StopIteration
2095    return self.make_results_hash()
2096  next = __next__
2097
2098  def make_results_hash(self):
2099    results = {}
2100    c = Redland.librdf_query_results_get_bindings_count(self._results)
2101    for i in range(c):
2102      n = Redland.librdf_query_results_get_binding_name(self._results,i)
2103      v = Redland.librdf_query_results_get_binding_value(self._results,i)
2104      if v is None:
2105        results[n] = None
2106      else:
2107        results[n] = Node(from_object=v)
2108
2109    return results
2110
2111  def finished(self):
2112    """Test if reached the last variable binding result"""
2113    if not self.is_bindings():
2114      raise RedlandError("Query result is not in variable bindings format")
2115    return (Redland.librdf_query_results_finished(self._results) != 0)
2116
2117  def as_stream(self):
2118    """Return the query results as a stream of triples (RDF.Statement)"""
2119    if not self.is_graph():
2120      raise RedlandError("Query result is not in RDF graph format")
2121    s=Redland.librdf_query_results_as_stream(self._results)
2122    if s is not None:
2123      return Stream(s, self)
2124    else:
2125      return None
2126
2127  def get_boolean(self):
2128    """Get the boolean query result"""
2129    if not self.is_boolean():
2130      raise RedlandError("Query result is not in boolean format")
2131    return (Redland.librdf_query_results_get_boolean(self._results) != 0)
2132
2133  def get_binding_value(self, offset):
2134    """Get the value of a variable binding by offset"""
2135    if not self.is_bindings():
2136      raise RedlandError("Query result is not in variable bindings format")
2137    n=Redland.librdf_query_results_get_binding_value(self._results, offset)
2138    if n is None:
2139      return None
2140    else:
2141      return Node(from_object=n, do_not_copy=1)
2142
2143  def get_binding_name(self, offset):
2144    """Get the name of a variable binding by offset"""
2145    if not self.is_bindings():
2146      raise RedlandError("Query result is not in variable bindings format")
2147    return Redland.librdf_query_results_get_binding_name(self._results, offset)
2148
2149  def get_binding_value_by_name(self, name):
2150    """Get the value of a variable binding by variable name"""
2151    if not self.is_bindings():
2152      raise RedlandError("Query result is not in variable bindings format")
2153    n=Redland.librdf_query_results_get_binding_value_by_name(self._results, name)
2154    if n is None:
2155      return None;
2156    else:
2157      return Node(from_object=n, do_not_copy=1)
2158
2159  def get_bindings_count(self):
2160    """Get the number of variable bindings in the query result"""
2161    if not self.is_bindings():
2162      raise RedlandError("Query result is not in variable bindings format")
2163    return Redland.librdf_query_results_get_bindings_count(self._results)
2164
2165  def __del__(self):
2166    global _debug
2167    if _debug:
2168      print("Destroying RDF.QueryResults")
2169    if self._results:
2170      Redland.librdf_free_query_results(self._results)
2171
2172  def to_file(self, name, format_uri=None, base_uri=None):
2173    """Serialize to filename name in syntax format_uri using the optional base URI."""
2174    if isinstance(format_uri, str):
2175      format_uri = Uri(string = format_uri)
2176    elif not PY3 and isinstance(format_uri, unicode):
2177      import Redland_python
2178      format_uri = Uri(string=Redland_python.unicode_to_bytes(format_uri))
2179    else:
2180      format_uri = None
2181
2182    if format_uri is not None:
2183      rformat_uri = format_uri._reduri
2184    else:
2185      rformat_uri = None
2186
2187    if isinstance(base_uri, str):
2188      base_uri = Uri(string = base_uri)
2189    elif not PY3 and isinstance(base_uri, unicode):
2190      import Redland_python
2191      base_uri = Uri(string=Redland_python.unicode_to_bytes(base_uri))
2192    if base_uri is not None:
2193      rbase_uri = base_uri._reduri
2194    else:
2195      rbase_uri = None
2196    return Redland.librdf_query_results_to_file(self._results, name, rformat_uri, rbase_uri)
2197
2198  def to_string(self, format_uri=None, base_uri=None):
2199    """Serialize to a string syntax format_uri using the optional base URI."""
2200    if self.is_graph():
2201      tmpmodel = Model(MemoryStorage())
2202      tmpmodel.add_statements(self.as_stream())
2203      serializer = Serializer()
2204      return serializer.serialize_model_to_string(tmpmodel, base_uri)
2205
2206    if self.is_boolean():
2207      return unicode(self.get_boolean())
2208
2209    if not self.is_bindings():
2210      raise RedlandError("Unknown query result format cannot be written as a string")
2211
2212    if isinstance(format_uri, str):
2213      format_uri = Uri(string = format_uri)
2214    elif not PY3 and isinstance(format_uri, unicode):
2215      import Redland_python
2216      format_uri = Uri(string=Redland_python.unicode_to_bytes(format_uri))
2217    else:
2218      format_uri = None
2219
2220    if format_uri is not None:
2221      rformat_uri = format_uri._reduri
2222    else:
2223      rformat_uri = None
2224    if isinstance(base_uri, str):
2225      base_uri = Uri(string = base_uri)
2226    elif not PY3 and isinstance(base_uri, unicode):
2227      import Redland_python
2228      base_uri = Uri(string=Redland_python.unicode_to_bytes(base_uri))
2229    if base_uri is not None:
2230      rbase_uri = base_uri._reduri
2231    else:
2232      rbase_uri = None
2233
2234    return Redland.librdf_query_results_to_string(self._results,
2235                                                  rformat_uri, rbase_uri)
2236
2237  def __str__(self):
2238    """Serialize to string syntax format."""
2239    return self.to_string()
2240
2241
2242# end class QueryResults
2243
2244
2245class Serializer(object):
2246  """ Redland Syntax Serializer Class
2247
2248  import RDF
2249  ser1=RDF.Serializer()
2250
2251  ser2=RDF.Serializer(mime_type="application/rdf+xml")
2252
2253  ser3=RDF.Serializer(name="ntriples")
2254
2255  A class for turning a Model into a syntax serialization (at present
2256  only to local files).
2257  """
2258
2259  def __init__(self, name=None, mime_type=None, uri=None):
2260    """Create an RDF Serializer (constructor).
2261
2262    The arguments name, mime_type and uri are all optional and
2263    when omitted the default serialization syntax is used.  If
2264    any arguments are given, they must all match for an appropriate
2265    syntax to be chosen.  For example, RDF/XML has a MIME type of
2266    'application/rdf+xml' so this can be given with the mime_type
2267    argument, however the N-Triples has none, so the 'ntriples' name
2268    must be used.  Most syntaxes have URIs.
2269    """
2270    global _world
2271    global _debug
2272    if _debug:
2273      print("Creating RDF.Serializer name=",name,"mime_type=",mime_type, \
2274        "uri=",uri)
2275
2276    self._serializer = None
2277
2278    if uri is not None:
2279      ruri = uri._reduri
2280    else:
2281      ruri = None
2282
2283    self._serializer=Redland.librdf_new_serializer(_world._world, name,
2284      mime_type, ruri)
2285    if self._serializer is None:
2286      raise RedlandError("Serializer construction failed")
2287
2288  def __del__(self):
2289    global _debug
2290    if _debug:
2291      print("Destroying RDF.Serializer")
2292    if self._serializer:
2293      Redland.librdf_free_serializer(self._serializer)
2294
2295  def serialize_model_to_file(self, name, model, base_uri=None):
2296    """Serialize to filename name the Model model using the
2297       optional base URI."""
2298    if isinstance(base_uri, str):
2299      base_uri = Uri(string = base_uri)
2300    elif not PY3 and isinstance(base_uri, unicode):
2301      import Redland_python
2302      base_uri = Uri(string=Redland_python.unicode_to_bytes(base_uri))
2303    if base_uri is not None:
2304      rbase_uri = base_uri._reduri
2305    else:
2306      rbase_uri = None
2307    return Redland.librdf_serializer_serialize_model_to_file(self._serializer,
2308      name, rbase_uri, model._model)
2309
2310  def serialize_model_to_string(self, model, base_uri=None):
2311    """Serialize to a string using the optional base URI."""
2312    if isinstance(base_uri, str):
2313      base_uri = Uri(string = base_uri)
2314    elif not PY3 and isinstance(base_uri, unicode):
2315      import Redland_python
2316      base_uri = Uri(string=Redland_python.unicode_to_bytes(base_uri))
2317    if base_uri is not None:
2318      rbase_uri = base_uri._reduri
2319    else:
2320      rbase_uri = None
2321    return Redland.librdf_serializer_serialize_model_to_string(self._serializer, rbase_uri, model._model)
2322
2323  def serialize_stream_to_string(self, stream, base_uri=None):
2324    """Serialize a stream to a string using the optional base URI."""
2325    if isinstance(base_uri, str):
2326      base_uri = Uri(string = base_uri)
2327    elif not PY3 and isinstance(base_uri, unicode):
2328      import Redland_python
2329      base_uri = Uri(string=Redland_python.unicode_to_bytes(base_uri))
2330    if base_uri is not None:
2331      rbase_uri = base_uri._reduri
2332    else:
2333      rbase_uri = None
2334    return Redland.librdf_serializer_serialize_stream_to_string(self._serializer, rbase_uri, stream._stream)
2335
2336  # TODO: features could usefully be implemented as a collection
2337
2338  def get_feature(self, uri):
2339    """Return the value of Serializer feature URI uri"""
2340    if not isinstance(uri, Uri):
2341      if isinstance(uri, str):
2342        uri = Uri(string=uri)
2343      elif not PY3 and isinstance(uri, unicode):
2344        import Redland_python
2345        uri = Uri(string=Redland_python.unicode_to_bytes(uri))
2346      else:
2347        raise TypeError("uri must be string or RDF.Uri")
2348
2349    return Redland.librdf_serializer_get_feature(self._serializer,uri._reduri)
2350
2351  def set_feature(self, uri, value):
2352    """Set the value of Serializer feature URI uri."""
2353    if not isinstance(uri, Uri):
2354      if isinstance(uri, str):
2355        uri = Uri(string=uri)
2356      elif not PY3 and isinstance(uri, unicode):
2357        import Redland_python
2358        uri = Uri(string=Redland_python.unicode_to_bytes(uri))
2359      else:
2360        raise TypeError("uri must be string or RDF.Uri")
2361    Redland.librdf_serializer_set_feature(self._serializer,uri._reduri,value)
2362
2363  def set_namespace(self, prefix, uri):
2364    """Set a namespace prefix and URI for the Serializer to use."""
2365    if not isinstance(uri, Uri):
2366      if isinstance(uri, str):
2367        uri = Uri(string=uri)
2368      elif not PY3 and isinstance(uri, unicode):
2369        import Redland_python
2370        uri = Uri(string=Redland_python.unicode_to_bytes(uri))
2371      else:
2372        raise TypeError("uri must be string or RDF.Uri")
2373    Redland.librdf_serializer_set_namespace(self._serializer, uri._reduri, prefix)
2374
2375
2376# end class Serializer
2377
2378
2379class NTriplesSerializer(Serializer):
2380  """Redland N-Triples Serializer class
2381
2382     import RDF
2383     ser=RDF.NTriplesSerializer()
2384  """
2385  def __init__(self):
2386    Serializer.__init__(self, name = "ntriples", mime_type = "", uri = None)
2387
2388
2389class RDFXMLSerializer(Serializer):
2390  """Redland RDF/XML Serializer class
2391
2392     import RDF
2393     ser=RDF.RDFXMLSerializer()
2394  """
2395  def __init__(self):
2396    Serializer.__init__(self, name = "rdfxml")
2397
2398class RDFXMLAbbrevSerializer(Serializer):
2399  """Redland RDF/XML with abbreviations Serializer class
2400
2401     import RDF
2402     ser=RDF.RDFXMLAbbrevSerializer()
2403  """
2404  def __init__(self):
2405    Serializer.__init__(self, name = "rdfxml-abbrev")
2406
2407class RSS10Serializer(Serializer):
2408  """Redland RSS 1.0 Serializer class
2409
2410     import RDF
2411     ser=RDF.RSS10Serializer()
2412  """
2413  def __init__(self):
2414    Serializer.__init__(self, name = "rss-1.0")
2415
2416class TurtleSerializer(Serializer):
2417  """Redland Turtle Serializer class
2418
2419     import RDF
2420     ser=RDF.TurtleSerializer()
2421  """
2422  def __init__(self):
2423    Serializer.__init__(self, name = "turtle")
2424
2425
2426class NS(object):
2427  """ Redland Namespace Utility Class
2428
2429  import RDF
2430  nspace = RDF.NS("http://example.com/foo#")
2431
2432  # creates an RDF Node for http://example.com/foo#blah
2433  node1 = nspace.blah
2434
2435  # creates an RDF Node for http://example.com/foo#blah
2436  node2 = nspace['blah']
2437
2438  A class for generating RDF Nodes with URIs from the same vocabulary
2439  (such as XML Namespace) varying only in the appended name in
2440  the vocabulary.  Each node returned is a pointer to a shared copy.
2441
2442  """
2443
2444  def __init__(self,prefix):
2445    self._prefix = prefix
2446    self._nodecache = {}
2447
2448  def _node(self,localName):
2449    if localName not in self._nodecache:
2450      self._nodecache[localName] = Redland.librdf_new_node_from_uri_string(_world._world, self._prefix+localName)
2451    return Node(from_object=self._nodecache[localName])
2452
2453  def __getitem__(self,localName):
2454    return self._node(localName)
2455
2456  def __getattr__(self,localName):
2457    return self._node(localName)
2458
2459
2460# global init, create our world.
2461
2462_world=World()
2463