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';
16 $class = ref($class) || $class;
18 return $id if (ref($id) && ref($id) == $class);
20 my $standalone = $editor ? 0 : 1;
21 $editor ||= new_editor();
23 my $self = bless { id => $id, editor => $editor, standalone => $standalone } => $class;
32 return $self if ($self->event);
35 $self->environment( {} );
38 $log->error("No Event ID provided");
39 die "No Event ID provided";
42 return $self if (!$self->id);
45 $self->editor->retrieve_action_trigger_event([
49 atev => [ qw/event_def/ ],
50 atevdef => [ qw/hook env params/ ]
56 if ($self->event->state eq 'valid') {
58 } elsif ($self->event->state eq 'invalid') {
60 } elsif ($self->event->state eq 'reacting') {
62 } elsif ($self->event->state eq 'reacted') {
65 } elsif ($self->event->state eq 'cleaning') {
68 } elsif ($self->event->state eq 'complete') {
72 } elsif ($self->event->state eq 'error') {
79 $self->update_state('found') || die 'Unable to update event state';
81 my $class = $self->_fm_class_by_hint( $self->event->event_def->hook->core_type );
83 my $meth = "retrieve_" . $class;
84 $meth =~ s/Fieldmapper:://;
87 $self->target( $self->editor->$meth( $self->event->target ) );
94 my $env = shift || $self->environment;
96 return $self if (defined $self->cleanedup);
98 if (defined $self->reacted) {
99 $self->update_state( 'cleaning') || die 'Unable to update event state';
101 my $cleanup = $self->reacted ? $self->event->event_def->cleanup_success : $self->event->event_def->cleanup_failure;
103 OpenILS::Application::Trigger::ModRunner::Cleanup
104 ->new( $cleanup, $env)
109 $log->error( shift() );
110 $self->update_state( 'error' ) || die 'Unable to update event state';
113 if ($self->cleanedup) {
114 $self->update_state( 'complete' ) || die 'Unable to update event state';
116 $self->update_state( 'error' ) || die 'Unable to update event state';
120 $self->{cleanedup} = undef;
127 my $env = shift || $self->environment;
129 return $self if (defined $self->reacted);
132 if ($self->event->event_def->group_field) { # can't react individually to a grouped definition
133 $self->{reacted} = undef;
135 $self->update_state( 'reacting') || die 'Unable to update event state';
138 OpenILS::Application::Trigger::ModRunner::Reactor
139 ->new( $self->event->event_def->reactor, $env )
144 $log->error( shift() );
145 $self->update_state( 'error' ) || die 'Unable to update event state';
148 if (defined $self->reacted) {
149 $self->update_state( 'reacted' ) || die 'Unable to update event state';
151 $self->update_state( 'error' ) || die 'Unable to update event state';
155 $self->{reacted} = undef;
163 return $self if (defined $self->valid);
165 if ($self->build_environment->environment->{complete}) {
166 $self->update_state( 'validating') || die 'Unable to update event state';
169 OpenILS::Application::Trigger::ModRunner::Validator
170 ->new( $self->event->event_def->validator, $self->environment )
175 $log->error( shift() );
176 $self->update_state( 'error' ) || die 'Unable to update event state';
179 if (defined $self->valid) {
181 $self->update_state( 'valid' ) || die 'Unable to update event state';
183 $self->update_state( 'invalid' ) || die 'Unable to update event state';
186 $self->update_state( 'error' ) || die 'Unable to update event state';
189 $self->{valid} = undef
197 return undef unless (ref $self);
200 $self->{cleanedup} = $c if (defined $c);
201 return $self->{cleanedup};
206 return undef unless (ref $self);
209 $self->{reacted} = $r if (defined $r);
210 return $self->{reacted};
215 return undef unless (ref $self);
218 $self->{valid} = $v if (defined $v);
219 return $self->{valid};
224 return undef unless (ref $self);
227 $self->{event} = $e if (defined $e);
228 return $self->{event};
233 return undef unless (ref $self);
236 $self->{id} = $i if (defined $i);
242 return undef unless (ref $self);
245 $self->{environment} = $e if (defined $e);
246 return $self->{environment};
251 return undef unless (ref $self);
254 $self->{editor} = $e if (defined $e);
255 return $self->{editor};
260 return undef unless (ref $self);
262 die 'Cannot unfind a reacted event' if (defined $self->reacted);
264 $self->update_state( 'pending' ) || die 'Unable to update event state';
266 $self->{event} = undef;
267 $self->{environment} = undef;
273 return undef unless (ref $self);
276 $self->{target} = $t if (defined $t);
277 return $self->{target};
282 return undef unless (ref $self);
285 $self->{standalone} = $t if (defined $t);
286 return $self->{standalone};
291 return undef unless ($self && ref $self);
294 return undef unless ($state);
296 if ($self->standalone) {
297 $self->editor->xact_begin || return undef;
300 my $e = $self->editor->retrieve_action_trigger_event( $self->id );
302 $log->error( "Could not retrieve object ".$self->id." for update" ) if (!$e);
306 $log->info( "Retrieved object ".$self->id." for update" );
307 $e->start_time( 'now' ) unless $e->start_time;
308 $e->update_time( 'now' );
309 $e->update_process( $$ );
312 $e->clear_start_time() if ($e->state eq 'pending');
314 my $ok = $self->editor->update_action_trigger_event( $e );
316 $self->editor->xact_rollback if ($self->standalone);
317 $log->error( "Update of event ".$self->id." failed" );
320 $e = $self->editor->data;
321 $e = $self->editor->retrieve_action_trigger_event( $e ) if (!ref($e));
323 $log->error( "Update of event ".$self->id." did not return an object" );
326 $log->info( "Update of event ".$e->id." suceeded" );
327 $ok = $self->editor->xact_commit if ($self->standalone);
331 $self->event->start_time( $e->start_time );
332 $self->event->update_time( $e->update_time );
333 $self->event->update_process( $e->update_process );
334 $self->event->state( $e->state );
340 sub build_environment {
342 return $self if ($self->environment->{complete});
344 $self->update_state( 'collecting') || die 'Unable to update event state';
348 $self->environment->{target} = $self->target;
349 $self->environment->{event} = $self->event;
350 $self->environment->{template} = $self->event->event_def->template;
352 $self->environment->{params}{ $_->param } = eval $_->value for ( @{$self->event->event_def->params} );
354 for my $e ( @{$self->event->event_def->env} ) {
356 @path = split('.', $e->path) if ($e->path);
357 @label = split('.', $e->label) if ($e->label);
359 $self->_object_by_path( $self->event->target, $e->collector, \@label, \@path );
362 if ($self->event->event_def->group_field) {
363 my @group_path = split('.', $self->event->event_def->group_field);
364 my $group_object = $self->_object_by_path( $self->event->target, undef, [], \@group_path );
367 $self->environment->{complete} = 1;
369 $log->error( shift() );
370 $self->update_state( 'error' ) || die 'Unable to update event state';
373 if ($self->environment->{complete}) {
374 $self->update_state( 'collected' ) || die 'Unable to update event state';
376 $self->update_state( 'error' ) || die 'Unable to update event state';
382 sub _fm_class_by_hint {
387 Fieldmapper->publish_fieldmapper->{$_}->{hint} eq $hint
388 } keys %{ Fieldmapper->publish_fieldmapper };
393 sub _object_by_path {
396 my $collector = shift;
400 my $step = shift(@$path);
402 my $fhint = Fieldmapper->publish_fieldmapper->{$context->class_name}{links}{$step}{class};
403 my $fclass = $self->_fm_class_by_hint( $fhint );
405 my $ffield = Fieldmapper->publish_fieldmapper->{$context->class_name}{links}{$step}{key};
406 my $rtype = Fieldmapper->publish_fieldmapper->{$context->class_name}{links}{$step}{reltype};
408 my $meth = 'retrieve_';
411 if ($rtype eq 'has_many') {
414 $lfield = $context->Identity;
418 $meth =~ s/Fieldmapper:://;
421 my $obj = $self->editor->$meth( { $ffield => $context->$lfield() } );
427 $obj_list = [$obj] if ($obj);
432 $self->_object_by_path( $_, $collector, $label, $path ) for (@$obj_list);
434 $obj = $$obj_list[0] if (!$multi);
435 $context->$step( $obj ) if ($obj && !$label);
440 my $obj_list = [$obj] if ($obj && !$multi);
441 $obj_list = $obj if ($multi);
444 for my $o ( @$obj_list ) {
446 OpenILS::Application::Trigger::ModRunner::Collector
447 ->new( $collector, $o )
453 $obj = $new_obj_list[0];
455 $obj = \@new_obj_list;
460 my $node = $self->environment;
461 my $i = 0; my $max = scalar(@$label) - 1;
462 for (; $i < $max; $i++) {
463 my $part = $$label[$i];
464 $$node{$part} ||= {};
465 $node = $$node{$part};
467 $$node{$$label[-1]} = $obj;
469 $context->$step( $obj ) if ($obj);