Orb/python/orb/mapcreators/toplevel.py
changeset 4 468f4c8d3d5b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Orb/python/orb/mapcreators/toplevel.py	Wed Aug 11 14:49:30 2010 +0100
@@ -0,0 +1,205 @@
+# Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of the License "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+from __future__ import with_statement
+try:
+    from xml.etree import cElementTree as etree
+except ImportError:
+    from xml.etree import ElementTree as etree
+from orb.lib import xml_decl
+import logging
+import os
+import copy
+
+
+logger = logging.getLogger('orb.mapcreators.toplevel')
+
+
+def component_map_lookup(rel_dir, mapname):
+    "Checks the file system to see if a component level map exists"
+    exists = os.path.exists(os.path.join(rel_dir, mapname))
+    if not exists:
+        logger.debug("Asked for a component map for '%s' but it does not exist" % mapname)
+    return exists
+
+
+class TopLevelMapCreator(object):
+    """
+    Uses the information in a SystemDefinition object to create a top level map that
+    links to all the component level maps together.
+    """
+    def __init__(self, sysdef, rel_dir, lookupmethod=component_map_lookup):
+        self.sysdef = sysdef
+        self._rel_dir = rel_dir
+        self._lookup = lookupmethod
+        self._root = etree.Element("map", title=sysdef.name, id=sysdef.name)
+
+    def _add_subelems(self, parent, item):
+        return etree.SubElement(parent, "topichead", navtitle=item.name, id=item.id)
+
+    def getmap(self):
+        def sort(item):
+            return item.name
+        layers = self.sysdef.layers
+        layers.sort(key=sort)
+        for layer in layers:
+            layer_elem = self._add_subelems(self._root, layer)
+            packages = layer.packages
+            packages.sort(key=sort)
+            for package in packages:
+                pkg_elem = self._add_subelems(layer_elem, package)
+                collections = package.collections
+                collections.sort(key=sort)                
+                for collection in collections:                    
+                    col_elem = self._add_subelems(pkg_elem, collection)
+                    components = collection.components
+                    components.sort(key=sort)
+                    for item in components:                        
+                        if self._lookup(self._rel_dir, "cmp_%s.ditamap" % item.id):
+                            col_header = self._add_subelems(col_elem, item) 
+                            etree.SubElement(col_header, "topicref", navtitle=item.name, href="cmp_%s.ditamap" % item.id, format="ditamap")
+        self._remove_empty_headings()
+        return self._root
+
+    def write(self, path):
+        with open(path, "w") as f:
+            f.write(xml_decl()+"\n")
+            f.write(etree.tostring(self.getmap()))
+            
+    def _remove_empty_headings(self):
+        new_root = copy.deepcopy(self._root)
+        empty_nodes = True
+        nodes_removed = 0
+        while empty_nodes:
+            nodes_removed = 0
+            for parent, newparent in zip(self._root.getiterator(), new_root.getiterator()):
+                for child, newchild in zip(parent, newparent):
+                    if len(list(child)) == 0 and not 'href' in child.attrib:
+                        newparent.remove(newchild)
+                        nodes_removed += 1
+            self._root = copy.deepcopy(new_root)
+            if nodes_removed == 0:
+                empty_nodes = False
+        self._root = new_root  
+
+
+################################################################
+# Unit test code
+################################################################
+import unittest
+from _shared import StubSysdef
+
+
+def mock_component_map_lookup(mapname, rel_dir):
+    return True
+
+
+class TestTopLevelMapCreator(unittest.TestCase):
+    def setUp(self):
+        self.mc = TopLevelMapCreator(StubSysdef(), ".", mock_component_map_lookup)
+        
+    def test_i_create_a_map_root_from_a_system_definition(self):                
+        root = self.mc.getmap()
+        self.assertTrue(root.tag == "map")
+        self.assertTrue(root.attrib['title'] == "Symbian^3")
+        self.assertTrue(root.attrib['id'] == "Symbian^3")
+
+    def test_i_create_correct_topicheads_from_layers(self):
+        root = self.mc.getmap()
+        self.assertEquals(len(root.findall("topichead")), 1)
+        os_elem = root.findall("topichead")[0]
+        self.assertEqual(os_elem.attrib["navtitle"], "OS")
+        self.assertEqual(os_elem.attrib["id"], "os")
+
+    def test_i_create_correct_topicheads_from_packages(self):
+        root = self.mc.getmap()
+        os_elem = root.findall("topichead")[0]
+        self.assertEquals(len(os_elem.findall("topichead")), 1)
+        pkg_elem = os_elem.findall("topichead")[0]        
+        self.assertEqual(pkg_elem.attrib["navtitle"], "Kernel and Hardware Services")
+        self.assertEqual(pkg_elem.attrib["id"], "kernelhwsrv")
+
+    def test_i_create_correct_topicheads_from_collections(self):
+        root = self.mc.getmap()
+        os_elem = root.findall("topichead")[0]
+        pkg_elem = os_elem.findall("topichead")[0]
+        self.assertEquals(len(pkg_elem.findall("topichead")), 1)
+        bootldr_elem = pkg_elem.findall("topichead")[0]
+        self.assertEqual(bootldr_elem.attrib["navtitle"], "Board Boot Loader")
+        self.assertEqual(bootldr_elem.attrib["id"], "brdbootldr")
+
+    def test_i_create_correct_topicheads_for_components(self):
+        root = self.mc.getmap()
+        os_elem = root.findall("topichead")[0]
+        pkg_elem = os_elem.findall("topichead")[0]
+        com_elem = pkg_elem.findall("topichead")[0]
+        comp_elem_header = com_elem.findall("topichead")[0]        
+        self.assertEqual(comp_elem_header.attrib["navtitle"], "Boot Loader")
+        self.assertEqual(comp_elem_header.attrib["id"], "ubootldr")
+
+    def test_i_create_correct_topicrefs_from_components(self):
+        root = self.mc.getmap()
+        os_elem = root.findall("topichead")[0]
+        pkg_elem = os_elem.findall("topichead")[0]
+        comp_elem = pkg_elem.findall("topichead")[0]
+        comp_elem_header = comp_elem.findall("topichead")[0]
+        self.assertEquals(len(comp_elem_header.findall("topicref")), 1)
+        ubootldr_elem = comp_elem_header.findall("topicref")[0]
+        self.assertEqual(ubootldr_elem.attrib["navtitle"], "Boot Loader")
+        self.assertEqual(ubootldr_elem.attrib["href"], "cmp_ubootldr.ditamap")
+        self.assertEqual(ubootldr_elem.attrib["format"], "ditamap")
+
+    def test_i_can_remove_empty_headings_from_a_top_level_map(self):
+        self.mc._root = etree.fromstring(empty_headings_toc)
+        self.mc._remove_empty_headings()
+        self.assertEquals(etree.tostring(self.mc._root), removed_empty_headings_toc)
+
+    def test_i_sort_the_map(self):
+        root = self.mc.getmap()
+        os_elem = root.findall("topichead")[0]
+        pkg_elem = os_elem.findall("topichead")[0]
+        com_elem = pkg_elem.findall("topichead")[0]
+        comp_elem_header = com_elem.findall("topichead")[0]        
+        self.assertEqual(comp_elem_header.attrib["navtitle"], "Boot Loader")
+        comp_elem_header = com_elem.findall("topichead")[1]        
+        self.assertEqual(comp_elem_header.attrib["navtitle"], "Kernel Architecture")
+
+
+empty_headings_toc = """\
+<map id="Symbian^3" title="Symbian^3">
+  <topichead id="os" navtitle="OS" >
+    <topichead id="kernelhwsrv" navtitle="Kernel and Hardware Services">
+      <topichead id="brdbootldr" navtitle="Board Boot Loader">
+        <topichead id="ubootldr" navtitle="Boot Loader"/>
+      </topichead>
+      <topichead id="bsptemplate" navtitle="Board Support Package Template">
+        <topichead id="asspandvariant" navtitle="Template ASSP and Variant">
+          <topicref format="ditamap" href="cmp_template_variant.ditamap" navtitle="template_variant" />
+        </topichead>
+      </topichead>      
+    </topichead>
+  </topichead>
+</map>"""
+
+
+removed_empty_headings_toc = """\
+<map id="Symbian^3" title="Symbian^3">
+  <topichead id="os" navtitle="OS">
+    <topichead id="kernelhwsrv" navtitle="Kernel and Hardware Services">
+      <topichead id="bsptemplate" navtitle="Board Support Package Template">
+        <topichead id="asspandvariant" navtitle="Template ASSP and Variant">
+          <topicref format="ditamap" href="cmp_template_variant.ditamap" navtitle="template_variant" />
+        </topichead>
+      </topichead>      
+    </topichead>
+  </topichead>
+</map>""" 
\ No newline at end of file