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