
    W'Fg46                         S SK r SSKJr  SSKJr   " S S\5      r " S S\5      r " S	 S
\5      rS r	 " S S\5      r
\
rg)    N   )xmlutil)logc                       \ rS rSrSrS rSrg)_XPathSegment   a  
Class representing a single 'segment' of an xpath string. For example,
the xpath:

    ./qemu:foo/bar[1]/baz[@somepro='someval']/@finalprop

will be split into the following segments:

    #1: nodename=., fullsegment=.
    #2: nodename=foo, nsname=qemu, fullsegment=qemu:foo
    #3: nodename=bar, condition_num=1, fullsegment=bar[1]
    #4: nodename=baz, condition_prop=somepro, condition_val=someval,
            fullsegment=baz[@somepro='somval']
    #5: nodename=finalprop, is_prop=True, fullsegment=@finalprop
c                    Xl         Xl        S U l        S U l        S U l        SU R                  ;   a  U R                  R                  S5      R                  S5      u  U l        nSU;   a@  UR                  S5      u  p4UR                  S5      U l        UR                  S5      U l        O%UR                  5       (       a  [        U5      U l        U R                  R                  S5      U l
        U R                  (       a  U R                  SS  U l        S U l        SU R                  ;   a)  U R                  R                  S5      u  U l        U l        g g )N[]=@'r   :)fullsegmentnodenamecondition_propcondition_valcondition_numstripsplitisdigitint
startswithis_propnsname)selfr   condcpropcvals        */usr/share/virt-manager/virtinst/xmlapi.py__init___XPathSegment.__init__   s	   &#"!!$--"&--"5"5c":"@"@"EDM4d{ $

3&+kk#&6#%)ZZ_"%(Y"}}//4<< MM!"-DM$--)-)<)<S)A&DK      )r   r   r   r   r   r   r   N)__name__
__module____qualname____firstlineno____doc__r!   __static_attributes__ r#   r    r   r      s    Br#   r   c                   4    \ rS rSrSrS r\S 5       rS rSr	g)_XPath8   z]
Helper class for performing manipulations of XPath strings. Splits
the xpath into segments.
c                    Xl         / U l        U R                   R                  S5       HC  nUS:X  a  U R                  S S U l        M  U R                  R                  [	        U5      5        ME     U R                  S   R
                  U l        U R
                  =(       a    U R                  S   R                  =(       d    S U l        U R
                  (       a  U R                  S S U l        U R                  U R                  5      U l	        g )N/z..)
	fullxpathsegmentsr   appendr   r   r   propnamejoinxpath)r   r1   ss      r    r!   _XPath.__init__=   s    "%%c*ADy $cr 2MM  q!12 + }}R(00D$--*;*D*DL<< MM#2.DMYYt}}-
r#   c                 2    SR                  S U  5       5      $ )Nr/   c              3   8   #    U  H  oR                   v   M     g 7fN)r   ).0r7   s     r    	<genexpr>_XPath.join.<locals>.<genexpr>O   s     8x!xs   )r5   )r2   s    r    r5   _XPath.joinM   s    xx8x888r#   c                 >    U R                  U R                  S S 5      $ )Nr0   )r5   r2   r   s    r    parent_xpath_XPath.parent_xpathQ   s    yys+,,r#   )r1   r   r4   r2   r6   N)
r$   r%   r&   r'   r(   r!   staticmethodr5   rB   r)   r*   r#   r    r,   r,   8   s%    .  9 9-r#   r,   c                       \ rS rSr0 r\S 5       rS rS rS r	S r
S rS rS	 rS
 rS rS rS rS rS rS rS rS rS rS rS rS rS rS rS rS rS rS r S r!Sr"g) _XMLBaseU   c                      X R                   U'   g r;   )
NAMESPACES)clsr   uris      r    register_namespace_XMLBase.register_namespaceW   s    !$vr#   c                     [        5       er;   NotImplementedErrorrA   s    r    copy_api_XMLBase.copy_api[       !##r#   c                     [        5       er;   rO   r   r6   s     r    count_XMLBase.count]   rS   r#   c                     [        5       er;   rO   )r   r1   s     r    _find_XMLBase._find_   rS   r#   c                     [        5       er;   rO   r   nodes     r    _node_tostring_XMLBase._node_tostringa   rS   r#   c                     [        5       er;   rO   r\   s     r    _node_get_text_XMLBase._node_get_textc   rS   r#   c                     [        5       er;   rO   r   r]   setvals      r    _node_set_text_XMLBase._node_set_texte   rS   r#   c                     [        5       er;   rO   )r   r]   r4   s      r    _node_get_property_XMLBase._node_get_propertyg   rS   r#   c                     [        5       er;   rO   )r   r]   r4   re   s       r    _node_set_property_XMLBase._node_set_propertyi   rS   r#   c                     [        5       er;   rO   )r   xpathseg
parentnodes      r    	_node_new_XMLBase._node_newk   rS   r#   c                     [        5       er;   rO   )r   parentxpathrp   newnodes       r    _node_add_child_XMLBase._node_add_childm   rS   r#   c                     [        5       er;   rO   )r   rp   	childnodes      r    _node_remove_child_XMLBase._node_remove_childo   rS   r#   c                     [        5       er;   rO   )r   r6   ru   s      r    _node_replace_child_XMLBase._node_replace_childq   rS   r#   c                     [        5       er;   rO   r   xmls     r    _node_from_xml_XMLBase._node_from_xmls   rS   r#   c                     [        5       er;   rO   r\   s     r    _node_has_content_XMLBase._node_has_contentu   rS   r#   c                     [        5       er;   rO   r\   s     r    _node_get_name_XMLBase._node_get_namew   rS   r#   c                     [        5       er;   rO   rU   s     r    
node_clear_XMLBase.node_cleary   rS   r#   c                     [        5       er;   rO   r   s     r    _sanitize_xml_XMLBase._sanitize_xml{   rS   r#   c                 l    U R                  U5      nUc  gU R                  U R                  U5      5      $ )N )rY   r   r^   )r   r6   r]   s      r    get_xml_XMLBase.get_xml~   s4    zz% <!!$"5"5d";<<r#   c                     U R                  U5      nUc  g U(       a  g[        U5      nUR                  (       a  U R                  X4R                  5      $ U R                  U5      $ )NT)rY   r,   r   ri   r4   ra   )r   r6   is_boolr]   xpathobjs        r    get_xpath_content_XMLBase.get_xpath_content   sX    zz% <%=**41B1BCC""4((r#   c                     U R                  U5      nUSL a  U R                  U5        g Uc'  Ub  U R                  XS 5        U R                  U5        g Uc  U R	                  U5      nUSL a  g U R                  XU5        g )NFT)rY   node_force_remove_node_set_content_node_remove_empty_node_make_stub)r   r6   re   r]   s       r    set_xpath_content_XMLBase.set_xpath_content   s}    zz% U?""5)^&&uD9##E*|++E2~""57r#   c                 l    U R                  U5      nU R                  U5      nU R                  X$U5        g r;   )r   r   rv   )r   r   r6   ru   rp   s        r    node_add_xml_XMLBase.node_add_xml   s2    %%c*))%0
U8r#   c                 H    U R                  U5      nU R                  X5        g)z2
Replace the node at xpath with the passed in xml
N)r   r}   )r   r6   r   ru   s       r    node_replace_xml_XMLBase.node_replace_xml   s"     %%c*  0r#   c                     [        U5      nU R                  UR                  5       5      nU R                  U5      nUb  Uc  gU R                  X45        g)z
Remove the element referenced at the passed xpath, regardless
of whether it has children or not, and then clean up the XML
chain
N)r,   rY   rB   rz   )r   r1   r   rp   ry   s        r    r   _XMLBase.node_force_remove   sO     )$ZZ 5 5 78
JJy)	!2
6r#   c                     U R                  U R                  S5      5      nX!:X  a  g [        [        S5      XS.-  5      e)N.zSXML did not have expected root element name '%(expectname)s', found '%(foundname)s')
expectname	foundname)r   rY   RuntimeError_)r   expected_root_namerootnames      r    validate_root_name_XMLBase.validate_root_name   sK    &&tzz#7) 8 9-EFG 	Gr#   c                     [        U5      nUb  [        U5      nUR                  (       a  U R                  X$R                  U5        g U R                  X#5        g r;   )r,   strr   rl   r4   rf   )r   r6   r]   re   r   s        r    r   _XMLBase._node_set_content   sG    %=[F##D*;*;VD-r#   c                    [        U5      nSnU R                  U5      nU(       d  [        R                  " SU-  5      eUR                  SS  H  nUnUSUR
                  -  -  nU R                  U5      nUb  UnM/  U R                  XT5      nU R                  XdU5        UnUR                  (       d  Mg  U R                  XER                  UR                  5        M     U$ )a  
Build all nodes for the passed xpath. For example, if XML is <foo/>,
and xpath=./bar/@baz, after this function the XML will be:

  <foo>
    <bar baz=''/>
  </foo>

And the node pointing to @baz will be returned, for the caller to
do with as they please.

There's also special handling to ensure that setting
xpath=./bar[@baz='foo']/frob will create

  <bar baz='foo'>
    <frob></frob>
  </bar>

Even if <bar> didn't exist before. So we fill in the dependent property
expression values
r   z'Did not find XML root node for xpath=%sr   Nz/%s)r,   rY   r   DevErrorr2   r   rq   rv   r   rl   r   )	r   r1   r   rt   rp   ro   oldxpathtmpnoderu   s	            r    r   _XMLBase._node_make_stub   s    , )$ZZ,
""=	IK K !))!"-H"H58#7#777Kjj-G"$
nnX:G  w? J &&&''
4K4K ..0! .& r#   c                 0   [        U5      nUR                  SS nSnU(       as  [         R                  U5      nUR                  5         UnU R	                  U5      nUc  gUc  MH  U R                  U5      (       a  gU R                  XF5        U(       a  Mr  gg)z
Walk backwards up the xpath chain, and remove each element
if it doesn't have any children or attributes, so we don't
leave stale elements in the XML
N)r,   r2   r5   poprY   r   rz   )r   r1   r   r2   parentr6   childs          r    r   _XMLBase._node_remove_empty   s     )$$$Q'KK)ELLNEZZ&F~}%%e,,##F2 hr#   r*   N)#r$   r%   r&   r'   rI   classmethodrL   rQ   rV   rY   r^   ra   rf   ri   rl   rq   rv   rz   r}   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r)   r*   r#   r    rF   rF   U   s    J% %$$$$$$$$$$$$$$$$$=	)8$9
17G.0d3r#   rF   c                 D    [        U =(       a    U R                  S:H  5      $ )Ntext)booltype)ns    r    node_is_textr     s    &aff&''r#   c                       \ rS rSrS rS rS rS rS rS r	S r
S	 rS
 rS rS rS rS rS rS rS rS rS rS rSrg)_Libxml2APIi  c                    [         R                  U 5        [        R                  " S5        [        R                  " U5      U l        U R
                  R                  5       U l        U R                  R                  U R
                  R                  5        U R                  R                  5        H   u  p#U R                  R                  X#5        M"     g )Nr   )rF   r!   libxml2keepBlanksDefaultparseDoc_docxpathNewContext_ctxsetContextNodechildrenrI   itemsxpathRegisterNs)r   r   keyvals       r    r!   _Libxml2API.__init__  s    $ 	!!!$$$S)	II--/			  !3!34--/HCII%%c/ 0r#   c                     [        U S5      (       d  g U R                  R                  5         S U l        U R                  R	                  5         S U l        g )Nr   )hasattrr   freeDocr   xpathFreeContextrA   s    r    __del___Libxml2API.__del__*  s@    tV$$					""$	r#   c                 H    UR                  S5      (       d  SU;   a  US-  nU$ )N
)endswithr   s     r    r   _Libxml2API._sanitize_xml3  s%    ||D!!dck4KC
r#   c                 \    [        U R                  R                  R                  5       5      $ r;   )r   r   r   	serializerA   s    r    rQ   _Libxml2API.copy_api8  s     499--779::r#   c                    [        U5      R                  n U R                  R                  U5      nU=(       a    US   =(       d    S $ ! [         a7  n[
        R                  " SXSS9  [        U< S[        U5      < 35      S eS nAff = f)Nz!fullxpath=%s xpath=%s eval failedT)exc_info r   )	r,   r6   r   	xpathEval	Exceptionr   debugr   r   )r   r1   r6   r]   es        r    rY   _Libxml2API._find;  s    y!''	H99&&u-D
  a(D)	  	HII9t5)SV<=4G	Hs   A	 	
B
2BB
c                 J    [        U R                  R                  U5      5      $ r;   )lenr   r   rU   s     r    rV   _Libxml2API.countE  s    499&&u-..r#   c                 "    UR                  5       $ r;   )r   r\   s     r    r^   _Libxml2API._node_tostringH  s    ~~r#   c                 B    [         R                  " U5      R                  $ r;   )r   r   r   r   s     r    r   _Libxml2API._node_from_xmlJ  s    $---r#   c                     UR                   $ r;   )contentr\   s     r    ra   _Libxml2API._node_get_textM  s    ||r#   c                 X    Ub  [         R                  " U5      nUR                  U5        g r;   )r   
xml_escape
setContentrd   s      r    rf   _Libxml2API._node_set_textO  s$    ''/Fr#   c                 L    UR                  U5      nU(       a  UR                  $ g r;   )hasPropr   )r   r]   r4   props       r    ri   _Libxml2API._node_get_propertyT  s"    ||H%<< r#   c                     Uc:  UR                  U5      nU(       a!  UR                  5         UR                  5         g g UR                  U[        R
                  " U5      5        g r;   )r   
unlinkNodefreeNodesetPropr   r   )r   r]   r4   re   r   s        r    rl   _Libxml2API._node_set_propertyX  sK    ><<)D!  LL7#5#5f#=>r#   c                 "  ^^ [         R                  " TR                  5      nTR                  (       d  U$ UU4S jnU" 5       nU(       d3  UR	                  U R
                  TR                     TR                  5      nUR                  U5        U$ )Nc                     > Tn U (       ac  [         R                  " U R                  5       5       H!  nUR                  TR                  :X  d  M  Us  $    U R                  5       n U (       a  Mb  g g r;   )r   listifynsDefsnamer   
get_parent)r   nsrp   ro   s     r    _find_parent_ns._Libxml2API._node_new.<locals>._find_parent_nsf  sP    F!//&--/:Bww(//1!	 ;  **,	 &r#   )r   newNoder   r   newNsrI   setNs)r   ro   rp   ru   r	  r  s    ``   r    rq   _Libxml2API._node_newa  sk    //("3"34N	- OOHOO4hooGBbr#   c                     U R                  U5      nU(       aZ  UR                  =(       d    /  Vs/ s H  o3R                  PM     nnU H  nUR                  U5        M     UR	                  S 5        g g s  snf r;   )rY   
propertiesr  	unsetPropr   )r   r6   r]   p	propnamess        r    r   _Libxml2API.node_clearu  sa    zz% *.//*?R*?A*?A*?IAq! OOD!	 As   A4c                 l    UR                   S:H  =(       a    UR                  =(       d    UR                  $ )Nelement)r   r   r  r\   s     r    r   _Libxml2API._node_has_content}  s#    yyI%L4==+KDOOLr#   c                     UR                   $ r;   )r  r\   s     r    r   _Libxml2API._node_get_name  s    yyr#   c                 ^   UnUR                  5       n[        U5      (       a   UR                  5         UR                  5         UR                  5         UR                  5         [	        UR
                   Vs/ s H  n[        U5      PM     sn5      (       a  UR                  S 5        g g s  snf r;   )get_prevr   r   r   allr   r   )r   rp   ry   r]   whiter   s         r    rz   _Libxml2API._node_remove_child  s     NN)<)<=)<AQ)<=>>!!$' ?=s   6B*c                    Un[        UR                  5       5      (       dh  UR                  5       n[        U5      (       a!  [        R                  " UR
                  5      nO[        R                  " S5      nUR                  U5        UR                  5       R
                  nUR                  [        R                  " S5      5        UR                  U5        UR                  [        R                  " U5      5        g )Nr   z  )r   get_lastr  r   newTextr   addChild)r   rt   rp   ru   ignoreprevsibnewlastendtexts           r    rv   _Libxml2API._node_add_child  s    J//122 ))+GG$$!//'//:!//$/(%%'//GOOD12G$GOOG45r#   c                 H    U R                  U5      nUR                  U5        g r;   )rY   replaceNode)r   r6   ru   oldnodes       r    r}   _Libxml2API._node_replace_child  s    **U#G$r#   )r   r   N)r$   r%   r&   r'   r!   r   r   rQ   rY   rV   r^   r   ra   rf   ri   rl   rq   r   r   r   rz   rv   r}   r)   r*   r#   r    r   r     sb    0
;*/ . 
 ?("M(6%r#   r   )r   r   r   loggerr   objectr   r,   rF   r   r   XMLAPIr*   r#   r    <module>r/     sU      
&BF &BR-V -:~3v ~3B(H%( H%V 
r#   