Home | History | Annotate | Download | only in writers
      1 #!/usr/bin/env python
      2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
      3 # Use of this source code is governed by a BSD-style license that can be
      4 # found in the LICENSE file.
      5 
      6 
      7 from xml.dom import minidom
      8 from grit.format.policy_templates.writers import plist_helper
      9 from grit.format.policy_templates.writers import xml_formatted_writer
     10 
     11 
     12 # This writer outputs a Preferences Manifest file as documented at
     13 # https://developer.apple.com/library/mac/documentation/MacOSXServer/Conceptual/Preference_Manifest_Files
     14 
     15 
     16 def GetWriter(config):
     17   '''Factory method for creating PListWriter objects.
     18   See the constructor of TemplateWriter for description of
     19   arguments.
     20   '''
     21   return PListWriter(['mac'], config)
     22 
     23 
     24 class PListWriter(xml_formatted_writer.XMLFormattedWriter):
     25   '''Class for generating policy templates in Mac plist format.
     26   It is used by PolicyTemplateGenerator to write plist files.
     27   '''
     28 
     29   STRING_TABLE = 'Localizable.strings'
     30   TYPE_TO_INPUT = {
     31     'string': 'string',
     32     'int': 'integer',
     33     'int-enum': 'integer',
     34     'string-enum': 'string',
     35     'main': 'boolean',
     36     'list': 'array',
     37     'dict': 'dictionary',
     38   }
     39 
     40   def _AddKeyValuePair(self, parent, key_string, value_tag):
     41     '''Adds a plist key-value pair to a parent XML element.
     42 
     43     A key-value pair in plist consists of two XML elements next two each other:
     44     <key>key_string</key>
     45     <value_tag>...</value_tag>
     46 
     47     Args:
     48       key_string: The content of the key tag.
     49       value_tag: The name of the value element.
     50 
     51     Returns:
     52       The XML element of the value tag.
     53     '''
     54     self.AddElement(parent, 'key', {}, key_string)
     55     return self.AddElement(parent, value_tag)
     56 
     57   def _AddStringKeyValuePair(self, parent, key_string, value_string):
     58     '''Adds a plist key-value pair to a parent XML element, where the
     59     value element contains a string. The name of the value element will be
     60     <string>.
     61 
     62     Args:
     63       key_string: The content of the key tag.
     64       value_string: The content of the value tag.
     65     '''
     66     self.AddElement(parent, 'key', {}, key_string)
     67     self.AddElement(parent, 'string', {}, value_string)
     68 
     69   def _AddTargets(self, parent):
     70     '''Adds the following XML snippet to an XML element:
     71       <key>pfm_targets</key>
     72       <array>
     73         <string>user-managed</string>
     74       </array>
     75 
     76       Args:
     77         parent: The parent XML element where the snippet will be added.
     78     '''
     79     array = self._AddKeyValuePair(parent, 'pfm_targets', 'array')
     80     self.AddElement(array, 'string', {}, 'user-managed')
     81 
     82   def PreprocessPolicies(self, policy_list):
     83     return self.FlattenGroupsAndSortPolicies(policy_list)
     84 
     85   def WritePolicy(self, policy):
     86     policy_name = policy['name']
     87     policy_type = policy['type']
     88     if policy_type == 'external':
     89       # This type can only be set through cloud policy.
     90       return
     91 
     92     dict = self.AddElement(self._array, 'dict')
     93     self._AddStringKeyValuePair(dict, 'pfm_name', policy_name)
     94     # Set empty strings for title and description. They will be taken by the
     95     # OSX Workgroup Manager from the string table in a Localizable.strings file.
     96     # Those files are generated by plist_strings_writer.
     97     self._AddStringKeyValuePair(dict, 'pfm_description', '')
     98     self._AddStringKeyValuePair(dict, 'pfm_title', '')
     99     self._AddTargets(dict)
    100     self._AddStringKeyValuePair(dict, 'pfm_type',
    101                                 self.TYPE_TO_INPUT[policy_type])
    102     if policy_type in ('int-enum', 'string-enum'):
    103       range_list = self._AddKeyValuePair(dict, 'pfm_range_list', 'array')
    104       for item in policy['items']:
    105         if policy_type == 'int-enum':
    106           element_type = 'integer'
    107         else:
    108           element_type = 'string'
    109         self.AddElement(range_list, element_type, {}, str(item['value']))
    110     elif policy_type == 'list':
    111       subkeys = self._AddKeyValuePair(dict, 'pfm_subkeys', 'array')
    112       subkeys_dict = self.AddElement(subkeys, 'dict')
    113       subkeys_type = self._AddKeyValuePair(subkeys_dict, 'pfm_type', 'string')
    114       self.AddText(subkeys_type, 'string')
    115 
    116   def BeginTemplate(self):
    117     self._plist.attributes['version'] = '1'
    118     dict = self.AddElement(self._plist, 'dict')
    119 
    120     app_name = plist_helper.GetPlistFriendlyName(self.config['app_name'])
    121     self._AddStringKeyValuePair(dict, 'pfm_name', app_name)
    122     self._AddStringKeyValuePair(dict, 'pfm_description', '')
    123     self._AddStringKeyValuePair(dict, 'pfm_title', '')
    124     self._AddStringKeyValuePair(dict, 'pfm_version', '1')
    125     self._AddStringKeyValuePair(dict, 'pfm_domain',
    126                                 self.config['mac_bundle_id'])
    127 
    128     self._array = self._AddKeyValuePair(dict, 'pfm_subkeys', 'array')
    129 
    130   def CreatePlistDocument(self):
    131     dom_impl = minidom.getDOMImplementation('')
    132     doctype = dom_impl.createDocumentType(
    133         'plist',
    134         '-//Apple//DTD PLIST 1.0//EN',
    135         'http://www.apple.com/DTDs/PropertyList-1.0.dtd')
    136     return dom_impl.createDocument(None, 'plist', doctype)
    137 
    138   def Init(self):
    139     self._doc = self.CreatePlistDocument()
    140     self._plist = self._doc.documentElement
    141 
    142   def GetTemplateText(self):
    143     return self.ToPrettyXml(self._doc)
    144