Mercurial > pub > Impl
annotate Lib/IMPL/Class/Property/Base.pm @ 250:129e48bb5afb
DOM refactoring
ObjectToDOM methods are virtual
QueryToDOM uses inflators
Fixed transform for the complex values in the ObjectToDOM
QueryToDOM doesn't allow to use complex values (HASHes) as values for nodes (overpost problem)
author | sergey |
---|---|
date | Wed, 07 Nov 2012 04:17:53 +0400 |
parents | 6d8092d8ce1b |
children | 6253872024a4 |
rev | line source |
---|---|
59
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
1 package IMPL::Class::Property::Base; |
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
2 use strict; |
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
3 |
230 | 4 use IMPL::Const qw(:all); |
59
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
5 |
60
b0c068da93ac
Lazy activation for the configuration objects (final concept)
wizard
parents:
59
diff
changeset
|
6 sub factoryParams { qw($class $name $set $get $validator) }; |
59
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
7 |
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
8 my %factoryCache; |
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
9 |
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
10 my $accessor_get_no = 'die new IMPL::Exception(\'The property is write only\',$name,$class) unless $get;'; |
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
11 my $accessor_set_no = 'die new IMPL::Exception(\'The property is read only\',$name,$class) unless $set;'; |
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
12 |
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
13 my $custom_accessor_get = 'unshift @_, $this and goto &$get;'; |
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
14 my $custom_accessor_set = 'unshift @_, $this and goto &$set;'; |
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
15 |
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
16 my $validator_code = '$this->$validator(@_);'; |
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
17 |
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
18 my %access_code = ( |
230 | 19 ACCESS_PUBLIC , "", |
20 ACCESS_PROTECTED, "die new IMPL::Exception('Can\\'t access the protected member',\$name,\$class,scalar caller) unless UNIVERSAL::isa(scalar caller,\$class);", | |
21 ACCESS_PRIVATE, "die new IMPL::Exception('Can\\'t access the private member',\$name,\$class,scalar caller) unless caller eq \$class;" | |
59
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
22 ); |
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
23 |
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
24 my $virtual_call = q( |
194 | 25 my $method = $this->can($name); |
59
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
26 return $this->$method(@_) unless $method == $accessor or caller->isa($class); |
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
27 ); |
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
28 |
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
29 my $owner_check = "die new IMPL::Exception('Set accessor is restricted to the owner',\$name,\$class,scalar caller) unless caller eq \$class;"; |
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
30 |
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
31 sub GenerateAccessors { |
194 | 32 my ($self,$param,@params) = @_; |
33 | |
34 my %accessors; | |
35 | |
36 if (not ref $param) { | |
230 | 37 if ($param & PROP_LIST) { |
38 $accessors{get} = ($param & PROP_GET) ? $self->GenerateGetList(@params) : undef; | |
39 $accessors{set} = ($param & PROP_SET) ? $self->GenerateSetList(@params) : undef; | |
194 | 40 } else { |
230 | 41 $accessors{get} = ($param & PROP_GET) ? $self->GenerateGet(@params) : undef; |
42 $accessors{set} = ($param & PROP_SET) ? $self->GenerateSet(@params) : undef; | |
194 | 43 } |
230 | 44 $accessors{owner} = (($param & PROP_OWNERSET) == PROP_OWNERSET) ? $owner_check : ""; |
194 | 45 } elsif (UNIVERSAL::isa($param,'HASH')) { |
46 $accessors{get} = $param->{get} ? $custom_accessor_get : undef; | |
47 $accessors{set} = $param->{set} ? $custom_accessor_set : undef; | |
48 $accessors{owner} = ""; | |
49 } else { | |
50 die new IMPL::Exception('The unsupported accessor/mutators supplied',$param); | |
51 } | |
52 | |
53 return \%accessors; | |
59
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
54 } |
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
55 |
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
56 sub GenerateSet { |
194 | 57 die new IMPL::Exception("Standard accessors not supported",'Set'); |
59
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
58 } |
194 | 59 |
59
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
60 sub GenerateGet { |
194 | 61 die new IMPL::Exception("Standard accessors not supported",'Get'); |
59
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
62 } |
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
63 |
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
64 sub GenerateGetList { |
194 | 65 die new IMPL::Exception("Standard accessors not supported",'GetList'); |
59
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
66 } |
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
67 |
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
68 sub GenerateSetList { |
194 | 69 my ($self) = @_; |
70 die new IMPL::Exception("Standard accessors not supported",'SetList'); | |
59
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
71 } |
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
72 |
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
73 sub Make { |
194 | 74 my ($self,$propInfo) = @_; |
75 | |
76 my $key = $self->MakeFactoryKey($propInfo); | |
77 | |
78 my $factoryInfo = $factoryCache{$key}; | |
79 | |
80 unless ($factoryInfo) { | |
81 my $mutators = $self->GenerateAccessors($propInfo->Mutators); | |
82 $factoryInfo = { | |
83 factory => $self->CreateFactory( | |
84 $access_code{ $propInfo->Access }, | |
85 $propInfo->Attributes->{validator} ? $validator_code : "", | |
86 $mutators->{owner}, | |
87 $mutators->{get} || $accessor_get_no, | |
88 $mutators->{set} || $accessor_set_no | |
89 ), | |
90 mutators => $mutators | |
91 }; | |
92 $factoryCache{$key} = $factoryInfo; | |
93 } | |
94 | |
95 { | |
96 no strict 'refs'; | |
97 *{ $propInfo->Class.'::'.$propInfo->Name } = $factoryInfo->{factory}->($self->RemapFactoryParams($propInfo)); | |
98 } | |
99 | |
100 my $mutators = $factoryInfo->{mutators}; | |
101 | |
102 $propInfo->canGet( $mutators->{get} ? 1 : 0 ); | |
103 $propInfo->canSet( $mutators->{set} ? 1 : 0 ); | |
104 $propInfo->ownerSet( $mutators->{owner} ); | |
105 | |
106 1; | |
59
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
107 } |
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
108 |
230 | 109 sub Implement { |
110 my ($self,$spec) = @_; | |
111 } | |
112 | |
59
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
113 # extract from property info: class, name, get_accessor, set_accessor, validator |
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
114 sub RemapFactoryParams { |
194 | 115 my ($self,$propInfo) = @_; |
116 | |
117 my $mutators = $propInfo->Mutators; | |
118 my $class = $propInfo->Class; | |
119 my $validator = $propInfo->Attributes->{validator}; | |
120 | |
121 die new IMPL::Exception('Can\'t find the specified validator',$class,$validator) if $validator and ref $validator ne 'CODE' and not $class->can($validator); | |
59
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
122 |
194 | 123 return ( |
124 $propInfo->get(qw(Class Name)), | |
125 (ref $mutators? | |
126 ($mutators->{set},$mutators->{get}) | |
127 : | |
128 (undef,undef) | |
129 ), | |
130 $validator | |
131 ); | |
59
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
132 } |
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
133 |
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
134 sub MakeFactoryKey { |
194 | 135 my ($self,$propInfo) = @_; |
136 | |
137 my ($access,$mutators,$validator) = ($propInfo->get(qw(Access Mutators)),$propInfo->Attributes->{validator}); | |
138 | |
139 my $implementor = ref $self || $self; | |
140 | |
141 return join ('', | |
142 $implementor, | |
143 $access, | |
144 $validator ? 'v' : 'n', | |
145 ref $mutators ? | |
146 ('c' , $mutators->{get} ? 1 : 0, $mutators->{set} ? 1 : 0) | |
147 : | |
148 ('s',$mutators) | |
149 ); | |
59
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
150 } |
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
151 |
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
152 sub CreateFactory { |
194 | 153 my ($self,$codeAccessCheck,$codeValidator,$codeOwnerCheck,$codeGet,$codeSet) = @_; |
154 | |
155 my $strParams = join(',',$self->factoryParams); | |
156 | |
157 my $factory = <<FACTORY; | |
158 | |
59
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
159 sub { |
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
160 my ($strParams) = \@_; |
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
161 my \$accessor; |
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
162 \$accessor = sub { |
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
163 my \$this = shift; |
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
164 $codeAccessCheck |
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
165 if (\@_) { |
194 | 166 $codeOwnerCheck |
167 $codeValidator | |
168 $codeSet | |
59
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
169 } else { |
194 | 170 $codeGet |
59
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
171 } |
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
172 } |
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
173 } |
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
174 FACTORY |
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
175 |
194 | 176 return ( eval $factory or die new IMPL::Exception("Syntax error due compiling the factory","$@") ); |
59
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
177 } |
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
178 |
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
179 1; |
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
180 |
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
181 __END__ |
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
182 |
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
183 =pod |
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
184 |
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
185 =head1 DESCRIPTION |
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
186 |
180 | 187 Базовый класс для реализации свойств. |
59
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
188 |
180 | 189 По существу свойства состоят из двух методов для установки и получения значений. Также |
190 существует несколько вариантов доступа к свойству, и метод верификации значения. Еще | |
191 свойства могут быть виртуальными. | |
59
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
192 |
180 | 193 Для создания реализатора свойств достаточно унаследовать от этого класса и описать |
194 методы для генерации кода получения и установки значения. | |
80 | 195 |
196 =head1 MEMBERS | |
197 | |
198 =over | |
199 | |
200 =item C<Make($propertyInfo)> | |
201 | |
180 | 202 Создает свойство у класса, на основе C<$propertyInfo>, описывающего свойство. C<IMPL::Class::PropertyInfo>. |
80 | 203 |
204 =back | |
59
0f3e369553bd
Rewritten property implementation (probably become slower but more flexible)
wizard
parents:
diff
changeset
|
205 |
180 | 206 =cut |