########################################################################
#
# File Name:            Util.py
#
# Documentation:        http://docs.4suite.org/4Rdf/Util.py.html
#
"""
Some useful utilities for RDF processing
WWW: http://4suite.org/4RDF         e-mail: support@4suite.org

Copyright (c) 2001 Fourthought Inc, USA.   All Rights Reserved.
See  http://4suite.org/COPYRIGHT  for license and copyright information
"""

from Ft.Rdf.Drivers import Memory
from Ft.Rdf import Model
from Ft.Rdf.Serializers.Dom import Serializer

def SerializeStatementList(slist, baseUri):
    db = Memory.CreateDb('')
    m = Model.Model(baseUri, db)
    m.add(slist)
    serializer = Serializer()
    outdoc = serializer.serialize(m)
    strstream = cStringIO.StringIO()
    xml.dom.ext.PrettyPrint(outdoc, stream=strstream)
    return strstream.getvalue()


#Query convenience functions

def GetSubject(model, predicate, object, statementUri=None,
               sourceUri=None, **flags):
    """
    Performs a complete on the given model, using the given object and
    predicate, None for the subject, with any given optional parameters
    passed through.  The first resulting statement is returned, and the
    subject extracted therefrom.  If no statements result, None is returned
    """
    kwargs = flags.copy()
    if statementUri is not None:
        kwargs.update({'statementUri': statementUri})
    if sourceUri is not None:
        kwargs.update({'sourceUri': sourceUri})
    stmts = apply(model.complete, (None, predicate, object), kwargs)
    if not stmts: return None
    return stmts[0].subject


def GetSubjects(model, predicate, object, statementUri=None,
                sourceUri=None, **flags):
    """
    Performs a complete on the given model, using the given object and
    predicate, None for the subject, with any given optional parameters
    passed through.  The list of subjects of the resulting statement is
    returned.  If no statements result, the empty list is returned
    """
    kwargs = flags.copy()
    if statementUri is not None:
        kwargs.update({'statementUri': statementUri})
    if sourceUri is not None:
        kwargs.update({'sourceUri': sourceUri})
    stmts = apply(model.complete, (None, predicate, object), kwargs)
    return map(lambda x: x.subject, stmts)


def GetPredicate(model, subject, object, statementUri=None,
                 sourceUri=None, **flags):
    """
    Performs a complete on the given model, using the given subject and
    object, None for the predicate, with any given optional parameters
    passed through.  The first resulting statement is returned, and the
    predicate extracted therefrom.  If no statements result, None is returned
    """
    kwargs = flags.copy()
    if statementUri is not None:
        kwargs.update({'statementUri': statementUri})
    if sourceUri is not None:
        kwargs.update({'sourceUri': sourceUri})
    stmts = apply(model.complete, (subject, object, None), kwargs)
    if not stmts: return None
    return stmts[0].predicate


def GetPredicates(model, subject, object, statementUri=None,
                  sourceUri=None, **flags):
    """
    Performs a complete on the given model, using the given subject and
    predicate, None for the object, with any given optional parameters
    passed through.  The list of predicates of the resulting statement is
    returned.  If no statements result, the empty list is returned
    """
    kwargs = flags.copy()
    if statementUri is not None:
        kwargs.update({'statementUri': statementUri})
    if sourceUri is not None:
        kwargs.update({'sourceUri': sourceUri})
    stmts = apply(model.complete, (subject, object, None), kwargs)
    return map(lambda x: x.predicate, stmts)

    
def GetObject(model, subject, predicate, statementUri=None,
              sourceUri=None, **flags):
    """
    Performs a complete on the given model, using the given subject and
    predicate, None for the object, with any given optional parameters
    passed through.  The first resulting statement is returned, and the
    object extracted therefrom.  If no statements result, None is returned
    """
    kwargs = flags.copy()
    if statementUri is not None:
        kwargs.update({'statementUri': statementUri})
    if sourceUri is not None:
        kwargs.update({'sourceUri': sourceUri})
    stmts = apply(model.complete, (subject, predicate, None), kwargs)
    if not stmts: return None
    return stmts[0].object


def GetObjects(model, subject, predicate, statementUri=None,
              sourceUri=None, **flags):
    """
    Performs a complete on the given model, using the given subject and
    predicate, None for the object, with any given optional parameters
    passed through.  The list of objects of the resulting statement is
    returned.  If no statements result, the empty list is returned
    """
    kwargs = flags.copy()
    if statementUri is not None:
        kwargs.update({'statementUri': statementUri})
    if sourceUri is not None:
        kwargs.update({'sourceUri': sourceUri})
    stmts = apply(model.complete, (subject, predicate, None), kwargs)
    return map(lambda x: x.object, stmts)

    
#Setting up models

from Ft.Rdf import Model
from xml.dom.ext.reader import PyExpat
from Ft.Rdf.Serializers.Dom import Serializer
reader = PyExpat.Reader()


from Ft.Rdf.Drivers import Memory

def DeserializeFromUri(uri, driver=Memory, dbName='', create=1):
    if create:
        db = driver.CreateDb(dbName)
    else:
        db = driver.GetDb(dbName)
    db.begin()

    model = Model.Model(db)
    doc = reader.fromUri(uri)

    serializer = Serializer()
    
    serializer.deserialize(model, doc, '')
    db.commit()
    reader.releaseNode(doc)
    return model, db

