
                             S r SSKJr  SSKJr  SSKJr  SSKJr  SSKrSSKrSr " S S	\	5      r
 " S
 S\
5      r " S S\5      rS rS rS rg)aZ  Code for handling Manifest file in a Java jar file.

Jar files are just zip files with a particular interpretation for certain files
in the zip under the META-INF/ directory. So we can read and write them using
the standard zipfile module.

The specification for jar files is at
http://docs.oracle.com/javase/7/docs/technotes/guides/jar/jar.html
    )absolute_import)division)unicode_literals)with_statementNzMETA-INF/MANIFEST.MFc                       \ rS rSrSrg)Error%    N__name__
__module____qualname____firstlineno____static_attributes__r
       -lib/googlecloudsdk/command_lib/app/jarfile.pyr   r   %       r   r   c                       \ rS rSrSrg)InvalidJarError)   r
   Nr   r
   r   r   r   r   )   r   r   r   c                       \ rS rSrSrS rSrg)Manifest-   a)  The parsed manifest from a jar file.

Attributes:
  main_section: a dict representing the main (first) section of the manifest.
    Each key is a string that is an attribute, such as 'Manifest-Version', and
    the corresponding value is a string that is the value of the attribute,
    such as '1.0'.
  sections: a dict representing the other sections of the manifest. Each key
    is a string that is the value of the 'Name' attribute for the section,
    and the corresponding value is a dict like the main_section one, for the
    other attributes.
c                     Xl         X l        g )Nmain_sectionsections)selfr   r   s      r   __init__Manifest.__init__;   s    $Mr   r   N)r   r   r   r   __doc__r   r   r
   r   r   r   r   -   s    r   r   c                     [         R                  " U 5       n UR                  [        5      R	                  S5      n[        X 5      sSSS5        $ ! [
         a     SSS5        gf = f! , (       d  f       g= f)a  Read and parse the manifest out of the given jar.

Args:
  jar_file_name: the name of the jar from which the manifest is to be read.

Returns:
  A parsed Manifest object, or None if the jar has no manifest.

Raises:
  IOError: if the jar does not exist or cannot be read.
zutf-8N)zipfileZipFileread_MANIFEST_NAMEdecodeKeyError_ParseManifest)jar_file_namejarmanifest_strings      r   ReadManifestr-   @   sg     }%077@o /9 &%  	 &% &%s-   A)$A
A)
A&A)%A&&A))
A7c                 \   SR                  U R                  5       5      R                  S5      n [        R                  " SU 5      nU Vs/ s H  n[        X15      PM     nnUS   n0 nUSS  H-  nUR                  S5      nUc  [        U< SU< 35      eXvU'   M/     [        XV5      $ s  snf )aJ  Parse a Manifest object out of the given string.

Args:
  manifest_string: a str or unicode that is the manifest contents.
  jar_file_name: a str that is the path of the jar, for use in exception
    messages.

Returns:
  A Manifest object parsed out of the string.

Raises:
  InvalidJarError: if the manifest is not well-formed.

z
{2,}r      NNamez(: Manifest entry has no Name attribute: )	join
splitlinesrstripresplit_ParseManifestSectiongetr   r   )	r,   r*   section_stringssparsed_sectionsr   r   entrynames	            r   r)   r)   T   s      IIo88:;BB4H/HHX7/-/- +1<-  / #,(qr"e99VD|*E3 4 4 tn # 
,	))/s   
B)c                     U R                  SS5      R                  S5      n U (       d  0 $  [        S U R                  S5       5       5      $ ! [         a    [        U< SU < 35      ef = f)aO  Parse a dict out of the given manifest section string.

Args:
  section: a str or unicode that is the manifest section. It looks something
    like this (without the >):
    > Name: section-name
    > Some-Attribute: some value
    > Another-Attribute: another value
  jar_file_name: a str that is the path of the jar, for use in exception
    messages.

Returns:
  A dict where the keys are the attributes (here, 'Name', 'Some-Attribute',
  'Another-Attribute'), and the values are the corresponding attribute values.

Raises:
  InvalidJarError: if the manifest section is not well-formed.
z
  r/   c              3   D   #    U  H  oR                  S S5      v   M     g7f)z: r0   N)r6   ).0lines     r   	<genexpr>(_ParseManifestSection.<locals>.<genexpr>   s     D0C

4##0Cs    z: Invalid manifest )replacer4   dictr6   
ValueErrorr   )sectionr*   s     r   r7   r7   t   sh    ( OOE2&--d3'	IPDd0CDDD	 P
}gN
OOPs    A A*)r!   
__future__r   r   r   r   r5   r#   r&   	Exceptionr   r   objectr   r-   r)   r7   r
   r   r   <module>rL      sZ    '  ' % 	  (I e v &:(*@Pr   