########################################################################
# $Header: /var/local/cvsroot/4Suite/Ft/Server/Server/SCore/RdfDocumentImp.py,v 1.22 2003/02/08 17:40:18 uogbuji Exp $
"""
RdfDocument repository resource class

Copyright 2003 Fourthought, Inc. (USA).
Detailed license and copyright information: http://4suite.org/COPYRIGHT
Project home, documentation, distributions: http://4suite.org/
"""

import cStringIO, types

import XmlDocumentImp

from Ft.Rdf.Serializers.Dom import Serializer
from Ft.Server.Common import ResourceTypes, Util
from Ft.Server.Server.Drivers import FtssInputSource
from Ft.Xml.Domlette import PrettyPrint
from Ft.Server.Server.Drivers.PathImp import RepoPathToUri


class RdfDocumentImp(XmlDocumentImp.XmlDocumentImp):
    """
    An RDF Document is a document that represents a set of RDF triples.
    Nothing is actually stored in the Repo as far as an XML file goes.
    """
    resourceType = ResourceTypes.ResourceType.RDF_DOCUMENT

    def getContent(self, nssMap=None):
        self._verifyTx()
        szr = Serializer()
        ns_map = nssMap or Util.GetUserNsMappings(self.getRoot())
        dom = szr.serialize(
            None, ns_map,
            stmts=self.getModel().complete(
                None, None, None,
                scope=RepoPathToUri(self.getAbsolutePath())
                )
            )
        st = cStringIO.StringIO()
        PrettyPrint(dom, stream=st)
        return st.getvalue()

    def newContent(self, src):
        # For a new document we don't need to delete any existing statements
        # and the source is set during creation.
        self._verifyTx()
        self._validateNewSrc(src)

        if isinstance(src, types.UnicodeType):
            src = src.encode('utf-8')
        dom = FtssInputSource.NonvalidatingReader.parseString(
            src, self._path.absolutePath, self._driver)

        szr = Serializer()
        szr.deserialize(self.getModel(), dom,
                        RepoPathToUri(self._path.absolutePath))
        return

    def setContent(self, src):
        self._verifyTx()
        self._validateNewSrc(src)

        if isinstance(src, types.UnicodeType):
            src = src.encode('utf-8')
        dom = FtssInputSource.NonvalidatingReader.parseString(
            src, self._path.absolutePath, self._driver)

        model = self.getModel()
        model.removePattern(None, None, None,
                            scope=RepoPathToUri(self._path.absolutePath))
        szr = Serializer()
        szr.deserialize(model, dom, RepoPathToUri(self._path.absolutePath))
        self._driver.updateResourceContent(self._path, src)
        return

    def deserializeAndAdd(self, src):
        """
        Deserialize a source document and add the resulting statements to a scope
        """
        self._verifyTx()
        self._validateNewSrc(src)

        dom = FtssInputSource.NonvalidatingReader.parseString(
                src.encode('utf-8'),
                self._path.absolutePathAsUri,
                self._driver)

        model = self.getModel()
        szr = Serializer()
        szr.deserialize(model, dom, RepoPathToUri(self._path.absolutePath))
        src = self.getContent()
        self._driver.updateResourceContent(self._path, src)
        return

    def deserializeAndRemove(self, src):
        """
        Deserialize a source document and remove the resulting statements from the scope
        """
        self._verifyTx()
        self._validateNewSrc(src)

        dom = FtssInputSource.NonvalidatingReader.parseString(
                src.encode('utf-8'),
                self._path.absolutePathAsUri,
                self._driver)

        from Ft.Rdf import Util
        model, db = Util.DeserializeFromNode(
            dom, scope=RepoPathToUri(self.getAbsolutePath()))
        stmts = model.complete(None, None, None,
                               scope=RepoPathToUri(self.getAbsolutePath()))
        self.getModel().remove(stmts)
        src = self.getContent()
        self._driver.updateResourceContent(self._path, src)
        return

    def complete(self, subject=None, predicate=None, object=None):
        """Perform a complete within this scope"""
        self._verifyTx()
        return self.getModel().complete(
            subject=subject, predicate=predicate,
            object=object,
            scope=RepoPathToUri(self.getAbsolutePath()))

    def _delete(self):
        self.getModel().removePattern(
            None, None, None,
            scope=RepoPathToUri(self._path.absolutePath))
        XmlDocumentImp.XmlDocumentImp._delete(self)
        return

