File Coverage

blib/lib/URI/urn.pm
Criterion Covered Total %
statement 58 71 81.6
branch 14 30 46.6
condition 1 6 16.6
subroutine 10 11 90.9
pod 1 3 33.3
total 84 121 69.4


line stmt bran cond sub pod time code
1             package URI::urn; # RFC 2141
2              
3 1     1   7 use strict;
  1         2  
  1         29  
4 1     1   5 use warnings;
  1         2  
  1         39  
5              
6             our $VERSION = '5.19';
7              
8 1     1   392 use parent 'URI';
  1         270  
  1         5  
9              
10 1     1   56 use Carp qw(carp);
  1         2  
  1         170  
11              
12             my %implementor;
13             my %require_attempted;
14              
15             sub _init {
16 1     1   2 my $class = shift;
17 1         6 my $self = $class->SUPER::_init(@_);
18 1         2 my $nid = $self->nid;
19              
20 1         2 my $impclass = $implementor{$nid};
21 1 50       2 return $impclass->_urn_init($self, $nid) if $impclass;
22              
23 1         2 $impclass = "URI::urn";
24 1 50       4 if ($nid =~ /^[A-Za-z\d][A-Za-z\d\-]*\z/) {
25 1         2 my $id = $nid;
26             # make it a legal perl identifier
27 1         2 $id =~ s/-/_/g;
28 1 50       3 $id = "_$id" if $id =~ /^\d/;
29              
30 1         2 $impclass = "URI::urn::$id";
31 1     1   7 no strict 'refs';
  1         2  
  1         621  
32 1 50       1 unless (@{"${impclass}::ISA"}) {
  1         8  
33 1 50       3 if (not exists $require_attempted{$impclass}) {
34             # Try to load it
35 1         2 my $_old_error = $@;
36 1         57 eval "require $impclass";
37 1 50 33     8 die $@ if $@ && $@ !~ /Can\'t locate.*in \@INC/;
38 1         3 $@ = $_old_error;
39             }
40 1 50       1 $impclass = "URI::urn" unless @{"${impclass}::ISA"};
  1         6  
41             }
42             }
43             else {
44 0 0       0 carp("Illegal namespace identifier '$nid' for URN '$self'") if $^W;
45             }
46 1         3 $implementor{$nid} = $impclass;
47              
48 1         7 return $impclass->_urn_init($self, $nid);
49             }
50              
51             sub _urn_init {
52 1     1   3 my($class, $self, $nid) = @_;
53 1         4 bless $self, $class;
54             }
55              
56             sub _nid {
57 2     2   4 my $self = shift;
58 2         6 my $opaque = $self->opaque;
59 2 50       5 if (@_) {
60 0         0 my $v = $opaque;
61 0         0 my $new = shift;
62 0         0 $v =~ s/[^:]*/$new/;
63 0         0 $self->opaque($v);
64             # XXX possible rebless
65             }
66 2         8 $opaque =~ s/:.*//s;
67 2         5 return $opaque;
68             }
69              
70             sub nid { # namespace identifier
71 2     2 0 8 my $self = shift;
72 2         5 my $nid = $self->_nid(@_);
73 2 50       5 $nid = lc($nid) if defined($nid);
74 2         6 return $nid;
75             }
76              
77             sub nss { # namespace specific string
78 5     5 0 8 my $self = shift;
79 5         13 my $opaque = $self->opaque;
80 5 100       12 if (@_) {
81 1         2 my $v = $opaque;
82 1         2 my $new = shift;
83 1 50       2 if (defined $new) {
84 1         8 $v =~ s/(:|\z).*/:$new/;
85             }
86             else {
87 0         0 $v =~ s/:.*//s;
88             }
89 1         3 $self->opaque($v);
90             }
91 5 100       23 return undef unless $opaque =~ s/^[^:]*://;
92 3         10 return $opaque;
93             }
94              
95             sub canonical {
96 0     0 1   my $self = shift;
97 0           my $nid = $self->_nid;
98 0           my $new = $self->SUPER::canonical;
99 0 0 0       return $new if $nid !~ /[A-Z]/ || $nid =~ /%/;
100 0 0         $new = $new->clone if $new == $self;
101 0           $new->nid(lc($nid));
102 0           return $new;
103             }
104              
105             1;