some minor fixes
[catagits/CatalystX-Declare.git] / lib / CatalystX / Declare / Controller / ActionPreparation.pm
1 use MooseX::Declare;
2
3 role CatalystX::Declare::Controller::ActionPreparation {
4
5     use aliased 'CatalystX::Declare::Action::CatchValidationError';
6     use aliased 'CatalystX::Declare::Dispatching::ChainTypeSensitivity';
7
8
9     method _apply_action_roles (Object $action, @roles) {
10
11         for my $role (CatchValidationError, @roles) {
12             my $fq_role = $self->_qualify_class_name(ActionRole => $role);
13
14             Class::MOP::load_class($fq_role);
15             $fq_role->meta->apply($action);
16         }
17     }
18
19     method _find_method_type_constraint (Str $name) {
20
21         $self->meta->find_method_type_constraint($name)
22             || do {
23                 my $method = $self->meta->find_method_by_name($name);
24                     ( $_ = $method->can('type_constraint') )
25                     ? $method->$_
26                     : undef
27             };
28     }
29
30     method _ensure_applied_dispatchtype_roles {
31
32         my $type = $self->_app->dispatcher->dispatch_type('Chained');
33
34         return
35             if $type->DOES(ChainTypeSensitivity);
36
37         my $immutable = $type->meta->is_immutable;
38         my %immutable_options;
39         if ($immutable) {
40             %immutable_options = $type->meta->immutable_options;
41             $type->meta->make_mutable;
42         }
43
44         # FIXME we really shouldn't have to tweak the dispatch type
45         ChainTypeSensitivity->meta->apply($type->meta);
46
47         $type->meta->make_immutable(%immutable_options)
48             if $immutable;
49     }
50
51     after register_actions {
52
53         $self->_ensure_applied_dispatchtype_roles;
54     }
55
56     around create_action (%args) {
57
58         my @action_roles = @{ delete($args{attributes}{CatalystX_Declarative_ActionRoles}) || [] };
59
60         my $action = $self->$orig(%args);
61
62         return $action
63             if $args{attributes}{Private};
64
65         $self->_apply_action_roles($action, @action_roles);
66
67         return $action 
68             unless $action->DOES(CatchValidationError);
69
70         my $tc = $self->_find_method_type_constraint($action->name);
71
72         return $action
73             unless $tc;
74
75         $action->method_type_constraint($tc);
76         $action->controller_instance($self);
77
78         return $action;
79     }
80 }