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.
7 class TemplateWriter(object):
8 '''Abstract base class for writing policy templates in various formats.
9 The methods of this class will be called by PolicyTemplateGenerator.
12 def __init__(self, platforms, config):
13 '''Initializes a TemplateWriter object.
16 platforms: List of platforms for which this writer can write policies.
17 config: A dictionary of information required to generate the template.
18 It contains some key-value pairs, including the following examples:
19 'build': 'chrome' or 'chromium'
20 'branding': 'Google Chrome' or 'Chromium'
21 'mac_bundle_id': The Mac bundle id of Chrome. (Only set when building
23 messages: List of all the message strings from the grd file. Most of them
24 are also present in the policy data structures that are passed to
25 methods. That is the preferred way of accessing them, this should only
26 be used in exceptional cases. An example for its use is the
27 IDS_POLICY_WIN_SUPPORTED_WINXPSP2 message in ADM files, because that
28 cannot be associated with any policy or group.
30 self.platforms = platforms
33 def IsDeprecatedPolicySupported(self, policy):
34 '''Checks if the given deprecated policy is supported by the writer.
37 policy: The dictionary of the policy.
40 True if the writer chooses to include the deprecated 'policy' in its
45 def IsFuturePolicySupported(self, policy):
46 '''Checks if the given future policy is supported by the writer.
49 policy: The dictionary of the policy.
52 True if the writer chooses to include the deprecated 'policy' in its
57 def IsPolicySupported(self, policy):
58 '''Checks if the given policy is supported by the writer.
59 In other words, the set of platforms supported by the writer
60 has a common subset with the set of platforms that support
64 policy: The dictionary of the policy.
67 True if the writer chooses to include 'policy' in its output.
69 if ('deprecated' in policy and policy['deprecated'] is True and
70 not self.IsDeprecatedPolicySupported(policy)):
73 if ('future' in policy and policy['future'] is True and
74 not self.IsFuturePolicySupported(policy)):
77 if '*' in self.platforms:
78 # Currently chrome_os is only catched here.
80 for supported_on in policy['supported_on']:
81 for supported_on_platform in supported_on['platforms']:
82 if supported_on_platform in self.platforms:
86 def CanBeRecommended(self, policy):
87 '''Checks if the given policy can be recommended.'''
88 return policy.get('features', {}).get('can_be_recommended', False)
90 def _GetPoliciesForWriter(self, group):
91 '''Filters the list of policies in the passed group that are supported by
95 group: The dictionary of the policy group.
97 Returns: The list of policies of the policy group that are compatible
100 if not 'policies' in group:
103 for policy in group['policies']:
104 if self.IsPolicySupported(policy):
105 result.append(policy)
109 '''Initializes the writer. If the WriteTemplate method is overridden, then
110 this method must be called as first step of each template generation
115 def WriteTemplate(self, template):
116 '''Writes the given template definition.
119 template: Template definition to write.
122 Generated output for the passed template definition.
124 self.messages = template['messages']
126 template['policy_definitions'] = \
127 self.PreprocessPolicies(template['policy_definitions'])
129 for policy in template['policy_definitions']:
130 if policy['type'] == 'group':
131 child_policies = self._GetPoliciesForWriter(policy)
132 child_recommended_policies = filter(self.CanBeRecommended,
135 # Only write nonempty groups.
136 self.BeginPolicyGroup(policy)
137 for child_policy in child_policies:
138 # Nesting of groups is currently not supported.
139 self.WritePolicy(child_policy)
140 self.EndPolicyGroup()
141 if child_recommended_policies:
142 self.BeginRecommendedPolicyGroup(policy)
143 for child_policy in child_recommended_policies:
144 self.WriteRecommendedPolicy(child_policy)
145 self.EndRecommendedPolicyGroup()
146 elif self.IsPolicySupported(policy):
147 self.WritePolicy(policy)
148 if self.CanBeRecommended(policy):
149 self.WriteRecommendedPolicy(policy)
152 return self.GetTemplateText()
154 def PreprocessPolicies(self, policy_list):
155 '''Preprocesses a list of policies according to a given writer's needs.
156 Preprocessing steps include sorting policies and stripping unneeded
157 information such as groups (for writers that ignore them).
158 Subclasses are encouraged to override this method, overriding
159 implementations may call one of the provided specialized implementations.
160 The default behaviour is to use SortPoliciesGroupsFirst().
163 policy_list: A list containing the policies to sort.
166 The sorted policy list.
168 return self.SortPoliciesGroupsFirst(policy_list)
170 def WritePolicy(self, policy):
171 '''Appends the template text corresponding to a policy into the
175 policy: The policy as it is found in the JSON file.
177 raise NotImplementedError()
179 def WriteRecommendedPolicy(self, policy):
180 '''Appends the template text corresponding to a recommended policy into the
184 policy: The recommended policy as it is found in the JSON file.
187 #raise NotImplementedError()
190 def BeginPolicyGroup(self, group):
191 '''Appends the template text corresponding to the beginning of a
192 policy group into the internal buffer.
195 group: The policy group as it is found in the JSON file.
199 def EndPolicyGroup(self):
200 '''Appends the template text corresponding to the end of a
201 policy group into the internal buffer.
205 def BeginRecommendedPolicyGroup(self, group):
206 '''Appends the template text corresponding to the beginning of a recommended
207 policy group into the internal buffer.
210 group: The recommended policy group as it is found in the JSON file.
214 def EndRecommendedPolicyGroup(self):
215 '''Appends the template text corresponding to the end of a recommended
216 policy group into the internal buffer.
220 def BeginTemplate(self):
221 '''Appends the text corresponding to the beginning of the whole
222 template into the internal buffer.
224 raise NotImplementedError()
226 def EndTemplate(self):
227 '''Appends the text corresponding to the end of the whole
228 template into the internal buffer.
232 def GetTemplateText(self):
233 '''Gets the content of the internal template buffer.
236 The generated template from the the internal buffer as a string.
238 raise NotImplementedError()
240 def SortPoliciesGroupsFirst(self, policy_list):
241 '''Sorts a list of policies alphabetically. The order is the
242 following: first groups alphabetically by caption, then other policies
243 alphabetically by name. The order of policies inside groups is unchanged.
246 policy_list: The list of policies to sort. Sub-lists in groups will not
249 policy_list.sort(key=self.GetPolicySortingKeyGroupsFirst)
252 def FlattenGroupsAndSortPolicies(self, policy_list, sorting_key=None):
253 '''Sorts a list of policies according to |sorting_key|, defaulting
254 to alphabetical sorting if no key is given. If |policy_list| contains
255 policies with type="group", it is flattened first, i.e. any groups' contents
256 are inserted into the list as first-class elements and the groups are then
260 for policy in policy_list:
261 if policy['type'] == 'group':
262 for grouped_policy in policy['policies']:
263 new_list.append(grouped_policy)
265 new_list.append(policy)
266 if sorting_key == None:
267 sorting_key = self.GetPolicySortingKeyName
268 new_list.sort(key=sorting_key)
271 def GetPolicySortingKeyName(self, policy):
272 return policy['name']
274 def GetPolicySortingKeyGroupsFirst(self, policy):
275 '''Extracts a sorting key from a policy. These keys can be used for
276 list.sort() methods to sort policies.
277 See TemplateWriter.SortPolicies for usage.
279 is_group = policy['type'] == 'group'
281 # Groups are sorted by caption.
282 str_key = policy['caption']
284 # Regular policies are sorted by name.
285 str_key = policy['name']
286 # Groups come before regular policies.
287 return (not is_group, str_key)