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
7from xml.dom import minidom
8from grit.format.policy_templates.writers import plist_helper
9from grit.format.policy_templates.writers import xml_formatted_writer
10
11
12def GetWriter(config):
13  '''Factory method for creating PListWriter objects.
14  See the constructor of TemplateWriter for description of
15  arguments.
16  '''
17  return PListWriter(['mac'], config)
18
19
20class PListWriter(xml_formatted_writer.XMLFormattedWriter):
21  '''Class for generating policy templates in Mac plist format.
22  It is used by PolicyTemplateGenerator to write plist files.
23  '''
24
25  STRING_TABLE = 'Localizable.strings'
26  TYPE_TO_INPUT = {
27    'string': 'string',
28    'int': 'integer',
29    'int-enum': 'integer',
30    'string-enum': 'string',
31    'main': 'boolean',
32    'list': 'array',
33    'dict': 'dictionary',
34  }
35
36  def _AddKeyValuePair(self, parent, key_string, value_tag):
37    '''Adds a plist key-value pair to a parent XML element.
38
39    A key-value pair in plist consists of two XML elements next two each other:
40    <key>key_string</key>
41    <value_tag>...</value_tag>
42
43    Args:
44      key_string: The content of the key tag.
45      value_tag: The name of the value element.
46
47    Returns:
48      The XML element of the value tag.
49    '''
50    self.AddElement(parent, 'key', {}, key_string)
51    return self.AddElement(parent, value_tag)
52
53  def _AddStringKeyValuePair(self, parent, key_string, value_string):
54    '''Adds a plist key-value pair to a parent XML element, where the
55    value element contains a string. The name of the value element will be
56    <string>.
57
58    Args:
59      key_string: The content of the key tag.
60      value_string: The content of the value tag.
61    '''
62    self.AddElement(parent, 'key', {}, key_string)
63    self.AddElement(parent, 'string', {}, value_string)
64
65  def _AddTargets(self, parent):
66    '''Adds the following XML snippet to an XML element:
67      <key>pfm_targets</key>
68      <array>
69        <string>user-managed</string>
70      </array>
71
72      Args:
73        parent: The parent XML element where the snippet will be added.
74    '''
75    array = self._AddKeyValuePair(parent, 'pfm_targets', 'array')
76    self.AddElement(array, 'string', {}, 'user-managed')
77
78  def PreprocessPolicies(self, policy_list):
79    return self.FlattenGroupsAndSortPolicies(policy_list)
80
81  def WritePolicy(self, policy):
82    policy_name = policy['name']
83    policy_type = policy['type']
84
85    dict = self.AddElement(self._array, 'dict')
86    self._AddStringKeyValuePair(dict, 'pfm_name', policy_name)
87    # Set empty strings for title and description. They will be taken by the
88    # OSX Workgroup Manager from the string table in a Localizable.strings file.
89    # Those files are generated by plist_strings_writer.
90    self._AddStringKeyValuePair(dict, 'pfm_description', '')
91    self._AddStringKeyValuePair(dict, 'pfm_title', '')
92    self._AddTargets(dict)
93    self._AddStringKeyValuePair(dict, 'pfm_type',
94                                self.TYPE_TO_INPUT[policy_type])
95    if policy_type in ('int-enum', 'string-enum'):
96      range_list = self._AddKeyValuePair(dict, 'pfm_range_list', 'array')
97      for item in policy['items']:
98        if policy_type == 'int-enum':
99          element_type = 'integer'
100        else:
101          element_type = 'string'
102        self.AddElement(range_list, element_type, {}, str(item['value']))
103
104  def BeginTemplate(self):
105    self._plist.attributes['version'] = '1'
106    dict = self.AddElement(self._plist, 'dict')
107
108    app_name = plist_helper.GetPlistFriendlyName(self.config['app_name'])
109    self._AddStringKeyValuePair(dict, 'pfm_name', app_name)
110    self._AddStringKeyValuePair(dict, 'pfm_description', '')
111    self._AddStringKeyValuePair(dict, 'pfm_title', '')
112    self._AddStringKeyValuePair(dict, 'pfm_version', '1')
113    self._AddStringKeyValuePair(dict, 'pfm_domain',
114                                self.config['mac_bundle_id'])
115
116    self._array = self._AddKeyValuePair(dict, 'pfm_subkeys', 'array')
117
118  def Init(self):
119    dom_impl = minidom.getDOMImplementation('')
120    doctype = dom_impl.createDocumentType(
121        'plist',
122        '-//Apple//DTD PLIST 1.0//EN',
123        'http://www.apple.com/DTDs/PropertyList-1.0.dtd')
124    self._doc = dom_impl.createDocument(None, 'plist', doctype)
125    self._plist = self._doc.documentElement
126
127  def GetTemplateText(self):
128    return self.ToPrettyXml(self._doc)
129