class FoxmlTest(unittest.TestCase):
    def setUp(self):
        self.annotation = Annotation(source_uri = "demo:26#xpointer('//cow')",
                                     dc_title = "Annotation about my love of the the word 'cow'",
                                     body_content = '<TEI><body>I love the word cow!</body></TEI>',
                                     body_mimetype = 'text/xml')
        self.annotation.create()
    
    def test_submission(self):
        self.annotation.submit()
        assert self.annotation.validate()

    def test_serialize(self):
        lst = Annotation.serialize([])

        lst = Annotation.serialize(['changeme:350'])

        lst = Annotation.serialize(['changeme:9, changeme:166'])
def rebuild():
    """
        A GET method that will rebuild the internal TDB index
        with all of the Annotation objects in Fedora 
    """
    try:
        query = "prefix fm: <info:fedora/fedora-system:def/model#> select ?s where {?s fm:hasModel <info:fedora/%s> }" \
                 % app.config.get('DEFUALT_ANNOTATION_CONTENT_MODEL')
        all_pids = (p.lstrip('info:fedora/') for p in Fedora.get_sparql_query_resuts(query))
        result, mimetype = Annotation.serialize(all_pids, format='nt', check_object=False)

        dataset = TDBFactory.createDataset(app.config['STORE_LOCATION'])

        # Remove all entries from the default model
        dataset.begin(ReadWrite.WRITE)
        try:
            model = dataset.getDefaultModel()
            model.begin()
            model.removeAll()
            model.commit()
            model.close()
            dataset.commit()
        except Exception, exc:
            raise
        finally:
            dataset.end()
            TDB.sync(dataset)

        # Load the triples
        dataset.begin(ReadWrite.WRITE)
        try:
            model = dataset.getDefaultModel()
            model.begin()
            n3_input_stream = ByteArrayInputStream(String(result).getBytes())            
            model.read(n3_input_stream, None, "N-TRIPLE")
            model.commit()
            model.close()
            dataset.commit() 
        except Exception, exc:
            raise
def flush():
    """
        A GET method that will serialize (dump) all Annotation objects in Fedora.

        An optional 'format' parameter to output the serialization 
        in different formats.

        Format options are:
            - nt (default)
            - rdf/xml or xml
            - rdf/json or json
            - turtle or ttl
            - n3
    """
    try:
        format = request.args.get('format', 'nt')
        query = "prefix fm: <info:fedora/fedora-system:def/model#> select ?s where {?s fm:hasModel <info:fedora/%s> }" \
                 % app.config.get('DEFUALT_ANNOTATION_CONTENT_MODEL')
        all_pids = (p.lstrip('info:fedora/') for p in Fedora.get_sparql_query_resuts(query))
        result, mimetype = Annotation.serialize(all_pids, format=format, check_object=False)
    except AnnotationError, ex:
        return jsonify({'value' : ex.value, 'trace' : traceback.format_stack()})
def show():
    """
        A GET method that takes a comma seperated list of Annotation
        (A-1) PIDs to serialize as the 'pid' parameter.
        
        An optional 'format' parameter to output the serialization 
        in different formats.

        Format options are:
            - rdf/xml or xml (default)
            - rdf/json or json
            - turtle or ttl
            - nt
            - n3
    """
    try:
        pid = request.args.get('pid', "")
        pids = filter(None, pid.split(','))
        if len(pids) == 0:
            raise AnnotationError("Must pass in at least one PID using the 'pid' parameter.")
        format = request.args.get('format', 'rdf/xml')
        result, mimetype = Annotation.serialize(pids, format=format, check_object=True)
    except AnnotationError, ex:
        return jsonify({'value' : ex.value, 'trace' : traceback.format_stack()})
 def setUp(self):
     self.annotation = Annotation(source_uri = "demo:26#xpointer('//cow')",
                                  dc_title = "Annotation about my love of the the word 'cow'",
                                  body_content = '<TEI><body>I love the word cow!</body></TEI>',
                                  body_mimetype = 'text/xml')
     self.annotation.create()
    def test_serialize(self):
        lst = Annotation.serialize([])

        lst = Annotation.serialize(['changeme:350'])

        lst = Annotation.serialize(['changeme:9, changeme:166'])
def rebuild_one():
    """
        A POST method that will rebuild the internal TDB index
        with a specific PID from Fedora
    """

    pid = request.form.get('pid', None)
    if pid is None:
        raise AnnotationError("Please pass a PID parameter to the rebuild POST request")

    print  "calling 'rebuild_one' with PID: %s" % pid

    try:
        # Get PID from Fedora and serialize it
        result, mimetype = Annotation.serialize([pid], format='nt', check_object=True)

        # Don't do anything if this there are no serialization results 
        # ie. was not an Annotation object

        dataset = TDBFactory.createDataset(app.config['STORE_LOCATION'])

        # Remove all triples from TDB involving this PID using SPARQL
        # This was my first attempt, but the SPARQL query does not
        # seem to be working.  Using the Jena API (below) also works.
        """
        query = "DELETE { ?s ?p ?o } WHERE { <info:fedora/%s> ?p ?o }" % pid
        update = UpdateFactory.create(String(query))
        dataset.begin(ReadWrite.WRITE)
        try:
            graph_store = GraphStoreFactory.create(dataset.getDefaultModel())
            update_processor = UpdateExecutionFactory.create(update, graph_store)
            results = update_processor.execute()
        except Exception, exc:
            raise
        finally:
            dataset.end()
            TDB.sync(dataset)
        """

        # Remove all triples from TDB involving this PID using Jena API
        # Start dataset WRITE transaction
        dataset.begin(ReadWrite.WRITE)
        try:
            resource = ResourceFactory.createResource("info:fedora/%s" % pid)
            model = dataset.getDefaultModel()
            model.removeAll(resource, None, None)
            model.commit()
            model.close()
            dataset.commit() 
        except Exception, exc:
            raise
        finally:
            dataset.end()
            TDB.sync(dataset)

        # Add new triples to TDB
        dataset.begin(ReadWrite.WRITE)
        try:
            model = dataset.getDefaultModel()
            model.begin()
            n3_input_stream = ByteArrayInputStream(String(result).getBytes())            
            model.read(n3_input_stream, None, "N-TRIPLE")
            model.commit()
            model.close()
            dataset.commit() 
        except Exception, exc:
            raise
def create():
    """
        A POST method that creates an Annotation (A-1) object
        based on a number of parameters.

        Required Parameters:

        source_uri:             The URI for the whole target object

        dc_title:               Dublin Core title associated with the annotation, 
                                i.e. "dublin core title goes here" 

        body_inline             Plain text string to store as the body

            OR

        body_content:           Contents of the body (XML, text, json, etc.)
            AND
        body_mimetype:          Mimetype of the body_content

            OR

        body_uri:               URI pointing to the body of the annotation


        Optional Parameters:

        annotator:              A string representing a user ID (0 or more)
                                ie. 'Charly'

        generator:              A string representing what generated the annotation
                                ie. 'Web Client'

        oax_style_uri:          A URI for a XSLT stylesheet used to render the whole target object. (0 or 1)

        oa_selector:            A string with the selector value(0 or 1)

        oa_selector_type_uri:   Required if an oa_selector is passed in
                                ie. oa:Fragment

        fragment_type:          URI describing the oa_selector type  Optional and only used if
                                an oa_selector is passed in.
                                ie. 'http://www.w3.org/TR/xpath/'

        body_content_model:     A string representing the body's content model
                                ie. 'tei-annotation'


        Will create 1 or 2 Fedora objects.  One will represent the actual annotation (A-1)
        and one will be the body of text that annotates the Fedora object (B-1).

        >>> import urllib
        >>> import urllib2
        >>> post_url = "http://localhost:5000/create"
        >>> params = { 
                "source_uri"    : "test:1#xpointer('/foo')",
                "body_content"  : "<TEI><body>text body</body></TEI>",
                "body_mimetype" : "text/xml",
                "dc_title"      : "Open Annotation Collaboration Annotation object (A-1)"
            }
        >>> encoded_data = urllib.urlencode( params )
        >>> request = urllib2.Request( post_url, encoded_data )
        >>> response = urllib2.urlopen( request )
        >>> print response.read()
        {
          "errors": [],
          "body_pid": "changeme:180",
          "annotation_pid": "changeme:181"
        }
    """

    try:
        annote = Annotation(source_uri = request.form.get('source_uri'),
                            dc_title = request.form.get('dc_title'),
                            annotated = datetime.utcnow(),
                            body_inline = request.form.get('body_inline', None),
                            body_content = request.form.get('body_content', None),
                            body_mimetype = request.form.get('body_mimetype', None),
                            body_uri = request.form.get('body_uri', None),
                            body_content_model = request.form.get('body_content_model', None),
                            annotator = request.form.get('annotator', None),
                            generator = request.form.get('generator', None),
                            oax_style_uri = request.form.get('oax_style_uri', None),
                            oa_selector = request.form.get('oa_selector', None),
                            oa_selector_type_uri = request.form.get('oa_selector_type_uri', None),
                            fragment_type = request.form.get('fragment_type', None))
        
        annote.create()
        annote.submit()
        if annote.validate():
            # Start dataset transaction
            dataset = TDBFactory.createDataset(app.config['STORE_LOCATION'])
            dataset.begin(ReadWrite.WRITE)
            try:
                model = dataset.getDefaultModel()
                model.begin()
                if annote.annotation_rdf is not None:
                    anno_input_stream = ByteArrayInputStream(String(tostring(annote.annotation_rdf)).getBytes())
                    model.read(anno_input_stream, None)
                    anno_input_stream.close()
                if annote.specific_target_rdf_element is not None:
                    spectaget_input_stream = ByteArrayInputStream(String(tostring(annote.specific_target_rdf_element)).getBytes())
                    model.read(spectaget_input_stream, None)
                    spectaget_input_stream.close()
                if annote.selector_rdf_element is not None:
                    selector_input_stream = ByteArrayInputStream(String(tostring(annote.selector_rdf_element)).getBytes())
                    model.read(selector_input_stream, None)
                    selector_input_stream.close()
                if annote.rels_ext_rdf_element is not None:
                    relsext_input_stream = ByteArrayInputStream(String(tostring(annote.rels_ext_rdf_element)).getBytes())
                    model.read(relsext_input_stream, None)
                    relsext_input_stream.close()
                if annote.body_inline_rdf_element is not None:
                    body_inline_input_stream = ByteArrayInputStream(String(tostring(annote.body_inline_rdf_element)).getBytes())
                    model.read(body_inline_input_stream, None)
                    body_inline_input_stream.close()
                model.commit()
                model.close()
                dataset.commit() 
            except Exception, exc:
                raise
            finally:
                dataset.end()
                TDB.sync(dataset)