195640e3a20adea634b4df4ccf8c93f411184c438joi@chromium.org#!/usr/bin/env python
295640e3a20adea634b4df4ccf8c93f411184c438joi@chromium.org# Copyright (c) 2012 The Chromium Authors. All rights reserved.
301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org# Use of this source code is governed by a BSD-style license that can be
401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org# found in the LICENSE file.
501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgclass TemplateWriter(object):
801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  '''Abstract base class for writing policy templates in various formats.
901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  The methods of this class will be called by PolicyTemplateGenerator.
1001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  '''
1101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
1201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def __init__(self, platforms, config):
1301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    '''Initializes a TemplateWriter object.
1401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
1501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    Args:
1601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      platforms: List of platforms for which this writer can write policies.
1701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      config: A dictionary of information required to generate the template.
1801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org        It contains some key-value pairs, including the following examples:
1901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org          'build': 'chrome' or 'chromium'
2001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org          'branding': 'Google Chrome' or 'Chromium'
2101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org          'mac_bundle_id': The Mac bundle id of Chrome. (Only set when building
2201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org            for Mac.)
2301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      messages: List of all the message strings from the grd file. Most of them
2401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org        are also present in the policy data structures that are passed to
2501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org        methods. That is the preferred way of accessing them, this should only
2601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org        be used in exceptional cases. An example for its use is the
2701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org        IDS_POLICY_WIN_SUPPORTED_WINXPSP2 message in ADM files, because that
2801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org        cannot be associated with any policy or group.
2901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    '''
3001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    self.platforms = platforms
3101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    self.config = config
3201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
3301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def IsDeprecatedPolicySupported(self, policy):
3401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    '''Checks if the given deprecated policy is supported by the writer.
3501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
3601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    Args:
3701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      policy: The dictionary of the policy.
3801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
3901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    Returns:
4001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      True if the writer chooses to include the deprecated 'policy' in its
4101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      output.
4201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    '''
4301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    return False
4401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
4501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def IsFuturePolicySupported(self, policy):
4601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    '''Checks if the given future policy is supported by the writer.
4701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
4801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    Args:
4901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      policy: The dictionary of the policy.
5001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
5101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    Returns:
5201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      True if the writer chooses to include the deprecated 'policy' in its
5301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      output.
5401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    '''
5501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    return False
5601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
5701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def IsPolicySupported(self, policy):
5801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    '''Checks if the given policy is supported by the writer.
5901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    In other words, the set of platforms supported by the writer
6001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    has a common subset with the set of platforms that support
6101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    the policy.
6201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
6301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    Args:
6401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      policy: The dictionary of the policy.
6501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
6601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    Returns:
6701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      True if the writer chooses to include 'policy' in its output.
6801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    '''
6901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    if ('deprecated' in policy and policy['deprecated'] is True and
7001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org        not self.IsDeprecatedPolicySupported(policy)):
7101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      return False
7201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
7301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    if ('future' in policy and policy['future'] is True and
7401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org        not self.IsFuturePolicySupported(policy)):
7501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      return False
7601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
7701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    if '*' in self.platforms:
7801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      # Currently chrome_os is only catched here.
7901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      return True
8001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    for supported_on in policy['supported_on']:
8101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      for supported_on_platform in supported_on['platforms']:
8201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org        if supported_on_platform in self.platforms:
8301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org          return True
8401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    return False
8501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
860bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org  def CanBeRecommended(self, policy):
870bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org    '''Checks if the given policy can be recommended.'''
880bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org    return policy.get('features', {}).get('can_be_recommended', False)
890bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org
90740badd5e3e44434a9a47b5d16749daac1e8ea80joaodasilva@chromium.org  def CanBeMandatory(self, policy):
91740badd5e3e44434a9a47b5d16749daac1e8ea80joaodasilva@chromium.org    '''Checks if the given policy can be mandatory.'''
92740badd5e3e44434a9a47b5d16749daac1e8ea80joaodasilva@chromium.org    return policy.get('features', {}).get('can_be_mandatory', True)
93740badd5e3e44434a9a47b5d16749daac1e8ea80joaodasilva@chromium.org
944c53b9ff18aff36dd4eb63ae7099a388be4afb6bjoaodasilva@chromium.org  def IsPolicySupportedOnPlatform(self, policy, platform):
954c53b9ff18aff36dd4eb63ae7099a388be4afb6bjoaodasilva@chromium.org    '''Checks if |policy| is supported on |platform|.
964c53b9ff18aff36dd4eb63ae7099a388be4afb6bjoaodasilva@chromium.org
974c53b9ff18aff36dd4eb63ae7099a388be4afb6bjoaodasilva@chromium.org    Args:
984c53b9ff18aff36dd4eb63ae7099a388be4afb6bjoaodasilva@chromium.org      policy: The dictionary of the policy.
994c53b9ff18aff36dd4eb63ae7099a388be4afb6bjoaodasilva@chromium.org      platform: The platform to check; one of 'win', 'mac', 'linux' or
1004c53b9ff18aff36dd4eb63ae7099a388be4afb6bjoaodasilva@chromium.org        'chrome_os'.
1014c53b9ff18aff36dd4eb63ae7099a388be4afb6bjoaodasilva@chromium.org    '''
1024c53b9ff18aff36dd4eb63ae7099a388be4afb6bjoaodasilva@chromium.org    is_supported = lambda x: platform in x['platforms']
1034c53b9ff18aff36dd4eb63ae7099a388be4afb6bjoaodasilva@chromium.org    return any(filter(is_supported, policy['supported_on']))
1044c53b9ff18aff36dd4eb63ae7099a388be4afb6bjoaodasilva@chromium.org
10501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def _GetPoliciesForWriter(self, group):
10601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    '''Filters the list of policies in the passed group that are supported by
10701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    the writer.
10801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
10901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    Args:
11001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      group: The dictionary of the policy group.
11101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
11201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    Returns: The list of policies of the policy group that are compatible
11301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      with the writer.
11401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    '''
11501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    if not 'policies' in group:
11601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      return []
11701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    result = []
11801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    for policy in group['policies']:
11901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      if self.IsPolicySupported(policy):
12001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org        result.append(policy)
12101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    return result
12201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
12301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def Init(self):
12401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    '''Initializes the writer. If the WriteTemplate method is overridden, then
12501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    this method must be called as first step of each template generation
12601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    process.
12701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    '''
12801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    pass
12901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
13001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def WriteTemplate(self, template):
13101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    '''Writes the given template definition.
13201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
13301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    Args:
13401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      template: Template definition to write.
13501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
13601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    Returns:
13701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      Generated output for the passed template definition.
13801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    '''
13901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    self.messages = template['messages']
14001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    self.Init()
14101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    template['policy_definitions'] = \
14201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org        self.PreprocessPolicies(template['policy_definitions'])
14301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    self.BeginTemplate()
14401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    for policy in template['policy_definitions']:
14501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      if policy['type'] == 'group':
14601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org        child_policies = self._GetPoliciesForWriter(policy)
1470bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org        child_recommended_policies = filter(self.CanBeRecommended,
1480bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org                                            child_policies)
14901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org        if child_policies:
15001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org          # Only write nonempty groups.
15101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org          self.BeginPolicyGroup(policy)
15201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org          for child_policy in child_policies:
15301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org            # Nesting of groups is currently not supported.
15401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org            self.WritePolicy(child_policy)
15501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org          self.EndPolicyGroup()
1560bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org        if child_recommended_policies:
1570bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org          self.BeginRecommendedPolicyGroup(policy)
1580bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org          for child_policy in child_recommended_policies:
1590bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org            self.WriteRecommendedPolicy(child_policy)
1600bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org          self.EndRecommendedPolicyGroup()
16101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      elif self.IsPolicySupported(policy):
16201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org        self.WritePolicy(policy)
1630bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org        if self.CanBeRecommended(policy):
1640bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org          self.WriteRecommendedPolicy(policy)
16501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    self.EndTemplate()
1660bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org
16701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    return self.GetTemplateText()
16801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
16901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def PreprocessPolicies(self, policy_list):
17001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    '''Preprocesses a list of policies according to a given writer's needs.
17101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    Preprocessing steps include sorting policies and stripping unneeded
17201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    information such as groups (for writers that ignore them).
17301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    Subclasses are encouraged to override this method, overriding
17401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    implementations may call one of the provided specialized implementations.
17501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    The default behaviour is to use SortPoliciesGroupsFirst().
17601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
17701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    Args:
17801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      policy_list: A list containing the policies to sort.
17901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
18001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    Returns:
18101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      The sorted policy list.
18201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    '''
18301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    return self.SortPoliciesGroupsFirst(policy_list)
18401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
18501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def WritePolicy(self, policy):
18601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    '''Appends the template text corresponding to a policy into the
18701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    internal buffer.
18801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
18901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    Args:
19001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      policy: The policy as it is found in the JSON file.
19101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    '''
19201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    raise NotImplementedError()
19301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
1940bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org  def WriteRecommendedPolicy(self, policy):
1950bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org    '''Appends the template text corresponding to a recommended policy into the
1960bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org    internal buffer.
1970bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org
1980bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org    Args:
1990bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org      policy: The recommended policy as it is found in the JSON file.
2000bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org    '''
2010bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org    # TODO
2020bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org    #raise NotImplementedError()
2030bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org    pass
2040bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org
20501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def BeginPolicyGroup(self, group):
20601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    '''Appends the template text corresponding to the beginning of a
20701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    policy group into the internal buffer.
20801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
20901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    Args:
21001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      group: The policy group as it is found in the JSON file.
21101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    '''
21201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    pass
21301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
21401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def EndPolicyGroup(self):
21501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    '''Appends the template text corresponding to the end of a
21601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    policy group into the internal buffer.
21701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    '''
21801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    pass
21901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
2200bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org  def BeginRecommendedPolicyGroup(self, group):
2210bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org    '''Appends the template text corresponding to the beginning of a recommended
2220bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org    policy group into the internal buffer.
2230bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org
2240bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org    Args:
2250bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org      group: The recommended policy group as it is found in the JSON file.
2260bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org    '''
2270bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org    pass
2280bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org
2290bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org  def EndRecommendedPolicyGroup(self):
2300bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org    '''Appends the template text corresponding to the end of a recommended
2310bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org    policy group into the internal buffer.
2320bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org    '''
2330bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org    pass
2340bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org
23501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def BeginTemplate(self):
23601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    '''Appends the text corresponding to the beginning of the whole
23701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    template into the internal buffer.
23801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    '''
23901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    raise NotImplementedError()
24001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
24101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def EndTemplate(self):
24201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    '''Appends the text corresponding to the end of the whole
24301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    template into the internal buffer.
24401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    '''
24501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    pass
24601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
24701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def GetTemplateText(self):
24801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    '''Gets the content of the internal template buffer.
24901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
25001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    Returns:
25101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      The generated template from the the internal buffer as a string.
25201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    '''
25301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    raise NotImplementedError()
25401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
25501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def SortPoliciesGroupsFirst(self, policy_list):
25601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    '''Sorts a list of policies alphabetically. The order is the
25701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    following: first groups alphabetically by caption, then other policies
25801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    alphabetically by name. The order of policies inside groups is unchanged.
25901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
26001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    Args:
26101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      policy_list: The list of policies to sort. Sub-lists in groups will not
26201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org        be sorted.
26301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    '''
26401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    policy_list.sort(key=self.GetPolicySortingKeyGroupsFirst)
26501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    return policy_list
26601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
26701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def FlattenGroupsAndSortPolicies(self, policy_list, sorting_key=None):
26801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    '''Sorts a list of policies according to |sorting_key|, defaulting
26901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    to alphabetical sorting if no key is given. If |policy_list| contains
27001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    policies with type="group", it is flattened first, i.e. any groups' contents
27101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    are inserted into the list as first-class elements and the groups are then
27201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    removed.
27301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    '''
27401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    new_list = []
27501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    for policy in policy_list:
27601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      if policy['type'] == 'group':
27701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org        for grouped_policy in policy['policies']:
27801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org          new_list.append(grouped_policy)
27901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      else:
28001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org        new_list.append(policy)
28101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    if sorting_key == None:
28201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      sorting_key = self.GetPolicySortingKeyName
28301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    new_list.sort(key=sorting_key)
28401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    return new_list
28501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
28601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def GetPolicySortingKeyName(self, policy):
28701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    return policy['name']
28801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
28901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def GetPolicySortingKeyGroupsFirst(self, policy):
29001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    '''Extracts a sorting key from a policy. These keys can be used for
29101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    list.sort() methods to sort policies.
29201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    See TemplateWriter.SortPolicies for usage.
29301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    '''
29401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    is_group = policy['type'] == 'group'
29501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    if is_group:
29601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      # Groups are sorted by caption.
29701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      str_key = policy['caption']
29801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    else:
29901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      # Regular policies are sorted by name.
30001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      str_key = policy['name']
30101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    # Groups come before regular policies.
30201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    return (not is_group, str_key)
303