/[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.15 - (show annotations) (download)
Sat Oct 9 05:33:21 2004 UTC (21 years, 9 months ago) by wakaba
Branch: MAIN
CVS Tags: before-dis2-200411, manakai-release-0-3-2, manakai-release-0-3-1, manakai-release-0-4-0, manakai-200612, HEAD
Changes since 1.14: +4 -3 lines
Use empty string if URI is undef

1
2 =head1 NAME
3
4 Message::Markup::XML::Error --- manakai: Error handling module for Message::Markup::XML::*
5
6 =head1 DESCRIPTION
7
8 This module provides the common error and/or warning handling interface
9 for the Message::Markup::XML::* modules. With this module, proper error
10 recovering and proper message outputing (eg. output as HTML element,
11 localized message, etc.) is easily implementable.
12
13 This module is part of manakai.
14
15 =cut
16
17 package Message::Markup::XML::Error;
18 use strict;
19 our $VERSION = do{my @r=(q$Revision: 1.14 $=~/\d+/g);sprintf "%d."."%02d" x $#r,@r};
20 our %NS;
21 *NS = \%Message::Markup::XML::NS;
22
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
41 my %_Error = (
42 ## Forward compatibility error
43 SYNTAX_UNSUPPORTED_XML_VERSION => {
44 description => 'Unsupported XML version (%s)',
45 level => 'wfc',
46 },
47 ## Syntax errors
48 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 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 SYNTAX_DATA_OUT_OF_ROOT_ELEMENT => {
89 description => 'Invalid data or markup out of root element',
90 level => 'wfc',
91 },
92 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 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 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 SYNTAX_INVALID_PUBID => {
211 description => 'This public identifier contains at least one invalid character (%s)',
212 level => 'wfc',
213 },
214 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_COMMENT_COM_NOT_CLOSED => {
224 description => 'Comment must be terminated with com and mdc ("-->")',
225 level => 'wfc',
226 },
227 SYNTAX_MD_COMMENT_DECL_EMPTY => {
228 description => 'Empty comment declaration ("<!>") is not allowed in XML',
229 level => 'wfc',
230 },
231 SYNTAX_MD_COMMENT_DS => {
232 description => 'ds (whitespace) in comment declaration is not allowed in XML',
233 level => 'wfc',
234 },
235 SYNTAX_MD_COMMENT_MULTIPLE => {
236 description => 'Multiple comment is not allowed in XML',
237 level => 'wfc',
238 },
239 SYNTAX_MD_KWD_EXPECTED => {
240 description => 'Keyword, com ("--") or mso ("[") should follow the mdo ("<!%s")',
241 level => 'wfc',
242 },
243 SYNTAX_MD_NAME_NOT_FOUND => {
244 description => 'Name is required by this type of declaration',
245 level => 'wfc',
246 },
247 SYNTAX_MD_NOT_CLOSED => {
248 description => 'Markup declaration must be terminated with mdc (">")',
249 level => 'wfc',
250 },
251 SYNTAX_MD_SYSID_NOT_FOUND => {
252 description => 'System identifier is required by this type of declaration',
253 level => 'wfc',
254 },
255 SYNTAX_MD_UNKNOWN_KWD => {
256 description => 'Keyword of markup declaration ("%s") is not defined in XML',
257 level => 'wfc',
258 },
259 SYNTAX_MS_IN_INTERNAL_SUBSET => {
260 description => 'Marked section cannot be used in the internal subset of the DTD in XML',
261 level => 'wfc',
262 },
263 SYNTAX_MS_INVALID_STATUS_STRING => {
264 description => 'Invalid string in the status keyword list',
265 level => 'wfc',
266 },
267 SYNTAX_MS_MULTIPLE_STATUS => {
268 description => 'Multiple status keyword (%s) cannot be used',
269 level => 'wfc',
270 },
271 SYNTAX_MS_NO_STATUS_KEYWORD => {
272 description => 'No status keyword found',
273 level => 'wfc',
274 },
275 SYNTAX_MS_NON_XML_STATUS => {
276 description => 'This status keyword (%s) cannot be used in XML',
277 level => 'wfc',
278 },
279 SYNTAX_MS_UNKNOWN_STATUS => {
280 description => 'Unknown status keyword (%s) is used',
281 level => 'wfc',
282 },
283 SYNTAX_PE_NDATA => {
284 description => 'Parameter entity must be a parsed entity',
285 level => 'wfc',
286 },
287 SYNTAX_ROOT_ELEMENT_NOT_FOUND => {
288 description => 'There is no root element (type = %s) in this document entity',
289 level => 'wfc',
290 },
291 SYNTAX_TAG_NOT_CLOSED => {
292 description => 'Tag must be closed in XML',
293 level => 'wfc',
294 },
295 SYNTAX_XML_DECLARE => {
296 description => 'Syntax of XML (or text) declaration is invalid',
297 level => 'wfc',
298 },
299 SYNTAX_XML_DECLARE_NO_ATTR => {
300 description => 'XML (or text) declaration has no (valid) pseudo attribute',
301 level => 'wfc',
302 },
303 SYNTAX_XML_DECLARE_NO_ENCODING_ATTR => {
304 description => q(Text declaration must have 'encoding' pseudo attribute),
305 level => 'wfc',
306 },
307 SYNTAX_XML_DECLARE_NO_VERSION_ATTR => {
308 description => q(XML declaration must have 'version' pseudo attribute),
309 level => 'wfc',
310 },
311 SYNTAX_XML_DECLARE_POSITION => {
312 description => 'XML declaration must be at the top of the entity',
313 level => 'wfc',
314 },
315 SYNTAX_XML_DECLARE_STANDALONE_ATTR => {
316 description => q(Text declaration cannot have 'standalone' pseudo attribute),
317 level => 'wfc',
318 },
319 ## Well-formedness error
320 WFC_ELEMENT_TYPE_MATCH => {
321 description => 'End tag (type = %s) does not match with start tag (type = %s)',
322 level => 'wfc',
323 },
324 WFC_ENTITY_DECLARED => {
325 description => 'Entity (%s) must be declared before it is referred',
326 level => 'wfc',
327 },
328 WFC_LEGAL_CHARACTER => {
329 description => sub {
330 my $r = sprintf 'The character referred (U-%08X) is not a legal XML Char',
331 $_[1]->{t};
332 $_[1]->{t} = undef;
333 $r;
334 },
335 level => 'wfc',
336 },
337 WFC_NO_EXTERNAL_ENTITY_REFERENCE => {
338 description => 'Attribute value must not contain reference to an external entity',
339 level => 'wfc',
340 },
341 WFC_NO_LE_IN_ATTRIBUTE_VALUE => {
342 description => 'Attribute value must not contain a less-than sign (<)',
343 level => 'wfc',
344 },
345 WFC_NO_RECURSION => {
346 description => 'Parsed entity (%s) must not contain a recursive reference to itself',
347 level => 'wfc',
348 },
349 WFC_NO_LT_IN_ATTRIBUTE_VALUE => {
350 description => 'Replacement text of entity reference in an attribute value literal cannot contain LESS-THAN SIGN (<) itself',
351 level => 'wfc',
352 },
353 WFC_PARSED_ENTITY => {
354 description => 'Entity reference (%s) must not refer non-parsed entity',
355 level => 'wfc',
356 },
357 WFC_PE_IN_INTERNAL_SUBSET => {
358 description => 'Parameter entity (%s) cannot be referred in markup declaration in internal subset of DTD',
359 level => 'wfc',
360 },
361 WFC_UNIQUE_ATT_SPEC => {
362 description => 'Dupulicate attribute specification',
363 level => 'wfc',
364 },
365 FATAL_ERR_DECODE_IMPL_ERR => {
366 description => 'Decode error (%s)',
367 level => 'fatal',
368 },
369 FATAL_ERR_PREDEFINED_ENTITY => {
370 description => 'Predefined entity (%s := %s) must be declared as of the XML specification defined',
371 level => 'fatal',
372 },
373 ## Validity error
374 VC_ENTITY_DECLARED => {
375 description => 'Entity "%s" should (or must to be valid) be declared before it is referred',
376 level => 'vc',
377 },
378 VC_NO_DUPLICATE_TOKENS => {
379 description => 'Group element ("%s") must be unique in the group',
380 level => 'vc',
381 },
382 VC_ROOT_ELEMENT_TYPE => {
383 description => 'Document type name ("%s") and element type name of the root element ("%s") should (or must to be valid) match',
384 level => 'vc',
385 },
386 VC_UNIQUE_ELEMENT_TYPE_NAME => {
387 description => 'Element type "%s" is already declared',
388 level => 'vc',
389 },
390 VC_UNIQUE_NOTATION_NAME => {
391 description => 'Notation "%s" is already declared',
392 level => 'vc',
393 },
394 ## Namespace well-formedness error
395 NS_SYNTAX_LNAME_IS_NCNAME => {
396 description => 'Character just after the colon (":") in QName ("%s") must be one of NameStartChar in namespaced XML document',
397 level => 'nswfc',
398 },
399 NC_PREFIX_NOT_DEFINED => {
400 description => 'Undeclared namespace prefix "%s" is used',
401 level => 'nswfc',
402 },
403 NS_SYNTAX_NAME_IS_NCNAME => {
404 description => 'Name with colon ("%s") cannot be used here in namespaced XML document',
405 level => 'nswfc',
406 },
407 NS_SYNTAX_NAME_IS_QNAME => {
408 description => 'Name with colon ("%s") must match with QName in namespaced XML document',
409 level => 'nswfc',
410 },
411 NC_UNIQUE_ATT_SPEC => {
412 description => 'Dupulicate attribute specification ("%s" == "<%s>:%s")',
413 level => 'wfc',
414 },
415 ## Namespace validity error
416 ## XML (non-fatal) error
417 ERR_EXT_ENTITY_NOT_FOUND => {
418 description => 'External entity ("%s" == <%s>) cannot be retrived (%s)',
419 level => 'vc',
420 },
421 ERR_XML_NDATA_REF_IN_ENTITY_VALUE => {
422 description => 'Unparsed entity "%s" cannot be referred in EntityValue',
423 level => 'warn', ## Was fatal error but refined by SE Errata
424 },
425 ERR_XML_SYSID_HAS_FRAGMENT => {
426 description => 'URI Reference converted from system identifier should not have the fragment identifier <%s>',
427 level => 'warn',
428 },
429 ## XML warning
430 WARN_PREDEFINED_ENTITY_NOT_DECLARED => {
431 description => 'Predefined general entity "%s" should be declared before it is referred for interoperability',
432 level => 'warn',
433 },
434 WARN_UNICODE_COMPAT_CHARACTER => {
435 description => sub {
436 my $r = sprintf 'Use of the character U+%04X is deprecated, since it is classified to compatible character in the Unicode Standard',
437 $_[1]->{t};
438 $_[1]->{t} = undef;
439 $r;
440 },
441 level => 'warn',
442 },
443 WARN_UNICODE_NONCHARACTER => {
444 description => sub {
445 my $r = sprintf 'Use of the code point U+%04X is deprecated, since it is noncharacter or control character in the Unicode Standard',
446 $_[1]->{t};
447 $_[1]->{t} = undef;
448 $r;
449 },
450 level => 'warn',
451 },
452 WARN_UNIQUE_ENTITY_NAME => {
453 description => 'General entity "%s" is already declared',
454 level => 'warn',
455 },
456 WARN_UNIQUE_PARAMETER_ENTITY_NAME => {
457 description => 'Parameter entity "%s" is already declared',
458 level => 'warn',
459 },
460 WARN_XML_ATTLIST_AT_LEAST_ONE_ATTR_DEF => {
461 description => 'For interoperability, at least one definition should be provided in an attlist declaration (element type = "%s")',
462 level => 'warn',
463 },
464 WARN_XML_ATTLIST_AT_MOST_ONE_ATTR_DEF => {
465 description => 'For interoperability, at most one definition for given attribute ("%s") should be provided',
466 level => 'warn',
467 },
468 WARN_XML_ATTLIST_AT_MOST_ONE_DECLARATION => {
469 description => 'For interoperability, at most one declaration for given element type ("%s") should be provided',
470 level => 'warn',
471 },
472 ## XML Names recommendation
473 WARN_XML_NS_URI_IS_RELATIVE => {
474 description => 'URI of XML Namespace name is a relative URI',
475 level => 'warn',
476 },
477 WARN_XMLNAMES_EXTERNAL_NS_ATTR => {
478 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',
479 level => 'warn',
480 },
481 ## RFC 3023 'SHOULD'
482 WARN_MT_DTD_EXTERNAL_SUBSET => {
483 description => q(Media type "application/xml-dtd" SHOULD be used for the external subset of the DTD or the external parameter entity),
484 level => 'warn',
485 },
486 WARN_MT_EXTERNAL_GENERAL_PARSED_ENTITY => {
487 description => q(Media type "application/xml-external-parsed-entity" SHOULD be used for the external general parsed entity),
488 level => 'warn',
489 },
490 WARN_MT_XML_FOR_EXT_GENERAL_ENTITY => {
491 description => 'Using media type %s for external general parsed entity is now forbidden unless the entity is also well-formed as a document entity',
492 level => 'warn',
493 },
494 ## Misc. XML related spec's warning
495 WARN_UNICODE_XML_NOT_SUITABLE_CHARACTER => {
496 description => sub {
497 my $r = sprintf 'Use of the character U+%04X is deprecated by W3C Note unicode-xml',
498 $_[1]->{t};
499 $_[1]->{t} = undef;
500 $r;
501 },
502 level => 'warn',
503 },
504 ## Implementation's warning
505 WARN_ATTLIST_DECLARATION_NOT_PROCESSED => {
506 description => 'This attlist declaration is not processed because unread parameter entity is referred before this declaration',
507 level => 'warn',
508 },
509 WARN_DOCTYPE_NOT_FOUND => {
510 description => 'No document type definition provided for this document',
511 level => 'warn',
512 },
513 WARN_ENTITY_DECLARATION_NOT_PROCESSED => {
514 description => 'This entity declaration is not processed because unread parameter entity is referred before this declaration',
515 level => 'warn',
516 },
517 WARN_EXTERNAL_DEFAULT_ATTR => {
518 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',
519 level => 'warn',
520 },
521 WARN_EXTERNALLY_DEFINED_ENTITY_REFERRED => {
522 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',
523 level => 'warn',
524 },
525 WARN_GUESS_ENCODING_IMPL_ERR => {
526 description => 'Guessing encoding procedure cause some error (%s)',
527 level => 'warn',
528 },
529 WARN_INVALID_URI_CHAR_IN_NS_NAME => {
530 description => 'URI of XML Namespace name contains at least one non-URI character',
531 level => 'warn',
532 },
533 WARN_INVALID_URI_CHAR_IN_SYSID => {
534 description => 'System identifier has at least one character that is invalid as part of URI Reference (%s)',
535 level => 'warn',
536 },
537 WARN_MT_TEXT_XML => {
538 description => q(In many case, labeling with the media type "text/xml" is inappropriate. Use "application/xml" or markup language specified type instead),
539 level => 'warn',
540 },
541 WARN_MT_TEXT_XML_EXTERNAL_PARSED_ENTITY => {
542 description => q(In many case, labeling with the media type "text/xml-external-parsed-entity" is inappropriate. Use "application/xml-external-parsed-entity" instead),
543 level => 'warn',
544 },
545 WARN_NO_CHARSET_PARAM => { ## charset parameter is optional
546 description => 'Charset parameter should be specified (%s)',
547 level => 'warn',
548 },
549 WARN_NO_CHARSET_PARAM_FOR_TEXT => { ## charset parameter have default value of ascii
550 description => q(Charset parameter is not specified, so default value 'us-ascii' is assumed (%s)),
551 level => 'warn',
552 },
553 WARN_NO_EXPLICIT_ENCODING_INFO => { ## BOM and '<?' guessing is failed (so general encoding guess is to be called)
554 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)),
555 level => 'warn',
556 },
557 WARN_PID_EMPTY => {
558 description => 'Public identifier is empty',
559 level => 'warn',
560 },
561 WARN_PID_IS_INVALID_URN => {
562 description => 'Public identifier (%s) seems an invalid URN',
563 level => 'warn',
564 },
565 WARN_PID_IS_NOT_FPI_NOR_URN => {
566 description => 'Public identifier (%s) should be a formal public identifier or a uniform resource name to ensure interoperability',
567 level => 'warn',
568 },
569 WARN_PID_IS_TOO_LONG => {
570 description => 'Public identifier (%s) should be shorter for interoperability',
571 level => 'warn',
572 },
573 WARN_PID_IS_URN_WITH_RESERVED_CHAR => {
574 description => 'Public identifier (%s) seems a URN and it contains one or more reserved character ("/" and/or "?") which should not be used',
575 level => 'warn',
576 },
577 WARN_SYSID_EMPTY => {
578 description => 'System identifier is empty, in most case it is wrong',
579 level => 'warn',
580 },
581 WARN_XML_DECLARE_NO_VERSION_ATTR => {
582 description => 'Text declaration does not have the version pseudo attribute',
583 level => 'warn',
584 },
585 ## Implementation message
586 MSG_EXTERNAL_DTD_SUBSET_USED => {
587 description => 'Alternative document type definition external subset (<%s>) is read instead of that declared by document instance',
588 level => 'warn',
589 },
590 ## Misc
591 UNKNOWN => {
592 description => 'Unknown error',
593 level => 'fatal',
594 },
595 );
596
597 sub raise ($$%) {
598 my ($caller, $o, %err) = @_;
599 my $error_type = $_Error{$err{type}} || $_Error{UNKNOWN};
600 my $error_msg = ref $error_type->{description} ? &{$error_type->{description}} ($o, \%err)
601 : $error_type->{description};
602 my @err_msg;
603 ref $err{t} eq 'ARRAY' ? @err_msg = @{$err{t}} : defined $err{t} ? @err_msg = $err{t} : undef;
604 $error_msg .= ' (%s)' if scalar (@err_msg) && ($error_msg !~ /%s/);
605 $error_msg = sprintf 'Entity %s <%s>: line %d position %d: '.$error_msg,
606 ($err{entity} || $o->{entity}
607 || {document_entity => '#document',
608 dtd_external_subset => '<!DOCTYPE>'}->{$o->{entity_type}}
609 || '##unknown'),
610 defined $o->{uri} ? $o->{uri} : '',
611 $o->{line}, $o->{pos}, @err_msg;
612 my $resolver = $caller->option ('error_handler');
613 if (ref $resolver) {
614 $resolver = &$resolver ($caller, $o, $error_type, $error_msg, {}); ## If returned false,
615 &_default_error_handler ($caller, $o, $error_type, $error_msg, {})
616 if $resolver; ## don't call this.
617 } else {
618 &_default_error_handler ($caller, $o, $error_type, $error_msg, {});
619 }
620 }
621
622 sub _default_error_handler ($$$$) {
623 my ($caller, $o, $error_type, $error_msg) = @_;
624 require Carp;
625 $Carp::CarpLevel = 1;
626 if ({qw/fatal 1 wfc 1 nswfc 1/}->{$error_type->{level}}) {
627 Carp::croak ($error_msg);
628 } else {
629 Carp::carp ($error_msg);
630 }
631 $Carp::CarpLevel = 0;
632 }
633
634 =head1 ERROR REPORTING WITH NODE INFORMATION
635
636 =over 4
637
638 =item $err = Message::Markup::XML::Error->new ({error definitions})
639
640 Constructs new error reporting object. Hash reference to error definition list (like %_Error
641 defined in this module) must be specified as an argument.
642
643 =cut
644
645 sub new ($$) {
646 my $class = shift;
647 bless shift, $class;
648 }
649
650 =item $err->raise_error ($node, %detail)
651
652 Raises an error (or a warning, if defined so)
653
654 =cut
655
656 sub raise_error ($$%) {
657 my ($self, $node, %err) = @_;
658 my $error_type = $self->{$err{type}} || $self->{UNKNOWN};
659 my $error_msg = ref $error_type->{description} ? &{$error_type->{description}} ($node, \%err)
660 : $error_type->{description};
661 my @err_msg;
662 ref $err{t} eq 'ARRAY' ? @err_msg = @{$err{t}} : defined $err{t} ? @err_msg = $err{t} : undef;
663 $error_msg .= ' (%s)' if scalar (@err_msg) && ($error_msg !~ /%s/);
664 $error_msg = sprintf $error_msg, @err_msg;
665 $err{node_path} = $self->_get_node_path ($node) if $node;
666 $err{raiser_type} = 'Message::Markup::XML::Validator';
667
668 my $resolver = $self->{-error_handler};
669 if (ref $resolver) {
670 $resolver = &$resolver ($self, $node, $error_type, $error_msg, \%err); ## If returned false,
671 $self->_default_error_handler_2 ($node, $error_type, $error_msg, \%err)
672 if $resolver; ## don't call this.
673 } else {
674 $self->_default_error_handler_2 ($node, $error_type, $error_msg, \%err);
675 }
676 }
677
678 sub _default_error_handler_2 ($$$$$) {
679 my ($self, $node, $error_type, $error_msg, $err) = @_;
680 require Carp;
681 $error_msg = $err->{node_path} . ': ' . $error_msg if $err->{node_path};
682 $error_msg = 'Document <'.$err->{uri}.'>: ' . $error_msg if $err->{uri};
683 if ({qw/fatal 1 nswfc 1/}->{$error_type->{level}}) {
684 Carp::croak ($error_msg);
685 } else {
686 Carp::carp ($error_msg);
687 }
688 }
689
690 sub _get_node_path ($$) {
691 my ($self, $node) = @_;
692 my $nn = '';
693 my $nt = $node->node_type;
694 my $nnsuri = $node->namespace_uri;
695 my $nlname = $node->local_name;
696 if ($nt eq '#element') {
697 $nn = $node->qname
698 . $self->_get_node_position ($node, namespace_uri => $nnsuri, local_name => $nlname,
699 type => $nt);
700 } elsif ($nt eq '#attribute') {
701 $nn = '@' . $node->qname;
702 } elsif ($nt eq '#text' || $nt eq '#comment') {
703 $nn = substr ($nt, 1) . '()' . $self->_get_node_position ($node, type => $nt);
704 } elsif ($nt eq '#pi') {
705 $nn = 'process-instruction("' . $nlname . '")'
706 . $self->_get_node_position ($node, local_name => $nlname, type => $nt);
707 } elsif ($nt eq '#section') {
708 my $nstatus = $node->get_attribute ('status', make_new_node => 1)->inner_text||'INCLUDE';
709 $nn = 'smxe:section("'.$nstatus.'")'
710 . $self->_get_node_position ($node, status => $nstatus, type => $nt);
711 } elsif ($nt eq '#declaration') {
712 $nn = 'smxe:declaration('.
713 ({split /\s+/, qq/$NS{SGML}attlist "ATTLIST"
714 $NS{SGML}doctype "DOCTYPE"
715 $NS{SGML}element "ELEMENT"
716 $NS{SGML}entity "ENTITY"
717 $NS{SGML}notation "NOTATION"/}->{$nnsuri}||'smxe:ns("'.$nnsuri.'")')
718 .')' . $self->_get_node_position ($node, namespace_uri => $nnsuri,
719 local_name => $nlname, type => $nt);
720 } elsif ($nt eq '#reference') {
721 $nn = 'smxe:ref('.
722 ({split /\s+/, qq/$NS{SGML}char:ref "char"
723 $NS{SGML}char:ref:hex "char"
724 $NS{SGML}entity "general"
725 $NS{SGML}entity:parameter "parameter"/}->{$nnsuri}||'smxe:ns("'.$nnsuri.'")')
726 .($nlname ? ', "'.$nlname.'"':'')
727 .')' . $self->_get_node_position ($node, namespace_uri => $nnsuri,
728 local_name => $nlname, type => $nt);
729 } elsif ($nt eq '#document') {
730 $nn = '/';
731 } elsif ($nt eq '#fragment') {
732 $nn = 'smxe:fragment()' . $self->_get_node_position ($node, type => $nt);
733 } elsif ($nt eq '#xml') {
734 $nn = 'smxe:xml()' . $self->_get_node_position ($node, type => $nt);
735 } else {
736 $nn = 'smxe:x-unknown("'.$nt.'")' . $self->_get_node_position ($node, type => $nt);
737 }
738 $nn = $self->_get_node_path ($node->parent_node) . '/' . $nn if ref $node->parent_node;
739 $nn = substr ($nn, 1) if substr ($nn, 0, 2) eq '//';
740 $nn;
741 }
742
743 sub _get_node_position ($$%) {
744 my ($self, $node, %prop) = @_;
745 my $node_str = overload::StrVal ($node);
746 if (ref $node->parent_node) {
747 my $i = 1;
748 for (@{$node->parent_node->child_nodes}) {
749 if ($node_str eq overload::StrVal ($_)) {
750 return '[smxe:position()='.$i.']';
751 } elsif (($prop{type} eq $_->node_type)
752 && (defined $prop{namespace_uri} ? ($prop{namespace_uri} eq $_->namespace_uri) : 1)
753 && (defined $prop{local_name} ? ($prop{local_name} eq $_->local_name) : 1)
754 && (defined $prop{status} ? ($prop{status} eq ($_->get_attribute
755 ('status', make_new_node => 1)->inner_text
756 || 'INCLUDE')) : 1)
757 ) {
758 $i++;
759 }
760 }
761 return '[smxe:error()]';
762 } else {
763 return '';
764 }
765 }
766
767 =head1 LICENSE
768
769 Copyright 2003 Wakaba <[email protected]>
770
771 This program is free software; you can redistribute it and/or
772 modify it under the same terms as Perl itself.
773
774 =cut
775
776 1; # $Date: 2003/09/14 01:09:36 $

[email protected]
ViewVC Help
Powered by ViewVC 1.1.24