"""

     
"""
__version__ = "$Revision: 1.2 $"
# $Source: /sources/public/2007/asn/straw2.py,v $


import re
import rdflib
from sys import stderr
from sys import stdout

import langio2
import qname
import rdfnodes

#  This difference is confusing me.   The RelaxNG for RDF/XML uses the
#  -datatypes version, and lots of others do, too.
# XS_NAMESPACE = "http://www.w3.org/2001/XMLSchema-datatypes"
XS_NAMESPACE = "http://www.w3.org/2001/XMLSchema"

OWL = rdflib.Namespace("http://www.w3.org/2002/07/owl#")
RDF = rdflib.Namespace("http://www.w3.org/1999/02/22-rdf-syntax-ns#")
RDFS = rdflib.Namespace("http://www.w3.org/2000/01/rdf-schema#")

RIF = rdflib.Namespace("http://www.w3.org/2007/rif#")


class Error(RuntimeError):
    """General error in straw2 package."""


class ObjectNode (rdfnodes.ObjectNode):

   def xdump(self, xml, pred=None):

      if pred:
         xml.begin(pred)

      t = self._graph.value(self.node, RDF.type)
      if t:
         xml.begin(t)
      else:
         xml.begin(RDF.Description)    # Hack Cough Cough Cough

      for p in self._graph.predicates(self.node):
         if p == RDF.type: continue
         for v in self._graph.objects(self.node, p):
            self._nodeCreator.obtain(v).xdump(xml, p)

      xml.end()

      if pred:
         xml.end()

class PlainLiteralNode (rdfnodes.PlainLiteralNode):

   def xdump(self, xml, pred=None):

      if self.lang:
         if pred:
            xml.begin(pred)
            xml.addAttribute("xml:lang", self.lang)
         else:
            raise Error
      else:
         xml.begin(pred)

      xml.addText(self.text)
      
      if pred:
         xml.end()


class TypedLiteralNode (rdfnodes.TypedLiteralNode):

   def xdump(self, xml, pred=None):

      if self.lang:
         if pred:
            xml.begin(pred, ["xsi:type", self.datatype])
         else:
            raise Error
      else:
         xml.begin(pred)

      xml.addText(self.text)
      
      if pred:
         xml.end()



class ListNode (rdfnodes.ListNode):

   def xdump(self, xml, pred=None):
      if pred:
         xml.begin(pred)
      for item in self.items:
         item.xdump(xml, RDF.li)
      if pred:
         xml.end()



def serialize(graph, top, sink=stderr):
   """

   >>> import straw2
   >>> import rdflib
   >>> store = rdflib.ConjunctiveGraph()
   >>> f = open('test-data/poscond-eg.rdf')
   >>> dummy = store.parse(f)
   >>> top = rdflib.URIRef('http://example.net/and')
   >>> straw2.serialize(store, top)

   """
   gen = Generator(graph=graph, top=top, stream=sink)
   gen.run()
   
class Generator (langio2.Generator) :
    """

    Output the XML in straw2 for the rif:Document described in the
    triplestore....?

    Or, for everything described in the triplestore?

    """

    def __init__(self, **kwargs):
        super(Generator, self).__init__(**kwargs)   
        self.xml = langio2.XMLTree()
        self.nc = rdfnodes.NodeCreator(self._graph,
                                       ObjectNode, PlainLiteralNode,
                                       TypedLiteralNode, ListNode)
        

    # XML Format
    
    def run(self):
       self.nc.obtain(self.top).xdump(self.xml)
       #for s, p, o in self._graph:
       #   print s, p, o
       #
       #for s in self._graph.subjects():
       #   self.nc.obtain(s).xdump(self.xml)
       self.xml.serializeTo(self)


if __name__ == "__main__":
    import doctest, sys
    doctest.testmod(sys.modules[__name__])
