package Lire::Config::XMLSpecListSpec;
use strict;
use base qw/Lire::Config::ListSpec/;
use Lire::Config::StringSpec;
use Lire::Config::ObjectSpec;
use Lire::Config::ListSpec;
use Lire::Config::ChartSpec;
use Lire::ReportSpec;
use Lire::FilterSpec;
use Lire::Utils qw/check_param/;
use Locale::TextDomain 'lire';
use Carp;
our $NAME_RE = qr/^([\w_-]+):([\w_.-]+)$/;
=pod
=head1 NAME
Lire::Config::XMLSpecListSpec - List of XML specifications.
=head1 DESCRIPTION
This Lire::Config::TypeSpec defines a special kind of ListSpec. It
overrides the has_component(), get(), component_names() and
components() methods so that every XML report specifications or filter
specifications are available. The specifications are created
dynamically at runtime.
=head2 new( 'name' => $name, 'type' => 'filters'|'reports )
Creates a new Lire::Config::XMLSpecListSpec object which will contains
a list of report or filter specifications configuration. The type
parameter is used to select whether Lire::ReportSpec or
Lire::FilterSpec will be creatd.
=cut
sub new {
my $self = shift->SUPER::new( @_ );
my $type = { @_ }->{'type'};
check_param( $type, 'type', qr/^filters|reports$/,
"'type' parameter should be either filters or reports" );
$self->{'_type'} = $type;
$self->{'_module'} = ( $type eq 'reports'
? 'Lire::ReportSpec' : 'Lire::FilterSpec' );
$self->{'_cache'} = {};
return $self;
}
=pod
=head2 type()
Returns the type of specification contained by this object.
=cut
sub type {
return $_[0]{'_type'};
}
=pod
=head2 has_component( $name )
This spec will return true when $name is of the form
I<superservice>:I<id> and there is an available I<id> specification
defined in I<superservice>. It returns false otherwise.
=cut
sub has_component {
my ( $self, $name ) = @_;
check_param( $name, 'name' );
my ( $super, $type ) = $name =~ /$NAME_RE/;
return 0 unless defined $super && defined $type;
return Lire::DlfSchema->has_superservice( $super ) &&
$self->{'_module'}->has_spec( $super, $type );
}
=pod
=head2 component_names()
Returns an array containing the configuration name of all available
specifications.
=cut
sub component_names {
my $self = $_[0];
my @specs = ();
foreach my $super ( Lire::DlfSchema->superservices() ) {
foreach my $type ( @{$self->{'_module'}->list_specs( $super )} ) {
push @specs, "$super:$type";
}
}
return @specs;
}
=pod
=head2 get( $name )
Returns an Lire::Config::ObjectSpec specification for the component
named $name. The ObjectSpec will instantiate a Lire::ReportSpec or
Lire::FilterSpec of the appropriate type.
=cut
sub get {
my ( $self, $name ) = @_;
croak "no component named '$name'" unless $self->has_component( $name );
return $self->{'_cache'}{$name}
if exists $self->{'_cache'}{$name};
my ( $super, $type ) = $name =~ /$NAME_RE/;
my $xml_spec = $self->{'_module'}->load( $super, $type );
my $spec =
new Lire::Config::ObjectSpec( 'name' => $name,
'i18n_domain' => "lire-$super",
'class' => $self->{'_module'},
'summary' => $xml_spec->title(),
'description' => $xml_spec->description(),
'label' => 'id',
);
$spec->add( new Lire::Config::StringSpec( 'name' => 'id',
'valid-re' => '^[\w.:-]+$',
'summary' => N__( 'Identifier' ),
'description' => '<para>' . join( "", N__( 'Identifier that uniquely identifies this specification among the report configuration. When two reports are merged, specifications with the same identifier are merged together.' ) ) . "</para>" ) );
my $title = new Lire::Config::StringSpec( 'name' => 'title',
'required' => 0,
'summary' => N__( 'Custom Title' ),
'description' => '<para>' . join( "", N__( 'If this parameter is set, its value will be used instead of the display title specified in the specification. This string will interpolate $name_ref with the parameter\'s value when the report is generated.' ) ) . '</para>' );
$title->default( $title->instance( 'value' => $xml_spec->display_title()));
$spec->add( $title );
foreach my $name ( $xml_spec->param_names() ) {
$spec->add( $xml_spec->param( $name )->as_type_spec() );
}
$self->_set_charts_spec( $xml_spec, $spec );
return $self->{'_cache'}{$name} = $spec;
}
sub _set_charts_spec {
my ( $self, $xml_spec, $spec ) = @_;
return unless $xml_spec->isa( 'Lire::ReportSpec' );
my $charts = new Lire::Config::ListSpec( 'name' => 'charts',
'summary' => N__( 'Charts' ),
'description' => '<para>' . join ( "", N__( "Parameters for the charts that should be generated from this subreport's data" ) ) . "</para>" );
$spec->add( $charts );
$charts->add( new Lire::Config::ChartSpec( 'name' => 'chart',
'summary' => N__( 'Chart' ),
'description' => '<para>' . join( "", N__( "Parameters for a chart that should be generated from this subreport's data." ) ) . "</para>" ) );
my $default = $charts->instance();
foreach my $cfg ( @{$xml_spec->chart_configs()} ) {
my $default_chart = $cfg->clone();
$default_chart->{'spec'} = $charts->get( 'chart' );
$default->append( $default_chart );
}
$charts->default( $default );
return;
}
=pod
=head2 components()
Returns an array containing all the Lire::Config::ObjectSpec defining
the available specifications.
=cut
sub components {
my $self = $_[0];
my @comps = ();
foreach my $name ( $self->component_names() ) {
push @comps, $self->get( $name );
}
return @comps;
}
1;
__END__
=pod
=head2 SEE ALSO
Lire::Config::ReportSectionSpec(3pm), Lire::Config::ReportSpec(3pm),
Lire::ReportSpec(3pm), Lire::FilterSpec(3pm).
=head1 VERSION
$Id: XMLSpecListSpec.pm,v 1.8 2006/07/23 13:16:31 vanbaal Exp $
=head1 AUTHOR
Francis J. Lacoste <flacoste@logreport.org>
=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
syntax highlighted by Code2HTML, v. 0.9.1