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';
15 $class = ref($class) || $class;
17 my $self = bless { id => $id, editor => new_editor() } => $class;
26 return $self if ($self->event);
29 $self->environment( {} );
31 return $self if (!$self->id);
34 $self->editor->retrieve_action_trigger_event([
38 atev => [ qw/event_def/ ],
39 atevdef => [ qw/hook env params/ ]
45 if ($self->event->state eq 'valid') {
47 } elsif ($self->event->state eq 'invalid') {
49 } elsif ($self->event->state eq 'reacting') {
51 } elsif ($self->event->state eq 'reacted') {
54 } elsif ($self->event->state eq 'cleaning') {
57 } elsif ($self->event->state eq 'complete') {
61 } elsif ($self->event->state eq 'error') {
68 $self->update_state('found') || die 'Unable to update event state';
70 my $class = $self->_fm_class_by_hint( $self->event->event_def->hook->core_type );
72 my $meth = "retreive_" . $class;
73 $meth =~ s/Fieldmapper:://;
76 $self->target( $self->editor->$meth( $self->event->target ) );
83 my $env = shift || $self->environment;
85 return $self if (defined $self->cleanedup);
87 if (defined $self->reacted) {
88 $self->update_state( 'cleaning') || die 'Unable to update event state';
90 my $cleanup = $self->reacted ? $self->event->event_def->cleanup_success : $self->event->event_def->cleanup_failure;
92 OpenILS::Application::Trigger::ModRunner::Cleanup
93 ->new( $cleanup, $env)
98 $log->error( shift() );
99 $self->update_state( 'error' ) || die 'Unable to update event state';
102 if ($self->cleanedup) {
103 $self->update_state( 'complete' ) || die 'Unable to update event state';
105 $self->update_state( 'error' ) || die 'Unable to update event state';
109 $self->{cleanedup} = undef;
116 my $env = shift || $self->environment;
118 return $self if (defined $self->reacted);
121 if ($self->event->event_def->group_field) { # can't react individually to a grouped definition
122 $self->{reacted} = undef;
124 $self->update_state( 'reacting') || die 'Unable to update event state';
127 OpenILS::Application::Trigger::ModRunner::Reactor
128 ->new( $self->event->event_def->reactor, $env )
133 $log->error( shift() );
134 $self->update_state( 'error' ) || die 'Unable to update event state';
137 if (defined $self->reacted) {
138 $self->update_state( 'reacted' ) || die 'Unable to update event state';
140 $self->update_state( 'error' ) || die 'Unable to update event state';
144 $self->{reacted} = undef;
152 return $self if (defined $self->valid);
154 if ($self->build_environment->environment->{complete}) {
155 $self->update_state( 'validating') || die 'Unable to update event state';
158 OpenILS::Application::Trigger::ModRunner::Validator
159 ->new( $self->event->event_def->validator, $self->environment )
164 $log->error( shift() );
165 $self->update_state( 'error' ) || die 'Unable to update event state';
168 if (defined $self->valid) {
170 $self->update_state( 'valid' ) || die 'Unable to update event state';
172 $self->update_state( 'invalid' ) || die 'Unable to update event state';
175 $self->update_state( 'error' ) || die 'Unable to update event state';
178 $self->{valid} = undef
186 return undef unless (ref $self);
189 $self->{cleanedup} = $c if (defined $c);
190 return $self->{cleanedup};
195 return undef unless (ref $self);
198 $self->{reacted} = $r if (defined $r);
199 return $self->{reacted};
204 return undef unless (ref $self);
207 $self->{valid} = $v if (defined $v);
208 return $self->{valid};
213 return undef unless (ref $self);
216 $self->{event} = $e if (defined $e);
217 return $self->{event};
222 return undef unless (ref $self);
225 $self->{id} = $i if (defined $i);
231 return undef unless (ref $self);
234 $self->{environment} = $e if (defined $e);
235 return $self->{environment};
240 return undef unless (ref $self);
243 $self->{editor} = $e if (defined $e);
244 return $self->{editor};
249 return undef unless (ref $self);
251 die 'Cannot unfind a reacted event' if (defined $self->reacted);
253 $self->update_state( 'pending' ) || die 'Unable to update event state';
255 $self->{event} = undef;
256 $self->{environment} = undef;
262 return undef unless (ref $self);
265 $self->{target} = $t if (defined $t);
266 return $self->{target};
271 return undef unless ($self && ref $self);
274 return undef unless ($state);
276 $self->editor->xact_begin || return undef;
278 my $e = $self->editor->retrieve_action_trigger_event( $self->id );
279 $e->start_time( 'now' ) unless $e->start_time;
280 $e->update_time( 'now' );
281 $e->update_process( $$ );
284 $e->clear_start_time() if ($e->state eq 'pending');
286 my $ok = $self->editor->update_action_trigger_event( $e );
288 $self->editor->xact_rollback;
291 $ok = $self->editor->xact_commit;
295 $e = $self->editor->data;
296 $self->event->start_time( $e->start_time );
297 $self->event->update_time( $e->update_time );
298 $self->event->update_process( $e->update_process );
299 $self->event->state( $e->state );
305 sub build_environment {
307 return $self if ($self->environment->{complete});
309 $self->update_state( 'collecting') || die 'Unable to update event state';
313 $self->environment->{target} = $self->target;
314 $self->environment->{event} = $self->event;
315 $self->environment->{template} = $self->event->event_def->template;
317 $self->environment->{params}{ $_->param } = eval $_->value for ( @{$self->event->event_def->params} );
319 for my $e ( @{$self->event->event_def->env} ) {
321 @path = split('.', $e->path) if ($e->path);
322 @label = split('.', $e->label) if ($e->label);
324 $self->_object_by_path( $self->event->target, $e->collector, \@label, \@path );
327 if ($self->event->event_def->group_field) {
328 my @group_path = split('.', $self->event->event_def->group_field);
329 my $group_object = $self->_object_by_path( $self->event->target, undef, [], \@group_path );
332 $self->environment->{complete} = 1;
334 $log->error( shift() );
335 $self->update_state( 'error' ) || die 'Unable to update event state';
338 if ($self->environment->{complete}) {
339 $self->update_state( 'collected' ) || die 'Unable to update event state';
341 $self->update_state( 'error' ) || die 'Unable to update event state';
347 sub _fm_class_by_hint {
352 Fieldmapper->publish_fieldmapper->{$_}->{hint} eq $hint
353 } keys %{ Fieldmapper->publish_fieldmapper };
358 sub _object_by_path {
361 my $collector = shift;
365 my $step = shift(@$path);
367 my $fhint = Fieldmapper->publish_fieldmapper->{$context->class_name}{links}{$step}{class};
368 my $fclass = $self->_fm_class_by_hint( $fhint );
370 my $ffield = Fieldmapper->publish_fieldmapper->{$context->class_name}{links}{$step}{key};
371 my $rtype = Fieldmapper->publish_fieldmapper->{$context->class_name}{links}{$step}{reltype};
373 my $meth = 'retrieve_';
376 if ($rtype eq 'has_many') {
379 $lfield = $context->Identity;
383 $meth =~ s/Fieldmapper:://;
386 my $obj = $self->editor->$meth( { $ffield => $context->$lfield() } );
392 $obj_list = [$obj] if ($obj);
397 $self->_object_by_path( $_, $collector, $label, $path ) for (@$obj_list);
399 $obj = $$obj_list[0] if (!$multi);
400 $context->$step( $obj ) if ($obj && !$label);
405 my $obj_list = [$obj] if ($obj && !$multi);
406 $obj_list = $obj if ($multi);
409 for my $o ( @$obj_list ) {
411 OpenILS::Application::Trigger::ModRunner::Collector
412 ->new( $collector, $o )
418 $obj = $new_obj_list[0];
420 $obj = \@new_obj_list;
425 my $node = $self->environment;
426 my $i = 0; my $max = scalar(@$label) - 1;
427 for (; $i < $max; $i++) {
428 my $part = $$label[$i];
429 $$node{$part} ||= {};
430 $node = $$node{$part};
432 $$node{$$label[-1]} = $obj;
434 $context->$step( $obj ) if ($obj);