Exemplo n.º 1
0
class rdfDict:
    """
    Provides a dictionary-like wrapper around a set of RDF triples with a
    common subject.  In addition to the standard dictionary interface
    provides convenience methods for manipulating the triples.
    """
    def __init__(self, subject, rdfStore=None):
        """
        Creates a new rdfDict given the particular subject and an optional
        TripleStore (rdfStore).  If no TripleStore is provided, creates a
        new one.
        """

        # store the subject
        self.subject = subject

        # store or create the triple store
        if rdfStore is None:
            self.store = TripleStore()
        else:
            self.store = rdfStore

    def __str__(self):
        """
        Return the string representation of this instance using an algorithm
        inspired by the Dublic Core dumb-down method.
        """

	output_str = ''
        pairs = []
	type_item = None
        
        for key in self:
	    if (key.find("#type") != -1): 
	      type_item = key
	    else:
	      pairs.append((key, self.getAll(key)))

	output_str = str(self.getFirst(type_item)) + ": "

	for pair in pairs:
	   output_str = '%s %s: %s;' % (output_str,
                                        str(pair[0]),
                                        ", ".join([str(n) for n in pair[1]]) ) 

	return output_str

    def about(self):
        """
        Return the subject used to create the instance (usually equivalent
        to rdf:about.
        """
        return self.subject

    def __getvalues(self, key):
        """
        Returns a list of values for a particular key; coerces BNodes to
        rdfDicts and mangles Literals with language attributes (if available).
        """

        values = [ n for n in self.store.objects(subject=self.subject,
                                                 predicate=key)
                   ]

        result = []
        
        for value in values:
            if (isinstance(value, BNode)):
                # coerce to rdfDict
                result.append(rdfDict(value, self.store))
            else:
                result.append(value)

        return result
                            
    def __getitem__(self, key):
        """
        Return the object described in RDF with a subject of self.subject
        and a predicate of key.  If more than one match is found, raises
        an AmbiguousKeyError.
        """

        result = self.__getvalues(key)

        if (len(result) == 0):
            # no item was found, throw an exception
            raise KeyError()
        elif (len(result) > 1):
            # check if there is more than one option
            raise AmbiguousKeyError()
        else:
            # otherwise return object value
            return result[0]

    def getFirst(self, key):
        """
        Returns the first object having the predicate key.  If no match is
        found returns None.
        """

        if ( (self.subject, URIRef(key), None) in self.store):
            return self.__getvalues(key)[0]
        else:
            return None
        
    def getAll(self, key):
        """
        Returns a list of objects which have a predicate of key.  The list
        may be empty or contain only a single element.
        """

	return self.__getvalues(key)

    def __setitem__(self, key, value):
        """
        Adds an RDF triple of the values (self.subject, key, value); any
        objects with the same subject/predicate are replaced.
        """

        if (self.subject, key, none) in self.store:
            del self[key]

        self.store.add( (self.subject, key, value) )
        
    def add (self, key, value):
        """
        Adds an RDF triple consisting of the subject, key and value.
        """
        
        self.store.add( (self.subject, key, value) )
        
    def addAll (self, key, values):
        """
        Adds the list of objects in values with the same subject and predicate.
        """
        
        for value in values:
            self.add (key, value)
            
    def __len__(self):
        """
        Returns the number of predicate-object pairs associated with the
        subject self.subject.
        """

        return len(self.store)

    def __delitem__(self, key):
        """
        Removes all items with the given key.
        """

        if (self.subject, key, None) in self.store:
            self.store.remove( (self.subject, key, None) )
        else:
            raise KeyError()

    def remove (self, key, value):
        """
        Removes a specific key-value pair.
        """
        
        self.store.remove( (self.subject, key, value) )

    def __iter__(self):
        """
        Returns an iterator over the unique keys (predicates)
        for the given subject.
        """

        return iter(sets.Set(self.store.predicates(subject=self.subject)))

    iterkeys = __iter__

    def __contains__(self, key):
        """
        Returns true if the given key appears as a predicate of the subject.
        """

        return ( (self.subject, key, None) in self.store )