/[suikacvs]/messaging/manakai/lib/Message/Markup/XML/Error.pm
Suika

Contents of /messaging/manakai/lib/Message/Markup/XML/Error.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.13 - (hide annotations) (download)
Sat Sep 13 09:04:02 2003 UTC (22 years, 10 months ago) by wakaba
Branch: MAIN
Changes since 1.12: +13 -7 lines
Bug fix

1 wakaba 1.1
2     =head1 NAME
3    
4 wakaba 1.12 Message::Markup::XML::Error --- manakai: Error handling module for Message::Markup::XML::*
5 wakaba 1.1
6     =head1 DESCRIPTION
7    
8 wakaba 1.3 This module provides the common error and/or warning handling interface
9 wakaba 1.12 for the Message::Markup::XML::* modules. With this module, proper error
10 wakaba 1.3 recovering and proper message outputing (eg. output as HTML element,
11     localized message, etc.) is easily implementable.
12    
13 wakaba 1.12 This module is part of manakai.
14 wakaba 1.1
15     =cut
16    
17 wakaba 1.12 package Message::Markup::XML::Error;
18 wakaba 1.1 use strict;
19 wakaba 1.13 our $VERSION = do{my @r=(q$Revision: 1.12 $=~/\d+/g);sprintf "%d."."%02d" x $#r,@r};
20 wakaba 1.6 our %NS;
21 wakaba 1.12 *NS = \%Message::Markup::XML::NS;
22 wakaba 1.3
23     ## Prefixes:
24     ## - 'SYNTAX_': don't match with XML 1.0 EBNF rules
25     ## - 'WFC_': violation of well-formedness constraint (fatal error)
26     ## - 'VC_': violation of validity constraint (error)
27     ## - 'NC_': violation of namespace constraint (error)
28     ## - 'NS_SYNTAX_': don't match with XML Namespace 1.0 EBNF rules (error)
29     ## - 'FATAL_ERR_': fatal error specified by XML 1.0 spec
30     ## - 'ERR_': error specified by XML 1.0 spec
31     ## - 'WARN_': don't fullfil XML spec's or implementor's recommendation
32    
33     ## Error levels:
34     ## - wfc: well-formedness (including syntax error)
35     ## - vc: validity
36     ## - nswfc: namespace well-formedness
37     ## - nsvc: namespace validity
38     ## - fatal: fatal error
39     ## - warn: warning
40 wakaba 1.1
41     my %_Error = (
42 wakaba 1.3 ## Forward compatibility error
43     SYNTAX_UNSUPPORTED_XML_VERSION => {
44     description => 'Unsupported XML version (%s)',
45     level => 'wfc',
46     },
47 wakaba 1.1 ## Syntax errors
48 w 1.7 SYNTAX_ATTLIST_ATTDEF_FIXED_NO_LITERAL => {
49     description => 'Fixed default value for the attribute (%s) is expected (%s)',
50     level => 'wfc',
51     },
52     SYNTAX_ATTLIST_ATTDEF_GROUP_INVALID_CHAR => {
53     description => 'Character "%s" cannot be used in group',
54     level => 'wfc',
55     },
56     SYNTAX_ATTLIST_ATTDEF_GROUP_INVALID_CONNECTOR => {
57     description => 'Invalid use of connector',
58     level => 'wfc',
59     },
60     SYNTAX_ATTLIST_ATTDEF_GROUP_NOTATION_NAME => {
61     description => 'Group element must be a notation Name (%s)',
62     level => 'wfc',
63     },
64     SYNTAX_ATTLIST_ATTDEF_NESTED_GROUP => {
65     description => 'Group cannot nest here',
66     level => 'wfc',
67     },
68     SYNTAX_ATTLIST_ATTDEF_NON_BAR_CONNECTOR => {
69     description => 'Connector of group elements in AttDef must be a VERTICAL BAR (|) in XML',
70     level => 'wfc',
71     },
72     SYNTAX_ATTLIST_ATTDEF_UNKNOWN_DEFAULT => {
73     description => 'Unknown attribute default type (#%s)',
74     level => 'wfc',
75     },
76     SYNTAX_ATTLIST_ATTDEF_UNKNOWN_TYPE => {
77     description => 'Unknown attribute type (%s)',
78     level => 'wfc',
79     },
80 wakaba 1.5 SYNTAX_ATTR_LITERAL_NOT_FOUND => {
81     description => 'Attribute value literal of the attribute (name = %s) is expected',
82     level => 'wfc',
83     },
84     SYNTAX_ATTR_NAME_OMITTED => {
85     description => 'Attribute name corresponding to the value (%s) must be specified in XML',
86     level => 'wfc',
87     },
88 wakaba 1.1 SYNTAX_DATA_OUT_OF_ROOT_ELEMENT => {
89     description => 'Invalid data or markup out of root element',
90     level => 'wfc',
91     },
92 wakaba 1.4 SYNTAX_DOCTYPE_NAME_NOT_FOUND => {
93     description => 'Document type name must be specified in the document type declaration',
94     level => 'wfc',
95     },
96     SYNTAX_DOCTYPE_PID_LITERAL_NOT_FOUND => {
97     description => 'Minimum literal for the public identifier must follow the keyword PUBLIC',
98     level => 'wfc',
99     },
100     SYNTAX_DOCTYPE_SYSID_LITERAL_NOT_FOUND => {
101     description => 'Literal of the system identifier must follow the keyword SYSTEM or the minimum literal of the public identifier in XML',
102     level => 'wfc',
103     },
104 w 1.7 SYNTAX_ELEMENT_CMODEL_GROUP_NOT_CLOSED => {
105     description => 'Content model group must be closed',
106     level => 'wfc',
107     },
108     SYNTAX_ELEMENT_CMODEL_INVALID_CONNECTOR => {
109     description => 'Invalid connector use (%s)',
110     level => 'wfc',
111     },
112     SYNTAX_ELEMENT_CMODEL_KWD_POSITION => {
113     description => 'Keyword (%s) cannot be wirtten here in XML',
114     level => 'wfc',
115     },
116     SYNTAX_ELEMENT_CMODEL_MIXED_NESTED => {
117     description => 'In mixed content model, group cannot nest',
118     level => 'wfc',
119     },
120     SYNTAX_ELEMENT_CMODEL_MIXED_OCCURENCE => {
121     description => 'In mixed content model (with one or more element), group must have occurence of "*"',
122     level => 'wfc',
123     },
124     SYNTAX_ELEMENT_CMODEL_NO_DELIMITER => {
125     description => 'Some kind of connector ("," / "|") is expected',
126     level => 'wfc',
127     },
128     SYNTAX_ELEMENT_CMODEL_PCDATA_CONNECTOR => {
129     description => 'Connector of mixed content model must be "|"',
130     level => 'wfc',
131     },
132     SYNTAX_ELEMENT_CMODEL_SAME_CONNECTOR => {
133     description => 'Connectors in a group must be all same one ("%s" rather than "%s" expected)',
134     level => 'wfc',
135     },
136     SYNTAX_ELEMENT_CMODEL_SGML_CONNECTOR => {
137     description => 'Connector "%s" cannot be used in XML',
138     level => 'wfc',
139     },
140     SYNTAX_ELEMENT_CMODEL_SGML_KWD => {
141     description => 'Content keyword "%s" cannot be used in XML',
142     level => 'wfc',
143     },
144     SYNTAX_ELEMENT_CMODEL_UNKNOWN_KWD => {
145     description => 'Unknown content keyword: "%s"',
146     level => 'wfc',
147     },
148 wakaba 1.1 SYNTAX_END_OF_MARKUP_NOT_FOUND => {
149     description => sub {
150     my ($o, $err) = @_;
151     my $o_start = $err->{t}->flag ('p_o_start');
152     my $r = $err->{t}->qname;
153     $r = sprintf 'line %d, position %d%s', $o_start->{line},
154     $o_start->{pos}, ($r ? '; '.$r : '') if ref $o_start;
155     $r ? $r = '; '.$r : 0;
156     $err->{t} = $err->{t}->node_type;
157     'Markup is not closed (%s'.$r.')';
158     },
159     level => 'wfc',
160     },
161     SYNTAX_END_TAG_NOT_FOUND => {
162     description => sub {
163     my ($o, $err) = @_;
164     my $o_start = $err->{t}->flag ('p_o_start');
165     my $r = '';
166     $r = sprintf 'line %d, position %d%s', $o_start->{line},
167     $o_start->{pos}, ($r ? '; '.$r : '') if ref $o_start;
168     $r ? $r = '; '.$r : 0;
169     $err->{t} = $err->{t}->qname;
170     'End tag of element (type = %s'.$r.') not found';
171     },
172     level => 'wfc',
173     },
174     SYNTAX_INVALID => {
175     description => 'This type of markup (%s) cannot appear here',
176     level => 'wfc',
177     },
178     SYNTAX_INVALID_CHAR => {
179     description => 'Invalid character (%s) at this context',
180     level => 'wfc',
181     },
182     SYNTAX_INVALID_DOCTYPE_POSITION => {
183     description => 'DOCTYPE declaration must be between xml declaration and the root element',
184     level => 'wfc',
185     },
186     SYNTAX_INVALID_KEYWORD => {
187     description => 'Invalid keyword (%s) at this context',
188     level => 'wfc',
189     },
190     SYNTAX_INVALID_LITERAL => {
191     description => 'Literal cannot be here ("%s")',
192     level => 'wfc',
193     },
194     SYNTAX_INVALID_MD => {
195     description => 'Invalid syntax of markup declaration',
196     level => 'wfc',
197     },
198     SYNTAX_INVALID_POSITION => {
199     description => sub {
200     my ($o) = shift;
201     'This type of markup (%s) cannot be used '.({
202     document_entity => 'out of DTD',
203     dtd_internal_subset => 'in the internal subset of DTD',
204     dtd_external_subset => 'in the external subset of DTD',
205     external_parsed_entity => 'in the external parsed entity',
206     general_external_parsed_entity => 'in the general external parsed entity',
207     }->{$o->{entity_type}||'document_entity'}||'in '.$o->{entity_type})},
208     level => 'wfc',
209     },
210 wakaba 1.3 SYNTAX_INVALID_PUBID => {
211     description => 'This public identifier contains at least one invalid character (%s)',
212     level => 'wfc',
213     },
214 wakaba 1.1 SYNTAX_LEGAL_CHARACTER => {
215     description => sub {
216     my $r = sprintf 'The character U-%08X is not a legal XML Char',
217     $_[1]->{t};
218     $_[1]->{t} = undef;
219     $r;
220     },
221     level => 'wfc',
222     },
223     SYNTAX_MD_NAME_NOT_FOUND => {
224     description => 'Name is required by this type of declaration',
225     level => 'wfc',
226     },
227     SYNTAX_MD_SYSID_NOT_FOUND => {
228     description => 'System identifier is required by this type of declaration',
229     level => 'wfc',
230     },
231 wakaba 1.4 SYNTAX_MS_IN_INTERNAL_SUBSET => {
232     description => 'Marked section cannot be used in the internal subset of the DTD in XML',
233     level => 'wfc',
234     },
235     SYNTAX_MS_INVALID_STATUS_STRING => {
236     description => 'Invalid string in the status keyword list',
237     level => 'wfc',
238     },
239     SYNTAX_MS_MULTIPLE_STATUS => {
240     description => 'Multiple status keyword (%s) cannot be used',
241     level => 'wfc',
242     },
243     SYNTAX_MS_NO_STATUS_KEYWORD => {
244     description => 'No status keyword found',
245     level => 'wfc',
246     },
247     SYNTAX_MS_NON_XML_STATUS => {
248     description => 'This status keyword (%s) cannot be used in XML',
249     level => 'wfc',
250     },
251     SYNTAX_MS_UNKNOWN_STATUS => {
252     description => 'Unknown status keyword (%s) is used',
253     level => 'wfc',
254     },
255 wakaba 1.1 SYNTAX_PE_NDATA => {
256     description => 'Parameter entity must be a parsed entity',
257     level => 'wfc',
258     },
259 wakaba 1.4 SYNTAX_ROOT_ELEMENT_NOT_FOUND => {
260     description => 'There is no root element (type = %s) in this document entity',
261     level => 'wfc',
262     },
263 wakaba 1.5 SYNTAX_TAG_NOT_CLOSED => {
264     description => 'Tag must be closed in XML',
265     level => 'wfc',
266     },
267 wakaba 1.1 SYNTAX_XML_DECLARE => {
268     description => 'Syntax of XML (or text) declaration is invalid',
269     level => 'wfc',
270     },
271     SYNTAX_XML_DECLARE_NO_ATTR => {
272 wakaba 1.3 description => 'XML (or text) declaration has no (valid) pseudo attribute',
273     level => 'wfc',
274     },
275     SYNTAX_XML_DECLARE_NO_ENCODING_ATTR => {
276     description => q(Text declaration must have 'encoding' pseudo attribute),
277     level => 'wfc',
278     },
279     SYNTAX_XML_DECLARE_NO_VERSION_ATTR => {
280     description => q(XML declaration must have 'version' pseudo attribute),
281 wakaba 1.1 level => 'wfc',
282     },
283     SYNTAX_XML_DECLARE_POSITION => {
284     description => 'XML declaration must be at the top of the entity',
285     level => 'wfc',
286     },
287 wakaba 1.3 SYNTAX_XML_DECLARE_STANDALONE_ATTR => {
288     description => q(Text declaration cannot have 'standalone' pseudo attribute),
289     level => 'wfc',
290     },
291 wakaba 1.1 ## Well-formedness error
292     WFC_ELEMENT_TYPE_MATCH => {
293     description => 'End tag (type = %s) does not match with start tag (type = %s)',
294     level => 'wfc',
295     },
296     WFC_ENTITY_DECLARED => {
297     description => 'Entity (%s) must be declared before it is referred',
298     level => 'wfc',
299     },
300     WFC_LEGAL_CHARACTER => {
301     description => sub {
302     my $r = sprintf 'The character referred (U-%08X) is not a legal XML Char',
303     $_[1]->{t};
304     $_[1]->{t} = undef;
305     $r;
306     },
307     level => 'wfc',
308     },
309     WFC_NO_EXTERNAL_ENTITY_REFERENCE => {
310     description => 'Attribute value must not contain reference to an external entity',
311     level => 'wfc',
312     },
313     WFC_NO_LE_IN_ATTRIBUTE_VALUE => {
314     description => 'Attribute value must not contain a less-than sign (<)',
315     level => 'wfc',
316     },
317     WFC_NO_RECURSION => {
318     description => 'Parsed entity (%s) must not contain a recursive reference to itself',
319     level => 'wfc',
320     },
321     WFC_NO_LT_IN_ATTRIBUTE_VALUE => {
322     description => 'Replacement text of entity reference in an attribute value literal cannot contain LESS-THAN SIGN (<) itself',
323     level => 'wfc',
324     },
325 wakaba 1.3 WFC_PARSED_ENTITY => {
326     description => 'Entity reference (%s) must not refer non-parsed entity',
327     level => 'wfc',
328     },
329 wakaba 1.1 WFC_PE_IN_INTERNAL_SUBSET => {
330     description => 'Parameter entity (%s) cannot be referred in markup declaration in internal subset of DTD',
331     level => 'wfc',
332     },
333     WFC_UNIQUE_ATT_SPEC => {
334     description => 'Dupulicate attribute specification',
335     level => 'wfc',
336     },
337 wakaba 1.3 FATAL_ERR_DECODE_IMPL_ERR => {
338     description => 'Decode error (%s)',
339     level => 'fatal',
340     },
341     FATAL_ERR_PREDEFINED_ENTITY => {
342 wakaba 1.4 description => 'Predefined entity (%s := %s) must be declared as of the XML specification defined',
343 wakaba 1.3 level => 'fatal',
344 wakaba 1.2 },
345 wakaba 1.1 ## Validity error
346     VC_ENTITY_DECLARED => {
347 w 1.9 description => 'Entity "%s" should (or must to be valid) be declared before it is referred',
348 wakaba 1.1 level => 'vc',
349     },
350 w 1.7 VC_NO_DUPLICATE_TOKENS => {
351 w 1.9 description => 'Group element ("%s") must be unique in the group',
352 w 1.7 level => 'vc',
353     },
354 w 1.9 VC_ROOT_ELEMENT_TYPE => {
355     description => 'Document type name ("%s") and element type name of the root element ("%s") should (or must to be valid) match',
356 wakaba 1.1 level => 'vc',
357     },
358 w 1.9 VC_UNIQUE_ELEMENT_TYPE_NAME => {
359     description => 'Element type "%s" is already declared',
360 wakaba 1.4 level => 'vc',
361     },
362 wakaba 1.1 VC_UNIQUE_NOTATION_NAME => {
363 w 1.9 description => 'Notation "%s" is already declared',
364     level => 'vc',
365 wakaba 1.1 },
366     ## Namespace well-formedness error
367 wakaba 1.5 NS_SYNTAX_LNAME_IS_NCNAME => {
368 w 1.9 description => 'Character just after the colon (":") in QName ("%s") must be one of NameStartChar in namespaced XML document',
369 wakaba 1.5 level => 'nswfc',
370     },
371 wakaba 1.1 NC_PREFIX_NOT_DEFINED => {
372 w 1.9 description => 'Undeclared namespace prefix "%s" is used',
373 wakaba 1.1 level => 'nswfc',
374     },
375     NS_SYNTAX_NAME_IS_NCNAME => {
376 w 1.9 description => 'Name with colon ("%s") cannot be used here in namespaced XML document',
377 wakaba 1.1 level => 'nswfc',
378     },
379 wakaba 1.5 NS_SYNTAX_NAME_IS_QNAME => {
380 w 1.9 description => 'Name with colon ("%s") must match with QName in namespaced XML document',
381 wakaba 1.5 level => 'nswfc',
382     },
383     NC_UNIQUE_ATT_SPEC => {
384 w 1.9 description => 'Dupulicate attribute specification ("%s" == "<%s>:%s")',
385 wakaba 1.5 level => 'wfc',
386     },
387 wakaba 1.1 ## Namespace validity error
388 wakaba 1.4 ## XML (non-fatal) error
389 wakaba 1.3 ERR_EXT_ENTITY_NOT_FOUND => {
390 w 1.9 description => 'External entity ("%s" == <%s>) cannot be retrived (%s)',
391 wakaba 1.3 level => 'vc',
392     },
393 wakaba 1.4 ERR_XML_NDATA_REF_IN_ENTITY_VALUE => {
394 w 1.9 description => 'Unparsed entity "%s" cannot be referred in EntityValue',
395 wakaba 1.4 level => 'warn', ## Was fatal error but refined by SE Errata
396     },
397     ERR_XML_SYSID_HAS_FRAGMENT => {
398 w 1.9 description => 'URI Reference converted from system identifier should not have the fragment identifier <%s>',
399 wakaba 1.3 level => 'warn',
400     },
401 wakaba 1.4 ## XML warning
402 wakaba 1.1 WARN_PREDEFINED_ENTITY_NOT_DECLARED => {
403 w 1.9 description => 'Predefined general entity "%s" should be declared before it is referred for interoperability',
404 wakaba 1.1 level => 'warn',
405     },
406     WARN_UNICODE_COMPAT_CHARACTER => {
407     description => sub {
408 w 1.7 my $r = sprintf 'Use of the character U+%04X is deprecated, since it is classified to compatible character in the Unicode Standard',
409 wakaba 1.1 $_[1]->{t};
410     $_[1]->{t} = undef;
411     $r;
412     },
413     level => 'warn',
414     },
415     WARN_UNICODE_NONCHARACTER => {
416     description => sub {
417 w 1.9 my $r = sprintf 'Use of the code point U+%04X is deprecated, since it is noncharacter or control character in the Unicode Standard',
418 wakaba 1.1 $_[1]->{t};
419     $_[1]->{t} = undef;
420     $r;
421     },
422     level => 'warn',
423     },
424     WARN_UNIQUE_ENTITY_NAME => {
425 w 1.9 description => 'General entity "%s" is already declared',
426 wakaba 1.1 level => 'warn',
427     },
428     WARN_UNIQUE_PARAMETER_ENTITY_NAME => {
429 w 1.9 description => 'Parameter entity "%s" is already declared',
430     level => 'warn',
431     },
432     WARN_XML_ATTLIST_AT_LEAST_ONE_ATTR_DEF => {
433     description => 'For interoperability, at least one definition should be provided in an attlist declaration (element type = "%s")',
434 wakaba 1.1 level => 'warn',
435     },
436 w 1.7 WARN_XML_ATTLIST_AT_MOST_ONE_ATTR_DEF => {
437 w 1.9 description => 'For interoperability, at most one definition for given attribute ("%s") should be provided',
438     level => 'warn',
439     },
440     WARN_XML_ATTLIST_AT_MOST_ONE_DECLARATION => {
441     description => 'For interoperability, at most one declaration for given element type ("%s") should be provided',
442 w 1.7 level => 'warn',
443     },
444 w 1.8 ## XML Names recommendation
445 wakaba 1.5 WARN_XML_NS_URI_IS_RELATIVE => {
446     description => 'URI of XML Namespace name is a relative URI',
447     level => 'warn',
448     },
449 w 1.8 WARN_XMLNAMES_EXTERNAL_NS_ATTR => {
450     description => 'Namespace declaration attribute ("%s" := <%s>) should be specified explicily in the start tag of element or default-declared in early part of internal subset',
451     level => 'warn',
452     },
453 wakaba 1.3 ## RFC 3023 'SHOULD'
454     WARN_MT_DTD_EXTERNAL_SUBSET => {
455     description => q(Media type "application/xml-dtd" SHOULD be used for the external subset of the DTD or the external parameter entity),
456     level => 'warn',
457     },
458     WARN_MT_EXTERNAL_GENERAL_PARSED_ENTITY => {
459     description => q(Media type "application/xml-external-parsed-entity" SHOULD be used for the external general parsed entity),
460     level => 'warn',
461     },
462     WARN_MT_XML_FOR_EXT_GENERAL_ENTITY => {
463     description => 'Using media type %s for external general parsed entity is now forbidden unless the entity is also well-formed as a document entity',
464     level => 'warn',
465     },
466 w 1.7 ## Misc. XML related spec's warning
467     WARN_UNICODE_XML_NOT_SUITABLE_CHARACTER => {
468     description => sub {
469     my $r = sprintf 'Use of the character U+%04X is deprecated by W3C Note unicode-xml',
470     $_[1]->{t};
471     $_[1]->{t} = undef;
472     $r;
473     },
474     level => 'warn',
475     },
476 wakaba 1.1 ## Implementation's warning
477 w 1.8 WARN_ATTLIST_DECLARATION_NOT_PROCESSED => {
478     description => 'This attlist declaration is not processed because unread parameter entity is referred before this declaration',
479     level => 'warn',
480     },
481 wakaba 1.4 WARN_DOCTYPE_NOT_FOUND => {
482     description => 'No document type definition provided for this document',
483     level => 'warn',
484     },
485     WARN_ENTITY_DECLARATION_NOT_PROCESSED => {
486     description => 'This entity declaration is not processed because unread parameter entity is referred before this declaration',
487     level => 'warn',
488     },
489 w 1.8 WARN_EXTERNAL_DEFAULT_ATTR => {
490     description => 'Attribute default value of "%s" is declared in external entity or declared after reference to external entity is occurred so non-validating processor may generate different groove',
491     level => 'warn',
492     },
493 wakaba 1.4 WARN_EXTERNALLY_DEFINED_ENTITY_REFERRED => {
494 w 1.8 description => 'The entity referred (%s) is declared in the external entity, so or declared after reference to external entity is occurred so non-validating processor may generate different groove',
495 wakaba 1.4 level => 'warn',
496     },
497 wakaba 1.3 WARN_GUESS_ENCODING_IMPL_ERR => {
498     description => 'Guessing encoding procedure cause some error (%s)',
499     level => 'warn',
500     },
501 wakaba 1.5 WARN_INVALID_URI_CHAR_IN_NS_NAME => {
502     description => 'URI of XML Namespace name contains at least one non-URI character',
503     level => 'warn',
504     },
505 wakaba 1.3 WARN_INVALID_URI_CHAR_IN_SYSID => {
506     description => 'System identifier has at least one character that is invalid as part of URI Reference (%s)',
507     level => 'warn',
508     },
509     WARN_MT_TEXT_XML => {
510     description => q(In many case, labeling with the media type "text/xml" is inappropriate. Use "application/xml" or markup language specified type instead),
511     level => 'warn',
512     },
513     WARN_MT_TEXT_XML_EXTERNAL_PARSED_ENTITY => {
514     description => q(In many case, labeling with the media type "text/xml-external-parsed-entity" is inappropriate. Use "application/xml-external-parsed-entity" instead),
515     level => 'warn',
516     },
517     WARN_NO_CHARSET_PARAM => { ## charset parameter is optional
518     description => 'Charset parameter should be specified (%s)',
519     level => 'warn',
520     },
521     WARN_NO_CHARSET_PARAM_FOR_TEXT => { ## charset parameter have default value of ascii
522     description => q(Charset parameter is not specified, so default value 'us-ascii' is assumed (%s)),
523     level => 'warn',
524     },
525     WARN_NO_EXPLICIT_ENCODING_INFO => { ## BOM and '<?' guessing is failed (so general encoding guess is to be called)
526     description => q(Neither upper level protocol nor XML's encoding declaration provide encoding scheme information (or cannot read the encoding declaration because of lack of guessability)),
527     level => 'warn',
528     },
529 wakaba 1.4 WARN_PID_EMPTY => {
530     description => 'Public identifier is empty',
531     level => 'warn',
532     },
533 wakaba 1.3 WARN_PID_IS_INVALID_URN => {
534     description => 'Public identifier (%s) seems an invalid URN',
535     level => 'warn',
536     },
537     WARN_PID_IS_NOT_FPI_NOR_URN => {
538     description => 'Public identifier (%s) should be a formal public identifier or a uniform resource name to ensure interoperability',
539     level => 'warn',
540     },
541     WARN_PID_IS_TOO_LONG => {
542     description => 'Public identifier (%s) should be shorter for interoperability',
543     level => 'warn',
544     },
545     WARN_PID_IS_URN_WITH_RESERVED_CHAR => {
546     description => 'Public identifier (%s) seems a URN and it contains one or more reserved character ("/" and/or "?") which should not be used',
547     level => 'warn',
548     },
549 wakaba 1.4 WARN_SYSID_EMPTY => {
550     description => 'System identifier is empty, in most case it is wrong',
551     level => 'warn',
552     },
553 wakaba 1.3 WARN_XML_DECLARE_NO_VERSION_ATTR => {
554     description => 'Text declaration does not have the version pseudo attribute',
555     level => 'warn',
556     },
557 wakaba 1.13 ## Implementation message
558     MSG_EXTERNAL_DTD_SUBSET_USED => {
559     description => 'Alternative document type definition external subset (<%s>) is read instead of that declared by document instance',
560     level => 'warn',
561     },
562 wakaba 1.1 ## Misc
563     UNKNOWN => {
564     description => 'Unknown error',
565 wakaba 1.3 level => 'fatal',
566 wakaba 1.1 },
567     );
568 wakaba 1.6
569 wakaba 1.1 sub raise ($$%) {
570 wakaba 1.6 my ($caller, $o, %err) = @_;
571 wakaba 1.1 my $error_type = $_Error{$err{type}} || $_Error{UNKNOWN};
572     my $error_msg = ref $error_type->{description} ? &{$error_type->{description}} ($o, \%err)
573     : $error_type->{description};
574     my @err_msg;
575     ref $err{t} eq 'ARRAY' ? @err_msg = @{$err{t}} : defined $err{t} ? @err_msg = $err{t} : undef;
576     $error_msg .= ' (%s)' if scalar (@err_msg) && ($error_msg !~ /%s/);
577 wakaba 1.6 $error_msg = sprintf 'Entity %s <%s>: line %d position %d: '.$error_msg,
578 w 1.7 ($err{entity} || $o->{entity}
579     || {document_entity => '#document',
580     dtd_external_subset => '<!DOCTYPE>'}->{$o->{entity_type}}
581     || '##unknown'),
582 wakaba 1.6 $o->{uri}, $o->{line}, $o->{pos}, @err_msg;
583     my $resolver = $caller->option ('error_handler');
584     if (ref $resolver) {
585 wakaba 1.13 $resolver = &$resolver ($caller, $o, $error_type, $error_msg, {}); ## If returned false,
586     &_default_error_handler ($caller, $o, $error_type, $error_msg, {})
587 wakaba 1.6 if $resolver; ## don't call this.
588     } else {
589 wakaba 1.13 &_default_error_handler ($caller, $o, $error_type, $error_msg, {});
590 wakaba 1.6 }
591     }
592    
593     sub _default_error_handler ($$$$) {
594     my ($caller, $o, $error_type, $error_msg) = @_;
595     require Carp;
596 w 1.7 $Carp::CarpLevel = 1;
597 wakaba 1.6 if ({qw/fatal 1 wfc 1 nswfc 1/}->{$error_type->{level}}) {
598     Carp::croak ($error_msg);
599     } else {
600     Carp::carp ($error_msg);
601     }
602 w 1.7 $Carp::CarpLevel = 0;
603 wakaba 1.6 }
604    
605     =head1 ERROR REPORTING WITH NODE INFORMATION
606    
607     =over 4
608    
609 wakaba 1.12 =item $err = Message::Markup::XML::Error->new ({error definitions})
610 wakaba 1.6
611     Constructs new error reporting object. Hash reference to error definition list (like %_Error
612     defined in this module) must be specified as an argument.
613    
614     =cut
615    
616     sub new ($$) {
617     my $class = shift;
618     bless shift, $class;
619     }
620    
621     =item $err->raise_error ($node, %detail)
622    
623     Raises an error (or a warning, if defined so)
624    
625     =cut
626    
627     sub raise_error ($$%) {
628     my ($self, $node, %err) = @_;
629     my $error_type = $self->{$err{type}} || $self->{UNKNOWN};
630     my $error_msg = ref $error_type->{description} ? &{$error_type->{description}} ($node, \%err)
631     : $error_type->{description};
632     my @err_msg;
633     ref $err{t} eq 'ARRAY' ? @err_msg = @{$err{t}} : defined $err{t} ? @err_msg = $err{t} : undef;
634     $error_msg .= ' (%s)' if scalar (@err_msg) && ($error_msg !~ /%s/);
635 wakaba 1.1 $error_msg = sprintf $error_msg, @err_msg;
636 wakaba 1.6 $err{node_path} = $self->_get_node_path ($node) if $node;
637 wakaba 1.13 $err{raiser_type} = 'Message::Markup::XML::Validator';
638 wakaba 1.6
639     my $resolver = $self->{-error_handler};
640     if (ref $resolver) {
641     $resolver = &$resolver ($self, $node, $error_type, $error_msg, \%err); ## If returned false,
642     $self->_default_error_handler_2 ($node, $error_type, $error_msg, \%err)
643     if $resolver; ## don't call this.
644     } else {
645 wakaba 1.11 $self->_default_error_handler_2 ($node, $error_type, $error_msg, \%err);
646 wakaba 1.6 }
647     }
648    
649     sub _default_error_handler_2 ($$$$$) {
650     my ($self, $node, $error_type, $error_msg, $err) = @_;
651 wakaba 1.1 require Carp;
652 wakaba 1.6 $error_msg = $err->{node_path} . ': ' . $error_msg if $err->{node_path};
653     $error_msg = 'Document <'.$err->{uri}.'>: ' . $error_msg if $err->{uri};
654     if ({qw/fatal 1 nswfc 1/}->{$error_type->{level}}) {
655     Carp::croak ($error_msg);
656     } else {
657     Carp::carp ($error_msg);
658     }
659     }
660    
661     sub _get_node_path ($$) {
662     my ($self, $node) = @_;
663     my $nn = '';
664     my $nt = $node->node_type;
665     my $nnsuri = $node->namespace_uri;
666     my $nlname = $node->local_name;
667     if ($nt eq '#element') {
668     $nn = $node->qname
669     . $self->_get_node_position ($node, namespace_uri => $nnsuri, local_name => $nlname,
670     type => $nt);
671     } elsif ($nt eq '#attribute') {
672     $nn = '@' . $node->qname;
673     } elsif ($nt eq '#text' || $nt eq '#comment') {
674 w 1.10 $nn = substr ($nt, 1) . '()' . $self->_get_node_position ($node, type => $nt);
675 wakaba 1.6 } elsif ($nt eq '#pi') {
676 w 1.10 $nn = 'process-instruction("' . $nlname . '")'
677 wakaba 1.6 . $self->_get_node_position ($node, local_name => $nlname, type => $nt);
678     } elsif ($nt eq '#section') {
679     my $nstatus = $node->get_attribute ('status', make_new_node => 1)->inner_text||'INCLUDE';
680     $nn = 'smxe:section("'.$nstatus.'")'
681     . $self->_get_node_position ($node, status => $nstatus, type => $nt);
682     } elsif ($nt eq '#declaration') {
683     $nn = 'smxe:declaration('.
684     ({split /\s+/, qq/$NS{SGML}attlist "ATTLIST"
685     $NS{SGML}doctype "DOCTYPE"
686     $NS{SGML}element "ELEMENT"
687     $NS{SGML}entity "ENTITY"
688     $NS{SGML}notation "NOTATION"/}->{$nnsuri}||'smxe:ns("'.$nnsuri.'")')
689     .')' . $self->_get_node_position ($node, namespace_uri => $nnsuri,
690     local_name => $nlname, type => $nt);
691     } elsif ($nt eq '#reference') {
692     $nn = 'smxe:ref('.
693     ({split /\s+/, qq/$NS{SGML}char:ref "char"
694     $NS{SGML}char:ref:hex "char"
695     $NS{SGML}entity "general"
696     $NS{SGML}entity:parameter "parameter"/}->{$nnsuri}||'smxe:ns("'.$nnsuri.'")')
697     .($nlname ? ', "'.$nlname.'"':'')
698     .')' . $self->_get_node_position ($node, namespace_uri => $nnsuri,
699     local_name => $nlname, type => $nt);
700     } elsif ($nt eq '#document') {
701     $nn = '/';
702     } elsif ($nt eq '#fragment') {
703     $nn = 'smxe:fragment()' . $self->_get_node_position ($node, type => $nt);
704     } elsif ($nt eq '#xml') {
705     $nn = 'smxe:xml()' . $self->_get_node_position ($node, type => $nt);
706     } else {
707     $nn = 'smxe:x-unknown("'.$nt.'")' . $self->_get_node_position ($node, type => $nt);
708     }
709 wakaba 1.13 $nn = $self->_get_node_path ($node->parent_node) . '/' . $nn if ref $node->parent_node;
710 wakaba 1.6 $nn = substr ($nn, 1) if substr ($nn, 0, 2) eq '//';
711     $nn;
712     }
713    
714     sub _get_node_position ($$%) {
715     my ($self, $node, %prop) = @_;
716     my $node_str = overload::StrVal ($node);
717 wakaba 1.13 if (ref $node->parent_node) {
718 wakaba 1.6 my $i = 1;
719     for (@{$node->parent_node->child_nodes}) {
720     if ($node_str eq overload::StrVal ($_)) {
721     return '[smxe:position()='.$i.']';
722     } elsif (($prop{type} eq $_->node_type)
723     && (defined $prop{namespace_uri} ? ($prop{namespace_uri} eq $_->namespace_uri) : 1)
724     && (defined $prop{local_name} ? ($prop{local_name} eq $_->local_name) : 1)
725     && (defined $prop{status} ? ($prop{status} eq ($_->get_attribute
726     ('status', make_new_node => 1)->inner_text
727     || 'INCLUDE')) : 1)
728     ) {
729     $i++;
730     }
731     }
732     return '[smxe:error()]';
733     } else {
734     return '';
735     }
736 wakaba 1.1 }
737    
738     =head1 LICENSE
739    
740     Copyright 2003 Wakaba <[email protected]>
741    
742     This program is free software; you can redistribute it and/or
743     modify it under the same terms as Perl itself.
744    
745     =cut
746    
747 wakaba 1.13 1; # $Date: 2003/09/07 03:09:18 $

[email protected]
ViewVC Help
Powered by ViewVC 1.1.24