########################################################################
#
# File Name:            Statement.py
#
# Documentation:        http://docs.4suite.org/4Rdf/Statement.py.html
#
"""
The model container for RDF meta-data: represents a graph
WWW: http://4suite.org/4RDF         e-mail: support@4suite.org

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

from Ft.Rdf import Resource, RdfException
from Ft.Rdf import RDF_MS_BASE
from Ft.Rdf import Container

import types
try:
    g_stringTypes= [types.StringType, types.UnicodeType]
except:
    g_stringTypes= [types.StringType]


# See this article for ideas on more efficient reification: http://lists.w3.org/Archives/Public/www-rdf-interest/2000Nov/0450.html


class Statement(Resource.Resource):
    def __init__(self, subject, predicate, object, statementUri='',
                 sourceUri='', aboutEach=0, aboutEachPrefix=0):
        Resource.Resource.__init__(self, statementUri)
        if not type(subject) in g_stringTypes:
            raise ValueError("Subject not of type string: %s"%subject)
        if not type(predicate) in g_stringTypes:
            raise ValueError("Predicate not of type string: %s"%predicate)
        if not type(object) in g_stringTypes:
            raise ValueError("Object not of type string: %s"%object)
        if not type(statementUri) in g_stringTypes:
            raise ValueError("Statement URI not of type string: %s"%statementUri)
        if not type(sourceUri) in g_stringTypes:
            raise ValueError("Source URI not of type string: %s"%sourceUri)

        self.subject = subject
        self.predicate = predicate
        self.object = object
        self.sourceUri = sourceUri
        self.aboutEach = aboutEach
        self.aboutEachPrefix = aboutEachPrefix
        #RDFQ: Is it OK for aboutEach to have a non-container object?  Assumed "yes"
#        if self.aboutEach:
#            if not isinstance(object, Container):
#                raise Exception(Error.ABOUT_EACH_OBJECT_NOT_CONTAINER)

    def reify(self, model, uri=None):
        if uri == None:
            uri = self.uri or model.generateUri()
        model.add(Statement(uri, RDF_MS_BASE+'type', RDF_MS_BASE+'Statement',
                            sourceUri=uri))
        model.add(Statement(uri, RDF_MS_BASE+'subject', self.subject,
                            sourceUri=uri))
        model.add(Statement(uri, RDF_MS_BASE+'predicate', self.predicate,
                            sourceUri=uri))
        model.add(Statement(uri, RDF_MS_BASE+'object', self.object,
                            sourceUri=uri))
        return uri

##    def matchSubject(self, testSubject):
##        return self.subject == testSubject

##    def matchPredicate(self, testPredicate):
##        return self.predicate == testPredicate

##    def matchObject(self, testObject):
##        if self.aboutEach and isinstance(self.object, Container):
##            return testObject in self.object
##        else:
##            return testObject == self.object

##    def match(self, subject, predicate, object):
##        return (not subject or self.matchSubject(subject)) and (not predicate or self.matchPredicate(predicate)) and (not object or self.matchObject(object))

##    def isEquivalent(self, other):
##        return self.match(other.subject, other.predicate, other.object)

##    def __cmp__(self, other):
##        return cmp((self.subject, self.predicate, self.object), (other.subject, other.predicate, other.object))
    
    def __repr__(self):
        if type(self.object) in g_stringTypes:
            st = '<RDF Statement at %s: [Subject: %s, Predicate: %s, Object: "%s"]>'%(id(self), self.subject, self.predicate, self.object)
        else:
            st = '<RDF Statement at %s: [Subject: %s, Predicate: %s, Object: %s]>'%(id(self), self.subject, self.predicate, self.object)
        return st

