PageRenderTime 28ms CodeModel.GetById 20ms app.highlight 3ms RepoModel.GetById 1ms app.codeStats 0ms

/src/lib/xml/xml_tree.e

http://github.com/tybor/Liberty
Specman e | 224 lines | 163 code | 28 blank | 33 comment | 7 complexity | e397bd1d1fcd6f979667ad9aae24a150 MD5 | raw file
  1-- See the Copyright notice at the end of this file.
  2--
  3class XML_TREE
  4   --
  5   -- DOM-like representation of an XML document
  6   --
  7   -- See also XML_PARSER
  8   --
  9
 10inherit
 11   XML_CALLBACKS
 12
 13create {ANY}
 14   make, with_error_handler
 15
 16feature {ANY}
 17   root: XML_COMPOSITE_NODE
 18         -- The root of the tree
 19
 20   attribute_at (a_attribute_name: UNICODE_STRING): UNICODE_STRING
 21         -- Usually to recover the "version" or "encoding" attributes
 22      do
 23         Result := tree_attributes.reference_at(a_attribute_name)
 24      end
 25
 26   set_processing_instruction (target: UNICODE_STRING; processor: PROCEDURE[TUPLE[UNICODE_STRING]])
 27      require
 28         target /= Void
 29         processor /= Void
 30      local
 31         processors: FAST_ARRAY[PROCEDURE[TUPLE[UNICODE_STRING]]]
 32      do
 33         processors := processing_instructions.reference_at(target)
 34         if processors = Void then
 35            create processors.make(0)
 36            processing_instructions.add(processors, target.twin)
 37         end
 38         processors.add_last(processor)
 39      end
 40
 41feature {}
 42   attributes: HASHED_DICTIONARY[UNICODE_STRING, UNICODE_STRING]
 43
 44   tree_attributes: like attributes
 45
 46   open_nodes: STACK[XML_COMPOSITE_NODE]
 47
 48   processing_instructions: HASHED_DICTIONARY[FAST_ARRAY[PROCEDURE[TUPLE[UNICODE_STRING]]], UNICODE_STRING]
 49      once
 50         create Result.make
 51      end
 52
 53feature {XML_PARSER}
 54   with_attribute (attribute_name: UNICODE_STRING; attribute_value: UNICODE_STRING; line, column: INTEGER)
 55      do
 56         if attribute_value=Void
 57          then attributes.put(Void, attribute_name.twin)
 58         else attributes.put(attribute_value.twin, attribute_name.twin)
 59         end
 60      end
 61
 62   open_node (node_name: UNICODE_STRING; line, column: INTEGER)
 63      local
 64         node: XML_COMPOSITE_NODE; i: INTEGER
 65      do
 66         node := new_node(node_name.twin, line, column)
 67         from
 68            i := attributes.lower
 69         until
 70            i > attributes.upper
 71         loop
 72            node.set_attribute(attributes.key(i), attributes.item(i))
 73            i := i + 1
 74         end
 75         attributes.clear_count
 76         open_nodes.push(node)
 77      end
 78
 79   close_node (node_name: UNICODE_STRING; line, column: INTEGER)
 80      local
 81         node: XML_COMPOSITE_NODE
 82      do
 83         node := open_nodes.top
 84         open_nodes.pop
 85         if open_nodes.is_empty then
 86            root := node
 87         else
 88            open_nodes.top.add_child(node)
 89         end
 90      end
 91
 92   open_close_node (node_name: UNICODE_STRING; line, column: INTEGER)
 93      do
 94         open_node(node_name, line, column)
 95         close_node(node_name, line, column)
 96      end
 97
 98   xml_header (line, column: INTEGER)
 99      do
100         check
101            tree_attributes.is_empty
102         end
103         tree_attributes.copy(attributes)
104         attributes.clear_count
105      end
106
107   processing_instruction (a_target, a_data: UNICODE_STRING)
108      local
109         processors: FAST_ARRAY[PROCEDURE[TUPLE[UNICODE_STRING]]]; i: INTEGER
110      do
111         processors := processing_instructions.reference_at(a_target)
112         if processors /= Void then
113            from
114               i := processors.lower
115            until
116               i > processors.upper
117            loop
118               processors.item(i).call([a_data])
119               i := i + 1
120            end
121         end
122      end
123
124   current_node: UNICODE_STRING
125      do
126         if not open_nodes.is_empty then
127            Result := open_nodes.top.name
128         end
129      end
130
131   entity (a_entity: UNICODE_STRING; line, column: INTEGER): UNICODE_STRING
132      do
133         -- The default tree does not recognize any other entity than XML defaults.
134      end
135
136   open_entity_url (a_entity: UNICODE_STRING; a_url: URL)
137      do
138         -- nothing to do?
139      end
140
141   close_entity_url (a_entity: UNICODE_STRING; a_url: URL)
142      do
143         -- nothing to do?
144      end
145
146   data (a_data: UNICODE_STRING; line, column: INTEGER)
147      local
148         d: XML_DATA_NODE
149      do
150         create d.make(a_data.twin, line, column)
151         open_nodes.top.add_child(d)
152      end
153
154   parse_error (line, column: INTEGER; message: STRING)
155      do
156         at_error := True
157         if error_handler /= Void then
158            error_handler.call([line, column, message])
159         else
160            std_error.put_string(message)
161            std_error.put_string(" at line ")
162            std_error.put_integer(line)
163            std_error.put_string(", column ")
164            std_error.put_integer(column)
165            std_error.put_new_line
166            die_with_code(1)
167         end
168      end
169
170   at_error: BOOLEAN
171
172feature {}
173   error_handler: PROCEDURE[TUPLE[INTEGER, INTEGER, STRING]]
174
175   make (url: URL)
176         -- read the xml tree at the given `url'
177      require
178         url.is_connected implies url.read
179      do
180         create attributes.make
181         create tree_attributes.make
182         create open_nodes.make
183         parser.connect_to(url)
184         parser.parse(Current)
185         parser.disconnect
186      end
187
188   with_error_handler (url: URL; a_error_handler: like error_handler)
189      do
190         error_handler := a_error_handler
191         make(url)
192      end
193
194   new_node (node_name: UNICODE_STRING; line, column: INTEGER): XML_COMPOSITE_NODE
195      do
196         create Result.make(node_name, line, column)
197      end
198
199   parser: XML_PARSER
200      once
201         create Result.make
202      end
203
204end -- class XML_TREE
205--
206-- Copyright (C) 2009-2017: by all the people cited in the AUTHORS file.
207--
208-- Permission is hereby granted, free of charge, to any person obtaining a copy
209-- of this software and associated documentation files (the "Software"), to deal
210-- in the Software without restriction, including without limitation the rights
211-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
212-- copies of the Software, and to permit persons to whom the Software is
213-- furnished to do so, subject to the following conditions:
214--
215-- The above copyright notice and this permission notice shall be included in
216-- all copies or substantial portions of the Software.
217--
218-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
219-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
220-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
221-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
222-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
223-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
224-- THE SOFTWARE.