• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
7import copy
8import types
9
10
11class PolicyTemplateGenerator:
12  '''Generates template text for a particular platform.
13
14  This class is used to traverse a JSON structure from a .json template
15  definition metafile and merge GUI message string definitions that come
16  from a .grd resource tree onto it. After this, it can be used to output
17  this data to policy template files using TemplateWriter objects.
18  '''
19
20  def _ImportMessage(self, msg_txt):
21    msg_txt = msg_txt.decode('utf-8')
22    # Replace the placeholder of app name.
23    msg_txt = msg_txt.replace('$1', self._config['app_name'])
24    msg_txt = msg_txt.replace('$2', self._config['os_name'])
25    msg_txt = msg_txt.replace('$3', self._config['frame_name'])
26    # Strip spaces and escape newlines.
27    lines = msg_txt.split('\n')
28    lines = [line.strip() for line in lines]
29    return "\n".join(lines)
30
31  def __init__(self, config, policy_data):
32    '''Initializes this object with all the data necessary to output a
33    policy template.
34
35    Args:
36      messages: An identifier to string dictionary of all the localized
37        messages that might appear in the policy template.
38      policy_definitions: The list of defined policies and groups, as
39        parsed from the policy metafile. Note that this list is passed by
40        reference and its contents are modified.
41        See chrome/app/policy.policy_templates.json for description and
42        content.
43    '''
44    # List of all the policies:
45    self._policy_data = copy.deepcopy(policy_data)
46    # Localized messages to be inserted to the policy_definitions structure:
47    self._messages = self._policy_data['messages']
48    self._config = config
49    for key in self._messages.keys():
50      self._messages[key]['text'] = self._ImportMessage(
51          self._messages[key]['text'])
52    self._policy_definitions = self._policy_data['policy_definitions']
53    self._ProcessPolicyList(self._policy_definitions)
54
55  def _ProcessSupportedOn(self, supported_on):
56    '''Parses and converts the string items of the list of supported platforms
57    into dictionaries.
58
59    Args:
60      supported_on: The list of supported platforms. E.g.:
61        ['chrome.win:8-10', 'chrome_frame:10-']
62
63    Returns:
64      supported_on: The list with its items converted to dictionaries. E.g.:
65      [{
66        'product': 'chrome',
67        'platform': 'win',
68        'since_version': '8',
69        'until_version': '10'
70      }, {
71        'product': 'chrome_frame',
72        'platform': 'win',
73        'since_version': '10',
74        'until_version': ''
75      }]
76    '''
77    result = []
78    for supported_on_item in supported_on:
79      product_platform_part, version_part = supported_on_item.split(':')
80
81      # TODO(joaodasilva): enable parsing 'android' as a platform and including
82      # that platform in the generated documentation. Just skip it for now to
83      # prevent build failures.
84      if product_platform_part == 'android':
85        continue
86
87      if '.' in product_platform_part:
88        product, platform = product_platform_part.split('.')
89        if platform == '*':
90          # e.g.: 'chrome.*:8-10'
91          platforms = ['linux', 'mac', 'win']
92        else:
93          # e.g.: 'chrome.win:-10'
94          platforms = [platform]
95      else:
96        # e.g.: 'chrome_frame:7-'
97        product = product_platform_part
98        platform = {
99          'chrome_os': 'chrome_os',
100          'chrome_frame': 'win'
101        }[product]
102        platforms = [platform]
103      since_version, until_version = version_part.split('-')
104      result.append({
105        'product': product,
106        'platforms': platforms,
107        'since_version': since_version,
108        'until_version': until_version
109      })
110    return result
111
112  def _PrintPolicyValue(self, item):
113    '''Produces a string representation for a policy value. Taking care to print
114    dictionaries in a sorted order.'''
115    if type(item) == types.StringType:
116      str_val = "'%s'" % item
117    elif isinstance(item, dict):
118      str_val = "{";
119      for it in sorted(item.iterkeys()):
120        str_val += "\'%s\': %s, " % (it, self._PrintPolicyValue(item[it]))
121      str_val = str_val.rstrip(", ") + "}";
122    else:
123      str_val = str(item)
124    return str_val;
125
126  def _ProcessPolicy(self, policy):
127    '''Processes localized message strings in a policy or a group.
128     Also breaks up the content of 'supported_on' attribute into a list.
129
130    Args:
131      policy: The data structure of the policy or group, that will get message
132        strings here.
133    '''
134    policy['desc'] = self._ImportMessage(policy['desc'])
135    policy['caption'] = self._ImportMessage(policy['caption'])
136    if 'label' in policy:
137      policy['label'] = self._ImportMessage(policy['label'])
138
139    if policy['type'] == 'group':
140      self._ProcessPolicyList(policy['policies'])
141    elif policy['type'] in ('string-enum', 'int-enum'):
142      # Iterate through all the items of an enum-type policy, and add captions.
143      for item in policy['items']:
144        item['caption'] = self._ImportMessage(item['caption'])
145    elif policy['type'] == 'dict' and 'example_value' in policy:
146      policy['example_value'] = self._PrintPolicyValue(policy['example_value'])
147    if policy['type'] != 'group':
148      if not 'label' in policy:
149        # If 'label' is not specified, then it defaults to 'caption':
150        policy['label'] = policy['caption']
151      policy['supported_on'] = self._ProcessSupportedOn(policy['supported_on'])
152
153  def _ProcessPolicyList(self, policy_list):
154    '''Adds localized message strings to each item in a list of policies and
155    groups. Also breaks up the content of 'supported_on' attributes into lists
156    of dictionaries.
157
158    Args:
159      policy_list: A list of policies and groups. Message strings will be added
160        for each item and to their child items, recursively.
161    '''
162    for policy in policy_list:
163      self._ProcessPolicy(policy)
164
165  def GetTemplateText(self, template_writer):
166    '''Generates the text of the template from the arguments given
167    to the constructor, using a given TemplateWriter.
168
169    Args:
170      template_writer: An object implementing TemplateWriter. Its methods
171        are called here for each item of self._policy_groups.
172
173    Returns:
174      The text of the generated template.
175    '''
176    return template_writer.WriteTemplate(self._policy_data)
177