fixed error message display bug in Reset Password
[catagits/Reaction.git] / lib / Reaction / InterfaceModel / Collection.pm
1 package Reaction::InterfaceModel::Collection;
2
3 use Reaction::Class;
4 use Scalar::Util qw/refaddr blessed/;
5 use aliased 'Reaction::Meta::InterfaceModel::Object::DomainModelAttribute';
6
7 # WARNING - DANGER: this is just an RFC, please DO NOT USE YET
8
9 use namespace::clean -except => [ qw(meta) ];
10 extends "Reaction::InterfaceModel::Object";
11
12
13
14 # consider supporting slice, first, iterator, last etc.
15 # pager functionality should probably be a role
16
17 # IM objects don't have write methods because those are handled through actions,
18 # no support for write actions either unless someone makes a good case for it
19 # many models may not even be writable, so we cant make that assumption...
20
21 # I feel like we should hasa result_class or object_class ?
22 # having this here would remove a lot of PITA complexity from
23 # ObjectClass and SchemaClass when it comes to munging with internals
24
25 #Answer: No, because collections should be able to hold more than one type of object
26
27 # ALL IMPLEMENTATIONS ARE TO ILLUSTRATE POSSIBLE BEHAVIOR ONLY. DON'T CONSIDER
28 # THEM CORRECT, OR FINAL. JUST A ROUGH DRAFT.
29
30 #domain_models are 'ro' unless otherwise specified
31 has _collection_store => (
32                           is  => 'rw',
33                           isa => 'ArrayRef',
34                           lazy_build => 1,
35                           clearer    => "_clear_collection_store",
36                           metaclass  => DomainModelAttribute,
37                          );
38
39 has 'member_type' => (is => 'ro', isa => 'ClassName');
40 sub _build__collection_store { [] };
41 sub members {
42   my $self = shift;
43   return @{ $self->_collection_store };
44 };
45
46 #return new member or it's index # ?
47 sub add_member {
48   my $self = shift;
49   my $new  = shift;
50   confess "Argument passed is not an object" unless blessed $new;
51   confess "Object Passed does not meet constraint isa Reaction::InterfaceModel::Object"
52     unless $new->isa('Reaction::InterfaceModel::Object');
53   my $store = $self->_collection_store;
54   push @$store, $new;
55   return $#$store; #return index # of inserted item
56 };
57 sub remove_member {
58   my $self = shift;
59   my $rem = shift;
60   confess "Argument passed is not an object" unless blessed $rem;
61   confess "Object Passed does not meet constraint isa Reaction::InterfaceModel::Object"
62     unless $rem->isa('Reaction::InterfaceModel::Object');
63
64   my $addr = refaddr $rem;
65   @{ $self->_collection_store } = grep {$addr ne refaddr $_ } @{ $self->_store };
66 };
67
68 #that was easy..
69 sub count_members {
70   my $self = shift;
71   return scalar @{ $self->_collection_store };
72 };
73
74 __PACKAGE__->meta->make_immutable;
75
76
77 1;
78
79 =head1 NAME
80
81 Reaction::InterfaceModel::Collection - Generic collections of
82 L<Reaction::InterfaceModel::Object>s
83
84 =head1 DESCRIPTION
85
86 The base class for C<InterfaceModel::Collection>s. The functionality implemented here
87 is minimal and it is expected that specialized collections be built by sublclassing
88 this and exploiting the roles system.
89
90 =head1 METHODS
91
92 =head2 members
93
94 Returns a list containing all known members of the collection
95
96 =head2 add_member $object
97
98 Will add the object passed to the collection
99
100 =head2 remove_member $object
101
102 Removed the object passed from the collection, if present
103
104 =head2 count_members
105
106 Returns the number of objects in the collection.
107
108 =head1 ATTRIBUTES
109
110 =head2 _collection_store
111
112 Read-write & lazy_build. Holds the arrayref where the collection of objects is
113 presently stored. Has a clearer of C<_clear_collection_store> and a predicate of
114  C<_has_collection_store>.
115
116 =head1 PRIVATE METHODS
117
118 _build__collection_store
119
120 Builder method for attribute_collection_store, returns an empty arrayref
121
122 =head1 AUTHORS
123
124 See L<Reaction::Class> for authors.
125
126 =head1 LICENSE
127
128 See L<Reaction::Class> for the license.
129
130 =cut