|
1 # Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies). |
|
2 # All rights reserved. |
|
3 # This component and the accompanying materials are made available |
|
4 # under the terms of the License "Eclipse Public License v1.0" |
|
5 # which accompanies this distribution, and is available |
|
6 # at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 # |
|
8 # Initial Contributors: |
|
9 # Nokia Corporation - initial contribution. |
|
10 # |
|
11 # Contributors: |
|
12 # |
|
13 from __future__ import with_statement |
|
14 try: |
|
15 from xml.etree import cElementTree as etree |
|
16 except ImportError: |
|
17 from xml.etree import ElementTree as etree |
|
18 from orb.lib import xml_decl, doctype_identifier |
|
19 import logging |
|
20 import os |
|
21 |
|
22 |
|
23 logger = logging.getLogger('orb.mapcreators.componentlevel') |
|
24 |
|
25 |
|
26 class ComponentExportsManager(object): |
|
27 """ |
|
28 Retrieves bld.infs from the systemdefinition and exports from |
|
29 the log file. |
|
30 |
|
31 get_export_path_for: When called with the path to a header file, |
|
32 returns the path the header file is exported to. |
|
33 """ |
|
34 def __init__(self, sysdef, component, exportsmap): |
|
35 self.sysdef = sysdef |
|
36 self.exportsmap = exportsmap |
|
37 self._fullpaths = [a[0] for a in self._get_export_headers(component)] |
|
38 self._basenames = [os.path.basename(a) for a in self._fullpaths] |
|
39 |
|
40 def _get_export_headers(self, component): |
|
41 export_headers = set() |
|
42 for bld_inf in self.sysdef.get_bldinfs(component.id): |
|
43 component_exports = self.exportsmap.get_exports(bld_inf) |
|
44 if component_exports != None: |
|
45 export_headers = export_headers.union(component_exports) |
|
46 logger.debug("I got these export headers from the log: %s" % (str(export_headers))) |
|
47 return export_headers |
|
48 |
|
49 def get_export_path_for(self, filepath): |
|
50 export_path = None |
|
51 for basename, fullpath in zip(self._basenames, self._fullpaths): |
|
52 if basename == os.path.basename(filepath): |
|
53 export_path = fullpath |
|
54 return export_path |
|
55 |
|
56 def is_public(self, filepath): |
|
57 return self.exportsmap.is_public(filepath) |
|
58 |
|
59 |
|
60 class ComponentMapCreator(object): |
|
61 "Writes out component level DITAMAPS" |
|
62 def __init__(self, output_dir): |
|
63 self.output_dir = output_dir |
|
64 |
|
65 def _process_elems(self, parent, entries): |
|
66 entries.sort(key=lambda item: item.navtitle) |
|
67 for entry in entries: |
|
68 href = entry.href if entry.href is not None else "" |
|
69 navtitle = entry.navtitle if entry.navtitle is not None else "" |
|
70 elem = etree.SubElement(parent, entry.tag, href=href, navtitle=navtitle) |
|
71 if len(entry.children) > 0: |
|
72 self._process_elems(elem, entry.children) |
|
73 |
|
74 def get_component_level_map(self, component, entries): |
|
75 root = etree.Element("cxxAPIMap", id="cmp_%s" % component.id, title=component.name) |
|
76 self._process_elems(root, entries) |
|
77 return root |
|
78 |
|
79 def write(self, root): |
|
80 if len(root) == 0: |
|
81 return |
|
82 with open(os.path.join(self.output_dir, root.get("id")+".ditamap"), "w") as f: |
|
83 f.write(xml_decl()+"\n") |
|
84 f.write(doctype_identifier("cxxAPIMap")+"\n") |
|
85 f.write(etree.tostring(root)) |
|
86 |
|
87 |
|
88 ################################################################ |
|
89 # Unit test code |
|
90 ################################################################ |
|
91 import unittest |
|
92 import shutil |
|
93 from _shared import StubSysdef, StubBldInfExportsMap, StubPackageLevelMapCreator |
|
94 |
|
95 |
|
96 class TestComponentExportsManager(unittest.TestCase): |
|
97 def test_i_get_the_correct_declaration_path_for_a_file(self): |
|
98 component_classicui_pub = StubSysdef().get_components("classicui")[0] |
|
99 cm = ComponentExportsManager(StubSysdef(), component_classicui_pub, StubBldInfExportsMap()) |
|
100 fpath = cm.get_export_path_for("W:/foo/bar/aknSoundinfo.h") |
|
101 self.assertEqual(fpath, "W:/epoc32/include/mw/aknSoundinfo.h") |
|
102 |
|
103 |
|
104 class TestComponentMapCreator(unittest.TestCase): |
|
105 |
|
106 def setUp(self): |
|
107 self.plmcreator = StubPackageLevelMapCreator(StubSysdef(),"") |
|
108 self.cmc = ComponentMapCreator(".") |
|
109 self.test_dir = os.path.abspath(os.path.join("TestComponentMapCreator_test")) |
|
110 os.makedirs(self.test_dir) |
|
111 |
|
112 def tearDown(self): |
|
113 shutil.rmtree(self.test_dir) |
|
114 |
|
115 def test_i_create_a_correct_component_level_map(self): |
|
116 expected_clm = """<cxxAPIMap id="cmp_classicui_pub" title="Classic UI Public Interfaces"> |
|
117 <cxxClassRef href="class_b_trace.xml#class_b_trace" navtitle="class_b_trace"> |
|
118 <cxxStructRef href="struct_b_trace_1_1_s_exec_extension.xml#struct_b_trace_1_1_s_exec_extension" navtitle="struct_b_trace_1_1_s_exec_extension" /> |
|
119 </cxxClassRef> |
|
120 <cxxClassRef href="class_c_active.xml#class_c_active" navtitle="class_c_active" /> |
|
121 <cxxClassRef href="class_c_active_scheduler.xml#class_c_active_scheduler" navtitle="class_c_active_scheduler"> |
|
122 <cxxClassRef href="class_c_active_scheduler_1_1_t_cleanup_bundle.xml#class_c_active_scheduler_1_1_t_cleanup_bundle" navtitle="class_c_active_scheduler_1_1_t_cleanup_bundle" /> |
|
123 </cxxClassRef> |
|
124 <cxxClassRef href="class_c_active_scheduler_wait.xml#class_c_active_scheduler_wait" navtitle="class_c_active_scheduler_wait" /> |
|
125 <cxxClassRef href="class_c_always_online_disk_space_observer.xml#class_c_always_online_disk_space_observer" navtitle="class_c_always_online_disk_space_observer" /> |
|
126 <cxxClassRef href="class_c_always_online_e_com_interface.xml#class_c_always_online_e_com_interface" navtitle="class_c_always_online_e_com_interface"> |
|
127 <cxxStructRef href="nested_and_removed.xml" navtitle="" /> |
|
128 <cxxStructRef href="struct_c_always_online_e_com_interface_1_1___c_e_com_interface_init_params.xml#struct_c_always_online_e_com_interface_1_1___c_e_com_interface_init_params" navtitle="struct_c_always_online_e_com_interface_1_1___c_e_com_interface_init_params" /> |
|
129 </cxxClassRef> |
|
130 <cxxClassRef href="class_c_always_online_manager.xml#class_c_always_online_manager" navtitle="class_c_always_online_manager" /> |
|
131 <cxxClassRef href="class_c_always_online_manager_server.xml#class_c_always_online_manager_server" navtitle="class_c_always_online_manager_server" /> |
|
132 <cxxStructRef href="struct___array_util.xml#struct___array_util" navtitle="struct___array_util" /> |
|
133 <cxxClassRef href="test_class_defined_in_src_path.xml#test_class_defined_in_src_path" navtitle="test_class_defined_in_src_path" /> |
|
134 </cxxAPIMap>""" |
|
135 classicui_comp = StubSysdef().get_components("classicui")[0] |
|
136 plm = self.plmcreator.get_package_level_map("classicui") |
|
137 exp_clm = etree.fromstring(expected_clm) |
|
138 clm = self.cmc.get_component_level_map(classicui_comp, plm) |
|
139 self.assertEqual(len(clm), len(exp_clm)) |
|
140 print etree.tostring(clm) |
|
141 for recieved, expected in zip(clm.getiterator(), exp_clm.getiterator()): |
|
142 self.assertEqual(recieved.tag, expected.tag) |
|
143 self.assertEqual(recieved.attrib, expected.attrib) |
|
144 |
|
145 def test_i_can_write_a_component_map_to_the_file_system(self): |
|
146 map = etree.fromstring(expected_clm) |
|
147 self.cmc.output_dir = self.test_dir |
|
148 self.cmc.write(map) |
|
149 map_path = os.path.join(self.test_dir, "cmp_classicui_pub.ditamap") # map names should be cmp_ + mapid |
|
150 self.assertTrue(os.path.exists(map_path)) |
|
151 content = open(map_path, "r").read() |
|
152 self.assertTrue(content.find("<?xml") == 0) # it has a doctype declaration |
|
153 self.assertTrue(content.find("<!DOCTYPE cxxAPIMap") != -1) # it has doctype decl |
|
154 self.assertTrue(content.find('<cxxAPIMap id="cmp_classicui_pub"') != -1) # it has the map |
|
155 |
|
156 def test_i_dont_write_out_an_empty_component_map_to_the_file_system(self): |
|
157 map = etree.fromstring(empty_clm) |
|
158 self.cmc.output_dir = self.test_dir |
|
159 self.cmc.write(map) |
|
160 map_path = os.path.join(self.test_dir, "cmp_classicui_pub.ditamap") # map names should be cmp_ + mapid |
|
161 self.assertFalse(os.path.exists(map_path)) # Shouldnt have been written out as map was empty |
|
162 |
|
163 |
|
164 expected_clm = """<cxxAPIMap id="cmp_classicui_pub" title="Classic UI Public Interfaces"> |
|
165 <cxxStructRef href="struct___array_util.xml#struct___array_util" navtitle="struct___array_util" /> |
|
166 <cxxClassRef href="class_c_active_scheduler.xml#class_c_active_scheduler" navtitle="class_c_active_scheduler"> |
|
167 <cxxClassRef href="class_c_active_scheduler_1_1_t_cleanup_bundle.xml#class_c_active_scheduler_1_1_t_cleanup_bundle" navtitle="class_c_active_scheduler_1_1_t_cleanup_bundle" /> |
|
168 </cxxClassRef> |
|
169 <cxxClassRef href="class_c_always_online_e_com_interface.xml#class_c_always_online_e_com_interface" navtitle="class_c_always_online_e_com_interface"> |
|
170 </cxxClassRef> |
|
171 </cxxAPIMap>""" |
|
172 |
|
173 empty_clm = """<cxxAPIMap id="cmp_classicui_pub" title="Classic UI Public Interfaces"></cxxAPIMap>""" |