File Coverage

lib/Any/Renderer/Data/Serializer.pm
Criterion Covered Total %
statement 7 9 77.7
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 12 83.3


line stmt bran cond sub pod time code
1             package Any::Renderer::Data::Serializer;
2              
3             # $Id: Serializer.pm,v 1.5 2006/09/04 12:15:54 johna Exp $
4              
5 1     1   6 use strict;
  1         1  
  1         51  
6 1     1   5 use vars qw($VERSION %Formats);
  1         30  
  1         66  
7 1     1   566 use Data::Serializer;
  0            
  0            
8             use File::Find;
9              
10             #If true data::serializer modules are loaded to check they compile
11             #Set to true value for safety at the cost of performance/memory (e.g. in a dev/test env)
12             use constant MUST_COMPILE => $ENV{ANY_RENDERER_DS_SAFE};
13              
14             $VERSION = sprintf"%d.%03d", q$Revision: 1.5 $ =~ /: (\d+)\.(\d+)/;
15              
16             sub new
17             {
18             my ( $class, $format, $options ) = @_;
19            
20             unless($Formats{$format}) {
21             _scan_available_formats(); #Discover if it's appeared recently
22             die("The format '$format' doesn't appear to be supported by Data::Serializer") unless($Formats{$format});
23             }
24            
25             my $self = {
26             'format' => $format,
27             'options' => $options,
28             };
29              
30             bless $self, $class;
31             return $self;
32             }
33              
34             sub render
35             {
36             my ( $self, $data ) = @_;
37              
38             TRACE ( "Rendering w/Data::Serializer" );
39             DUMP ("Input data structure", $data );
40              
41             my $ds = new Data::Serializer('serializer' => $self->{format}, 'options' => $self->{options}) or die($!);
42             my $string = $ds->raw_serialize($data);
43             TRACE("Rendered as: " . $string);
44             return $string;
45             }
46              
47             sub requires_template
48             {
49             my ( $format ) = @_;
50             return 0; #None do
51             }
52              
53             sub available_formats
54             {
55             _scan_available_formats();
56             return [ sort keys %Formats ];
57             }
58              
59              
60             sub _scan_available_formats
61             {
62             TRACE ( "Generating list of all possible formats" );
63              
64             my @possible_locations = grep { -d $_ } map { File::Spec->catdir ( $_, split ( /::/, 'Data::Serializer' ) ) } @INC;
65              
66             my %found;
67             my $collector = sub
68             {
69             return unless $_ =~ /\.pm$/;
70              
71             my $file = $File::Find::name;
72             $file =~ s/\Q$File::Find::topdir\E//;
73             $file =~ s/\.pm$//;
74              
75             my @dirs = File::Spec->splitdir ( $file );
76             shift @dirs;
77             $file = join ( "::", @dirs );
78              
79             return if $file eq 'Cookbook'; #Skip non-backend modules in D::S namespace
80              
81             $found{ $file } = 1;
82             };
83              
84             File::Find::find ( $collector, @possible_locations );
85            
86             #Only add those that compile
87             if(MUST_COMPILE) {
88             %Formats = ();
89             foreach my $module (keys %found) {
90             eval {
91             _load_module($module);
92             $Formats{$module} = 1;
93             };
94             warn($@) if($@);
95             }
96             } else {
97             %Formats = %found;
98             }
99            
100             DUMP("Available formats", \%Formats);
101             }
102              
103             sub _load_module {
104             my $file = shift;
105              
106             my $module = "Data::Serializer::" . $file;
107             TRACE ( "Loading Data::Serializer backend '" . $module . "'" );
108             die ("Module name $module looks dodgy - will not load") unless($module =~ /^[\w:]+$/); #Protect against code injection
109             eval "require " . $module;
110             die ("Data::Serializer - problem loading backend module: ". $@ ) if ( $@ );
111            
112             return $module;
113             }
114              
115             sub TRACE {}
116             sub DUMP {}
117              
118             1;
119              
120             =head1 NAME
121              
122             Any::Renderer::Data::Serializer - adaptor for Any::Renderer to use any Data::Serializer backends
123              
124             =head1 SYNOPSIS
125              
126             use Any::Renderer;
127              
128             my %options = ();
129             my $format = "YAML"; #One of the formats provided by Data::Serializer
130             my $r = new Any::Renderer ( $format, \%options );
131              
132             my $data_structure = [...]; # arbitrary structure code
133             my $string = $r->render ( $data_structure );
134              
135             =head1 DESCRIPTION
136              
137             Any::Renderer::Data::Serializer renders any Perl data structure passed to it into
138             a string representation using modules exposing the Data::Serializer API.
139              
140             =head1 FORMATS
141              
142             All the formats supported by Data::Serializer. Try this to find out what's available on your system:
143              
144             perl -MAny::Renderer::Data::Serializer -e "print join(qq{\n}, sort @{Any::Renderer::Data::Serializer::available_formats()})"
145              
146             =head1 METHODS
147              
148             =over 4
149              
150             =item $r = new Any::Renderer::Data::Serializer($format, \%options)
151              
152             See L for a description of valid values for C<$format>.
153             C<%options> are passed through to the backend module (e.g. to XML::Dumper)
154              
155             =item $string = $r->render($data_structure)
156              
157             The main method.
158              
159             =item $bool = Any::Renderer::Data::Serializer::requires_template($format)
160              
161             This will be false for these formats.
162              
163             =item $list_ref = Any::Renderer::Data::Serializer::available_formats()
164              
165             This will discover the formats supported by your Data::Serializer installation.
166              
167             =back
168              
169             =head1 ENVIRONMENT
170              
171             Set the C environment variable to a true value if you want to check each Data::Serializer
172             backend compiles before adding it to the list of available formats.
173             This is safer in that modules with missing dependencies are not advertised as available but it incurs a
174             CPU and memory overhead.
175              
176             =head1 SEE ALSO
177              
178             L, L
179              
180             =head1 VERSION
181              
182             $Revision: 1.5 $ on $Date: 2006/09/04 12:15:54 $ by $Author: johna $
183              
184             =head1 AUTHOR
185              
186             John Alden
187              
188             =head1 COPYRIGHT
189              
190             (c) BBC 2006. This program is free software; you can redistribute it and/or modify it under the GNU GPL.
191              
192             See the file COPYING in this distribution, or http://www.gnu.org/licenses/gpl.txt
193              
194             =cut