File Coverage

blib/lib/Treex/PML/Backend/Storable.pm
Criterion Covered Total %
statement 34 110 30.9
branch 0 46 0.0
condition 0 13 0.0
subroutine 12 20 60.0
pod 0 5 0.0
total 46 194 23.7


line stmt bran cond sub pod time code
1             package Treex::PML::Backend::Storable;
2 1     1   979 use Treex::PML;
  1         2  
  1         131  
3 1     1   20 use Storable qw(nstore_fd fd_retrieve);
  1         5  
  1         55  
4 1     1   7 use Treex::PML::IO qw( close_backend);
  1         2  
  1         55  
5 1     1   7 use strict;
  1         2  
  1         37  
6              
7 1     1   6 use vars qw($VERSION);
  1         3  
  1         44  
8             BEGIN {
9 1     1   31 $VERSION='2.24'; # version template
10             }
11 1     1   7 use UNIVERSAL::DOES;
  1         3  
  1         48  
12 1     1   7 use Scalar::Util qw(blessed reftype refaddr);
  1         3  
  1         1048  
13              
14             sub test {
15 0     0 0   my ($f,$encoding)=@_;
16 0 0         if (ref($f)) {
17 0           return $f->getline()=~/^pst0/;
18             } else {
19 0           my $fh = open_backend($f,"r");
20 0   0       my $test = $fh && test($fh,$encoding);
21 0           close_backend($fh);
22 0           return $test;
23             }
24             }
25              
26             sub open_backend {
27 0     0 0   Treex::PML::IO::open_backend(@_[0,1]);
28             }
29              
30             sub read {
31 0     0 0   my ($fd,$fs)=@_;
32 0           binmode($fd);
33 0           my $restore = fd_retrieve($fd);
34              
35 0           my $api_version = $restore->[6];
36 0 0         unless ($Treex::PML::COMPATIBLE_API_VERSION{ $api_version }) {
37 0 0         $api_version='0.001' unless defined $api_version;
38 0           warn "Warning: the binary file ".$fs->filename." is a dump of structures created by possibly incompatible Treex::PML API version $api_version (the current Treex::PML API version is $Treex::PML::API_VERSION)\n";
39             }
40              
41             # support for old Fslib-based documents:
42 0 0 0       if (ref($restore->[0]) eq 'FSFormat' and not defined($Fslib::VERSION)) {
43             # upgrade to Treex::PML
44             # warn "Warning: Detected Fslib-based file and Fslib is not loaded: upgrading to Treex::PML!\n";
45 0           upgrade_from_fslib($restore);
46             }
47              
48 0           $fs->changeTail(@{$restore->[2]});
  0            
49 0           $fs->[13]=$restore->[3]; # metaData
50 0           my $appData = delete $fs->[13]->{'StorableBackend:savedAppData'};
51 0 0         if ($appData) {
52 0           $fs->changeAppData($_,$appData->{$_}) foreach keys(%$appData);
53             }
54 0           $fs->changePatterns(@{$restore->[4]});
  0            
55 0           $fs->changeHint($restore->[5]);
56              
57             # place to update some internal stuff if necessary
58 0           my $schema = $fs->metaData('schema');
59 0 0 0       if (ref($schema) and !$schema->{-api_version}) {
60 0           $schema->convert_from_hash();
61 0           $schema->post_process();
62             }
63 0           $fs->changeFS($restore->[0]);
64 0           $fs->changeTrees(@{$restore->[1]});
  0            
65 0           $fs->FS->renew_specials();
66              
67             # $fs->_weakenLinks;
68             }
69              
70              
71             sub write {
72 0     0 0   my ($fd,$fs)=@_;
73 0           binmode($fd);
74 0           my $metaData = { %{$fs->[13]} };
  0            
75 0           my $ref = $fs->appData('ref');
76 0   0       $metaData->{'StorableBackend:savedAppData'}||={};
77 0           foreach my $savedAppData ($metaData->{'StorableBackend:savedAppData'}) {
78 0           $savedAppData->{'id-hash'} = $fs->appData('id-hash');
79             $savedAppData->{'ref'} = {
80             map {
81 0 0         my $val = $ref->{$_};
  0            
82 0 0         UNIVERSAL::DOES::does($val,'Treex::PML::Instance') ? ($_ => $val) : ()
83             } keys %$ref
84             } if ref $ref;
85             }
86 0           nstore_fd([$fs->FS,
87             $fs->treeList,
88             [$fs->tail],
89             $metaData,
90             [$fs->patterns],
91             $fs->hint,
92             $Treex::PML::API_VERSION
93             ],$fd);
94             }
95              
96             sub upgrade_from_fslib {
97 0     0 0   my @next = @_;
98 0           my %seen;
99 0           $seen{refaddr($_)}=1 for @next;
100 0           while (@next) {
101 0           my $object = shift @next;
102 0           my $ref = ref($object);
103 0 0         next unless $ref;
104 0           my $is = blessed($object);
105 0 0         if (defined $is) {
106 0 0         if ($is =~ /^Treex/) {
    0          
    0          
    0          
    0          
    0          
    0          
    0          
107             } elsif ($is eq 'FSNode') {
108 0           bless $object, 'Treex::PML::Node';
109             } elsif ($is eq 'Fslib::Type') {
110 0           bless $object, 'Treex::PML::Backend::Storable::CopmpatType';
111             } elsif ($is =~ /^Fslib::(.*)$/) {
112 0           bless $object, qq{Treex::PML::$1};
113             } elsif ($is =~ /^PMLSchema(::.*)?$/) {
114 0           bless $object, qq{Treex::PML::Schema$1};
115             } elsif ($is eq 'FSFile') {
116 0           bless $object, 'Treex::PML::Document';
117             } elsif ($is eq 'FSFormat') {
118 0           bless $object, 'Treex::PML::FSFormat';
119             } elsif ($is eq 'PMLInstance') {
120 0           bless $object, 'Treex::PML::Instance';
121             }
122 0           $ref = reftype($object);
123             }
124 0 0         for (($ref eq 'HASH') ? values(%$object)
    0          
    0          
125             : ($ref eq 'ARRAY') ? @$object
126             : ($ref eq 'SCALAR') ? $$object : ()) {
127 0   0       my $key = refaddr($_) || next;
128 0 0         push @next, $_ unless ($seen{$key}++);
129             }
130             }
131             }
132              
133             package Treex::PML::Backend::Storable::CopmpatType;
134 1     1   9 use Carp;
  1         4  
  1         87  
135 1     1   9 use warnings;
  1         2  
  1         32  
136 1     1   6 use strict;
  1         11  
  1         26  
137 1     1   6 use vars qw($AUTOLOAD);
  1         2  
  1         194  
138             # This is handler for obsoleted class 'Fslib::Type'
139             # which has no API-compatible counterpart in Treex::PML.
140             # The object is a pair (ARRAYref) containing PML schema and type declaration.
141             sub schema {
142 0     0     my ($self)=@_;
143 0           return $self->[0];
144             }
145             sub type_decl {
146 0     0     my ($self)=@_;
147 0           return $self->[1];
148             }
149             # delegate every method to the type
150             sub AUTOLOAD {
151 0     0     my $self = shift;
152 0 0         croak "$self is not an object" unless ref($self);
153 0           my $name = $AUTOLOAD;
154 0           $name =~ s/.*://; # strip fully-qualified portion
155 0           return $self->[1]->$name(@_);
156             }
157              
158             1;
159             __END__