1 package OpenILS::Application::Trigger::Event;
2 use OpenSRF::EX qw/:try/;
4 use OpenSRF::Utils::Logger qw/:level/;
6 use OpenILS::Utils::Fieldmapper;
7 use OpenILS::Utils::CStoreEditor q/:funcs/;
8 use OpenILS::Application::Trigger::ModRunner;
10 my $log = 'OpenSRF::Utils::Logger';
14 $class = ref($class) || $class;
17 return undef unless ($id);
19 my $cstore = new_editor();
20 my $event = $cstore->retrieve_action_trigger_event( $id );
21 return undef unless ($event);
23 return bless { id => $id, event => $event, environment => {}, editor => $cstore } => $class;
29 if (defined $self->reacted) {
30 $self->update_state( 'cleaning') || die 'Unable to update event state';
32 my $cleanup = $self->reacted ? $self->definition->cleanup_success : $self->definition->cleanup_failure;
34 OpenILS::Application::Trigger::ModRunner
35 ->new( $cleanup, $self->environment )
40 $log->error( shift() );
41 $self->update_state( 'error' ) || die 'Unable to update event state';
44 if ($self->cleanedup) {
45 $self->update_state( 'complete' ) || die 'Unable to update event state';
47 $self->update_state( 'error' ) || die 'Unable to update event state';
51 $self->{cleanedup} = undef;
60 if ($self->definition->group_field) { # can't react individually to a grouped definition
61 $self->{reacted} = undef;
63 $self->update_state( 'reacting') || die 'Unable to update event state';
66 OpenILS::Application::Trigger::ModRunner
67 ->new( $self->definition->reactor, $self->environment )
72 $log->error( shift() );
73 $self->update_state( 'error' ) || die 'Unable to update event state';
76 if (defined $self->reacted) {
77 $self->update_state( 'reacted' ) || die 'Unable to update event state';
79 $self->update_state( 'error' ) || die 'Unable to update event state';
83 $self->{reacted} = undef;
91 return $self if (defined $self->valid);
93 if ($self->build_environment->environment->{complete}) {
94 $self->update_state( 'validating') || die 'Unable to update event state';
97 OpenILS::Application::Trigger::ModRunner
98 ->new( $self->definition->validator, $self->environment )
103 $log->error( shift() );
104 $self->update_state( 'error' ) || die 'Unable to update event state';
107 if (defined $self->valid) {
109 $self->update_state( 'valid' ) || die 'Unable to update event state';
111 $self->update_state( 'invalid' ) || die 'Unable to update event state';
114 $self->update_state( 'error' ) || die 'Unable to update event state';
117 $self->{valid} = undef
125 return undef unless (ref $self);
128 $self->{cleanedup} = $c if (defined $c);
129 return $self->{cleanedup};
134 return undef unless (ref $self);
137 $self->{reacted} = $r if (defined $r);
138 return $self->{reacted};
143 return undef unless (ref $self);
146 $self->{valid} = $v if (defined $v);
147 return $self->{valid};
152 return undef unless (ref $self);
155 $self->{event} = $e if (defined $e);
156 return $self->{event};
161 return undef unless (ref $self);
164 $self->{id} = $i if (defined $i);
170 return undef unless (ref $self);
173 $self->{environment} = $e if (defined $e);
174 return $self->{environment};
179 return undef unless (ref $self);
182 $self->{editor} = $e if (defined $e);
183 return $self->{editor};
188 return undef unless (ref $self);
191 $self->{target} = $t if (defined $t);
192 return $self->{target};
197 return undef unless (ref $self);
200 $self->{definition} = $d if (defined $d);
201 return $self->{definition};
206 return undef unless ($self && ref $self);
208 my $state = shift || return undef;
210 $self->editor->xact_begin || return undef;
211 $self->event->update_time( 'now' );
212 $self->event->update_process( $$ );
213 $self->event->state( $state );
214 $self->editor->update_action_trigger_event( $self->event );
215 $self->editor->xact_commit || return undef;
219 sub build_environment {
221 return $self if ($self->environment->{complete});
223 $self->update_state( 'collecting') || die 'Unable to update event state';
226 $self->definition( $self->editor->retrieve_action_trigger_event_definition( $self->event->event_def ) );
228 $self->definition->hook( $self->editor->retrieve_action_trigger_hook( $self->definition->hook ) );
229 $self->definition->validator( $self->editor->retrieve_action_trigger_validator( $self->definition->validator ) );
230 $self->definition->reactor( $self->editor->retrieve_action_trigger_reactor( $self->definition->reactor ) );
231 $self->definition->cleanup_success( $self->editor->retrieve_action_trigger_cleanup( $self->definition->cleanup_success ) ) if $self->definition->cleanup_success;
232 $self->definition->cleanup_failure( $self->editor->retrieve_action_trigger_cleanup( $self->definition->cleanup_failure ) ) if $self->definition->cleanup_failure;
234 my $class = $self->_fm_class_by_hint( $self->definition->hook->core_type );
236 my $meth = "retreive_" . $class;
237 $meth =~ s/Fieldmapper:://;
240 $self->target( $self->editor->$meth( $self->event->target ) );
241 $self->environment->{target} = $self->target;
242 $self->environment->{event} = $self->event->to_bare_hash;
243 $self->environment->{template} = $self->definition->template;
245 my @env_list = $self->editor->search_action_trigger_environment( { event_def => $self->event->event_def } );
246 my @param_list = $self->editor->search_action_trigger_params( { event_def => $self->event->event_def } );
248 $self->environment->{params}{ $_->param } = eval $_->value for ( @param_list );
250 for my $e ( @env_list ) {
252 @path = split('.', $e->path) if ($e->path);
253 @label = split('.', $e->label) if ($e->label);
255 my $collector = $e->collector;
256 $self->_object_by_path( $target, $collector, \@label, \@path );
259 $self->environment->{complete} = 1;
261 $log->error( shift() );
262 $self->update_state( 'error' ) || die 'Unable to update event state';
265 if ($self->environment->{complete}) {
266 $self->update_state( 'collected' ) || die 'Unable to update event state';
268 $self->update_state( 'error' ) || die 'Unable to update event state';
274 sub _fm_class_by_hint {
279 Fieldmapper->publish_fieldmapper->{$_}->{hint} eq $hint
280 } keys %{ Fieldmapper->publish_fieldmapper };
285 sub _object_by_path {
288 my $collector = shift;
292 my $step = shift(@$path);
294 my $fhint = Fieldmapper->publish_fieldmapper->{$context->class_name}{links}{$step}{class};
295 my $fclass = $self->_fm_class_by_hint( $fhint );
297 my $ffield = Fieldmapper->publish_fieldmapper->{$context->class_name}{links}{$step}{key};
298 my $rtype = Fieldmapper->publish_fieldmapper->{$context->class_name}{links}{$step}{reltype};
300 my $meth = 'retrieve_';
303 if ($rtype eq 'has_many') {
306 $lfield = $context->Identity;
310 $meth =~ s/Fieldmapper:://;
313 my $obj = $self->editor->$meth( { $ffield => $context->$lfield() } );
319 $obj_list = [$obj] if ($obj);
324 $self->_object_by_path( $_, $collector, $label, $path ) for (@$obj_list);
326 $obj = $$obj_list[0] if (!$multi);
327 $context->$step( $obj ) if ($obj && !$label);
332 my $obj_list = [$obj] if ($obj && !$multi);
333 $obj_list = $obj if ($multi);
336 for my $o ( @$obj_list ) {
338 OpenILS::Application::Trigger::ModRunner
339 ->new( $collector, $o )
345 $obj = $new_obj_list[0];
347 $obj = \@new_obj_list;
352 my $node = $self->environment;
353 my $i = 0; my $max = scalar(@$label) - 1;
354 for (; $i < $max; $i++) {
355 my $part = $$label[$i];
356 $$node{$part} ||= {};
357 $node = $$node{$part};
359 $$node{$$label[-1]} = $obj;
361 $context->$step( $obj ) if ($obj);