| Index: grit/format/policy_templates/writers/admx_writer.py
 | 
| ===================================================================
 | 
| --- grit/format/policy_templates/writers/admx_writer.py	(revision 0)
 | 
| +++ grit/format/policy_templates/writers/admx_writer.py	(revision 0)
 | 
| @@ -0,0 +1,327 @@
 | 
| +# Copyright (c) 2011 The Chromium Authors. All rights reserved.
 | 
| +# Use of this source code is governed by a BSD-style license that can be
 | 
| +# found in the LICENSE file.
 | 
| +
 | 
| +from xml.dom import minidom
 | 
| +from grit.format.policy_templates.writers import xml_formatted_writer
 | 
| +
 | 
| +
 | 
| +def GetWriter(config):
 | 
| +  '''Factory method for instanciating the ADMXWriter. Every Writer needs a
 | 
| +  GetWriter method because the TemplateFormatter uses this method to
 | 
| +  instantiate a Writer.
 | 
| +  '''
 | 
| +  return ADMXWriter(['win'], config)
 | 
| +
 | 
| +
 | 
| +class ADMXWriter(xml_formatted_writer.XMLFormattedWriter):
 | 
| +  '''Class for generating an ADMX policy template. It is used by the
 | 
| +  PolicyTemplateGenerator to write the admx file.
 | 
| +  '''
 | 
| +
 | 
| +  # DOM root node of the generated ADMX document.
 | 
| +  _doc = None
 | 
| +
 | 
| +  # The ADMX "policies" element that contains the ADMX "policy" elements that
 | 
| +  # are generated.
 | 
| +  _active_policies_elem = None
 | 
| +
 | 
| +  def _AdmlString(self, name):
 | 
| +    '''Creates a reference to the named string in an ADML file.
 | 
| +    Args:
 | 
| +      name: Name of the referenced ADML string.
 | 
| +    '''
 | 
| +    return '$(string.' + name + ')'
 | 
| +
 | 
| +  def _AdmlStringExplain(self, name):
 | 
| +    '''Creates a reference to the named explanation string in an ADML file.
 | 
| +    Args:
 | 
| +      name: Name of the referenced ADML explanation.
 | 
| +    '''
 | 
| +    return '$(string.' + name + '_Explain)'
 | 
| +
 | 
| +  def _AdmlPresentation(self, name):
 | 
| +    '''Creates a reference to the named presentation element in an ADML file.
 | 
| +    Args:
 | 
| +      name: Name of the referenced ADML presentation element.
 | 
| +    '''
 | 
| +    return '$(presentation.' + name + ')'
 | 
| +
 | 
| +  def _AddPolicyNamespaces(self, parent, prefix, namespace):
 | 
| +    '''Generates the ADMX "policyNamespace" element and adds the elements to the
 | 
| +    passed parent element. The namespace of the generated ADMX document is
 | 
| +    define via the ADMX "target" element. Used namespaces are declared with an
 | 
| +    ADMX "using" element. ADMX "target" and "using" elements are children of the
 | 
| +    ADMX "policyNamespace" element.
 | 
| +
 | 
| +    Args:
 | 
| +      parent: The parent node to which all generated elements are added.
 | 
| +      prefix: A logical name that can be used in the generated ADMX document to
 | 
| +        refere to this namespace.
 | 
| +      namespace: Namespace of the generated ADMX document.
 | 
| +    '''
 | 
| +    policy_namespaces_elem = self.AddElement(parent, 'policyNamespaces')
 | 
| +    attributes = {
 | 
| +      'prefix': prefix,
 | 
| +      'namespace': namespace,
 | 
| +    }
 | 
| +    self.AddElement(policy_namespaces_elem, 'target', attributes)
 | 
| +    attributes = {
 | 
| +      'prefix': 'windows',
 | 
| +      'namespace': 'Microsoft.Policies.Windows',
 | 
| +    }
 | 
| +    self.AddElement(policy_namespaces_elem, 'using', attributes)
 | 
| +
 | 
| +  def _AddCategory(self, parent, name, display_name,
 | 
| +                   parent_category_name=None):
 | 
| +    '''Adds an ADMX category element to the passed parent node. The following
 | 
| +    snippet shows an example of a category element where "chromium" is the value
 | 
| +    of the parameter name:
 | 
| +
 | 
| +    <category displayName="$(string.chromium)" name="chromium"/>
 | 
| +
 | 
| +    Args:
 | 
| +      parent: The parent node to which all generated elements are added.
 | 
| +      name: Name of the category.
 | 
| +      display_name: Display name of the category.
 | 
| +      parent_category_name: Name of the parent category. Defaults to None.
 | 
| +    '''
 | 
| +    attributes = {
 | 
| +      'name': name,
 | 
| +      'displayName': display_name,
 | 
| +    }
 | 
| +    category_elem = self.AddElement(parent, 'category', attributes)
 | 
| +    if parent_category_name:
 | 
| +      attributes = {'ref': parent_category_name}
 | 
| +      self.AddElement(category_elem, 'parentCategory', attributes)
 | 
| +
 | 
| +  def _AddCategories(self, parent, categories):
 | 
| +    '''Generates the ADMX "categories" element and adds it to the passed parent
 | 
| +    node. The "categories" element defines the category for the policies defined
 | 
| +    in this ADMX document. Here is an example of an ADMX "categories" element:
 | 
| +
 | 
| +    <categories>
 | 
| +      <category displayName="$(string.google)" name="google"/>
 | 
| +      <category displayName="$(string.googlechrome)" name="googlechrome">
 | 
| +        <parentCategory ref="google"/>
 | 
| +      </category>
 | 
| +    </categories>
 | 
| +
 | 
| +    Args:
 | 
| +      parent: The parent node to which all generated elements are added.
 | 
| +      categories_path: The categories path e.g. ['google', 'googlechrome']. For
 | 
| +        each level in the path a "category" element will be generated. Except
 | 
| +        for the root level, each level refers to its parent. Since the root
 | 
| +        level category has no parent it does not require a parent reference.
 | 
| +    '''
 | 
| +    self._categories_elem = self.AddElement(parent, 'categories')
 | 
| +    category_name = None
 | 
| +    for category in categories:
 | 
| +      parent_category_name = category_name
 | 
| +      category_name = category
 | 
| +      self._AddCategory(self._categories_elem, category_name,
 | 
| +                        self._AdmlString(category_name), parent_category_name)
 | 
| +
 | 
| +  def _AddSupportedOn(self, parent, supported_os):
 | 
| +    '''Generates the "supportedOn" ADMX element and adds it to the passed
 | 
| +    parent node. The "supportedOn" element contains information about supported
 | 
| +    Windows OS versions. The following code snippet contains an example of a
 | 
| +    "supportedOn" element:
 | 
| +
 | 
| +    <supportedOn>
 | 
| +      <definitions>
 | 
| +        <definition name="SUPPORTED_WINXPSP2"
 | 
| +                    displayName="$(string.SUPPORTED_WINXPSP2)"/>
 | 
| +        </definitions>
 | 
| +        ...
 | 
| +    </supportedOn>
 | 
| +
 | 
| +    Args:
 | 
| +      parent: The parent element to which all generated elements are added.
 | 
| +      supported_os: List with all supported Win OSes.
 | 
| +    '''
 | 
| +    supported_on_elem = self.AddElement(parent, 'supportedOn')
 | 
| +    definitions_elem = self.AddElement(supported_on_elem, 'definitions')
 | 
| +    attributes = {
 | 
| +      'name': supported_os,
 | 
| +      'displayName': self._AdmlString(supported_os)
 | 
| +    }
 | 
| +    self.AddElement(definitions_elem, 'definition', attributes)
 | 
| +
 | 
| +  def _AddStringPolicy(self, parent, name):
 | 
| +    '''Generates ADMX elements for a String-Policy and adds them to the
 | 
| +    passed parent node.
 | 
| +    '''
 | 
| +    attributes = {
 | 
| +      'id': name,
 | 
| +      'valueName': name,
 | 
| +    }
 | 
| +    self.AddElement(parent, 'text', attributes)
 | 
| +
 | 
| +  def _AddIntPolicy(self, parent, name):
 | 
| +    '''Generates ADMX elements for an Int-Policy and adds them to the passed
 | 
| +    parent node.
 | 
| +    '''
 | 
| +    attributes = {
 | 
| +      'id': name,
 | 
| +      'valueName': name,
 | 
| +    }
 | 
| +    self.AddElement(parent, 'decimal', attributes)
 | 
| +
 | 
| +  def _AddEnumPolicy(self, parent, policy):
 | 
| +    '''Generates ADMX elements for an Enum-Policy and adds them to the
 | 
| +    passed parent element.
 | 
| +    '''
 | 
| +    name = policy['name']
 | 
| +    items = policy['items']
 | 
| +    attributes = {
 | 
| +      'id': name,
 | 
| +      'valueName': name,
 | 
| +    }
 | 
| +    enum_elem = self.AddElement(parent, 'enum', attributes)
 | 
| +    for item in items:
 | 
| +      attributes = {'displayName': self._AdmlString(item['name'])}
 | 
| +      item_elem = self.AddElement(enum_elem, 'item', attributes)
 | 
| +      value_elem = self.AddElement(item_elem, 'value')
 | 
| +      value_string = str(item['value'])
 | 
| +      if policy['type'] == 'int-enum':
 | 
| +        self.AddElement(value_elem, 'decimal', {'value': value_string})
 | 
| +      else:
 | 
| +        self.AddElement(value_elem, 'string', {}, value_string)
 | 
| +
 | 
| +  def _AddListPolicy(self, parent, name):
 | 
| +    '''Generates ADMX XML elements for a List-Policy and adds them to the
 | 
| +    passed parent element.
 | 
| +    '''
 | 
| +    attributes = {
 | 
| +      # The ID must be in sync with ID of the corresponding element in the ADML
 | 
| +      # file.
 | 
| +      'id': name + 'Desc',
 | 
| +      'valuePrefix': '',
 | 
| +      'key': self.config['win_reg_key_name'] + '\\' + name,
 | 
| +    }
 | 
| +    self.AddElement(parent, 'list', attributes)
 | 
| +
 | 
| +  def _AddMainPolicy(self, parent):
 | 
| +    '''Generates ADMX elements for a Main-Policy amd adds them to the
 | 
| +    passed parent element.
 | 
| +    '''
 | 
| +    enabled_value_elem = self.AddElement(parent, 'enabledValue');
 | 
| +    self.AddElement(enabled_value_elem, 'decimal', {'value': '1'})
 | 
| +    disabled_value_elem = self.AddElement(parent, 'disabledValue');
 | 
| +    self.AddElement(disabled_value_elem, 'decimal', {'value': '0'})
 | 
| +
 | 
| +  def _GetElements(self, policy_group_elem):
 | 
| +    '''Returns the ADMX "elements" child from an ADMX "policy" element. If the
 | 
| +    "policy" element has no "elements" child yet, a new child is created.
 | 
| +
 | 
| +    Args:
 | 
| +      policy_group_elem: The ADMX "policy" element from which the child element
 | 
| +        "elements" is returned.
 | 
| +
 | 
| +    Raises:
 | 
| +      Exception: The policy_group_elem does not contain a ADMX "policy" element.
 | 
| +    '''
 | 
| +    if policy_group_elem.tagName != 'policy':
 | 
| +      raise Exception('Expected a "policy" element but got a "%s" element'
 | 
| +                      % policy_group_elem.tagName)
 | 
| +    elements_list = policy_group_elem.getElementsByTagName('elements');
 | 
| +    if len(elements_list) == 0:
 | 
| +      return self.AddElement(policy_group_elem, 'elements')
 | 
| +    elif len(elements_list) == 1:
 | 
| +      return elements_list[0]
 | 
| +    else:
 | 
| +      raise Exception('There is supposed to be only one "elements" node but'
 | 
| +                      ' there are %s.' % str(len(elements_list)))
 | 
| +
 | 
| +  def WritePolicy(self, policy):
 | 
| +    '''Generates AMDX elements for a Policy. There are four different policy
 | 
| +    types: Main-Policy, String-Policy, Enum-Policy and List-Policy.
 | 
| +    '''
 | 
| +    policies_elem = self._active_policies_elem
 | 
| +    policy_type = policy['type']
 | 
| +    policy_name = policy['name']
 | 
| +
 | 
| +    attributes = {
 | 
| +      'name': policy_name,
 | 
| +      'class': self.config['win_group_policy_class'],
 | 
| +      'displayName': self._AdmlString(policy_name),
 | 
| +      'explainText': self._AdmlStringExplain(policy_name),
 | 
| +      'presentation': self._AdmlPresentation(policy_name),
 | 
| +      'key': self.config['win_reg_key_name'],
 | 
| +    }
 | 
| +    # Store the current "policy" AMDX element in self for later use by the
 | 
| +    # WritePolicy method.
 | 
| +    policy_elem = self.AddElement(policies_elem, 'policy',
 | 
| +                                  attributes)
 | 
| +    self.AddElement(policy_elem, 'parentCategory',
 | 
| +                    {'ref': self._active_policy_group_name})
 | 
| +    self.AddElement(policy_elem, 'supportedOn',
 | 
| +                    {'ref': self.config['win_supported_os']})
 | 
| +    if policy_type == 'main':
 | 
| +      self.AddAttribute(policy_elem, 'valueName', policy_name)
 | 
| +      self._AddMainPolicy(policy_elem)
 | 
| +    elif policy_type == 'string':
 | 
| +      parent = self._GetElements(policy_elem)
 | 
| +      self._AddStringPolicy(parent, policy_name)
 | 
| +    elif policy_type == 'int':
 | 
| +      parent = self._GetElements(policy_elem)
 | 
| +      self._AddIntPolicy(parent, policy_name)
 | 
| +    elif policy_type in ('int-enum', 'string-enum'):
 | 
| +      parent = self._GetElements(policy_elem)
 | 
| +      self._AddEnumPolicy(parent, policy)
 | 
| +    elif policy_type == 'list':
 | 
| +      parent = self._GetElements(policy_elem)
 | 
| +      self._AddListPolicy(parent, policy_name)
 | 
| +    elif policy_type == 'group':
 | 
| +      pass
 | 
| +    else:
 | 
| +      raise Exception('Unknown policy type %s.' % policy_type)
 | 
| +
 | 
| +  def BeginPolicyGroup(self, group):
 | 
| +    '''Generates ADMX elements for a Policy-Group.
 | 
| +    '''
 | 
| +    policy_group_name = group['name']
 | 
| +    attributes = {
 | 
| +      'name': policy_group_name,
 | 
| +      'displayName': self._AdmlString(policy_group_name + '_group'),
 | 
| +    }
 | 
| +    category_elem = self.AddElement(self._categories_elem,
 | 
| +                                    'category',
 | 
| +                                    attributes)
 | 
| +    attributes = {
 | 
| +      'ref': self.config['win_category_path'][-1],
 | 
| +    }
 | 
| +    self.AddElement(category_elem, 'parentCategory', attributes)
 | 
| +    self._active_policy_group_name = policy_group_name
 | 
| +
 | 
| +  def EndPolicyGroup(self):
 | 
| +    self._active_policy_group_name = self.config['win_category_path'][-1]
 | 
| +
 | 
| +  def BeginTemplate(self):
 | 
| +    '''Generates the skeleton of the ADMX template. An ADMX template contains
 | 
| +    an ADMX "PolicyDefinitions" element with four child nodes: "policies"
 | 
| +    "policyNamspaces", "resources", "supportedOn" and "categories"
 | 
| +    '''
 | 
| +    dom_impl = minidom.getDOMImplementation('')
 | 
| +    self._doc = dom_impl.createDocument(None, 'policyDefinitions', None)
 | 
| +    policy_definitions_elem = self._doc.documentElement
 | 
| +
 | 
| +    policy_definitions_elem.attributes['revision'] = '1.0'
 | 
| +    policy_definitions_elem.attributes['schemaVersion'] = '1.0'
 | 
| +
 | 
| +    self._AddPolicyNamespaces(policy_definitions_elem,
 | 
| +                              self.config['admx_prefix'],
 | 
| +                              self.config['admx_namespace'])
 | 
| +    self.AddElement(policy_definitions_elem, 'resources',
 | 
| +                    {'minRequiredRevision' : '1.0'})
 | 
| +    self._AddSupportedOn(policy_definitions_elem,
 | 
| +                         self.config['win_supported_os'])
 | 
| +    self._AddCategories(policy_definitions_elem,
 | 
| +                        self.config['win_category_path'])
 | 
| +    self._active_policies_elem = self.AddElement(policy_definitions_elem,
 | 
| +                                                 'policies')
 | 
| +    self._active_policy_group_name = self.config['win_category_path'][-1]
 | 
| +
 | 
| +  def GetTemplateText(self):
 | 
| +    return self.ToPrettyXml(self._doc)
 | 
| 
 | 
| Property changes on: grit/format/policy_templates/writers/admx_writer.py
 | 
| ___________________________________________________________________
 | 
| Added: svn:eol-style
 | 
|    + LF
 | 
| 
 | 
| 
 |