File Coverage

blib/lib/Wizard/SaveAble.pm
Criterion Covered Total %
statement 10 12 83.3
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 14 16 87.5


line stmt bran cond sub pod time code
1             # -*- perl -*-
2             #
3             # Wizard - A Perl package for implementing system administration
4             # applications in the style of Windows wizards.
5             #
6             #
7             # This module is
8             #
9             # Copyright (C) 1999 Jochen Wiedmann
10             # Am Eisteich 9
11             # 72555 Metzingen
12             # Germany
13             #
14             # Email: joe@ispsoft.de
15             # Phone: +49 7123 14887
16             #
17             # and Amarendran R. Subramanian
18             # Grundstr. 32
19             # 72810 Gomaringen
20             # Germany
21             #
22             # Email: amar@ispsoft.de
23             # Phone: +49 7072 920696
24             #
25             # All Rights Reserved.
26             #
27             # You may distribute under the terms of either the GNU General Public
28             # License or the Artistic License, as specified in the Perl README file.
29             #
30             # $Id$
31             #
32              
33 1     1   669 use strict;
  1         3  
  1         39  
34              
35 1     1   1118 use Symbol ();
  1         1022  
  1         25  
36 1     1   3000 use Data::Dumper ();
  1         7701  
  1         29  
37 1     1   492 use IO::AtomicFile ();
  0            
  0            
38             use File::Basename ();
39             use File::Path ();
40              
41             package Wizard::SaveAble;
42              
43             $Wizard::SaveAble::VERSION = '0.01';
44              
45              
46             =pod
47              
48             =head1 NAME
49              
50             Wizard::SaveAble - A package for automatically saved objects.
51              
52              
53             =head1 SYNOPSIS
54              
55             # Tell a SaveAble object that it's modified
56             $obj->Modified(1);
57              
58             # Tell the SaveAble object to store itself back to disk
59             $obj->Store();
60              
61              
62             =head1 DESCRIPTION
63              
64             An object of the class Wizard::SaveAble is something that knows whether
65             it has to be saved or not. To that end it offers methods like I
66             and I.
67              
68              
69             =head1 CLASS INTERFACE
70              
71             All methods are throwing a Perl exception in case of errors.
72              
73              
74             =head2 Constructors
75              
76             # Create an empty SaveAble object and associate a file name to it.
77             my $obj = Wizard::SaveAble->new('file' => $file);
78              
79             # Load a SaveAble object from a file.
80             my $obj = Wizard::SaveAble->new($file);
81              
82             # Same thing, but creating an empty object if $file doesn't exist
83             my $obj = Wizard::SaveAble->new('file' => $file, 'load' => 1);
84              
85             (Class method) There are two possible constructors for the
86             I class: The first is creating an empty object, you
87             typically use a subclass of I here. The most important
88             attribute is the I name where the object should later be stored.
89              
90             The other constructor is loading an already existing object from a file.
91             The object is automatically blessed into the same class again, typically
92             a subclass of Wizard::SaveAble.
93              
94             =cut
95              
96             sub _load {
97             my $proto = shift; my $file = shift;
98             my $self = do $file;
99             die "Failed to load Wizard::SaveAble object from $file: $@" if $@;
100             die "Error while loading $file: Object returned is not an instance"
101             . " of Wizard::SaveAble: " . (defined($self) ? $self : "undef")
102             unless UNIVERSAL::isa($self, "Wizard::SaveAble");
103             $self->Modified(0);
104             $self->File($file);
105             $self;
106             }
107              
108             sub new {
109             my $proto = shift;
110             return $proto->_load(shift) if @_ == 1;
111             my $self = { @_ };
112             my $file = delete $self->{'file'} if (exists($self->{'file'}));
113             if (exists($self->{'load'}) and delete $self->{'load'}) {
114             return $proto->_load($file) if $file and -f $file;
115             }
116             bless($self, (ref($proto) || $proto));
117             $self->Modified(1);
118             $self->File($file);
119             $self->CreateMe($file);
120             $self;
121             }
122              
123             sub CreateMe {
124             my $self = shift;
125             $self->{'_wizard_saveable_createme'} = shift if @_;
126             $self->{'_wizard_saveable_createme'};
127             }
128              
129             =pod
130              
131             =head2 Setting and Querying an objects status
132              
133             # Tell an object that it's modified
134             $obj->Modified(1);
135             # Query whether an object is modified
136             $modified = $obj->Modified()
137              
138             (Instance methods) The I method is used to determine whether an
139             object needs to be saved or not.
140              
141             =cut
142              
143             sub Modified {
144             my $self = shift;
145             if (@_) {
146             if (shift) {
147             $self->{'_wizard_saveable_modified'} = 1;
148             } else {
149             delete $self->{'_wizard_saveable_modified'};
150             }
151             }
152             exists($self->{'_wizard_saveable_modified'});
153             }
154              
155              
156             =pod
157              
158             =head2 Setting and Querying an objects file name
159              
160             # Set the objects associated file
161             $obj->File($file);
162             # Query the objects associated file
163             $file = $obj->File();
164              
165             (Instance methods) The I method is used to determine whether an
166             object needs to be saved or not.
167              
168             =cut
169              
170             sub File {
171             my $self = shift;
172             $self->{'_wizard_saveable_file'} = shift if @_;
173             $self->{'_wizard_saveable_file'};
174             }
175              
176              
177             =pod
178              
179             =head2 Storing an object to disk
180              
181             $obj->Store();
182              
183             (Instance Method) The object is stored back to disk into the file that
184             was fixed within the constructor.
185              
186             =cut
187              
188             sub Store {
189             my $self = shift;
190              
191             # Create a copy of the object to work with it.
192             my $copy = { %$self };
193             bless($copy, ref($self));
194              
195             return unless delete $copy->{'_wizard_saveable_modified'};
196              
197             delete $copy->{'_wizard_saveable_createme'};
198             my $file = delete $copy->{'_wizard_saveable_file'};
199             my $dir = File::Basename::dirname($file);
200             die "Failed to create directory $dir: $!"
201             unless -d $dir || File::Path::mkpath([$dir], 0, 0644);
202              
203             my $dump = Data::Dumper->new([$copy], ['obj']);
204             $dump->Indent(1);
205             my $fh = IO::AtomicFile->open($file, "w")
206             or die "Failed to create file $file: $!";
207             if (!$fh->print("my ", $dump->Dump()) || !$fh->close()) {
208             my $msg = $!;
209             $fh->delete();
210             die "Failed to write file $file: $msg";
211             }
212             $self->Modified(0);
213             }
214              
215              
216             =pod
217              
218             =head1 AUTHORS AND COPYRIGHT
219              
220             This module is
221              
222             Copyright (C) 1999 Jochen Wiedmann
223             Am Eisteich 9
224             72555 Metzingen
225             Germany
226              
227             Email: joe@ispsoft.de
228             Phone: +49 7123 14887
229              
230             and Amarendran R. Subramanian
231             Grundstr. 32
232             72810 Gomaringen
233             Germany
234              
235             Email: amar@ispsoft.de
236             Phone: +49 7072 920696
237              
238             All Rights Reserved.
239              
240             You may distribute under the terms of either the GNU General Public
241             License or the Artistic License, as specified in the Perl README file.
242              
243              
244             =head1 SEE ALSO
245              
246             L, L
247              
248             =cut
249