90% there with Reflector code generation!
[catagits/Reaction.git] / lib / Reaction / InterfaceModel / Action.pm
1 package Reaction::InterfaceModel::Action;
2
3 use Reaction::Meta::InterfaceModel::Action::Class;
4 use metaclass 'Reaction::Meta::InterfaceModel::Action::Class';
5
6 use Reaction::Meta::Attribute;
7 use Reaction::Class;
8
9 class Action which {
10
11   has target_model => (is => 'ro', required => 1,
12                        metaclass => 'Reaction::Meta::Attribute');
13
14   has ctx => (isa => 'Catalyst', is => 'ro', required => 1,
15                 metaclass => 'Reaction::Meta::Attribute');
16
17   implements parameter_attributes => as {
18     shift->meta->parameter_attributes;
19   };
20
21   implements parameter_hashref => as {
22     my ($self) = @_;
23     my %params;
24     foreach my $attr ($self->parameter_attributes) {
25       my $reader = $attr->get_read_method;
26       my $predicate = $attr->predicate;
27       next if defined($predicate) && !$self->$predicate;
28       $params{$attr->name} = $self->$reader;
29     }
30     return \%params;
31   };
32
33   implements can_apply => as {
34     my ($self) = @_;
35     foreach my $attr ($self->parameter_attributes) {
36       my $predicate = $attr->predicate;
37       if ($attr->is_required) {
38         return 0 unless $self->$predicate;
39       }
40       if ($attr->has_valid_values) {
41         unless ($predicate && !($self->$predicate)) {
42           my $reader = $attr->get_read_method;
43           return 0 unless $attr->check_valid_value($self, $self->$reader);
44         }
45       }
46     }
47     return 1;
48   };
49
50   implements error_for => as {
51     my ($self, $attr) = @_;
52     confess "No attribute passed to error_for" unless defined($attr);
53     unless (ref($attr)) {
54       my $meta = $self->meta->find_attribute_by_name($attr);
55       confess "Can't find attribute ${attr} on $self" unless $meta;
56       $attr = $meta;
57     }
58     return $self->error_for_attribute($attr);
59   };
60
61   implements error_for_attribute => as {
62     my ($self, $attr) = @_;
63     if ($attr->is_required) {
64       my $predicate = $attr->predicate;
65       unless ($self->$predicate) {
66         return $attr->name." is required";
67       }
68     }
69     if ($attr->has_valid_values) {
70       my $reader = $attr->get_read_method;
71       unless ($attr->check_valid_value($self, $self->$reader)) {
72         return "Not a valid value for ".$attr->name;
73       }
74     }
75     return; # ok
76   };
77
78   sub sync_all { }
79
80 };
81
82 1;
83
84 =head1 NAME
85
86 Reaction::InterfaceModel::Action
87
88 =head1 SYNOPSIS
89
90 =head1 DESCRIPTION
91
92 =head2 target_model
93
94 =head2 ctx
95
96 =head2 parameter_attributes
97
98 =head1 SEE ALSO
99
100 L<Reaction::Meta::Attribute>
101
102 =head1 AUTHORS
103
104 See L<Reaction::Class> for authors.
105
106 =head1 LICENSE
107
108 See L<Reaction::Class> for the license.
109
110 =cut