PageRenderTime 46ms CodeModel.GetById 37ms app.highlight 3ms RepoModel.GetById 1ms app.codeStats 1ms

/src/lib/storage/internal/xml_repository_impl.e

http://github.com/tybor/Liberty
Specman e | 295 lines | 205 code | 31 blank | 59 comment | 4 complexity | 32174a42e53144940c3814bb744ee463 MD5 | raw file
  1-- This file is part of a Liberty Eiffel library.
  2-- See the full copyright at the end.
  3--
  4deferred class XML_REPOSITORY_IMPL[O_ -> STORABLE]
  5   --
  6   -- Implementation of the XML store and retrieval
  7   --
  8   -- Schema:
  9   --
 10   --   <!DOCTYPE repository [
 11   --
 12   --   <!ELEMENT repository (layout | reference | embedded | basic)* >
 13   --   <!ATTLIST repository version CDATA #REQUIRED >
 14   --
 15   --   <!ELEMENT layout (reference | embedded | basic | array)* >
 16   --   <!ATTLIST layout type CDATA #REQUIRED >
 17   --   <!ATTLIST layout ref ID #REQUIRED >
 18   --
 19   --   <!ELEMENT reference (EMPTY) >
 20   --   <!ATTLIST reference name CDATA >
 21   --   <!ATTLIST reference ref IDREF #REQUIRED >
 22   --   <!ATTLIST reference transient (true|false) #REQUIRED >
 23   --
 24   --   <!ELEMENT embedded (reference | embedded | basic | array)* >
 25   --   <!ATTLIST embedded name CDATA >
 26   --   <!ATTLIST embedded type CDATA #REQUIRED >
 27   --
 28   --   <!ELEMENT basic (EMPTY) >
 29   --   <!ATTLIST basic name CDATA >
 30   --   <!ATTLIST basic type CDATA #REQUIRED >
 31   --   <!ATTLIST basic value CDATA #REQUIRED >
 32   --
 33   --   <!ELEMENT array (reference | embedded | basic)* >
 34   --   <!ATTLIST array name CDATA >
 35   --   <!ATTLIST array type CDATA #REQUIRED >
 36   --   <!ATTLIST array capacity CDATA #REQUIRED >
 37   --
 38   --   ] >
 39   --
 40inherit
 41   XML_CALLBACKS
 42   REPOSITORY_IMPL[O_]
 43
 44insert
 45   UNICODE_CHARACTERS
 46
 47feature {} -- Implementation of update
 48   update_name: STRING ""
 49
 50   update_ref: STRING ""
 51
 52   update_type: STRING ""
 53
 54   update_value: STRING ""
 55
 56   update_capacity: STRING ""
 57
 58   update_version: STRING ""
 59
 60   xml: XML_PARSER
 61      once
 62         create Result.make
 63      end
 64
 65   do_update (in_stream: INPUT_STREAM)
 66      do
 67         xml.connect_to(in_stream.url)
 68         xml.parse(Current)
 69      end
 70
 71   last_line: INTEGER
 72      do
 73         Result := xml.line
 74      end
 75
 76   last_column: INTEGER
 77      do
 78         Result := xml.column
 79      end
 80
 81feature {}
 82   open_nodes: FAST_ARRAY[STRING]
 83      once
 84         create Result.with_capacity(4)
 85      end
 86
 87feature {XML_PARSER}
 88   with_attribute (attribute_name: UNICODE_STRING; attribute_value: UNICODE_STRING; line, column: INTEGER)
 89      local
 90         error: STRING
 91      do
 92         inspect
 93            attribute_name.as_utf8
 94         when "name" then
 95            update_name.copy(attribute_value.as_utf8)
 96         when "type" then
 97            update_type.copy(attribute_value.as_utf8)
 98         when "ref" then
 99            update_ref.copy(attribute_value.as_utf8)
100         when "value" then
101            update_value.copy(attribute_value.as_utf8)
102         when "capacity" then
103            update_capacity.copy(attribute_value.as_utf8)
104         when "version" then
105            update_version.copy(attribute_value.as_utf8)
106         else
107            error := once ""
108            error.copy(once "Unknown attribute: ")
109            attribute_name.utf8_encode_in(error)
110            fire_update_error(error, line, column)
111         end
112      end
113
114   open_node (node_name: UNICODE_STRING; line, column: INTEGER)
115      local
116         n, s, error: STRING; layout: REPOSITORY_LAYOUT
117      do
118         n := node_name.as_utf8
119         s := strings.new_twin(n)
120         open_nodes.add_last(s)
121         layout := new_layout(n)
122         update_layouts.push(layout)
123         inspect
124            n
125         when "repository" then
126            if not update_version.is_equal(version) then
127               error := once ""
128               error.copy(once "Incompatible versions: expected ")
129               error.append(version)
130               error.append(once " but got ")
131               error.append(update_version)
132               fire_update_error(error, line, column)
133            end
134            open_repository(layout, line, column)
135         when "layout" then
136            open_layout(update_type, update_ref.to_integer, layout, line, column)
137         when "reference" then
138            open_reference(update_name, update_ref.to_integer, layout, line, column)
139         when "embedded" then
140            open_embedded(update_name, update_type, layout, line, column)
141         when "basic" then
142            open_basic(update_name, update_type, update_value, layout, line, column)
143         when "array" then
144            open_array(update_name, update_type, update_capacity.to_integer, layout, line, column)
145         else
146            error := once ""
147            error.copy(once "Unknown node: ")
148            node_name.utf8_encode_in(error)
149            fire_update_error(error, line, column)
150         end
151         clear_attributes
152      end
153
154   close_node (node_name: UNICODE_STRING; line, column: INTEGER)
155      local
156         error: STRING
157      do
158         strings.recycle(open_nodes.last)
159         open_nodes.remove_last
160         inspect
161            node_name.as_utf8
162         when "repository" then
163            close_repository(line, column)
164         when "layout" then
165            close_layout(line, column)
166         when "reference" then
167            close_reference(line, column)
168         when "embedded" then
169            close_embedded(line, column)
170         when "basic" then
171            close_basic(line, column)
172         when "array" then
173            close_array(line, column)
174         else
175            error := once ""
176            error.copy(once "Unknown node: ")
177            node_name.utf8_encode_in(error)
178            fire_update_error(error, line, column)
179         end
180      end
181
182   open_close_node (node_name: UNICODE_STRING; line, column: INTEGER)
183      do
184         open_node(node_name, line, column)
185         close_node(node_name, line, column)
186      end
187
188   current_node: UNICODE_STRING
189      do
190         Result := once U""
191         Result.clear_count
192         if not Result.utf8_decode_from(open_nodes.last) then
193            Result := Void
194         end
195      end
196
197   xml_header (line, column: INTEGER)
198      do
199         clear_attributes
200      end
201
202   processing_instruction (a_target, a_data: UNICODE_STRING)
203      do
204         fire_update_error(once "Unexpected processing instruction", last_line, last_column)
205      end
206
207   entity (a_entity: UNICODE_STRING; line, column: INTEGER): UNICODE_STRING
208      do
209         fire_update_error(once "Unexpected entity", line, column)
210      end
211
212   open_entity_url (a_entity: UNICODE_STRING; a_url: URL)
213         -- XML_REPOSITORY doesn't use entity urls
214      do
215         fire_update_error(once "Unexpected entityurl", last_line, last_column)
216      end
217
218   close_entity_url (a_entity: UNICODE_STRING; a_url: URL)
219      do
220      end
221
222   data (a_data: UNICODE_STRING; line, column: INTEGER)
223      local
224         i: INTEGER; break: BOOLEAN
225      do
226         from
227            i := a_data.lower
228         until
229            i > a_data.upper or else break
230         loop
231            if not is_separator(a_data.item(i)) then
232               fire_update_error(once "Separator expected", line, column)
233            end
234            i := i + 1
235         end
236      end
237
238   parse_error (line, column: INTEGER; message: STRING)
239      do
240         at_error := True
241         fire_update_error(message, line, column)
242      end
243
244   at_error: BOOLEAN
245
246feature {} -- Internals
247   frozen version: STRING "1"
248
249   clear_attributes
250      do
251         update_name.clear_count
252         update_ref.clear_count
253         update_type.clear_count
254         update_value.clear_count
255         update_capacity.clear_count
256         update_version.clear_count
257      end
258
259   strings: STRING_RECYCLING_POOL
260      once
261         create Result.make
262      end
263
264feature {} -- Default transient objects
265   register_transient_objects
266      do
267         transient.register(to_internals, once "Repository")
268      end
269
270   unregister_transient_objects
271      do
272         transient.unregister(once "Repository")
273      end
274
275end -- class XML_REPOSITORY_IMPL
276--
277-- Copyright (C) 2009-2017: by all the people cited in the AUTHORS file.
278--
279-- Permission is hereby granted, free of charge, to any person obtaining a copy
280-- of this software and associated documentation files (the "Software"), to deal
281-- in the Software without restriction, including without limitation the rights
282-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
283-- copies of the Software, and to permit persons to whom the Software is
284-- furnished to do so, subject to the following conditions:
285--
286-- The above copyright notice and this permission notice shall be included in
287-- all copies or substantial portions of the Software.
288--
289-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
290-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
291-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
292-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
293-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
294-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
295-- THE SOFTWARE.