File Coverage

blib/lib/Catmandu/Store/FedoraCommons/DC.pm
Criterion Covered Total %
statement 4 6 66.6
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 6 8 75.0


line stmt bran cond sub pod time code
1             package Catmandu::Store::FedoraCommons::DC;
2              
3 1     1   111491 use Moo;
  1         10905  
  1         6  
4 1     1   1436 use XML::LibXML;
  0            
  0            
5             use Data::Validate::Type qw(:boolean_tests);
6              
7             has fedora => (is => 'ro' , required => 1);
8              
9             # REQUIRED METHODS FOR A MODEL
10              
11             sub get {
12             my ($self,$pid) = @_;
13            
14             return undef unless $pid;
15            
16             my $res = $self->fedora->getDatastreamDissemination( pid => $pid , dsID => 'DC');
17            
18             return undef unless $res->is_ok;
19            
20             my $data = $res->parse_content;
21             my $perl = $self->deserialize($data);
22            
23             { _id => $pid , %$perl };
24             }
25              
26             sub update {
27             my ($self,$obj) = @_;
28             my $pid = $obj->{_id};
29              
30             return undef unless $pid;
31            
32             my ($valid,$reason) = $self->valid($obj);
33            
34             unless ($valid) {
35             warn "data is not valid";
36             return undef;
37             }
38            
39             my $xml = $self->serialize($obj);
40             my $result = $self->fedora->modifyDatastream( pid => $pid , dsID => 'DC', xml => $xml);
41              
42             return $result->is_ok;
43             }
44              
45             # HELPER METHODS
46              
47             # Die fast data validator
48             sub valid {
49             my ($self,$perl) = @_;
50            
51             unless (is_hashref($perl)) {
52             return wantarray ? (0, "not a HASH ref") : undef ;
53             }
54            
55             unless (Data::Validate::Type::filter_hashref($perl, allow_empty => 0)) {
56             return wantarray ? (0, "empty HASH ref") : undef;
57             }
58            
59             my $found = undef;
60            
61             for my $key (keys %$perl) {
62             my $value = $perl->{$key};
63            
64             next if $key eq '_id';
65            
66             unless ($key =~ m{^(contributor|coverage|creator|date|description|format|identifier|language|publisher|relation|rights|source|subject|title|type)$}) {
67             return wantarray ? (0, "unknown field $key") : undef;
68             }
69            
70             unless (is_arrayref($value)) {
71             return wantarray ? (0, "field $key isn't an ARRAY") : undef;
72             }
73            
74             for my $value_str (@$value) {
75             unless (is_string($value_str)) {
76             return wantarray ? (0, "field $key value isn't a string") : undef;
77             }
78             }
79            
80             $found = 1;
81             }
82            
83             unless (defined $found) {
84             return wantarray ? (0, "need at least one field") : undef;
85             }
86            
87             return wantarray ? (1,"ok") : 1;
88             }
89              
90             sub serialize {
91             my ($self,$perl) = @_;
92             my $dom = XML::LibXML::Document->new( '1.0', 'UTF-8' );
93             my $dc = $dom->createElementNS('http://www.openarchives.org/OAI/2.0/oai_dc/','oai_dc:dc');
94             $dom->setDocumentElement($dc);
95            
96             for my $dc_elem (qw(contributor coverage creator date description format identifier language publisher relation rights source subject title type)) {
97            
98             next unless (exists $perl->{$dc_elem} && ref $perl->{$dc_elem} eq 'ARRAY');
99            
100             for my $dc_value (@{$perl->{$dc_elem}}) {
101             my $node = $dom->createElementNS('http://purl.org/dc/elements/1.1/',"dc:$dc_elem");
102             $node->appendTextNode($dc_value);
103             $dc->appendChild($node);
104             }
105             }
106            
107             my $xml = $dom->toString(2);
108            
109             $xml =~ s{<\?[^>]+\?>}{};
110            
111             return $xml;
112             }
113              
114             sub deserialize {
115             my ($self,$xml) = @_;
116             my $dom = XML::LibXML->load_xml(string => $xml);
117             my $xc = XML::LibXML::XPathContext->new( $dom );
118             $xc->registerNs('oai_dc','http://www.openarchives.org/OAI/2.0/oai_dc/');
119             $xc->registerNs('dc','http://purl.org/dc/elements/1.1/');
120            
121             my $result = {};
122             my @nodes = $xc->findnodes("//oai_dc:dc/*");
123            
124             for my $node (@nodes) {
125             my $name = $node->nodeName;
126             my $value = $node->textContent;
127            
128             $name =~ s/\w+://;
129            
130             push @{ $result->{$name} } , $value;
131             }
132            
133             return $result;
134             }
135              
136             1;