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
= null is writable
49 redef var entity_resolver
= null is writable
50 redef var dtd_handler
= null is writable
51 redef var content_handler
= null is writable
52 redef var error_handler
= 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
) do
77 if parent
== null then
80 return parent
.feature_recognized
(name
)
84 redef fun feature_readable
(name
) do
85 if parent
== null then
88 return parent
.feature_readable
(name
)
92 redef fun feature_writable
(name
) 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
) 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
, value
) 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
) do
147 if parent
== null then
150 return parent
.property_recognized
(name
)
154 redef fun property_readable
(name
) do
155 if parent
== null then
158 return parent
.property_readable
(name
)
162 redef fun property_writable
(name
) 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
) 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
, value
) 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
) do
219 redef fun parse_file
(system_id
) do
220 var source
= new InputSource
222 source
.system_id
= system_id
227 ############################################################################
230 redef fun resolve_entity
(public_id
, system_id
) do
231 if entity_resolver
== null then
234 return entity_resolver
.resolve_entity
(public_id
, system_id
)
239 ############################################################################
242 redef fun notation_decl
(name
, public_id
, system_id
) do
243 if dtd_handler
!= null then
244 dtd_handler
.notation_decl
(name
, public_id
, system_id
)
248 redef fun unparsed_entity_decl
(name
, public_id
, system_id
) do
249 if dtd_handler
!= null then
250 dtd_handler
.unparsed_entity_decl
(name
, public_id
, system_id
)
255 ############################################################################
258 redef fun document_locator
=(locator
) do
259 if content_handler
!= null then
260 content_handler
.document_locator
= locator
264 redef fun start_document
do
265 if content_handler
!= null then
266 content_handler
.start_document
270 redef fun end_document
do
271 if content_handler
!= null then
272 content_handler
.end_document
276 redef fun start_prefix_mapping
(prefix
, uri
) do
277 if content_handler
!= null then
278 content_handler
.start_prefix_mapping
(prefix
, uri
)
282 redef fun end_prefix_mapping
(prefix
) do
283 if content_handler
!= null then
284 content_handler
.end_prefix_mapping
(prefix
)
288 redef fun start_element
(uri
, local_name
, qname
, atts
) do
289 if content_handler
!= null then
290 content_handler
.start_element
(uri
, local_name
, qname
, atts
)
294 redef fun end_element
(uri
, local_name
, qname
) do
295 if content_handler
!= null then
296 content_handler
.end_element
(uri
, local_name
, qname
)
300 redef fun characters
(str
) do
301 if content_handler
!= null then
302 content_handler
.characters
(str
)
306 redef fun ignorable_whitespace
(str
) do
307 if content_handler
!= null then
308 content_handler
.ignorable_whitespace
(str
)
312 redef fun processing_instruction
(target
, data
) do
313 if content_handler
!= null then
314 content_handler
.processing_instruction
(target
, data
)
318 redef fun skipped_entity
(name
) do
319 if content_handler
!= null then
320 content_handler
.skipped_entity
(name
)
325 ############################################################################
328 redef fun warning
(exception
) do
329 if error_handler
!= null then
330 error_handler
.warning
(exception
)
334 redef fun error
(exception
) do
335 if error_handler
!= null then
336 error_handler
.error
(exception
)
340 redef fun fatal_error
(exception
) do
341 if error_handler
!= null then
342 error_handler
.fatal_error
(exception
)
348 ############################################################################
351 # Set up before a parse.
353 # Before every parse, check whether the parent is
354 # non-null, and re-register the filter for all of the
356 private fun setup_parse
do
357 assert parent_is_not_null
: parent
!= 0 else
358 sys
.stderr
.write
("No parent for filter.")
360 parent
.entity_resolver
= self
361 parent
.dtd_handler
= self
362 parent
.content_handler
= self
363 parent
.error_handler
= self