File Coverage

blib/lib/WebService/Cmis/AtomEntry.pm
Criterion Covered Total %
statement 10 12 83.3
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 14 16 87.5


line stmt bran cond sub pod time code
1             package WebService::Cmis::AtomEntry;
2              
3             =head1 NAME
4              
5             WebService::Cmis::AtomEntry - Representation of a cmis object
6              
7             =head1 DESCRIPTION
8              
9             Base class for entries in a L.
10              
11             Sub classes:
12              
13             =cut
14              
15 1     1   6511 use strict;
  1         2  
  1         39  
16 1     1   6 use warnings;
  1         2  
  1         34  
17 1     1   4 use WebService::Cmis qw(:namespaces :relations :contenttypes);
  1         2  
  1         315  
18 1     1   468 use XML::LibXML qw(:libxml);
  0            
  0            
19              
20             our $CMIS_XPATH_TITLE = new XML::LibXML::XPathExpression('./*[local-name() = "title" and namespace-uri() ="'.ATOM_NS.'"]');
21             our $CMIS_XPATH_UPDATED = new XML::LibXML::XPathExpression('./*[local-name() = "updated" and namespace-uri() ="'.ATOM_NS.'"]');
22             our $CMIS_XPATH_SUMMARY = new XML::LibXML::XPathExpression('./*[local-name() = "summary" and namespace-uri() ="'.ATOM_NS.'"]');
23             our $CMIS_XPATH_PUBLISHED = new XML::LibXML::XPathExpression('./*[local-name() = "published" and namespace-uri() ="'.ATOM_NS.'"]');
24             our $CMIS_XPATH_EDITED = new XML::LibXML::XPathExpression('./*[local-name() = "edited" and namespace-uri() ="'.APP_NS.'"]');
25             our $CMIS_XPATH_AUTHOR = new XML::LibXML::XPathExpression('./*[local-name() = "author" and namespace-uri() ="'.ATOM_NS.'"]');
26             our $CMIS_XPATH_ID = new XML::LibXML::XPathExpression('./*[local-name() = "id" and namespace-uri() ="'.ATOM_NS.'"]');
27              
28             =head1 METHODS
29              
30             =over 4
31              
32             =item new()
33              
34             =cut
35              
36             sub new {
37             my $class = shift;
38              
39             my $this = bless({ @_ }, $class);
40             $this->_initData;
41             return $this;
42             }
43              
44             =item _initData
45              
46             resets the internal cache of this entry.
47              
48             =cut
49              
50             sub _initData {
51             my $this = shift;
52              
53             $this->{name} = undef;
54             $this->{summary} = undef;
55             $this->{title} = undef;
56             $this->{published} = undef;
57             $this->{edited} = undef;
58             $this->{updated} = undef;
59             $this->{author} = undef;
60             }
61              
62             =item reload
63              
64             a plain AtomEntry has got no way to reload itself. that's only possible for
65             cmis objects comping from a repository.
66              
67             =cut
68              
69             sub reload {}
70              
71             =item _xmlDoc
72              
73             internal helper to make sure the xmlDoc is loaded.
74             don't use on plain AtomEntries without providing an xmlDoc to the constructor
75              
76             =cut
77              
78             sub _xmlDoc {
79             my $this = shift;
80              
81             $this->reload unless defined $this->{xmlDoc};
82              
83             unless (defined $this->{xmlDoc}) {
84             throw Error::Simple("Can't fetch xmlDoc, even though I tried to reload() this $this");
85             }
86              
87             return $this->{xmlDoc};
88             }
89              
90             =item _getDocumentElement -> $xmlNode
91              
92             returns the document element of the current xmlDoc or the xmlDoc
93             itself if this object is constructed using an element instead of a complete document.
94              
95             =cut
96              
97             sub _getDocumentElement {
98             my $xmlDoc = $_[0]->_xmlDoc;
99             return ($xmlDoc && $xmlDoc->isa("XML::LibXML::Document"))?$xmlDoc->documentElement:$xmlDoc;
100             }
101              
102             =item toString()
103              
104             return a string representation of this object
105              
106             =cut
107              
108             sub toString {
109             return $_[0]->getId;
110             }
111              
112             =item getId
113              
114             returns the unique ID of the change entry.
115              
116             =cut
117              
118             sub getId {
119             return $_[0]->{xmlDoc}->findvalue($CMIS_XPATH_ID);
120             }
121              
122              
123             =item getTitle -> $title
124              
125             returns the value of the object's atom:title property.
126              
127             =cut
128              
129             sub getTitle {
130             my $this = shift;
131              
132             unless (defined $this->{title}) {
133             $this->{title} = $this->_getDocumentElement->findvalue($CMIS_XPATH_TITLE);
134             }
135              
136             return $this->{title};
137             }
138              
139             =item getSummary -> $summary
140              
141             returns the value of the object's atom:summary property.
142              
143             =cut
144              
145             sub getSummary {
146             my $this = shift;
147              
148             unless ($this->{summary}) {
149             $this->{summary} = $this->_getDocumentElement->findvalue($CMIS_XPATH_SUMMARY);
150             }
151              
152             return $this->{summary};
153             }
154              
155             =item updateSummary($text) -> $this
156              
157             changes the atom:summary of this object
158              
159             Warning: some repos don't maintain the atom:summary field. As a consequence,
160             updateSummary() might fail with a C<400 Bad Request> error message. Try using
161             the dublin core's dc:description via L for that
162             instead.
163              
164             =cut
165              
166             sub updateSummary {
167             my ($this, $text) = @_;
168              
169             # get the self link
170             my $selfUrl = $this->getSelfLink;
171              
172             # build the entry based on the properties provided
173             my $xmlEntryDoc = $this->{repository}->createEntryXmlDoc(summary => $text);
174              
175             # do a PUT of the entry
176             my $result = $this->{repository}{client}->put($selfUrl, $xmlEntryDoc->toString, ATOM_XML_TYPE);
177              
178             # reset the xmlDoc for this object with what we got back from
179             # the PUT, then call initData we dont' want to call
180             # self.reload because we've already got the parsed XML--
181             # there's no need to fetch it again
182              
183             $this->{xmlDoc} = $result;
184             $this->_initData;
185              
186             return $this;
187             }
188              
189              
190             =item getUpdated -> $epoch
191              
192             returns the value of the object's atom:updated property.
193              
194             =cut
195              
196             sub getUpdated {
197             my $this = shift;
198              
199             unless ($this->{updated}) {
200             require WebService::Cmis::Property;
201             $this->{updated} = WebService::Cmis::Property::parseDateTime($this->_getDocumentElement->findvalue($CMIS_XPATH_UPDATED));
202             }
203              
204             return $this->{updated};
205             }
206              
207             =item getPublished -> $epoch
208              
209             returns the value of the object's atom:published property,
210              
211             =cut
212              
213             sub getPublished {
214             my $this = shift;
215              
216             unless ($this->{published}) {
217             require WebService::Cmis::Property;
218             $this->{published} = WebService::Cmis::Property::parseDateTime($this->_getDocumentElement->findvalue($CMIS_XPATH_PUBLISHED));
219             }
220              
221             return $this->{published};
222             }
223              
224             =item getEdited -> $epoch
225              
226             returns the value of the object's app:edited property,
227              
228             =cut
229              
230             sub getEdited {
231             my $this = shift;
232              
233             unless ($this->{edited}) {
234             require WebService::Cmis::Property;
235             $this->{edited} = WebService::Cmis::Property::parseDateTime($this->_getDocumentElement->findvalue($CMIS_XPATH_EDITED));
236             }
237              
238             return $this->{edited};
239             }
240              
241              
242             =item getAuthor -> $author
243              
244             returns the value of the object's atom:author property.
245              
246             =cut
247              
248             sub getAuthor {
249             my $this = shift;
250              
251             unless ($this->{author}) {
252             $this->{author} = $this->_getDocumentElement->findvalue($CMIS_XPATH_AUTHOR);
253             }
254              
255             return $this->{author};
256             }
257              
258             =item getLink($relation, $linkType) -> $href
259              
260             returns the href attribute of an Atom link element for the
261             specified relation.
262              
263             =cut
264              
265             sub getLink {
266             my ($this, $relation, $linkType, $dontReload) = @_;
267              
268             $relation = '*' unless defined $relation;
269              
270             my $selector = $relation eq '*'?
271             './*[local-name() = "link" and namespace-uri() = "'.ATOM_NS.'"]':
272             './*[local-name() = "link" and namespace-uri() = "'.ATOM_NS.'" and @rel="'.$relation.'"]';
273              
274             my @nodes = $this->_getDocumentElement->findnodes($selector);
275              
276             foreach my $linkElement (@nodes) {
277             my $attrs = $linkElement->attributes;
278              
279             if (defined $linkType) {
280             my $type = $attrs->getNamedItem('type');
281             next unless $type && $type->value =~ /$linkType/;
282             }
283             my $href = $attrs->getNamedItem('href')->value;
284             return $href;
285             }
286              
287             # try again by reloading the object
288             unless ($dontReload) {
289             $this->reload;
290             return $this->getLink($relation, $linkType, 1);
291             }
292              
293             return;
294             }
295              
296              
297             =back
298              
299             =head1 AUTHOR
300              
301             Michael Daum C<< >>
302              
303             =head1 COPYRIGHT AND LICENSE
304              
305             Copyright 2012-2013 Michael Daum
306              
307             This module is free software; you can redistribute it and/or modify it under
308             the same terms as Perl itself. See F.
309              
310             =cut
311              
312             1;