aboutsummaryrefslogtreecommitdiff
path: root/grit/format/policy_templates/policy_template_generator.py
blob: 3fad8cadd26d4a519f5c4c419be13bef34bacd7b (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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
#!/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.


import copy
import types


class PolicyTemplateGenerator:
  '''Generates template text for a particular platform.

  This class is used to traverse a JSON structure from a .json template
  definition metafile and merge GUI message string definitions that come
  from a .grd resource tree onto it. After this, it can be used to output
  this data to policy template files using TemplateWriter objects.
  '''

  def _ImportMessage(self, msg_txt):
    msg_txt = msg_txt.decode('utf-8')
    # Replace the placeholder of app name.
    msg_txt = msg_txt.replace('$1', self._config['app_name'])
    msg_txt = msg_txt.replace('$2', self._config['os_name'])
    msg_txt = msg_txt.replace('$3', self._config['frame_name'])
    # Strip spaces and escape newlines.
    lines = msg_txt.split('\n')
    lines = [line.strip() for line in lines]
    return "\n".join(lines)

  def __init__(self, config, policy_data):
    '''Initializes this object with all the data necessary to output a
    policy template.

    Args:
      messages: An identifier to string dictionary of all the localized
        messages that might appear in the policy template.
      policy_definitions: The list of defined policies and groups, as
        parsed from the policy metafile. Note that this list is passed by
        reference and its contents are modified.
        See chrome/app/policy.policy_templates.json for description and
        content.
    '''
    # List of all the policies:
    self._policy_data = copy.deepcopy(policy_data)
    # Localized messages to be inserted to the policy_definitions structure:
    self._messages = self._policy_data['messages']
    self._config = config
    for key in self._messages.keys():
      self._messages[key]['text'] = self._ImportMessage(
          self._messages[key]['text'])
    self._policy_definitions = self._policy_data['policy_definitions']
    self._ProcessPolicyList(self._policy_definitions)

  def _ProcessSupportedOn(self, supported_on):
    '''Parses and converts the string items of the list of supported platforms
    into dictionaries.

    Args:
      supported_on: The list of supported platforms. E.g.:
        ['chrome.win:8-10', 'chrome_frame:10-']

    Returns:
      supported_on: The list with its items converted to dictionaries. E.g.:
      [{
        'product': 'chrome',
        'platform': 'win',
        'since_version': '8',
        'until_version': '10'
      }, {
        'product': 'chrome_frame',
        'platform': 'win',
        'since_version': '10',
        'until_version': ''
      }]
    '''
    result = []
    for supported_on_item in supported_on:
      product_platform_part, version_part = supported_on_item.split(':')

      if '.' in product_platform_part:
        product, platform = product_platform_part.split('.')
        if platform == '*':
          # e.g.: 'chrome.*:8-10'
          platforms = ['linux', 'mac', 'win']
        else:
          # e.g.: 'chrome.win:-10'
          platforms = [platform]
      else:
        # e.g.: 'chrome_frame:7-'
        product, platform = {
          'android':      ('chrome',        'android'),
          'chrome_os':    ('chrome_os',     'chrome_os'),
          'chrome_frame': ('chrome_frame',  'win'),
          'ios':          ('chrome',        'ios'),
        }[product_platform_part]
        platforms = [platform]
      since_version, until_version = version_part.split('-')
      result.append({
        'product': product,
        'platforms': platforms,
        'since_version': since_version,
        'until_version': until_version
      })
    return result

  def _PrintPolicyValue(self, item):
    '''Produces a string representation for a policy value. Taking care to print
    dictionaries in a sorted order.'''
    if type(item) == types.StringType:
      str_val = "'%s'" % item
    elif isinstance(item, dict):
      str_val = "{";  
      for it in sorted(item.iterkeys()):
        str_val += "\'%s\': %s, " % (it, self._PrintPolicyValue(item[it]))
      str_val = str_val.rstrip(", ") + "}";  
    else:
      str_val = str(item)
    return str_val;  

  def _ProcessPolicy(self, policy):
    '''Processes localized message strings in a policy or a group.
     Also breaks up the content of 'supported_on' attribute into a list.

    Args:
      policy: The data structure of the policy or group, that will get message
        strings here.
    '''
    policy['desc'] = self._ImportMessage(policy['desc'])
    policy['caption'] = self._ImportMessage(policy['caption'])
    if 'label' in policy:
      policy['label'] = self._ImportMessage(policy['label'])

    if policy['type'] == 'group':
      self._ProcessPolicyList(policy['policies'])
    elif policy['type'] in ('string-enum', 'int-enum'):
      # Iterate through all the items of an enum-type policy, and add captions.
      for item in policy['items']:
        item['caption'] = self._ImportMessage(item['caption'])
    elif policy['type'] == 'dict' and 'example_value' in policy:
      policy['example_value'] = self._PrintPolicyValue(policy['example_value'])
    if policy['type'] != 'group':
      if not 'label' in policy:
        # If 'label' is not specified, then it defaults to 'caption':
        policy['label'] = policy['caption']
      policy['supported_on'] = self._ProcessSupportedOn(policy['supported_on'])

  def _ProcessPolicyList(self, policy_list):
    '''Adds localized message strings to each item in a list of policies and
    groups. Also breaks up the content of 'supported_on' attributes into lists
    of dictionaries.

    Args:
      policy_list: A list of policies and groups. Message strings will be added
        for each item and to their child items, recursively.
    '''
    for policy in policy_list:
      self._ProcessPolicy(policy)

  def GetTemplateText(self, template_writer):
    '''Generates the text of the template from the arguments given
    to the constructor, using a given TemplateWriter.

    Args:
      template_writer: An object implementing TemplateWriter. Its methods
        are called here for each item of self._policy_groups.

    Returns:
      The text of the generated template.
    '''
    return template_writer.WriteTemplate(self._policy_data)