aboutsummaryrefslogtreecommitdiff
path: root/grit/format/policy_templates/writers/plist_writer.py
blob: 6d929d6542687720a1dd3cde095a7886773600e3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#!/usr/bin/env python
# Copyright (c) 2012 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.


from xml.dom import minidom
from grit.format.policy_templates.writers import plist_helper
from grit.format.policy_templates.writers import xml_formatted_writer


# This writer outputs a Preferences Manifest file as documented at
# https://developer.apple.com/library/mac/documentation/MacOSXServer/Conceptual/Preference_Manifest_Files


def GetWriter(config):
  '''Factory method for creating PListWriter objects.
  See the constructor of TemplateWriter for description of
  arguments.
  '''
  return PListWriter(['mac'], config)


class PListWriter(xml_formatted_writer.XMLFormattedWriter):
  '''Class for generating policy templates in Mac plist format.
  It is used by PolicyTemplateGenerator to write plist files.
  '''

  STRING_TABLE = 'Localizable.strings'
  TYPE_TO_INPUT = {
    'string': 'string',
    'int': 'integer',
    'int-enum': 'integer',
    'string-enum': 'string',
    'string-enum-list': 'array',
    'main': 'boolean',
    'list': 'array',
    'dict': 'dictionary',
  }

  def _AddKeyValuePair(self, parent, key_string, value_tag):
    '''Adds a plist key-value pair to a parent XML element.

    A key-value pair in plist consists of two XML elements next two each other:
    <key>key_string</key>
    <value_tag>...</value_tag>

    Args:
      key_string: The content of the key tag.
      value_tag: The name of the value element.

    Returns:
      The XML element of the value tag.
    '''
    self.AddElement(parent, 'key', {}, key_string)
    return self.AddElement(parent, value_tag)

  def _AddStringKeyValuePair(self, parent, key_string, value_string):
    '''Adds a plist key-value pair to a parent XML element, where the
    value element contains a string. The name of the value element will be
    <string>.

    Args:
      key_string: The content of the key tag.
      value_string: The content of the value tag.
    '''
    self.AddElement(parent, 'key', {}, key_string)
    self.AddElement(parent, 'string', {}, value_string)

  def _AddTargets(self, parent, policy):
    '''Adds the following XML snippet to an XML element:
      <key>pfm_targets</key>
      <array>
        <string>user-managed</string>
      </array>

      Args:
        parent: The parent XML element where the snippet will be added.
    '''
    array = self._AddKeyValuePair(parent, 'pfm_targets', 'array')
    if self.CanBeRecommended(policy):
      self.AddElement(array, 'string', {}, 'user')
    if self.CanBeMandatory(policy):
      self.AddElement(array, 'string', {}, 'user-managed')

  def PreprocessPolicies(self, policy_list):
    return self.FlattenGroupsAndSortPolicies(policy_list)

  def WritePolicy(self, policy):
    policy_name = policy['name']
    policy_type = policy['type']
    if policy_type == 'external':
      # This type can only be set through cloud policy.
      return

    dict = self.AddElement(self._array, 'dict')
    self._AddStringKeyValuePair(dict, 'pfm_name', policy_name)
    # Set empty strings for title and description. They will be taken by the
    # OSX Workgroup Manager from the string table in a Localizable.strings file.
    # Those files are generated by plist_strings_writer.
    self._AddStringKeyValuePair(dict, 'pfm_description', '')
    self._AddStringKeyValuePair(dict, 'pfm_title', '')
    self._AddTargets(dict, policy)
    self._AddStringKeyValuePair(dict, 'pfm_type',
                                self.TYPE_TO_INPUT[policy_type])
    if policy_type in ('int-enum', 'string-enum'):
      range_list = self._AddKeyValuePair(dict, 'pfm_range_list', 'array')
      for item in policy['items']:
        if policy_type == 'int-enum':
          element_type = 'integer'
        else:
          element_type = 'string'
        self.AddElement(range_list, element_type, {}, str(item['value']))
    elif policy_type in ('list', 'string-enum-list'):
      subkeys = self._AddKeyValuePair(dict, 'pfm_subkeys', 'array')
      subkeys_dict = self.AddElement(subkeys, 'dict')
      subkeys_type = self._AddKeyValuePair(subkeys_dict, 'pfm_type', 'string')
      self.AddText(subkeys_type, 'string')

  def BeginTemplate(self):
    self._plist.attributes['version'] = '1'
    dict = self.AddElement(self._plist, 'dict')

    app_name = plist_helper.GetPlistFriendlyName(self.config['app_name'])
    self._AddStringKeyValuePair(dict, 'pfm_name', app_name)
    self._AddStringKeyValuePair(dict, 'pfm_description', '')
    self._AddStringKeyValuePair(dict, 'pfm_title', '')
    self._AddStringKeyValuePair(dict, 'pfm_version', '1')
    self._AddStringKeyValuePair(dict, 'pfm_domain',
                                self.config['mac_bundle_id'])

    self._array = self._AddKeyValuePair(dict, 'pfm_subkeys', 'array')

  def CreatePlistDocument(self):
    dom_impl = minidom.getDOMImplementation('')
    doctype = dom_impl.createDocumentType(
        'plist',
        '-//Apple//DTD PLIST 1.0//EN',
        'http://www.apple.com/DTDs/PropertyList-1.0.dtd')
    return dom_impl.createDocument(None, 'plist', doctype)

  def Init(self):
    self._doc = self.CreatePlistDocument()
    self._plist = self._doc.documentElement

  def GetTemplateText(self):
    return self.ToPrettyXml(self._doc)