Biblio-COUNTER

 view release on metacpan or  search on metacpan

lib/Biblio/COUNTER.pm  view on Meta::CPAN

package Biblio::COUNTER;

use Biblio::COUNTER::Report;

use warnings;
use strict;

use vars qw($VERSION);

$VERSION = '0.11';

sub report {
    my ($cls, $how, %args) = @_;
    if (ref($how) eq 'ARRAY') {
        die "Instantiating a report from an array not yet implemented";
    }
    elsif (ref($how)) {
        # Read report from a filehandle
        my $fh = $how;
        my $callbacks = delete($args{'callback'}) || {};
        my $report = Biblio::COUNTER::Report->new(
            %args,
            'fh' => $fh,
            'callback' => {
                'output' => sub {
                    my ($self, $output) = @_;
                    print $output, "\n";
                },
                %$callbacks,
            },
            'rows'     => [],
            'errors'   => 0,
            'warnings' => 0,
            # Current position within the report
            'r' => 0,
            'c' => '',
            # Current scope (REPORT, HEADER, or RECORD)
            'scope' => undef,
            # Current field (NAME, DESCRIPTION, etc. or TITLE, PUBLISHER, etc.)
            'field' => undef,
            # Containers
            'report' => undef,
            'header' => undef,
            'record' => undef,
            'container' => undef,  # Current container
        );
    }
    else {
        # Instantiate a named report, e.g., "Journal Report 1 (R2)"
        my $name = $how;
        my ($genre, $number, $release) = $cls->_parse_report_name($name);
        die "Unrecognized report type: $name"
            unless defined $genre;
        # Create the "model" object
        $cls = "Biblio::COUNTER::Report::Release${release}::${genre}Report${number}";
        die "Unimplemented report type: $name"
            unless eval "use $cls; 1";
        return $cls->new(%args);
    }
}

sub _parse_report_name {
    my ($cls, $name) = @_;
    my ($genre, $number, $release);
    if ($name =~ s/^\s*(Journal|Database|Book)\s+Report\s+(\w+)\s*//) {
        ($genre, $number) = ($1, $2);
    }
    else {
        return;
    }
    if ($name =~ /^\(R?(\d+[a-z]?)\)/) {
        $release = $1;
    }
    else {
        $release = 2;  # XXX Safe to default?
    }
    return ($genre, $number, $release);
}


1;


=pod

=head1 NAME

Biblio::COUNTER - COUNTER Codes of Practice report processing

lib/Biblio/COUNTER.pm  view on Meta::CPAN

Each I<$code> must be a coderef, not the name of a function or method.

If an event is not specified in this hash, then the default action for the
event will be taken.

=back

=item B<name>

Get or set the report's name: this is the official name defined by the COUNTER
codes of practice.  See L<REPORTS SUPPORTED> for a complete list of the
reports supported by this verison of L<Biblio::COUNTER|Biblio::COUNTER>.

=item B<code>

Get or set the report's code: this is the short string (e.g., C<JR1>)
that identifies the type, B<but not the version>, of a COUNTER report.

=item B<description>

Get or set the report's description: this is the official description
defined by the COUNTER codes of practice.  For example, the C<Journal
Report 1 (R2)> report has the description C<Number of Successful
Full-Text Article Requests by Month and Journal>.

=item B<date_run>

Get or set the date on which the report was run.  The date, if valid, is in
the ISO8601 standard form C<YYYY-MM-DD>.

=item B<criteria>

Get or set the report criteria.  This is a free text field.

=item B<periods>

Get or set the periods for which the report contains counts.  To
simplify things, periods are returned (and must be set) in the ISO 8601
standard form C<YYYY-MM>.

=item B<publisher>

Get or set the publisher common to all of the resources in the report.

=item B<platform>

Get or set the platform common to all of the resources in the report.

=back

=head1 CALLBACKS

While processing a report, a number of different B<events> occur. For
example,  a B<fixed> event occurs when a field whose value is invalid
is corrected.  For event different kind of event, a B<callback> may be
specified that is triggered each time the event occurs; see the B<report>
method for how to specify a callback.

Callbacks must be coderefs, not function or method names.

For example, the following callbacks may be used to provide an indication of
the progress in processing it:

    $record_number = 0;
    %callbacks = (
        'begin_report' => sub {
            print STDERR "Beginning report: ";
        },
        'end_header' => sub {
            my ($report, $header) = @_;
            print STDERR $report->name, "\n";
        }
        'end_record' => sub {
            my ($report, $record) = @_;
            ++$record_number;
            print STDERR "$record_number "
                if $record_number % 20 == 0;
            print STDERR "\n"
                if $record_number % 200 == 0;
        },
        'end_report' => sub {
            my ($report) = @_;
            if ($report->is_valid) {
                print STDERR "OK\n";
            }
            else {
                print STDERR "INVALID\n";
            }
        },
    );

By default, the only callback defined is for B<output>; it prints each
line of input (corrected, if there were correctable problems) to
standard output. (Spurious blank lines are not printed.)

Events fall into four broad categories: B<structure>, B<validation>,
B<tracing>, and B<data>.

=head2 Structure

Logically, a COUNTER report has the following structure:

    report
        header
        body
            record
            record
            ...

=over 4

=item B<begin_file>(I<$report>, I<$file>)

Parsing of the given file is beginning. This is always the first event
triggered.  At the time this callback is invoked, the report has not yet been
identified.

=item B<end_file>(I<$report>, I<$file>)

Parsing of the given file has ended. This is always the last event
triggered.

=item B<begin_report>(I<$report>)

Processing of the report is beginning.  At the time this callback is invoked,



( run in 2.259 seconds using v1.01-cache-2.11-cpan-d7f47b0818f )