File Coverage

lib/Data/DublinCore.pm
Criterion Covered Total %
statement 12 12 100.0
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 16 16 100.0


line stmt bran cond sub pod time code
1             # Copyrights 2009-2015 by [Mark Overmeer].
2             # For other contributors see ChangeLog.
3             # See the manual pages for details on the licensing terms.
4             # Pod stripped from pm file by OODoc 2.01.
5 2     2   17421 use warnings;
  2         3  
  2         82  
6 2     2   10 use strict;
  2         4  
  2         79  
7              
8             package Data::DublinCore;
9 2     2   9 use vars '$VERSION';
  2         2  
  2         111  
10             $VERSION = '1.00';
11              
12 2     2   10 use base 'XML::Compile::Cache';
  2         3  
  2         857  
13             our $VERSION = '0.01';
14              
15             use Log::Report 'data-dublincore', syntax => 'SHORT';
16              
17             use XML::Compile::Util qw/type_of_node unpack_type pack_type SCHEMA2001/;
18             use XML::LibXML::Simple qw/XMLin/;
19             use Scalar::Util qw/weaken/;
20              
21              
22             use Data::DublinCore::Util;
23             use XML::Compile::Util qw/XMLNS/;
24              
25             # map namespace always to the newest implementation of the protocol
26             my $newest = '20080211';
27             my %ns2version = (&NS_DC_ELEMS11 => $newest);
28              
29             my %info =
30             ( 20020312 => {}
31             , 20021212 => {}
32             , 20030402 => {}
33             , 20060106 => {}
34             , 20080211 => {}
35             );
36              
37             # there are no other options yet
38             my @prefixes =
39             ( dc => NS_DC_ELEMS11
40             , dcterms => NS_DC_TERMS
41             , dcmi => NS_DC_DCMITYPE
42             , xml => XMLNS
43             );
44              
45             #----------------
46              
47              
48             sub new($)
49             { my $class = shift;
50             $class->SUPER::new(direction => 'RW', @_);
51             }
52              
53             sub init($)
54             { my ($self, $args) = @_;
55             $args->{allow_undeclared} = 1
56             unless exists $args->{allow_undeclared};
57              
58             my $r = $args->{opts_readers} ||= {};
59             $r = $args->{opts_readers} = +{ @$r } if ref $r eq 'ARRAY';
60              
61             $r->{mixed_elements} = 'XML_NODE';
62             my $s = $self;
63             weaken $s; # avoid memory leak
64             # $r->{mixed_elements} = sub { $s->_handle_any_type(@_) };
65             $r->{any_type} = sub { $s->_handle_any_type(@_) };
66             $args->{any_element} ||= 'ATTEMPT';
67              
68             $self->SUPER::init($args);
69              
70             my $version = $args->{version} || $newest;
71              
72             unless(exists $info{$version})
73             { exists $ns2version{$version}
74             or error __x"DC version {v} not recognized", v => $version;
75             $version = $ns2version{$version};
76             }
77             $self->{version} = $version;
78             my $info = $info{$version};
79              
80             $self->addPrefixes(@prefixes);
81             $self->addKeyRewrite('PREFIXED(dc,xml,dcterms)');
82              
83             (my $xsd = __FILE__) =~ s!\.pm!/xsd!;
84             my @xsds;
85             if($version lt 2003)
86             { @xsds = glob "$xsd/dc$version/*";
87             }
88             else
89             { @xsds = glob "$xsd/dc$version/{dcmitype,dcterms,dc}.xsd";
90              
91             # tricky... the application will load the following two,
92             # specifying the targetNamespace. Use with
93             # $self->importDefinitions('qualifieddc', target_namespace => );
94             $self->knownNamespace($_ => "$xsd/dc$version/$_.xsd")
95             for qw/qualifieddc simpledc/;
96             }
97              
98             $self->importDefinitions(\@xsds);
99             $self->importDefinitions(XMLNS);
100              
101             $self->addHook
102             ( action => 'READER'
103             , type => 'dc:SimpleLiteral'
104             , replace => sub { $self->_simple_literal(@_) }
105             );
106              
107             $self;
108             }
109              
110             sub _simple_literal($$$) # stupid mixed anytype
111             { my ($self, $node, $args, $path, $type, $r) = @_;
112             XMLin $node, ContentKey => '_';
113             }
114              
115              
116             # Business::XPDL shows how to create conversions here... but all
117             # DC versions are backwards compatible
118             sub from($@)
119             { my ($thing, $source, %args) = @_;
120              
121             my $xml = XML::Compile->dataToXML($source);
122             my $top = type_of_node $xml;
123             my ($ns, $topname) = unpack_type $top;
124             my $version = $ns2version{$ns}
125             or error __x"unknown DC version with namespace {ns}", ns => $ns;
126              
127             my $self = ref $thing ? $thing : $thing->new(version => $version);
128             my $r = $self->reader($top, %args)
129             or error __x"root node `{top}' not recognized", top => $top;
130              
131             ($top, $r->($xml));
132             }
133              
134              
135             sub version() {shift->{version}}
136             sub namespace() {shift->{namespace}}
137              
138             1;