File Coverage

blib/lib/Repository/Simple/Engine.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 Repository::Simple::Engine;
2              
3 1     1   47021 use strict;
  1         3  
  1         34  
4 1     1   5 use warnings;
  1         2  
  1         42  
5              
6             our $VERSION = '0.06';
7              
8 1     1   11040 use Readonly;
  0            
  0            
9             use Repository::Simple::Util;
10              
11             our @CARP_NOT = qw( Repository::Simple::Util );
12              
13             require Exporter;
14              
15             our @ISA = qw( Exporter );
16              
17             our @EXPORT_OK = qw( $NODE_EXISTS $PROPERTY_EXISTS $NOT_EXISTS );
18             our %EXPORT_TAGS = ( exists_constants => \@EXPORT_OK );
19              
20             # Return values for path_exists()
21             Readonly our $NODE_EXISTS => 1;
22             Readonly our $PROPERTY_EXISTS => 2;
23             Readonly our $NOT_EXISTS => 0;
24              
25             =head1 NAME
26              
27             Repository::Simple::Engine - Abstract base class for storage engines
28              
29             =head1 DESCRIPTION
30              
31             This documentation is meant for developers wishing to implement a content repository engine. If you just want to know how to use the repository API, L is where you'll want to go.
32              
33             A developer may extend this class to provide a new storage engine. Each engine is simply an implementation of the bridge API specified here and requires only a single package.
34              
35             To implement a content repository engine, create a subclass of L that implements all the methods described in this documentation.
36              
37             package Repository::Simple::Engine::MyCustom;
38              
39             use strict;
40             use warnings;
41              
42             use base qw( Repository::Simple::Engine );
43              
44             sub new { ... }
45             sub node_type_named { ... }
46             sub property_type_named { ... }
47             sub path_exists { ... }
48             sub node_type_of { ... }
49             sub property_type_of { ... }
50             sub nodes_in { ... }
51             sub properties_in { ... }
52             sub get_scalar { ... }
53             sub set_scalar { ... }
54             sub get_handle { ... }
55             sub set_handle { ... }
56             sub namespaces { ... }
57             sub has_permission { ... }
58              
59             =head1 METHODS
60              
61             Every storage engine must implement the following methods:
62              
63             =over
64              
65             =item $engine = Repository::Simple::Engine-Enew(@args)
66              
67             This method constructs an instance of the engine. The arguments can be anything you want. The C method of L will pass the arguments directly to the new method upon creation. I.e.,
68              
69             my $repository = Repository::Simple->attach(
70             MyEngine => qw( a b c )
71             );
72              
73             would effectively call:
74              
75             Repository::Simple::Engine::MyEngine->new('a', 'b', 'c');
76              
77             This interface doesn't define anything specific regarding these arguments.
78              
79             This method must return an instance of the storage engine upon which all the other methods may be called.
80              
81             A basic default implementation is provided that simply treats all arguments given as a hash and blesses that hash into the class. Therefore, you can use the built-in implementation like this:
82              
83             sub new {
84             my ($class, $some_arg) = @_;
85            
86             # Do some manipulations on $some_arg...
87              
88             my $self = $class->SUPER::new( some_arg => $some_arg );
89              
90             # Do some manipulations on $self
91            
92             return $self;
93             }
94              
95             =cut
96              
97             sub new {
98             my $class = shift;
99              
100             return bless { @_ }, $class;
101             }
102              
103             =item $exists = $engine-Epath_exists($path)
104              
105             Returns information regarding whether a given path refers to a node, a property, or nothing. The method must return one of the following values:
106              
107             =over
108              
109             =item C<$NOT_EXISTS>
110              
111             There is no node or property at the given path, C<$path>.
112              
113             =item C<$NODE_EXISTS>
114              
115             There is a node at the given path, C<$path>.
116              
117             =item C<$PROPERTY_EXISTS>
118              
119             There is a property at the given path, C<$path>.
120              
121             =back
122              
123             These can be imported from the L package:
124              
125             use Repository::Simple::Engine qw(
126             $NOT_EXISTS $NODE_EXISTS $PROPERTY_EXISTS
127             );
128              
129             # OR
130             use Repository::Simple::Engine qw( :exists_constants );
131              
132             This method must be implemented by subclasses. No implementation is provided.
133              
134             =cut
135              
136             sub path_exists {
137             die 'path_exists() must be implemented in subclass';
138             }
139              
140             =item $node_type = $engine-Enode_type_named($name)
141              
142             Given a node type name, this method returns an instance of L for the matching node type or C if no node type by the given name exists.
143              
144             This method must be implemented by subclasses. No implementation is provided.
145              
146             =cut
147              
148             sub node_type_named {
149             die "node_type_named() must be implemented by subclass";
150             }
151              
152             =item $property_type = $engine-Eproperty_type_named($name)
153              
154             Given a property type name, this method returns an instance of L for the matching property type or C if no property type by the given name exists.
155              
156             This method must be implemented by subclasses. No implementation is provided.
157              
158             =cut
159              
160             sub property_type_named {
161             die "property_type_named() must be implemented by subclass";
162             }
163              
164             =item @names = $engine-Enodes_in($path)
165              
166             Given a path, this method should return all the child nodes of that path or an empty list if the node found has no children. If the given path itself does not exist, the method must die.
167              
168             The nodes should be returned as names relative to the given path.
169              
170             This method must be implemented by subclasses. No implementation is provided.
171              
172             =cut
173              
174             sub nodes_in {
175             die 'nodes_in() must be implemented by subclass';
176             }
177              
178             =item @names = $engine-Eproperties_in($path)
179              
180             Given a path, this method should return all the child properties of the node at the given path or an empty list if the node found has no children. If the given path itself does not exist or does not refer to a node, the method must die.
181              
182             Properties must be returned as names relative to the given path.
183              
184             This method must be implemented by subclasses. No implementation is provided.
185              
186             =cut
187              
188             sub properties_in {
189             die 'properties_in() must be implemented by subclass';
190             }
191              
192             =item $node_type = $engine-Enode_type_of($path)
193              
194             Given a path, this method should return the L object for the node at that path. If there is no node at that path, then the method must die.
195              
196             This method must be implemented by subclasses. No implementation is provided.
197              
198             =cut
199              
200             sub node_type_of {
201             die 'node_type_of() must be implemented by subclass';
202             }
203              
204             =item $property_type = $engine-Eproperty_type_of($path)
205              
206             Return the property type of the given class via a L instance. If there is no property at that path, then the method must die.
207              
208             This method must be implemented by subclasses. No implementation is provided.
209              
210             =cut
211              
212             sub property_type_of {
213             die 'property_type_of() must be implemented by subclass';
214             }
215              
216             =item $scalar = $engine-Eget_scalar($path)
217              
218             Return the value of the property at the given path as a scalar value.
219              
220             This method must be implemented by subclasses. No implementation is provided.
221              
222             =cut
223              
224             sub get_scalar {
225             die 'get_scalar() must be implemented by subclass';
226             }
227              
228             =item $engine-Eset_scalar($path, $value)
229              
230             Set the value stored the property at C<$path> to the scalar value C<$scalar>.
231              
232             This method is optional. If your engine does not support writes, then it does
233             not need to define this method.
234              
235             See C for information on how these changes are actually committed.
236              
237             =cut
238              
239             sub set_scalar {
240             die 'set_scalar() is not supported.';
241             }
242              
243             =item $handle = $engine-Eget_handle($path, $mode)
244              
245             Return the value of the property at the given path as an IO handle, with the given mode, C<$mode>. The C<$mode> must be one of:
246              
247             =over
248              
249             =item *
250              
251             "<"
252              
253             =item *
254              
255             ">"
256              
257             =item *
258              
259             ">>"
260              
261             =item *
262              
263             "+<"
264              
265             =item *
266              
267             "+>"
268              
269             =item *
270              
271             "+>>"
272              
273             =back
274              
275             These have the same meaning as the Perl C built-in (i.e., read, write, append, read-write, write-read, append-read).
276              
277             This method must be implemented by subclasses. No implementation is provided.
278              
279             An implementation must support reading properties by handle for all properties, but is not required to implement write or append handles. If writes or appends are not available, the method must throw an exception when an unsupported file handle type is requested.
280              
281             The user is required B to call C on any file handle returned via this method, but might do so anyway. The result of such behavior is undefined. It is suggested that the engine should make sure any returned file handles are closed when the appropriate save handle is called.
282              
283             Whether or not writes/appends are supported does not affect whether or not C is supported.
284              
285             See C for information on how these changes are actually committed.
286              
287             =cut
288              
289             sub get_handle {
290             die 'get_handle() must be implemented by subclass';
291             }
292              
293             =item $engine-Eset_handle($path, $handle)
294              
295             This method allows the user to set a value using a custom file handle. This
296             file handle must be a read-handle ready to read immediately using the C or C. This specification recommends the use of L or L for creating these file handles.
297              
298             This operation is optional and does not need to be implemented if the engine does not handle write operations. Whether this method is implemented does not affect whether or not C supports writes/appends.
299              
300             See C for information on how these changes are actually committed.
301              
302             =cut
303              
304             sub set_handle {
305             die 'set_handle() is not supported';
306             }
307              
308             =item $namespaces = $engine-Enamespaces
309              
310             This method returns a reference to a hash of all the namespaces the storage engine currently supports. The keys are the prefixes and the values are URLs.
311              
312             =cut
313              
314             sub namespaces {
315             die 'namespaces() must be implemented by subclass';
316             }
317              
318             =item $test = $engine-Ehas_permission($path, $action)
319              
320             Tests to see if the current engine session has permission to perform the given action, C<$action>, on path, C<$path>. This method should return a true value if permissions would allow the action to proceed. Return false if the action would fail. The repository will attempt to guarantee that this method will not be called when it is not applicable.
321              
322             The C<$action> is one of the constants described under C in the documentation for L.
323              
324             =cut
325              
326             sub has_permission {
327             die 'has_permission() must be implemented by subclass';
328             }
329              
330             =item $engine-Esave_property($path)
331              
332             This method is responsible for committing changes made by C, C (using a write or append file handle), and C. If any of these methods are implemented, this method must also be implemented.
333              
334             Changes made by one of the mutator methods must be set on the property given path, C<$path>, by the time C returns. However, the changes may be committed sooner.
335              
336             The implementation of this method is optional, but required if any of C, writes/appends via C, or C are implemented.
337              
338             =cut
339              
340             sub save_property {
341             die 'save_property() is not supported'
342             }
343              
344             =back
345              
346             =head1 SEE ALSO
347              
348             L
349              
350             =head1 AUTHOR
351              
352             Andrew Sterling Hanenkamp, Ehanenkamp@cpan.orgE
353              
354             =head1 LICENSE AND COPYRIGHT
355              
356             Copyright 2006 Andrew Sterling Hanenkamp Ehanenkamp@cpan.orgE. All
357             Rights Reserved.
358              
359             This module is free software; you can redistribute it and/or modify it under
360             the same terms as Perl itself. See L.
361              
362             This program is distributed in the hope that it will be useful, but WITHOUT
363             ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
364             FOR A PARTICULAR PURPOSE.
365              
366             =cut
367              
368             1