File Coverage

inc/XML/SAX/ParserFactory.pm
Criterion Covered Total %
statement 47 75 62.6
branch 7 20 35.0
condition n/a
subroutine 10 11 90.9
pod 0 3 0.0
total 64 109 58.7


line stmt bran cond sub pod time code
1             #line 1
2             # $Id: ParserFactory.pm,v 1.13 2002/11/19 18:25:47 matt Exp $
3              
4             package XML::SAX::ParserFactory;
5 1     1   879  
  1         3  
  1         54  
6 1     1   6 use strict;
  1         2  
  1         64  
7             use vars qw($VERSION);
8              
9             $VERSION = '1.01';
10 1     1   1502  
  1         1378  
  1         322  
11 1     1   888 use Symbol qw(gensym);
  1         3  
  1         61  
12 1     1   12 use XML::SAX;
  1         2  
  1         937  
13             use XML::SAX::Exception;
14              
15 1     1 0 2 sub new {
16 1         10 my $class = shift;
17 1         3 my %params = @_; # TODO : Fix this in spec.
18 1         8 my $self = bless \%params, $class;
19 1         2 $self->{KnownParsers} = XML::SAX->parsers();
20             return $self;
21             }
22              
23 1     1 0 14 sub parser {
24 1         3 my $self = shift;
25 1 50       5 my @parser_params = @_;
26 1         6 if (!ref($self)) {
27             $self = $self->new();
28             }
29 1         5
30             my $parser_class = $self->_parser_class();
31 1         3  
32 1 50       5 my $version = '';
33 0         0 if ($parser_class =~ s/\s*\(([\d\.]+)\)\s*$//) {
34             $version = " $1";
35             }
36              
37 1     1   10 {
  1         2  
  1         1247  
  1         1  
38 1 50       2 no strict 'refs';
  1         8  
39 1     1   999 if (!keys %{"${parser_class}::"}) {
  1         16387  
  1         21  
  1         102  
40             eval "use $parser_class $version;";
41             }
42             }
43 1         14  
44             return $parser_class->new(@parser_params);
45             }
46              
47 0     0 0 0 sub require_feature {
48 0         0 my $self = shift;
49 0         0 my ($feature) = @_;
50 0         0 $self->{RequiredFeatures}{$feature}++;
51             return $self;
52             }
53              
54 1     1   1 sub _parser_class {
55             my $self = shift;
56              
57 1 50       5 # First try ParserPackage
58 0         0 if ($XML::SAX::ParserPackage) {
59             return $XML::SAX::ParserPackage;
60             }
61              
62 1 50       4 # Now check if required/preferred is there
63 0         0 if ($self->{RequiredFeatures}) {
  0         0  
64             my %required = %{$self->{RequiredFeatures}};
65             # note - we never go onto the next try (ParserDetails.ini),
66             # because if we can't provide the requested feature
67 0         0 # we need to throw an exception.
68 0         0 PARSER:
69 0         0 foreach my $parser (reverse @{$self->{KnownParsers}}) {
70 0 0       0 foreach my $feature (keys %required) {
71 0         0 if (!exists $parser->{Features}{$feature}) {
72             next PARSER;
73             }
74             }
75 0         0 # got here - all features must exist!
76             return $parser->{Name};
77             }
78             # TODO : should this be NotSupported() ?
79 0         0 throw XML::SAX::Exception (
80             Message => "Unable to provide required features",
81             );
82             }
83              
84 1         3 # Next try SAX.ini
85 12         25 for my $dir (@INC) {
86 12 50       393 my $fh = gensym();
87 0         0 if (open($fh, "$dir/SAX.ini")) {
88 0         0 my $param_list = XML::SAX->_parse_ini_file($fh);
89 0 0       0 my $params = $param_list->[0]->{Features};
90 0         0 if ($params->{ParserPackage}) {
91             return $params->{ParserPackage};
92             }
93             else {
94 0         0 # we have required features (or nothing?)
95 0         0 PARSER:
96 0         0 foreach my $parser (reverse @{$self->{KnownParsers}}) {
97 0 0       0 foreach my $feature (keys %$params) {
98 0         0 if (!exists $parser->{Features}{$feature}) {
99             next PARSER;
100             }
101 0         0 }
102             return $parser->{Name};
103 0         0 }
104             XML::SAX->do_warn("Unable to provide SAX.ini required features. Using fallback\n");
105 0         0 }
106             last; # stop after first INI found
107             }
108             }
109 1 50       2  
  1         5  
110 0         0 if (@{$self->{KnownParsers}}) {
111             return $self->{KnownParsers}[-1]{Name};
112             }
113 1         3 else {
114             return "XML::SAX::PurePerl"; # backup plan!
115             }
116             }
117              
118             1;
119             __END__