1package Net::Google::DataAPI::Role::Entry;
2use Any::Moose '::Role';
3use Carp;
4use XML::Atom;
5use XML::Atom::Entry;
6our $VERSION = '0.02';
7
8has container => (
9    isa => 'Maybe[Net::Google::DataAPI::Role::Entry]',
10    is => 'ro',
11);
12
13has service => (
14    does => 'Net::Google::DataAPI::Role::Service',
15    is => 'ro',
16    required => 1,
17    lazy_build => 1,
18    weak_ref => 1,
19    handles => ['ns'],
20);
21
22sub _build_service { shift->container->service };
23
24my %rel2label = (
25    edit => 'editurl',
26    self => 'selfurl',
27);
28
29for my $label (values %rel2label) {
30    has $label => (
31        isa => 'Str',
32        is => 'ro',
33        lazy_build => 1,
34    );
35
36    __PACKAGE__->meta->add_method(
37        "_build_$label" => sub {
38            my $self = shift;
39            for my $link ($self->atom->link) {
40                my $rel = $rel2label{$link->rel} or next;
41                return $link->href if $rel eq $label;
42            }
43        }
44    );
45}
46
47has atom => (
48    isa => 'XML::Atom::Entry',
49    is => 'rw',
50    trigger => sub {
51        my ($self, $arg) = @_;
52        my $id = $self->atom->get($self->atom->ns, 'id');
53        croak "can't set different id!" if $self->id && $self->id ne $id;
54        $self->from_atom;
55    },
56    handles => ['elem', 'author'],
57);
58
59has id => (
60    isa => 'Str',
61    is => 'ro',
62    lazy_build => 1,
63);
64
65sub _build_id {
66    my $self = shift;
67    $self->atom->get($self->atom->ns, 'id') || '';
68}
69
70has title => (
71    isa => 'Str',
72    is => 'rw',
73    trigger => sub {$_[0]->update},
74    lazy_build => 1,
75);
76
77sub _build_title {
78    my $self = shift;
79    $self->atom ? $self->atom->title : 'untitled';
80}
81
82has etag => (
83    isa => 'Str',
84    is => 'rw',
85    lazy_build => 1,
86);
87
88sub _build_etag {
89    my $self = shift;
90    $self->atom or return '';
91    $self->elem->getAttributeNS($self->ns('gd')->{uri}, 'etag');
92}
93
94
95sub from_atom {
96    my ($self) = @_;
97    for my $attr ($self->meta->get_all_attributes) {
98        $attr->name eq 'service' and next;
99        $attr->clear_value($self) if $attr->{lazy};
100    }
101}
102
103sub to_atom {
104    my ($self) = @_;
105    my $entry = XML::Atom::Entry->new;
106    $entry->title($self->title);
107    return $entry;
108}
109
110sub sync {
111    my ($self) = @_;
112    my $entry = $self->service->get_entry($self->selfurl);
113    $self->atom($entry);
114}
115
116sub update {
117    my ($self) = @_;
118    $self->etag or return;
119    my $atom = $self->service->put(
120        {
121            self => $self,
122            entry => $self->to_atom,
123        }
124    );
125    $self->container->sync if $self->container;
126    $self->atom($atom);
127}
128
129sub delete {
130    my $self = shift;
131    my $res = $self->service->delete({self => $self});
132    $self->container->sync if $self->container;
133    return $res->is_success;
134}
135
136no Any::Moose '::Role';
137
1381;
139
140__END__
141
142=pod
143
144=head1 NAME
145
146Net::Google::DataAPI::Role::Entry - represents entry of Google Data API
147
148=head1 SYNOPSIS
149
150    package MyEntry;
151    use Any::Moose;
152    use Net::Google::DataAPI;
153    with 'Net::Google::DataAPI::Role::Entry';
154
155    entry_has some_data => (
156        is => 'ro',
157        isa => 'Str',
158        tagname => 'somedata',
159        ns => 'gd',
160    );
161
162    1;
163
164=head1 DESCRIPTION
165
166Net::Google::DataAPI::Role::Entry provides base functionalities for the entry of Google Data API.
167
168=head1 AUTHOR
169
170Nobuo Danjou E<lt>danjou@soffritto.orgE<gt>
171
172=head1 SEE ALSO
173
174L<Net::Google::DataAPI>
175
176=head1 LICENSE
177
178This library is free software; you can redistribute it and/or modify
179it under the same terms as Perl itself.
180
181=cut
182
183