1 package OpenILS::Utils::SpiderMonkey;
2 use strict; use warnings;
3 use OpenSRF::Utils::Logger qw(:logger);
4 use OpenILS::Utils::ScriptRunner;
5 use base 'OpenILS::Utils::ScriptRunner';
6 use JavaScript::SpiderMonkey;
9 my ( $class, %params ) = @_;
10 $class = ref($class) || $class;
11 my $self = { file => $params{file}, libs => $params{libs} };
12 return bless( $self, $class );
16 my( $self, $context ) = @_;
17 $self->{ctx} = $context if $context;
23 my $js = JavaScript::SpiderMonkey->new();
25 $js->function_set("perl_print", sub { print "@_\n"; } );
26 $js->function_set("log_activity", sub { $logger->activity(@_); return 1;} );
27 $js->function_set("log_error", sub { $logger->error(@_); return 1;} );
28 $js->function_set("log_warn", sub { $logger->warn(@_); return 1;} );
29 $js->function_set("log_info", sub { $logger->info(@_); return 1;} );
30 $js->function_set("log_debug", sub { $logger->debug(@_); return 1;} );
31 $js->function_set("log_internal", sub { $logger->internal(@_); return 1;} );
32 $js->function_set("debug", sub { $logger->debug(@_); return 1;} );
33 $js->function_set("alert", sub { $logger->warn(@_); return 1;} );
35 $self->load_lib($_) for @{$self->{libs}};
40 my( $self, $filename ) = @_;
41 $self->{file} = $filename;
46 my $file = shift() || $self->{file};
47 my $js = $self->context;
49 if( ! open(F, $file) ) {
50 $logger->error("Error opening script file: $file");
54 if( ! $js->eval(join("\n", <F>)) ) {
55 $logger->error("Script ($file) eval failed in SpiderMonkey run: $@");
64 my( $self, $file ) = @_;
75 my( $self, $key ) = @_;
76 return $self->context->property_get($key);
80 my( $self, $obj_key, $meth_name, $sub ) = @_;
81 my $obj = $self->context->object_by_path( $obj_key );
82 $self->context->function_set( $meth_name, $sub, $obj ) if $obj;
87 my( $self, $key, $val ) = @_;
88 return unless defined($key);
90 if (ref($val) =~ /^Fieldmapper/o) {
91 $self->insert_fm($key, $val);
92 } elsif (ref($val) and $val =~ /ARRAY/o) {
93 $self->insert_array($key, $val);
94 } elsif (ref($val) and $val =~ /HASH/o) {
95 $self->insert_hash($key, $val);
96 } elsif (ref($val) and $val =~ /CODE/o) {
97 $self->context->function_set( $key, $val );
98 } elsif (!ref($val)) {
100 $self->context->property_by_path(
103 sub { my( $k, $v ) = @_; $val = $v; }
106 $self->context->property_by_path($key);
118 my( $self, $key, $fm ) = @_;
119 my $ctx = $self->context;
120 return undef unless ($ctx and $key and $fm);
121 my $o = $ctx->object_by_path($key);
123 for my $f ( $fm->properties ) {
126 $self->insert("$key.$f", $val);
128 $ctx->property_by_path(
132 my $k = _js_prop_name(shift());
137 my $k = _js_prop_name(shift());
148 my( $self, $key, $hash ) = @_;
149 my $ctx = $self->context;
150 return undef unless ($ctx and $key and $hash);
151 $ctx->object_by_path($key);
153 for my $k ( keys %$hash ) {
156 $self->insert("$key.$k", $v);
158 $ctx->property_by_path(
160 sub { $hash->{_js_prop_name(shift())} },
162 my( $key, $val ) = @_;
163 $hash->{_js_prop_name($key)} = $val; }
172 my( $self, $key, $array ) = @_;
173 my $ctx = $self->context;
174 return undef unless ($ctx and $key and $array);
176 my $a = $ctx->array_by_path($key);
179 for my $v ( @$array ) {
181 my $elobj = $ctx->object_by_path('__tmp_arr_el'.$__array_id);
182 $self->insert('__tmp_arr_el'.$__array_id, $v);
183 $ctx->array_set_element_as_object( $a, $ind, $elobj );
186 $ctx->array_set_element( $a, $ind, $v ) if defined($v);