"""

read/write instances (triples) to XML files
following the conventions we use in the rnc
module.
   
the parser *knows the schema* unlike in RDF,
so it can tell what's a list vs set, etc.


FIRST APPROXIMATION -- serialize python objects, and
don't use the schema.    we could serialize python objects
using the schema if we know the rdf_type of each object.
(I guess we could use the same conventsions as python.py)
[ that is -- implicit namespace. ]

ISSUE - id/ref -- what do we do about repeated things?  do we just
repeat them, and damn the identity issue?  No -- doesn't work for
cyclical structures.  Of course, we're not expecting rulebases to be
cyclical -- so we can just print a warning if they are.


get data from an rdflib.Graph?
"""

from objectmodel import ObjectModel, Class, Property
from namespace import ns
import re
from sys import stderr

class Error(RuntimeError):
   pass

class Generator:
    """
 
    >>> import omxml
    >>> import sys

    x>>> kb = omxml.testKB()
    x>>> schema = omxml.testSchema()

    >>> root = omxml.test_object_1

    >>> g = omxml.Generator()   # pass in ontology
    >>> g.serialize(sys.stdout, root)

    """

    def __init__(self, model):
        self.model = model

    def item_by_name(self, name):
        for i in self.model.classes:
            if str(i) == str(name):
                return i
        for i in self.model.properties:
            if str(i) == str(name):
                return i
        raise Error, 'Attempt to serialize an object of a class not in this ontology'
            
    def serialize(self, out, obj, prefix=""):
        classname = ob.__class__.__name__
        classobj = self.item_by_name(classname)
        out.write(prefix+"<")
        out.write(classname)   ## use qname
        out.write(">\n")

        for prop in self.model.propertiesForClassWithInheritance(classobj):
            self.serializeProperty(prop, out, prefix+"  ")
            
        out.write(prefix+"</")
        out.write(self.class_tag(obj))
        out.write(">\n")

    def serializeProperty(self, prop, out, prefix):

        #  should just be using a triple store...
        
        attr = prop.uri[prop.uri.rindex("#"):]    #  @@ wild guess
        
        
        
        # switch on list/multi and the range

        # find out the name of the python property be used here....

                # @@@ xml-escape the value
                out.write(prefix+'  <'+key+'>')
                out.write(value)
                out.write('</'+key+'>\n')
            else:
                out.write(prefix+'  <'+key+'>\n')
                self.serialize(out, value, prefix+'    ')
                out.write(prefix+'  </'+key+'>\n')

class A:
    pass
class B:
    pass
class C:
    pass

a = A()
a.name = "a"
a.hello = "goodbye"
a.friend1 = B()
a.friend2 = B()
a.friend3 = C()

test_object_1 = a

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