OLD | NEW |
(Empty) | |
| 1 # Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. |
| 4 |
| 5 |
| 6 import itertools |
| 7 |
| 8 |
| 9 class TemplateWriter(object): |
| 10 '''Abstract base class for writing policy templates in various formats. |
| 11 The methods of this class will be called by PolicyTemplateGenerator. |
| 12 ''' |
| 13 |
| 14 def __init__(self, platforms, config): |
| 15 '''Initializes a TemplateWriter object. |
| 16 |
| 17 Args: |
| 18 platforms: List of platforms for which this writer can write policies. |
| 19 config: A dictionary of information required to generate the template. |
| 20 It contains some key-value pairs, including the following examples: |
| 21 'build': 'chrome' or 'chromium' |
| 22 'branding': 'Google Chrome' or 'Chromium' |
| 23 'mac_bundle_id': The Mac bundle id of Chrome. (Only set when building |
| 24 for Mac.) |
| 25 messages: List of all the message strings from the grd file. Most of them |
| 26 are also present in the policy data structures that are passed to |
| 27 methods. That is the preferred way of accessing them, this should only |
| 28 be used in exceptional cases. An example for its use is the |
| 29 IDS_POLICY_WIN_SUPPORTED_WINXPSP2 message in ADM files, because that |
| 30 cannot be associated with any policy or group. |
| 31 ''' |
| 32 self.platforms = platforms |
| 33 self.config = config |
| 34 |
| 35 def IsDeprecatedPolicySupported(self, policy): |
| 36 '''Checks if the given deprecated policy is supported by the writer. |
| 37 |
| 38 Args: |
| 39 policy: The dictionary of the policy. |
| 40 |
| 41 Returns: |
| 42 True if the writer chooses to include the deprecated 'policy' in its |
| 43 output. |
| 44 ''' |
| 45 return False |
| 46 |
| 47 def IsFuturePolicySupported(self, policy): |
| 48 '''Checks if the given future policy is supported by the writer. |
| 49 |
| 50 Args: |
| 51 policy: The dictionary of the policy. |
| 52 |
| 53 Returns: |
| 54 True if the writer chooses to include the deprecated 'policy' in its |
| 55 output. |
| 56 ''' |
| 57 return False |
| 58 |
| 59 def IsPolicySupported(self, policy): |
| 60 '''Checks if the given policy is supported by the writer. |
| 61 In other words, the set of platforms supported by the writer |
| 62 has a common subset with the set of platforms that support |
| 63 the policy. |
| 64 |
| 65 Args: |
| 66 policy: The dictionary of the policy. |
| 67 |
| 68 Returns: |
| 69 True if the writer chooses to include 'policy' in its output. |
| 70 ''' |
| 71 if ('deprecated' in policy and policy['deprecated'] is True and |
| 72 not self.IsDeprecatedPolicySupported(policy)): |
| 73 return False |
| 74 |
| 75 if ('future' in policy and policy['future'] is True and |
| 76 not self.IsFuturePolicySupported(policy)): |
| 77 return False |
| 78 |
| 79 if '*' in self.platforms: |
| 80 # Currently chrome_os is only catched here. |
| 81 return True |
| 82 for supported_on in policy['supported_on']: |
| 83 for supported_on_platform in supported_on['platforms']: |
| 84 if supported_on_platform in self.platforms: |
| 85 return True |
| 86 return False |
| 87 |
| 88 def _GetPoliciesForWriter(self, group): |
| 89 '''Filters the list of policies in the passed group that are supported by |
| 90 the writer. |
| 91 |
| 92 Args: |
| 93 group: The dictionary of the policy group. |
| 94 |
| 95 Returns: The list of policies of the policy group that are compatible |
| 96 with the writer. |
| 97 ''' |
| 98 if not 'policies' in group: |
| 99 return [] |
| 100 result = [] |
| 101 for policy in group['policies']: |
| 102 if self.IsPolicySupported(policy): |
| 103 result.append(policy) |
| 104 return result |
| 105 |
| 106 def Init(self): |
| 107 '''Initializes the writer. If the WriteTemplate method is overridden, then |
| 108 this method must be called as first step of each template generation |
| 109 process. |
| 110 ''' |
| 111 pass |
| 112 |
| 113 def WriteTemplate(self, template): |
| 114 '''Writes the given template definition. |
| 115 |
| 116 Args: |
| 117 template: Template definition to write. |
| 118 |
| 119 Returns: |
| 120 Generated output for the passed template definition. |
| 121 ''' |
| 122 self.messages = template['messages'] |
| 123 self.Init() |
| 124 template['policy_definitions'] = \ |
| 125 self.PreprocessPolicies(template['policy_definitions']) |
| 126 self.BeginTemplate() |
| 127 for policy in template['policy_definitions']: |
| 128 if policy['type'] == 'group': |
| 129 child_policies = self._GetPoliciesForWriter(policy) |
| 130 if child_policies: |
| 131 # Only write nonempty groups. |
| 132 self.BeginPolicyGroup(policy) |
| 133 for child_policy in child_policies: |
| 134 # Nesting of groups is currently not supported. |
| 135 self.WritePolicy(child_policy) |
| 136 self.EndPolicyGroup() |
| 137 elif self.IsPolicySupported(policy): |
| 138 self.WritePolicy(policy) |
| 139 self.EndTemplate() |
| 140 return self.GetTemplateText() |
| 141 |
| 142 def PreprocessPolicies(self, policy_list): |
| 143 '''Preprocesses a list of policies according to a given writer's needs. |
| 144 Preprocessing steps include sorting policies and stripping unneeded |
| 145 information such as groups (for writers that ignore them). |
| 146 Subclasses are encouraged to override this method, overriding |
| 147 implementations may call one of the provided specialized implementations. |
| 148 The default behaviour is to use SortPoliciesGroupsFirst(). |
| 149 |
| 150 Args: |
| 151 policy_list: A list containing the policies to sort. |
| 152 |
| 153 Returns: |
| 154 The sorted policy list. |
| 155 ''' |
| 156 return self.SortPoliciesGroupsFirst(policy_list) |
| 157 |
| 158 def WritePolicy(self, policy): |
| 159 '''Appends the template text corresponding to a policy into the |
| 160 internal buffer. |
| 161 |
| 162 Args: |
| 163 policy: The policy as it is found in the JSON file. |
| 164 ''' |
| 165 raise NotImplementedError() |
| 166 |
| 167 def BeginPolicyGroup(self, group): |
| 168 '''Appends the template text corresponding to the beginning of a |
| 169 policy group into the internal buffer. |
| 170 |
| 171 Args: |
| 172 group: The policy group as it is found in the JSON file. |
| 173 ''' |
| 174 pass |
| 175 |
| 176 def EndPolicyGroup(self): |
| 177 '''Appends the template text corresponding to the end of a |
| 178 policy group into the internal buffer. |
| 179 ''' |
| 180 pass |
| 181 |
| 182 def BeginTemplate(self): |
| 183 '''Appends the text corresponding to the beginning of the whole |
| 184 template into the internal buffer. |
| 185 ''' |
| 186 raise NotImplementedError() |
| 187 |
| 188 def EndTemplate(self): |
| 189 '''Appends the text corresponding to the end of the whole |
| 190 template into the internal buffer. |
| 191 ''' |
| 192 pass |
| 193 |
| 194 def GetTemplateText(self): |
| 195 '''Gets the content of the internal template buffer. |
| 196 |
| 197 Returns: |
| 198 The generated template from the the internal buffer as a string. |
| 199 ''' |
| 200 raise NotImplementedError() |
| 201 |
| 202 def SortPoliciesGroupsFirst(self, policy_list): |
| 203 '''Sorts a list of policies alphabetically. The order is the |
| 204 following: first groups alphabetically by caption, then other policies |
| 205 alphabetically by name. The order of policies inside groups is unchanged. |
| 206 |
| 207 Args: |
| 208 policy_list: The list of policies to sort. Sub-lists in groups will not |
| 209 be sorted. |
| 210 ''' |
| 211 policy_list.sort(key=self.GetPolicySortingKeyGroupsFirst) |
| 212 return policy_list |
| 213 |
| 214 def FlattenGroupsAndSortPolicies(self, policy_list, sorting_key=None): |
| 215 '''Sorts a list of policies according to |sorting_key|, defaulting |
| 216 to alphabetical sorting if no key is given. If |policy_list| contains |
| 217 policies with type="group", it is flattened first, i.e. any groups' contents |
| 218 are inserted into the list as first-class elements and the groups are then |
| 219 removed. |
| 220 ''' |
| 221 new_list = [] |
| 222 for policy in policy_list: |
| 223 if policy['type'] == 'group': |
| 224 for grouped_policy in policy['policies']: |
| 225 new_list.append(grouped_policy) |
| 226 else: |
| 227 new_list.append(policy) |
| 228 if sorting_key == None: |
| 229 sorting_key = self.GetPolicySortingKeyName |
| 230 new_list.sort(key=sorting_key) |
| 231 return new_list |
| 232 |
| 233 def GetPolicySortingKeyName(self, policy): |
| 234 return policy['name'] |
| 235 |
| 236 def GetPolicySortingKeyGroupsFirst(self, policy): |
| 237 '''Extracts a sorting key from a policy. These keys can be used for |
| 238 list.sort() methods to sort policies. |
| 239 See TemplateWriter.SortPolicies for usage. |
| 240 ''' |
| 241 is_group = policy['type'] == 'group' |
| 242 if is_group: |
| 243 # Groups are sorted by caption. |
| 244 str_key = policy['caption'] |
| 245 else: |
| 246 # Regular policies are sorted by name. |
| 247 str_key = policy['name'] |
| 248 # Groups come before regular policies. |
| 249 return (not is_group, str_key) |
OLD | NEW |