3
d<                 @   s   d dl Z d dlZd dlmZ d dlZd dlZd dlZd dlZd dlm	Z	m
Z
 d dlT d dlmZ dZdZejeZeeZeje edd	 eD Zd
ZG dd dejZG dd deZdd Zdd Zdd Zdd Z dd Z!dd Z"dS )    N)etree)DEFAULT_NAMESPACESsorted_attributes)*)
SerializerzLion Krischerz"krischer@geophysik.uni-muenchen.dec             c   s   | ]}t | |fV  qd S )N)FULL_NAMES_MAP).0Zrec_type_id r	   8/tmp/pip-build-7vycvbft/prov/prov/serializers/provxml.py	<genexpr>   s    r   z http://www.w3.org/2001/XMLSchemac               @   s   e Zd ZdS )ProvXMLExceptionN)__name__
__module____qualname__r	   r	   r	   r
   r      s   r   c               @   s<   e Zd ZdZdddZdddZdd	 Zd
d Zdd ZdS )ProvXMLSerializerz9PROV-XML serializer for :class:`~prov.model.ProvDocument`Fc             K   s|   | j | j|d}x | jjD ]}| j |||d qW tj|}t|tjrf|jtj	|dddj
d n|j|dddd dS )	a  
        Serializes a :class:`~prov.model.ProvDocument` instance to `PROV-XML
        <http://www.w3.org/TR/prov-xml/>`_.

        :param stream: Where to save the output.
        :type force_types: boolean, optional
        :param force_types: Will force xsd:types to be written for most
            attributes mainly PROV-"attributes", e.g. tags not in the
            PROV namespace. Off by default meaning xsd:type attributes will
            only be set for prov:type, prov:location, and prov:value as is
            done in the official PROV-XML specification. Furthermore the
            types will always be set if the Python type requires it. False
            is a good default and it should rarely require changing.
        )bundleforce_types)r   elementr   T)xml_declarationpretty_printzutf-8zUTF-8)r   r   encodingN)serialize_bundledocumentZbundlesr   ElementTree
isinstanceio
TextIOBasewritetostringdecode)selfstreamr   kwargsZxml_rootr   etr	   r	   r
   	serialize%   s    

zProvXMLSerializer.serializeNc             C   s  dd | j jj D }| j jjr0| j jjj|d< x"|jD ]}||kr8|j||j< q8W x8tj D ],\}}|j}|jdkr|j	d}|||j< q^W |dk	rt
j|td|d}	nt
jtd|d}	|jrt|j|	jtd	< x|jD ]}
|
j }|
jrt|
jnd}|rtd	|i}nd}t|
j}| j||}t
j|	t||}xJt||D ]:\}}t
j|t|jj|j}t|tjjr|jdt d
 gkrd|jjj|jjf |jt!d< |j"dk	r|j"|jt#d< |j$}nRt|tjj%r|t&krd|jt!d< t|}n t|t'j'r(|j( }nt|}t)t'j't*t+tjj,g}t-|}|spt.||ksp|t/t0t1gkrht!d|jkrht|j2d rh|t&ko| rh|t3t4gkrhd}t|t)rt5}|j6 }n|t|trt7}njt|t*rt8}nXt|t+rt9}nFt|t'j'r8|jjdks2d|jj6 krLt:}nt|tjj,rLt;}|dk	rht||jt!d< |t&kr|r||jtd< n||_<qTW qW |	S )a  
        Serializes a bundle or document to PROV XML.

        :param bundle: The bundle or document.
        :param element: The XML element to write to. Will be created if None.
        :type force_types: boolean, optional
        :param force_types: Will force xsd:types to be written for most
            attributes mainly PROV-"attributes", e.g. tags not in the
            PROV namespace. Off by default meaning xsd:type attributes will
            only be set for prov:type, prov:location, and prov:value as is
            done in the official PROV-XML specification. Furthermore the
            types will always be set if the Python type requires it. False
            is a good default and it should rarely require changing.
        c             S   s   i | ]}|j |jqS r	   )uriprefix)r   nsr	   r	   r
   
<dictcomp>W   s   z6ProvXMLSerializer.serialize_bundle.<locals>.<dictcomp>NZxsd#bundleContent)nsmapr   idZInternationalizedStringz%s:%stypelangz	xsd:QNamezprov:provtimeref)=r   _namespacesZget_registered_namespaces_defaultr%   
namespacesr&   r   itemsrstripr   
SubElement_ns_provElement
identifierstrattribZ_recordsget_typeZ_identifierlist
attributes_derive_record_labelr   _ns	namespace	localpartr   r/   modelLiteraldatatypePROV_ns_xsilangtag_ns_xmlvalueZQualifiedNameZPROV_ATTRIBUTE_QNAMESdatetime	isoformatboolfloatintZ
Identifiertupler-   	PROV_TYPEZPROV_LOCATIONZ
PROV_VALUE
startswithZPROV_ATTR_TIMEZ
PROV_LABELZXSD_BOOLEANlowerZ
XSD_STRINGZ
XSD_DOUBLEZXSD_INTZXSD_DATETIMEZ
XSD_ANYURItext)r    r   r   r   r+   rB   keyrK   r%   Zxml_bundle_rootrecordrec_typer:   attrsr?   	rec_labelelemattrZsubelemvZALWAYS_CHECKZxsd_typer	   r	   r
   r   F   s    









z"ProvXMLSerializer.serialize_bundlec          
   K   s   t |tjrPtj 4}|j|j jd |jdd tj	|j
 }W dQ R X ntj	|j
 }x$|jdD ]}|j }|j| qjW tjj }| j|| |S )z
        Deserialize from `PROV-XML <http://www.w3.org/TR/prov-xml/>`_
        representation to a :class:`~prov.model.ProvDocument` instance.

        :param stream: Input data.
        zutf-8r   Nz//comment())r   r   r   BytesIOr   readencodeseekr   parsegetrootZxpathZ	getparentremover/   rD   ZProvDocumentdeserialize_subtree)r    r!   r"   bufxml_doccpr   r	   r	   r
   deserialize   s    

zProvXMLSerializer.deserializec             C   s  x|D ]}t j|}|jtd jkr0td|jdkrHtjdt	 qt
d}||jkrd|j| nd}|dk	rzt||}|jdkr|j|d}| j|| qt|}t|j }	t|	 }
td	|jkrt||jtd	 }|jtd	 |f |j|
||}|
|	kr|j|	 qW |S )
a  
        Deserialize an etree element containing a PROV document or a bundle
        and write it to the provided internal object.

        :param xml_doc: An etree element containing the information to read.
        :param bundle: The bundle object to write to.
        r/   z2Non PROV element discovered in document or bundle.otherz[Document contains non-PROV information in <prov:other>. It will be ignored in this package.r,   Nr*   )r:   r-   )r   QNamerB   r   r%   r   	localnamewarningswarnUserWarningr8   r<   xml_qname_to_QualifiedNamer   re   _extract_attributesFULL_PROV_RECORD_IDS_MAPPROV_BASE_CLSrH   appendrG   Z
new_recordZadd_asserted_type)r    rg   r   r   qnameZid_tagZrec_idbr?   Zq_prov_namerX   rK   Zrecr	   r	   r
   re      s:    	




z%ProvXMLSerializer.deserialize_subtreec             C   sl   t | }x^t|D ]R\}}|tkr$qt|tjjr8|j}|tkrt| |kr|j	||f t | }P qW |S )aD  
        Helper function trying to derive the record label taking care of
        subtypes and what not. It will also remove the type declaration for
        the attributes if it was used to specialize the type.

        :param rec_type: The type of records.
        :param attributes: The attributes of the record.
        )
r   r>   rR   r   r/   rD   rE   rK   rt   rd   )r    rX   r?   rZ   rV   rK   r	   r	   r
   r@   *  s    	z&ProvXMLSerializer._derive_record_label)F)NF)	r   r   r   __doc__r$   r   rj   re   r@   r	   r	   r	   r
   r   "   s   
!
 8r   c       	      C   s   g }x| D ]}t j|}t|d|j|jf }x|jj D ]\}}|tdkrt||}|tkrnt||j	}qt
jj|j	|}q:|tdkrt||}q:|tdkrt
jj|j	|d}q:tjd|t|t|f t q:W |js|j	}|j||f q
W |S )zr
    Extract the PROV attributes from an etree element.

    :param element: The lxml.etree.Element instance.
    z%s:%sr-   r1   r.   )rI   zThe element '%s' contains an attribute %s='%s' which is not representable in the prov module's internal data model and will thus be ignored.)r   rl   rq   r&   rm   r<   r5   rH   Z	XSD_QNAMErU   r/   rD   rE   r8   rJ   rn   ro   r;   rp   ru   )	r   r?   ZsubelZsqnameZ_trV   rK   rF   Z_vr	   r	   r
   rr   A  s.    



rr   c             C   s   d|kr\|j dd\}}|| jkr\| j| }|tkr:t}n|tjkrJt}n
t||}|| S d | jkr| jd  }td|}|| S td| d S )N:    z/Could not create a valid QualifiedName for "%s")splitr+   XML_XSD_URIZXSDrG   r%   Z	Namespacer   )r   Z	qname_strr&   rC   Zns_urir'   r	   r	   r
   rq   j  s     






rq   c             C   s   d| |f S )Nz{%s}%sr	   )r'   tagr	   r	   r
   rA     s    rA   c             C   s   t td j| S )Nr/   )rA   r   r%   )r~   r	   r	   r
   r8     s    r8   c             C   s   t td j| S )Nxsi)rA   r   r%   )r~   r	   r	   r
   rH     s    rH   c             C   s   d}t || S )Nz$http://www.w3.org/XML/1998/namespace)rA   )r~   ZNS_XMLr	   r	   r
   rJ     s    rJ   )#rL   logginglxmlr   r   rn   r/   Zprov.identifierZ
prov.modelr   r   Zprov.constantsZprov.serializersr   
__author__	__email__	getLoggerr   loggerdictZ
PROV_N_MAPr   updateZADDITIONAL_N_MAPrs   r}   Errorr   r   rr   rq   rA   r8   rH   rJ   r	   r	   r	   r
   <module>   s6   

  !)