package Lire::DlfCategoriser;

use strict;

use base qw/Lire::DlfAnalyser/;

use Carp;

=pod

=head1 NAME

Lire::DlfCategoriser - Base class for analysers which produce extended
DLF records.

=head1 SYNOPSIS

  use base qw/ Lire::DlfCategoriser /;

  sub categorise {
    my ( $self, $dlf ) = @_;

    # Adds the extended field to DLF.

    return;
  }


=head1 DESCRIPTION

This package defines a base class that can be use for
Lire::DlfAnalyser which writes to an ExtendedSchema. The categoriser
only have to implement the categorise() method instead of the
more generic analyse().

=head1 META INFORMATION METHODS

The Lire::DlfCategoriser should implement the same meta-information
methods than the Lire::DlfAnalyser (name(), src_schema(),
dst_schema(), title(), description()).

=head1 IMPLEMENTATION METHODS

The categoriser does its job using the initialise() and categorise()
methods.

=head2 analyse( $process, $config )

The Lire::DlfCategoriser implements the analyse() method. It will
run the query on the src_schema() using the correct filter and will
call categorise() on each DLF returned. The extended fiels will then
be written to dst_schema(). Errors should be reported by dying.

=cut

sub analyse {
    my ( $self, $process, $config ) = @_;

    my $dst_schema = Lire::DlfSchema::load_schema( $self->dst_schema() );
    croak "'" . $self->name() . "' analyser doesn't declare to write to an ExtendedSchema: '" . $self->dst_schema() . "'"
      unless $dst_schema->isa( 'Lire::ExtendedSchema' );

    eval { $self->initialise( $config ) };
    if ( $@ ) {
        $process->error( "Error during initialise: $@" );
        return;
    }
    my $schema = Lire::DlfSchema::load_schema( $self->src_schema() );
    my $query = $schema->dlf_query();
    $query->set_sort_spec( $schema->timestamp_field()->name() );

    my $filter = $process->source_filter();
    $query->set_filter_clause( $filter->sql_expr(), @{$filter->sql_params()} )
      if defined $filter;

    my $result = $query->execute( $process->dlf_store() );
    while ( defined( my $dlf = $result->next_row() ) ) {
        eval { $self->categorise( $dlf ) };
        if ( $@ ) {
            $process->error( $@ ) if $@;
        } else {
            $process->write_dlf( $dlf );
        }
    }

    eval { $self->finalise( $config ) };
    $process->error( "Error during initialise: $@" ) if ( $@ );

    return;
}

=pod

=head2 initialise( $config )

This method is called before the categorise() method is called.

The $config parameter contains configuration data that was specified
in the AnalysisJob for that analyser. To register configuration
specification for you DlfCategoriser, you just need to define a
configuration specification under the name
I<analyser_name>_properties. This should be either a RecordSpec or
ObjectSpec.

=cut

sub initialise {
    croak "initialise() not implemented by ", ref $_[0] || $_[0];
}

=pod

=head2 categorise( $dlf )

Called one for each DLf records that should be categorised. The
categoriser should add the extended fields directly to the $dlf hash
reference.

=cut

sub categorise {
    croak "categorise() not implemented by ", ref $_[0] || $_[0];
}

=pod

=head2 finalise( $config )

This method is called after all the DLF records were categorised. 

The $config parameter contains configuration data that was specified
in the AnalysisJob for that analyser. To register configuration
specification for you DlfCategoriser, you just need to define a
configuration specification under the name
I<analyser_name>_properties. This should be either a RecordSpec or
ObjectSpec.

The default implementation does nothing.

=cut

sub finalise { 
    # Empty method
}

# keep perl happy
1;

__END__

=pod

=head1 SEE ALSO

Lire::DlfAnalyserProcess(3pm), Lire::DlfStore(3pm),
Lire::PluginManager(3pm), Lire::DlfAnalyser(3pm)

=head1 AUTHOR

Francis J. Lacoste <flacoste@logreport.org>

=head1 VERSION

$Id: DlfCategoriser.pm,v 1.6 2006/07/23 13:16:28 vanbaal Exp $

=head1 COPYRIGHT

Copyright (C) 2004 Stichting LogReport Foundation LogReport@LogReport.org

This file is part of Lire.

Lire is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program (see COPYING); if not, check with
http://www.gnu.org/copyleft/gpl.html.

=cut

