- add third_party src.
[platform/framework/web/crosswalk.git] / src / tools / grit / grit / format / policy_templates / writers / template_writer.py
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
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.
10   '''
11
12   def __init__(self, platforms, config):
13     '''Initializes a TemplateWriter object.
14
15     Args:
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
22             for Mac.)
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.
29     '''
30     self.platforms = platforms
31     self.config = config
32
33   def IsDeprecatedPolicySupported(self, policy):
34     '''Checks if the given deprecated policy is supported by the writer.
35
36     Args:
37       policy: The dictionary of the policy.
38
39     Returns:
40       True if the writer chooses to include the deprecated 'policy' in its
41       output.
42     '''
43     return False
44
45   def IsFuturePolicySupported(self, policy):
46     '''Checks if the given future policy is supported by the writer.
47
48     Args:
49       policy: The dictionary of the policy.
50
51     Returns:
52       True if the writer chooses to include the deprecated 'policy' in its
53       output.
54     '''
55     return False
56
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
61     the policy.
62
63     Args:
64       policy: The dictionary of the policy.
65
66     Returns:
67       True if the writer chooses to include 'policy' in its output.
68     '''
69     if ('deprecated' in policy and policy['deprecated'] is True and
70         not self.IsDeprecatedPolicySupported(policy)):
71       return False
72
73     if ('future' in policy and policy['future'] is True and
74         not self.IsFuturePolicySupported(policy)):
75       return False
76
77     if '*' in self.platforms:
78       # Currently chrome_os is only catched here.
79       return True
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:
83           return True
84     return False
85
86   def CanBeRecommended(self, policy):
87     '''Checks if the given policy can be recommended.'''
88     return policy.get('features', {}).get('can_be_recommended', False)
89
90   def _GetPoliciesForWriter(self, group):
91     '''Filters the list of policies in the passed group that are supported by
92     the writer.
93
94     Args:
95       group: The dictionary of the policy group.
96
97     Returns: The list of policies of the policy group that are compatible
98       with the writer.
99     '''
100     if not 'policies' in group:
101       return []
102     result = []
103     for policy in group['policies']:
104       if self.IsPolicySupported(policy):
105         result.append(policy)
106     return result
107
108   def Init(self):
109     '''Initializes the writer. If the WriteTemplate method is overridden, then
110     this method must be called as first step of each template generation
111     process.
112     '''
113     pass
114
115   def WriteTemplate(self, template):
116     '''Writes the given template definition.
117
118     Args:
119       template: Template definition to write.
120
121     Returns:
122       Generated output for the passed template definition.
123     '''
124     self.messages = template['messages']
125     self.Init()
126     template['policy_definitions'] = \
127         self.PreprocessPolicies(template['policy_definitions'])
128     self.BeginTemplate()
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,
133                                             child_policies)
134         if child_policies:
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)
150     self.EndTemplate()
151
152     return self.GetTemplateText()
153
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().
161
162     Args:
163       policy_list: A list containing the policies to sort.
164
165     Returns:
166       The sorted policy list.
167     '''
168     return self.SortPoliciesGroupsFirst(policy_list)
169
170   def WritePolicy(self, policy):
171     '''Appends the template text corresponding to a policy into the
172     internal buffer.
173
174     Args:
175       policy: The policy as it is found in the JSON file.
176     '''
177     raise NotImplementedError()
178
179   def WriteRecommendedPolicy(self, policy):
180     '''Appends the template text corresponding to a recommended policy into the
181     internal buffer.
182
183     Args:
184       policy: The recommended policy as it is found in the JSON file.
185     '''
186     # TODO
187     #raise NotImplementedError()
188     pass
189
190   def BeginPolicyGroup(self, group):
191     '''Appends the template text corresponding to the beginning of a
192     policy group into the internal buffer.
193
194     Args:
195       group: The policy group as it is found in the JSON file.
196     '''
197     pass
198
199   def EndPolicyGroup(self):
200     '''Appends the template text corresponding to the end of a
201     policy group into the internal buffer.
202     '''
203     pass
204
205   def BeginRecommendedPolicyGroup(self, group):
206     '''Appends the template text corresponding to the beginning of a recommended
207     policy group into the internal buffer.
208
209     Args:
210       group: The recommended policy group as it is found in the JSON file.
211     '''
212     pass
213
214   def EndRecommendedPolicyGroup(self):
215     '''Appends the template text corresponding to the end of a recommended
216     policy group into the internal buffer.
217     '''
218     pass
219
220   def BeginTemplate(self):
221     '''Appends the text corresponding to the beginning of the whole
222     template into the internal buffer.
223     '''
224     raise NotImplementedError()
225
226   def EndTemplate(self):
227     '''Appends the text corresponding to the end of the whole
228     template into the internal buffer.
229     '''
230     pass
231
232   def GetTemplateText(self):
233     '''Gets the content of the internal template buffer.
234
235     Returns:
236       The generated template from the the internal buffer as a string.
237     '''
238     raise NotImplementedError()
239
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.
244
245     Args:
246       policy_list: The list of policies to sort. Sub-lists in groups will not
247         be sorted.
248     '''
249     policy_list.sort(key=self.GetPolicySortingKeyGroupsFirst)
250     return policy_list
251
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
257     removed.
258     '''
259     new_list = []
260     for policy in policy_list:
261       if policy['type'] == 'group':
262         for grouped_policy in policy['policies']:
263           new_list.append(grouped_policy)
264       else:
265         new_list.append(policy)
266     if sorting_key == None:
267       sorting_key = self.GetPolicySortingKeyName
268     new_list.sort(key=sorting_key)
269     return new_list
270
271   def GetPolicySortingKeyName(self, policy):
272     return policy['name']
273
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.
278     '''
279     is_group = policy['type'] == 'group'
280     if is_group:
281       # Groups are sorted by caption.
282       str_key = policy['caption']
283     else:
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)