package AutoloadConverterScripting; use strict; no strict 'refs'; no strict 'subs'; use ConvertBinaryFile; use gsprintf 'gsprintf'; # This plugin inherits from ConvertBinaryFile as a base line (so by default # behaviour is no different to ConvertBinaryFile). If it can find the # plugin named in '::autoConverterScripting' then it loads this in as well # ,setting variables visible to the outside world that indicate whether: # 1. it found the named plugin, and # 2. if the named plugin itself could find the necessary programs it # needs to run sub _dynamicISA { my ($autoPackage) = @_; my ($autoName) = ($autoPackage =~ m/(^.*)Converter$/); my $autoVar = lc($autoName); my $self = {}; $self->{'_autoPackage'} = $autoPackage; $self->{'_autoName'} = $autoName; $self->{'_autoVar'} = $autoVar; # Always want this @AutoloadConverterScripting::ISA = ('ConvertBinaryFile' ); # Now see if requested Converter plugin is around eval("require $autoPackage"); if ($@) { # Useful debugging statement if there is a syntax error in the plugin print STDERR "$@\n"; $self->{'scripting_ext_installed'} = 0; $self->{'scripting_ext_working'} = 0; } else { # Successfully found $self->{'scripting_ext_installed'} = 1; # now check whether it can run soffice if (eval "\$${autoPackage}::${autoVar}_conversion_available") { $self->{'scripting_ext_working'} = 1; } else { $self->{'scripting_ext_working'} = 0; } } if ($self->{'scripting_ext_working'}) { push(@AutoloadConverterScripting::ISA, $autoPackage); } return $self; } my $arguments = []; my $options = { 'name' => "ConverterScripting", 'desc' => "{ConverterScripting.desc}", 'abstract' => "yes", 'inherits' => "yes", 'args' => $arguments }; #### # This plugin takes an extra initial parameter in its constructor (compared # with the norm). The extra parameter specifies which plugin it should # try to dynamically load ##### sub new { my ($class) = shift (@_); my ($autoPackage, $pluginlist,$inputargs,$hashArgOptLists) = @_; push(@$pluginlist, $class); my $dynamic_self = _dynamicISA($autoPackage); my $autoName = $dynamic_self->{'_autoName'}; my $autoVar = $dynamic_self->{'_autoVar'}; if ($dynamic_self->{'scripting_ext_installed'}) { my ($cpackage,$cfilename,$cline,$csubr,$chas_args,$cwantarray) = caller(0); print STDERR "$class: $autoName Extension to Greenstone detected for $cpackage\n"; if ($dynamic_self->{'scripting_ext_working'}) { # print STDERR "... and it appears to be working\n"; } else { print STDERR "... but it appears to be broken\n"; &gsprintf(STDERR, "AutoloadConverter: {AutoloadConverter.noconversionavailable}"); my $dictentry_reason = eval "$autoPackage\.\$${autoPackage}::no_${autoVar}_conversion_reason"; &gsprintf(STDERR, " ({$dictentry_reason})\n"); } } if ($dynamic_self->{'scripting_ext_working'}) { my $opt_scripting_args = [ { 'name' => "$autoVar\_scripting", 'desc' => "{$autoPackage.$autoVar\_scripting}", 'type' => "flag", 'reqd' => "no" } ]; push(@$arguments,@$opt_scripting_args); } push(@{$hashArgOptLists->{"ArgList"}},@{$arguments}); push(@{$hashArgOptLists->{"OptList"}},$options); my $self; if ($dynamic_self->{'scripting_ext_working'}) { my $autoc_self = eval "new $autoPackage(\$pluginlist, \$inputargs, \$hashArgOptLists,1);"; my $cbf_self = new ConvertBinaryFile($pluginlist, $inputargs, $hashArgOptLists); $self = BasePlugin::merge_inheritance($dynamic_self,$autoc_self, $cbf_self); $self->{"{$autoVar}_available"} = 1; } else { $self = new ConvertBinaryFile($pluginlist, $inputargs, $hashArgOptLists); $self->{"{$autoVar}_available"} = 0; } return bless $self, $class; } sub init { my $self = shift (@_); my ($verbosity, $outhandle, $failhandle) = @_; my $autoPackage = $self->{'_autoPackage'}; $self->SUPER::init($verbosity,$outhandle,$failhandle); if ($self->{'scripting_ext_working'}) { eval "\$self->${autoPackage}::init();"; } } sub begin { my $self = shift (@_); my $autoPackage = $self->{'_autoPackage'}; if ($self->{'scripting_ext_working'}) { eval "\$self->${autoPackage}::begin(\@_);"; } $self->SUPER::begin(@_); } sub deinit { # called only once, after all plugin passes have been done my ($self) = @_; my $autoPackage = $self->{'_autoPackage'}; if ($self->{'scripting_ext_working'}) { eval "\$self->${autoPackage}::deinit()"; } $self->SUPER::deinit(); } # if the dynamically loaded Converter plugins is working, and scripting is on,, then call its convert # method, otherwise fall back to ConvertBinaryFile method. sub tmp_area_convert_file { my $self = shift (@_); my ($output_ext, $input_filename, $textref) = @_; my $autoPackage = $self->{'_autoPackage'}; my $autoVar = $self->{'_autoVar'}; my $autoName = $self->{'_autoName'}; if ($self->{'scripting_ext_working'} && $self->{"${autoVar}_scripting"}) { my ($result, $result_str, $new_filename) = eval "\$self->${autoPackage}::convert(\$input_filename, \$output_ext);"; if ($result != 0) { return $new_filename; } my $outhandle=$self->{'outhandle'}; print $outhandle "$autoName Conversion error\n"; print $outhandle $result_str; return ""; } else { return $self->ConvertBinaryFile::tmp_area_convert_file(@_); } }