• Home
  • History
  • Annotate
  • 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
6from xml.dom import minidom
7from grit.format.policy_templates.writers import xml_formatted_writer
8
9
10def GetWriter(config):
11  '''Factory method for instanciating the ADMLWriter. Every Writer needs a
12  GetWriter method because the TemplateFormatter uses this method to
13  instantiate a Writer.
14  '''
15  return ADMLWriter(['win'], config)
16
17
18class ADMLWriter(xml_formatted_writer.XMLFormattedWriter):
19  ''' Class for generating an ADML policy template. It is used by the
20  PolicyTemplateGenerator to write the ADML file.
21  '''
22
23  # DOM root node of the generated ADML document.
24  _doc = None
25
26  # The string-table contains all ADML "string" elements.
27  _string_table_elem = None
28
29  # The presentation-table is the container for presentation elements, that
30  # describe the presentation of Policy-Groups and Policies.
31  _presentation_table_elem = None
32
33  def _AddString(self, parent, id, text):
34    ''' Adds an ADML "string" element to the passed parent. The following
35    ADML snippet contains an example:
36
37    <string id="$(id)">$(text)</string>
38
39    Args:
40      parent: Parent element to which the new "string" element is added.
41      id: ID of the newly created "string" element.
42      text: Value of the newly created "string" element.
43    '''
44    string_elem = self.AddElement(parent, 'string', {'id': id})
45    string_elem.appendChild(self._doc.createTextNode(text))
46
47  def WritePolicy(self, policy):
48    '''Generates the ADML elements for a Policy.
49    <stringTable>
50      ...
51      <string id="$(policy_group_name)">$(caption)</string>
52      <string id="$(policy_group_name)_Explain">$(description)</string>
53    </stringTable>
54
55    <presentationTables>
56      ...
57      <presentation id=$(policy_group_name)/>
58    </presentationTables>
59
60    Args:
61      policy: The Policy to generate ADML elements for.
62    '''
63    policy_type = policy['type']
64    policy_name = policy['name']
65    if 'caption' in policy:
66      policy_caption = policy['caption']
67    else:
68      policy_caption = policy_name
69    if 'desc' in policy:
70      policy_description = policy['desc']
71    else:
72      policy_description = policy_name
73    if 'label' in policy:
74      policy_label = policy['label']
75    else:
76      policy_label = policy_name
77
78    self._AddString(self._string_table_elem, policy_name, policy_caption)
79    self._AddString(self._string_table_elem, policy_name + '_Explain',
80                    policy_description)
81    presentation_elem = self.AddElement(
82        self._presentation_table_elem, 'presentation', {'id': policy_name})
83
84    if policy_type == 'main':
85      pass
86    elif policy_type in ('string', 'dict'):
87      # 'dict' policies are configured as JSON-encoded strings on Windows.
88      textbox_elem = self.AddElement(presentation_elem, 'textBox',
89                                     {'refId': policy_name})
90      label_elem = self.AddElement(textbox_elem, 'label')
91      label_elem.appendChild(self._doc.createTextNode(policy_label))
92    elif policy_type == 'int':
93      textbox_elem = self.AddElement(presentation_elem, 'decimalTextBox',
94                                     {'refId': policy_name})
95      textbox_elem.appendChild(self._doc.createTextNode(policy_label + ':'))
96    elif policy_type in ('int-enum', 'string-enum'):
97      for item in policy['items']:
98        self._AddString(self._string_table_elem, item['name'], item['caption'])
99      dropdownlist_elem = self.AddElement(presentation_elem, 'dropdownList',
100                                          {'refId': policy_name})
101      dropdownlist_elem.appendChild(self._doc.createTextNode(policy_label))
102    elif policy_type in ('list', 'string-enum-list'):
103      self._AddString(self._string_table_elem,
104                      policy_name + 'Desc',
105                      policy_caption)
106      listbox_elem = self.AddElement(presentation_elem, 'listBox',
107                                     {'refId': policy_name + 'Desc'})
108      listbox_elem.appendChild(self._doc.createTextNode(policy_label))
109    elif policy_type == 'group':
110      pass
111    elif policy_type == 'external':
112      # This type can only be set through cloud policy.
113      pass
114    else:
115      raise Exception('Unknown policy type %s.' % policy_type)
116
117  def BeginPolicyGroup(self, group):
118    '''Generates ADML elements for a Policy-Group. For each Policy-Group two
119    ADML "string" elements are added to the string-table. One contains the
120    caption of the Policy-Group and the other a description. A Policy-Group also
121    requires an ADML "presentation" element that must be added to the
122    presentation-table. The "presentation" element is the container for the
123    elements that define the visual presentation of the Policy-Goup's Policies.
124    The following ADML snippet shows an example:
125
126    Args:
127      group: The Policy-Group to generate ADML elements for.
128    '''
129    # Add ADML "string" elements to the string-table that are required by a
130    # Policy-Group.
131    self._AddString(self._string_table_elem, group['name'] + '_group',
132                    group['caption'])
133
134  def _AddBaseStrings(self, string_table_elem, build):
135    ''' Adds ADML "string" elements to the string-table that are referenced by
136    the ADMX file but not related to any specific Policy-Group or Policy.
137    '''
138    self._AddString(string_table_elem, self.config['win_supported_os'],
139                    self.messages['win_supported_winxpsp2']['text'])
140    recommended_name = '%s - %s' % \
141        (self.config['app_name'], self.messages['doc_recommended']['text'])
142    if build == 'chrome':
143      self._AddString(string_table_elem,
144                      self.config['win_mandatory_category_path'][0],
145                      'Google')
146      self._AddString(string_table_elem,
147                      self.config['win_mandatory_category_path'][1],
148                      self.config['app_name'])
149      self._AddString(string_table_elem,
150                      self.config['win_recommended_category_path'][1],
151                      recommended_name)
152    elif build == 'chromium':
153      self._AddString(string_table_elem,
154                      self.config['win_mandatory_category_path'][0],
155                      self.config['app_name'])
156      self._AddString(string_table_elem,
157                      self.config['win_recommended_category_path'][0],
158                      recommended_name)
159
160  def BeginTemplate(self):
161    dom_impl = minidom.getDOMImplementation('')
162    self._doc = dom_impl.createDocument(None, 'policyDefinitionResources',
163                                        None)
164    policy_definitions_resources_elem = self._doc.documentElement
165    policy_definitions_resources_elem.attributes['revision'] = '1.0'
166    policy_definitions_resources_elem.attributes['schemaVersion'] = '1.0'
167
168    self.AddElement(policy_definitions_resources_elem, 'displayName')
169    self.AddElement(policy_definitions_resources_elem, 'description')
170    resources_elem = self.AddElement(policy_definitions_resources_elem,
171                                     'resources')
172    self._string_table_elem = self.AddElement(resources_elem, 'stringTable')
173    self._AddBaseStrings(self._string_table_elem, self.config['build'])
174    self._presentation_table_elem = self.AddElement(resources_elem,
175                                                   'presentationTable')
176
177  def GetTemplateText(self):
178    # Using "toprettyxml()" confuses the Windows Group Policy Editor
179    # (gpedit.msc) because it interprets whitespace characters in text between
180    # the "string" tags. This prevents gpedit.msc from displaying the category
181    # names correctly.
182    # TODO(markusheintz): Find a better formatting that works with gpedit.
183    return self._doc.toxml()
184