def test_selector_datastream(self):
     should_be = """
                 <foxml:datastream ID="selector" FEDORA_URI="info:fedora/1/selector" STATE="A" CONTROL_GROUP="M">
                   <foxml:datastreamVersion ID="selector.0" LABEL="Selector data for OAC annotation" MIMETYPE="application/rdf+xml">
                     <foxml:xmlContent>
                       <rdf:RDF>
                         <rdf:Description rdf:about="info:fedora/{{ANNO1_PID}}/selector">
                           <rdf:type rdf:resource="oa:FragmentSelector"/>
                           <rdf:value>/my/xpath/</rdf:value>
                         </rdf:Description>
                       </rdf:RDF>
                     </foxml:xmlContent>
                   </foxml:datastreamVersion>
                 </foxml:datastream>
                 """
     ele = Foxml.get_selector_rdf_element(
         pid="1", oa_selector="/my/xpath/", oa_selector_type_uri="oa:FragmentSelector"
     )
     ds = Foxml.get_xml_datastream(
         element=ele,
         id="selector",
         mime="application/rdf+xml",
         label="Selector data for OAC annotation",
         fedora_uri="info:fedora/1/selector",
     )
    def test_specific_target_datastream(self):
        should_be = """
                    <foxml:datastream ID="specifictarget" FEDORA_URI="info:fedora/1/specifictarget" STATE="A" CONTROL_GROUP="M">
                      <foxml:datastreamVersion ID="specifictarget.0" LABEL="SpecificTarget data for OAC annotation" MIMETYPE="application/rdf+xml">
                        <foxml:xmlContent>
                          <rdf:RDF>
                            <rdf:Description rdf:about="info:fedora/1/SpecificTarget">
                              <rdf:type rdf:resource="oa:SpecificResource"/>
                              <oa:hasSource rdf:resource="source:2"/>
                              <oax:hasStyle rdf:resource="style:3"/>
                              <oa:hasSelector rdf:resource="info:fedora/1/selector"/>
                            </rdf:Description>
                          </rdf:RDF>
                        </foxml:xmlContent>
                      </foxml:datastreamVersion>
                    </foxml:datastream>
                    """

        ele = Foxml.get_specific_target_rdf_element(pid="1", source_uri="source:2", oax_style_uri="style:3")
        ds = Foxml.get_xml_datastream(
            element=ele,
            id="specifictarget",
            mime="application/rdf+xml",
            label="SpecificTarget data for OAC annotation",
            fedora_uri="info:fedora/1/specifictarget",
        )
 def test_datastream_version_element(self):
     dsv = Foxml.get_datastream_version_element(
         id="1",
         mime="application/rdf+xml",
         label="super element!",
         format_uri="info:fedora/fedora-system:FedoraRELSExt-1.0",
     )
 def test_object_properties(self):
     should_be = """
                 <foxml:objectProperties xmlns:foxml="info:fedora/fedora-system:def/foxml#">
                     <foxml:property NAME="info:fedora/fedora-system:def/model#state" VALUE="A" />
                     <foxml:property NAME="info:fedora/fedora-system:def/model#label" VALUE="OAC object" />
                 </foxml:objectProperties>
                 """
     op = Foxml.get_object_properties()
    def edit(self):
        if self._annotation_pid is None:
            raise AnnotationError("pid is required for Editing")

        # Dublin Core Datastream
        if self._dc_title is not None:
            dc_annotation = "DC"
            dublin_core = Foxml.get_dublin_core_element(pid=self._annotation_pid, title=self._dc_title)
            Fedora.put_datastream(pid=self._annotation_pid, dsid=dc_annotation, element=dubln_core)
 def test_annotation_datastream(self):
     should_be = """
                 <foxml:datastream ID="annotation" FEDORA_URI="info:fedora/1/annotation" STATE="A" CONTROL_GROUP="M">
                   <foxml:datastreamVersion ID="annotation.0" LABEL="" MIMETYPE="text/xml">
                     <foxml:xmlContent>
                       <rdf:RDF>
                         <rdf:Description rdf:about="info:fedora/1">
                           <rdf:type rdf:resource="oa:Annotation"/>
                           <oa:hasBody rdf:resource="body:1"/>
                           <oa:hasTarget rdf:resource="info:fedora/1/SpecificTarget"/>
                           <oa:modelVersion rdf:resource="http://www.openannotation.org/spec/core/20120509.html"/>
                           <oa:generated>{{datetime}}</oa:generated>
                           <oa:annotator>Mac</oa:annotator>
                           <oa:generator>Web</oa:generator>
                           <oa:annotated>{{datetime}}</oa:annotated>
                         </rdf:Description>
                         <rdf:Description rdf:about="1">
                           <rdf:type rdf:resource="oa:Body"/>
                           <dc:format>text/xml</dc:format>
                         </rdf:Description>
                       </rdf:RDF>
                     </foxml:xmlContent>
                   </foxml:datastreamVersion>
                 </foxml:datastream>
                 """
     ele = Foxml.get_annotation_rdf_element(
         pid="1",
         body_uri="body:1",
         oa_selector="/my/xpath",
         body_mimetype="text/xml",
         annotator="Mac",
         generator="Web",
     )
     ds = Foxml.get_xml_datastream(
         element=ele,
         id="annotation",
         mime="application/rdf+xml",
         label="OAC annotation core",
         fedora_uri="info:fedora/1/annotation",
     )
 def test_dublin_core_datastream(self):
     should_be = """
                 <foxml:datastream ID="DC" FEDORA_URI="info:fedora/1/DC" STATE="A" CONTROL_GROUP="M">
                   <foxml:datastreamVersion ID="DC1.0" LABEL="Dublin Core Record for this object" MIMETYPE="text/xml" FORMAT_URI="http://www.openarchives.org/OAI/2.0/oai_dc/">
                     <foxml:xmlContent>
                       <oai_dc:dc xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/oai_dc/ http://www.openarchives.org/OAI/2.0/oai_dc.xsd">
                         <dc:identifier>1</dc:identifier>
                         <dc:title>super!</dc:title>
                       </oai_dc:dc>
                     </foxml:xmlContent>
                   </foxml:datastreamVersion>
                 </foxml:datastream>
                 """
     ele = Foxml.get_dublin_core_element(pid="1", title="super!")
     ds = Foxml.get_xml_datastream(
         element=ele,
         id="DC",
         version_id="DC1",
         mime="text/xml",
         label="Dublin Core Record for this object",
         fedora_uri="info:fedora/1/DC",
         format_uri="http://www.openarchives.org/OAI/2.0/oai_dc/",
     )
    def test_rels_ext_model_datastream(cls, **kwargs):
        should_be = """
                    <foxml:datastream ID="RELS-EXT" STATE="A" CONTROL_GROUP="X" VERSIONABLE="true">
                        <foxml:datastreamVersion ID="RELS-EXT.0" LABEL="RDF Statements about this object" MIMETYPE="application/rdf+xml" FORMAT_URI="info:fedora/fedora-system:FedoraRELSExt-1.0">
                            <foxml:xmlContent>
                                <rdf:RDF>
                                    <rdf:Description rdf:about="info:fedora/1">
                                        <fedora-model:hasModel rdf:resource="info:fedora/bdr-cmodel:tei-annotation"/>
                                    </rdf:Description>
                                </rdf:RDF>
                            </foxml:xmlContent>
                        </foxml:datastreamVersion>
                    </foxml:datastream>
                    """
        ele = Foxml.get_rels_ext_model_element(pid="1", models=["tei-annotation"])

        ds = Foxml.get_xml_datastream(
            element=ele,
            id="RELS-EXT",
            mime="application/rdf+xml",
            label="RDF Statements about this object",
            format_uri="info:fedora/fedora-system:FedoraRELSExt-1.0",
        )
 def test_rdf_annotation_element(self):
     should_be = """ 
                 <rdf:RDF>
                     <rdf:Description rdf:about="info:fedora/1">
                         <rdf:type rdf:resource="oa:Annotation"/>
                         <oa:hasBody rdf:resource="body:2"/>
                         <oa:hasTarget rdf:resource="info:fedora/1/SpecificTarget"/>
                         <oa:modelVersion rdf:resource="http://www.openannotation.org/spec/core/20120509.html"/>
                     </rdf:Description>
                     <rdf:Description rdf:about="body:2">
                         <rdf:type rdf:resource="oa:Body"/>
                         <dc:format>text/xml</dc:format>
                     </rdf:Description>
                 </rdf:RDF>
                 """
     rdf = Foxml.get_annotation_rdf_element(pid="1", body_uri="body:2", body_mimetype="text/xml")
 def test_put(self):
     ele = Foxml.get_annotation_rdf_element(pid='changeme:9', body_uri='changeme:8', body_mimetype='text/xml')
     Fedora.put_datastream(pid='changeme:9', dsid='annotation', element=ele)
    def serialize(cls, pids, format=None, check_object=None):
        """
        Get list of datastreams from an array of PIDs

        With those, get all rdf:Description elements and output
        in the format specified.

        Format options are:
            - rdf/xml or xml (default)
            - rdf/json or json
            - turtle or ttl
            - nt
            - n3

        Optional "check_object" parameter will check the object's
        content model before serializing to make sure it is equal to the
        default content type for annotate objects set in the config.
        """
        if format is None:
            format = "xml"

        if check_object is None:
            check_object = True

        xmls = []

        for pid in pids:

            # Make sure we only serialize Annotation objects
            if check_object:
                try:
                    content_models = Fedora.get_content_models(pid)
                except:
                    raise AnnotationError("PID %s not found in Fedora" % pid)

                oac_model = "info:fedora/%s" % app.config.get("DEFUALT_ANNOTATION_CONTENT_MODEL")
                if oac_model not in content_models:
                    continue

            datastreams = Fedora.get_datastream_list(pid)
            if not isinstance(datastreams, list):
                # There was an error with this PID, skip it
                continue
            for d in datastreams:
                [xmls.append(x) for x in Foxml.get_rdf_descriptions(Fedora.get_datastream(pid, d))]

        rdf_xml_string = Foxml.get_rdf_string_from_descriptions(list(xmls))

        out = Graph()
        out.parse(data=rdf_xml_string, format="application/rdf+xml")

        if format.lower() == "rdf/xml" or format.lower() == "xml":
            return out.serialize(format="xml"), "application/rdf+xml"
        if format.lower() == "n3":
            return out.serialize(format="n3"), "text/rdf+n3"
        elif format.lower() == "turtle" or format.lower() == "ttl":
            return out.serialize(format="turtle"), "text/turtle"
        elif format.lower() == "nt":
            return out.serialize(format="nt"), "text/nt"
        elif format.lower() == "rdf/json" or format.lower() == "json":
            return out.serialize(format="rdf-json"), "application/rdf+json"
        else:
            raise AnnotationError("Serialization format '%s' is not supported.")
    def build_annotation(self):
        self._annotation_pid = Fedora.get_pid()

        foxml = Foxml(pid=self._annotation_pid)
        self._annotation_uri = "info:fedora/%s" % self._annotation_pid

        # Object Properties
        foxml.create_object_properties()
        # Dublin Core Datastream
        dc_uri = "%s/DC" % self._annotation_uri
        dublin_core = Foxml.get_dublin_core_element(pid=self._annotation_pid, title=self._dc_title)
        foxml.create_xml_datastream(
            element=dublin_core,
            id="DC",
            version_id="DC1",
            mime="text/xml",
            label="Dublin Core Record for this object",
            fedora_uri=dc_uri,
            format_uri="http://www.openarchives.org/OAI/2.0/oai_dc/",
        )

        # Inline Body Datastream
        self.body_inline_rdf_element = None
        if self._body_inline is not None:
            self._body_uri = "%s/inlinebody" % self._annotation_uri
            self.body_inline_rdf_element = Foxml.get_body_inline_rdf_element(
                pid=self._annotation_pid, body_uri=self._body_uri, body_inline=self._body_inline
            )
            foxml.create_xml_datastream(
                element=self.body_inline_rdf_element,
                id="inlinebody",
                mime="application/rdf+xml",
                label="Inline Body for OAC annotation",
                fedora_uri=self._body_uri,
            )

        # Annotation Datastream
        anno_uri = "%s/annotation" % self._annotation_uri
        self.annotation_rdf = Foxml.get_annotation_rdf_element(
            pid=self._annotation_pid,
            body_uri=self._body_uri,
            oa_selector=self._oa_selector,
            body_mimetype=self._body_mimetype,
            annotated=self._annotated,
            generator=self._generator,
            annotator=self._annotator,
        )
        foxml.create_xml_datastream(
            element=self.annotation_rdf,
            id="annotation",
            mime="application/rdf+xml",
            label="OAC annotation core",
            fedora_uri=anno_uri,
        )

        # RELS-EXT Datastream
        # This 'get' should never fall back to '' because there is a default annotation content model ('oac:oa-annotation')
        oac_model = app.config.get("DEFUALT_ANNOTATION_CONTENT_MODEL", "")

        # The PID of the SDef object for Annotation Serialization
        # This is not required by Fedora so it was removed.
        # serialization_service = "oac-sdef:serialize"
        # self.rels_ext_rdf_element = Foxml.get_rels_ext_model_element(pid=self._annotation_pid,
        #                                                             models=[oac_model],
        #                                                             services=[serialization_service])
        self.rels_ext_rdf_element = Foxml.get_rels_ext_model_element(pid=self._annotation_pid, models=[oac_model])
        foxml.create_xml_datastream(
            element=self.rels_ext_rdf_element,
            id="RELS-EXT",
            mime="application/rdf+xml",
            label="RDF Statements about this object",
            format_uri="info:fedora/fedora-system:FedoraRELSExt-1.0",
        )

        self.specific_target_rdf_element = None
        self.selector_rdf_element = None
        if self._oa_selector is not None:
            # SpecificTarget Datastream
            sptg_uri = "%s/specifictarget" % self._annotation_uri
            self.specific_target_rdf_element = Foxml.get_specific_target_rdf_element(
                pid=self._annotation_pid, source_uri=self._source_uri, oax_style_uri=self._oax_style_uri
            )
            foxml.create_xml_datastream(
                element=self.specific_target_rdf_element,
                id="specifictarget",
                mime="application/rdf+xml",
                label="SpecificTarget data for OAC annotation",
                fedora_uri=sptg_uri,
            )

            # Selector Datastream
            sele_uri = "%s/selector" % self._annotation_uri
            self.selector_rdf_element = Foxml.get_selector_rdf_element(
                pid=self._annotation_pid,
                oa_selector=self._oa_selector,
                oa_selector_type_uri=self._oa_selector_type_uri,
                fragment_type=self._fragment_type,
            )
            foxml.create_xml_datastream(
                element=self.selector_rdf_element,
                id="selector",
                mime="application/rdf+xml",
                label="Selector data for OAC annotation",
                fedora_uri=sele_uri,
            )

        self._annotation = foxml.get_foxml()
    def build_body(self):
        if self._body_uri is None and self._body_inline is None:
            try:
                assert self._body_content is not None
                assert self._body_mimetype is not None

                self._body_pid = Fedora.get_pid()

                foxml = Foxml(pid=self._body_pid)
                # Object Properties
                foxml.create_object_properties()
                # Dublin Core Datastream
                dublin_core = Foxml.get_dublin_core_element(
                    pid=self._body_pid, title="Open Annotation Collaboration body object (B-1)"
                )
                foxml.create_xml_datastream(
                    element=dublin_core,
                    id="DC",
                    version_id="DC1",
                    mime="text/xml",
                    label="Dublin Core Record for this object",
                )
                # Attach body
                if self._body_mimetype == "text/xml":
                    foxml.create_xml_datastream(
                        element=self._body_content, id="OAC_BODY", label="OAC Body Content", mime=self._body_mimetype
                    )
                else:
                    raise AnnotationError("Only body contents with mimetype 'text/xml' is allowed at this time.")

                # Optional RELS-EXT Datastream for the content model
                if self._body_content_model is not None:
                    body_rels_ext_rdf_element = Foxml.get_rels_ext_model_element(
                        pid=self._body_pid, models=[self._body_content_model]
                    )
                    foxml.create_xml_datastream(
                        element=body_rels_ext_rdf_element,
                        id="RELS-EXT",
                        mime="application/rdf+xml",
                        label="RDF Statements about this object",
                        format_uri="info:fedora/fedora-system:FedoraRELSExt-1.0",
                    )

                self._body_uri = "info:fedora/%s" % self._body_pid
                self._body = foxml.get_foxml()
            except:
                raise  # AnnotationError("Could not create the (B-1) body object from passed parameters")
 def test_get_xml_content_element(self):
     xmlc = Foxml.get_xml_content_element()
 def test_datastream_element(self):
     ds = Foxml.get_datastream_element(
         id="1", state="A", control_group="TXXVGA", fedora_uri="info:fedora/1/something"
     )
 def test_xml_body_content_datastream(self):
     body_string = "<TEI><body>Some TEI text goes here.</body></TEI>"
     body = Foxml.get_xml_datastream(element=body_string, id="OAC_BODY", label="OAC Body Content", mime="text/xml")