1 # This file is part of NIT ( http://www.nitlanguage.org ).
3 # This file is free software, which comes along with NIT. This software is
4 # distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
5 # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
6 # PARTICULAR PURPOSE. You can modify it is you want, provided this header
7 # is kept unaltered, and a notification of the changes is added.
8 # You are allowed to redistribute it and sell it, alone or is a part of
11 # Base class for deriving an XML filter.
12 module sax
::helpers
::xml_filter_impl
14 import sax
::xml_reader
15 import sax
::xml_filter
16 import sax
::input_source
17 import sax
::sax_locator
18 import sax
::attributes
19 import sax
::entity_resolver
20 import sax
::dtd_handler
21 import sax
::content_handler
22 import sax
::error_handler
23 import sax
::sax_parse_exception
25 # Base class for deriving an XML filter.
27 # This class is designed to sit between an `XMLReader`
28 # and the client application's event handlers. By default, it
29 # does nothing but pass requests up to the reader and events
30 # on to the handlers unmodified, but subclasses can override
31 # specific methods to modify the event stream or the configuration
32 # requests as they pass through.
34 # Note: The original source code and documentation of this class comes, in part,
35 # from [SAX 2.0](http://www.saxproject.org).
45 redef var parent
: nullable XMLReader = null is writable
49 redef var entity_resolver
: nullable EntityResolver = null is writable
50 redef var dtd_handler
: nullable DTDHandler = null is writable
51 redef var content_handler
: nullable ContentHandler = null is writable
52 redef var error_handler
: nullable ErrorHandler = null is writable
55 ############################################################################
58 # Construct an empty XML filter, with no parent.
60 # This filter will have no parent: you must assign a parent
61 # before you start a parse or do any configuration with
62 # `feature=` or `property=`, unless you use this as
63 # a pure event consumer rather than as an `XMLReader`.
69 # Construct an XML filter with the specified parent.
72 init with_parent
(parent_reader
: XMLReader) do
73 parent
= parent_reader
76 redef fun feature_recognized
(name
: String): Bool do
77 if parent
== null then
80 return parent
.feature_recognized
(name
)
84 redef fun feature_readable
(name
: String): Bool do
85 if parent
== null then
88 return parent
.feature_readable
(name
)
92 redef fun feature_writable
(name
: String): Bool do
93 if parent
== null then
96 return parent
.feature_writable
(name
)
100 # Look up the value of a feature.
102 # This will always fail if the parent is `null`.
106 # * `name`: The feature name.
110 # The current value of the feature.
112 # SEE: `feature_recognized`
114 # SEE: `feature_readable`
115 redef fun feature
(name
: String): Bool do
116 assert sax_recognized
: parent
!= null else
117 sys
.stderr
.write
("Feature: {name}\n")
119 return parent
.feature
(name
)
122 # Set the value of a feature.
124 # This will always fail if the parent is `null`.
128 # * `name`: feature name.
129 # * `value`: requested feature value.
133 # `true` if the feature is set; `false` if the feature can not be set given
134 # the current context.
136 # SEE: `feature_recognized`
138 # SEE: `feature_writable`
139 redef fun feature
=(name
: String, value
: Bool) do
140 assert sax_recognized
: parent
!= null else
141 sys
.stderr
.write
("Feature: {name}\n")
143 parent
.feature
(name
) = value
146 redef fun property_recognized
(name
: String): Bool do
147 if parent
== null then
150 return parent
.property_recognized
(name
)
154 redef fun property_readable
(name
: String): Bool do
155 if parent
== null then
158 return parent
.property_readable
(name
)
162 redef fun property_writable
(name
: String): Bool do
163 if parent
== null then
166 return parent
.property_writable
(name
)
170 # Look up the value of a property.
174 # * `name`: The property name.
178 # The current value of the property.
180 # SEE: `property_recognized`
182 # SEE: `property_readable`
183 redef fun property
(name
: String): nullable Object do
184 assert sax_recognized
: parent
!= null else
185 sys
.stderr
.write
("Property: {name}\n")
187 return parent
.property
(name
)
190 # Set the value of a property.
192 # This will always fail if the parent is `null`.
196 # * `name`: property name.
197 # * `value`: requested feature value.
201 # `true` if the property is set; `false` if the property can not be set
202 # given the current context.
204 # SEE: `property_recognized`
206 # SEE: `property_writable`
207 redef fun property
=(name
: String, value
: nullable Object) do
208 assert sax_recognized
: parent
!= null else
209 sys
.stderr
.write
("Property: {name}\n")
211 parent
.property
(name
) = value
214 redef fun parse
(input
: InputSource) do
219 redef fun parse_file
(system_id
: String) do
220 var source
= new InputSource
222 source
.system_id
= system_id
227 ############################################################################
230 redef fun resolve_entity
(public_id
: nullable String,
231 system_id
: nullable String):
232 nullable InputSource do
233 if entity_resolver
== null then
236 return entity_resolver
.resolve_entity
(public_id
, system_id
)
241 ############################################################################
244 redef fun notation_decl
(name
: String, public_id
: String,
245 system_id
: String) do
246 if dtd_handler
!= null then
247 dtd_handler
.notation_decl
(name
, public_id
, system_id
)
251 redef fun unparsed_entity_decl
(name
: String, public_id
: String,
252 system_id
: String) do
253 if dtd_handler
!= null then
254 dtd_handler
.unparsed_entity_decl
(name
, public_id
, system_id
)
259 ############################################################################
262 redef fun document_locator
=(locator
: SAXLocator) do
263 if content_handler
!= null then
264 content_handler
.document_locator
= locator
268 redef fun start_document
do
269 if content_handler
!= null then
270 content_handler
.start_document
274 redef fun end_document
do
275 if content_handler
!= null then
276 content_handler
.end_document
280 redef fun start_prefix_mapping
(prefix
: String, uri
: String) do
281 if content_handler
!= null then
282 content_handler
.start_prefix_mapping
(prefix
, uri
)
286 redef fun end_prefix_mapping
(prefix
: String) do
287 if content_handler
!= null then
288 content_handler
.end_prefix_mapping
(prefix
)
292 redef fun start_element
(uri
: String, local_name
: String, qname
: String,
294 if content_handler
!= null then
295 content_handler
.start_element
(uri
, local_name
, qname
, atts
)
299 redef fun end_element
(uri
: String, local_name
: String, qname
: String) do
300 if content_handler
!= null then
301 content_handler
.end_element
(uri
, local_name
, qname
)
305 redef fun characters
(str
: String) do
306 if content_handler
!= null then
307 content_handler
.characters
(str
)
311 redef fun ignorable_whitespace
(str
: String) do
312 if content_handler
!= null then
313 content_handler
.ignorable_whitespace
(str
)
317 redef fun processing_instruction
(target
: String, data
: nullable String) do
318 if content_handler
!= null then
319 content_handler
.processing_instruction
(target
, data
)
323 redef fun skipped_entity
(name
: String) do
324 if content_handler
!= null then
325 content_handler
.skipped_entity
(name
)
330 ############################################################################
333 redef fun warning
(exception
: SAXParseException) do
334 if error_handler
!= null then
335 error_handler
.warning
(exception
)
339 redef fun error
(exception
: SAXParseException) do
340 if error_handler
!= null then
341 error_handler
.error
(exception
)
345 redef fun fatal_error
(exception
: SAXParseException) do
346 if error_handler
!= null then
347 error_handler
.fatal_error
(exception
)
353 ############################################################################
356 # Set up before a parse.
358 # Before every parse, check whether the parent is
359 # non-null, and re-register the filter for all of the
361 private fun setup_parse
do
362 assert parent_is_not_null
: parent
!= 0 else
363 sys
.stderr
.write
("No parent for filter.")
365 parent
.entity_resolver
= self
366 parent
.dtd_handler
= self
367 parent
.content_handler
= self
368 parent
.error_handler
= self