
                             d Z ddlmZ ddlmZ ddlmZ ddlmZ ddlZddlZdZ G d d	e	      Z
 G d
 de
      Z G d de      Zd Zd Zd Zy)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                       e Zd Zy)ErrorN__name__
__module____qualname__     -lib/googlecloudsdk/command_lib/app/jarfile.pyr   r   %       r   r   c                       e Zd Zy)InvalidJarErrorNr	   r   r   r   r   r   )   r   r   r   c                       e Zd ZdZd Zy)Manifesta=  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                      || _         || _        y )N)main_sectionsections)selfr   r   s      r   __init__zManifest.__init__;   s    $DDMr   N)r
   r   r   __doc__r   r   r   r   r   r   -   s    r   r   c                     t        j                  |       5 }	 |j                  t              j	                  d      }t        ||       cddd       S # t
        $ r Y ddd       yw xY w# 1 sw Y   yxY w)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&   @   si     }%077@o /=9 &%  	 &% &%s-   A($AA(	A%A($A%%A((A1c                 P   dj                  | j                               j                  d      } t        j                  d|       }|D cg c]  }t        ||       }}|d   }i }|dd D ]*  }|j                  d      }|t        |d|      |||<   , t        ||      S c c}w )a\  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/-/- +1m<-  / #,(qr"e99VD|*E3 4 4 htn # 
,	))/s   	B#c                     | j                  dd      j                  d      } | si S 	 t        d | j                  d      D              S # t        $ r t        |d|       w xY w)ak  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   @   K   | ]  }|j                  d d        yw)z: r)   N)r/   ).0lines     r   	<genexpr>z(_ParseManifestSection.<locals>.<genexpr>   s     D0C

4#0Cs   z: Invalid manifest )replacer-   dictr/   
ValueErrorr   )sectionr#   s     r   r0   r0   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   r.   r   r   	Exceptionr   r   objectr   r&   r"   r0   r   r   r   <module>rD      sZ    '  ' % 	  (I e v &:(*@Pr   