Mercurial > pub > Impl
annotate Lib/IMPL/Config.pm @ 100:df6b4f054957
Schema in progress
Added simple mailer
author | wizard |
---|---|
date | Thu, 06 May 2010 00:54:17 +0400 |
parents | 2f31ecabe9ea |
children | 76515373dac0 |
rev | line source |
---|---|
49 | 1 package IMPL::Config; |
2 use strict; | |
3 use warnings; | |
4 | |
60
b0c068da93ac
Lazy activation for the configuration objects (final concept)
wizard
parents:
58
diff
changeset
|
5 use base qw(IMPL::Object::Accessor IMPL::Object::Serializable IMPL::Object::Autofill); |
49 | 6 |
7 __PACKAGE__->PassThroughArgs; | |
8 | |
9 use IMPL::Class::Member; | |
10 use IMPL::Class::PropertyInfo; | |
11 use IMPL::Exception; | |
12 | |
13 use IMPL::Serialization; | |
14 use IMPL::Serialization::XmlFormatter; | |
15 | |
60
b0c068da93ac
Lazy activation for the configuration objects (final concept)
wizard
parents:
58
diff
changeset
|
16 |
b0c068da93ac
Lazy activation for the configuration objects (final concept)
wizard
parents:
58
diff
changeset
|
17 |
49 | 18 sub LoadXMLFile { |
19 my ($self,$file) = @_; | |
20 | |
21 my $class = ref $self || $self; | |
22 | |
23 my $serializer = new IMPL::Serializer( | |
24 Formatter => new IMPL::Serialization::XmlFormatter( | |
25 IdentOutput => 1, | |
26 SkipWhitespace => 1 | |
27 ) | |
28 ); | |
29 | |
30 open my $hFile,'<',$file or die new IMPL::Exception("Failed to open file",$file,$!); | |
31 | |
32 my $obj; | |
33 eval { | |
34 $obj = $serializer->Deserialize($hFile); | |
35 }; | |
36 | |
37 if ($@) { | |
38 my $e=$@; | |
39 die new IMPL::Exception("Can't load the configuration file",$file,$e); | |
40 } | |
41 return $obj; | |
42 } | |
43 | |
44 sub SaveXMLFile { | |
45 my ($this,$file) = @_; | |
46 | |
47 my $serializer = new IMPL::Serializer( | |
48 Formatter => new IMPL::Serialization::XmlFormatter( | |
49 IdentOutput => 1, | |
50 SkipWhitespace => 1 | |
51 ) | |
52 ); | |
53 | |
54 open my $hFile,'>',$file or die new IMPL::Exception("Failed to open file",$file,$!); | |
55 | |
56 $serializer->Serialize($hFile, $this); | |
57 } | |
58 | |
59 sub xml { | |
60 my $this = shift; | |
61 my $serializer = new IMPL::Serializer( | |
62 Formatter => new IMPL::Serialization::XmlFormatter( | |
63 IdentOutput => 1, | |
64 SkipWhitespace => 1 | |
65 ) | |
66 ); | |
67 my $str = ''; | |
68 open my $hFile,'>',\$str or die new IMPL::Exception("Failed to open stream",$!); | |
69 | |
70 $serializer->Serialize($hFile, $this); | |
71 | |
72 undef $hFile; | |
73 | |
74 return $str; | |
75 } | |
76 | |
77 sub save { | |
78 my ($this,$ctx) = @_; | |
63
76b878ad6596
Added serialization support for the IMPL::Object::List
wizard
parents:
60
diff
changeset
|
79 |
76b878ad6596
Added serialization support for the IMPL::Object::List
wizard
parents:
60
diff
changeset
|
80 my $val; |
49 | 81 |
63
76b878ad6596
Added serialization support for the IMPL::Object::List
wizard
parents:
60
diff
changeset
|
82 $val = $this->rawGet($_) and $ctx->AddVar($_ => $val) foreach map $_->Name, $this->get_meta( |
76b878ad6596
Added serialization support for the IMPL::Object::List
wizard
parents:
60
diff
changeset
|
83 'IMPL::Class::PropertyInfo', |
76b878ad6596
Added serialization support for the IMPL::Object::List
wizard
parents:
60
diff
changeset
|
84 sub { |
76b878ad6596
Added serialization support for the IMPL::Object::List
wizard
parents:
60
diff
changeset
|
85 $_->Access == IMPL::Class::Member::MOD_PUBLIC and |
76b878ad6596
Added serialization support for the IMPL::Object::List
wizard
parents:
60
diff
changeset
|
86 $_->canGet; |
76b878ad6596
Added serialization support for the IMPL::Object::List
wizard
parents:
60
diff
changeset
|
87 }, |
76b878ad6596
Added serialization support for the IMPL::Object::List
wizard
parents:
60
diff
changeset
|
88 1); |
49 | 89 } |
90 | |
58 | 91 sub spawn { |
92 goto &LoadXMLFile; | |
93 } | |
94 | |
60
b0c068da93ac
Lazy activation for the configuration objects (final concept)
wizard
parents:
58
diff
changeset
|
95 sub get { |
b0c068da93ac
Lazy activation for the configuration objects (final concept)
wizard
parents:
58
diff
changeset
|
96 my $this = shift; |
b0c068da93ac
Lazy activation for the configuration objects (final concept)
wizard
parents:
58
diff
changeset
|
97 |
b0c068da93ac
Lazy activation for the configuration objects (final concept)
wizard
parents:
58
diff
changeset
|
98 if (@_ == 1) { |
b0c068da93ac
Lazy activation for the configuration objects (final concept)
wizard
parents:
58
diff
changeset
|
99 my $obj = $this->SUPER::get(@_); |
b0c068da93ac
Lazy activation for the configuration objects (final concept)
wizard
parents:
58
diff
changeset
|
100 return UNIVERSAL::isa($obj,'IMPL::Config::Activator') ? $obj->activate : $obj; |
b0c068da93ac
Lazy activation for the configuration objects (final concept)
wizard
parents:
58
diff
changeset
|
101 } else { |
b0c068da93ac
Lazy activation for the configuration objects (final concept)
wizard
parents:
58
diff
changeset
|
102 my @objs = $this->SUPER::get(@_); |
b0c068da93ac
Lazy activation for the configuration objects (final concept)
wizard
parents:
58
diff
changeset
|
103 return map UNIVERSAL::isa($_,'IMPL::Config::Activator') ? $_->activate : $_, @objs ; |
b0c068da93ac
Lazy activation for the configuration objects (final concept)
wizard
parents:
58
diff
changeset
|
104 } |
b0c068da93ac
Lazy activation for the configuration objects (final concept)
wizard
parents:
58
diff
changeset
|
105 } |
b0c068da93ac
Lazy activation for the configuration objects (final concept)
wizard
parents:
58
diff
changeset
|
106 |
b0c068da93ac
Lazy activation for the configuration objects (final concept)
wizard
parents:
58
diff
changeset
|
107 sub rawGet { |
b0c068da93ac
Lazy activation for the configuration objects (final concept)
wizard
parents:
58
diff
changeset
|
108 my $this = shift; |
b0c068da93ac
Lazy activation for the configuration objects (final concept)
wizard
parents:
58
diff
changeset
|
109 return $this->SUPER::get(@_); |
b0c068da93ac
Lazy activation for the configuration objects (final concept)
wizard
parents:
58
diff
changeset
|
110 } |
b0c068da93ac
Lazy activation for the configuration objects (final concept)
wizard
parents:
58
diff
changeset
|
111 |
b0c068da93ac
Lazy activation for the configuration objects (final concept)
wizard
parents:
58
diff
changeset
|
112 sub Exists { |
b0c068da93ac
Lazy activation for the configuration objects (final concept)
wizard
parents:
58
diff
changeset
|
113 $_[0]->SUPER::get($_[1]) ? 1 : 0; |
b0c068da93ac
Lazy activation for the configuration objects (final concept)
wizard
parents:
58
diff
changeset
|
114 } |
b0c068da93ac
Lazy activation for the configuration objects (final concept)
wizard
parents:
58
diff
changeset
|
115 |
49 | 116 1; |
117 __END__ | |
118 | |
119 =pod | |
120 | |
73 | 121 =head1 NAME |
122 | |
123 C<IMPL::Config> - базовый класс для настраиваемого приложения. | |
124 | |
125 =head1 SYNOPSIS | |
49 | 126 |
73 | 127 =begin code |
128 | |
129 # define application | |
130 | |
131 package MyApp; | |
132 use base qw(IMPL::Config); | |
49 | 133 |
134 use IMPL::Class::Property; | |
135 use IMPL::Config::Class; | |
136 | |
137 BEGIN { | |
138 public property SimpleString => prop_all; | |
60
b0c068da93ac
Lazy activation for the configuration objects (final concept)
wizard
parents:
58
diff
changeset
|
139 public property DataSource => prop_all; |
49 | 140 } |
141 | |
142 sub CTOR { | |
143 my $this = shift; | |
73 | 144 |
60
b0c068da93ac
Lazy activation for the configuration objects (final concept)
wizard
parents:
58
diff
changeset
|
145 $this->DataSource( |
b0c068da93ac
Lazy activation for the configuration objects (final concept)
wizard
parents:
58
diff
changeset
|
146 new IMPL::Config::Activator( |
73 | 147 factory => 'MyDataSource', |
148 parameters=>{ | |
60
b0c068da93ac
Lazy activation for the configuration objects (final concept)
wizard
parents:
58
diff
changeset
|
149 host => 'localhost', |
b0c068da93ac
Lazy activation for the configuration objects (final concept)
wizard
parents:
58
diff
changeset
|
150 user => 'dbuser' |
b0c068da93ac
Lazy activation for the configuration objects (final concept)
wizard
parents:
58
diff
changeset
|
151 } |
b0c068da93ac
Lazy activation for the configuration objects (final concept)
wizard
parents:
58
diff
changeset
|
152 ) |
b0c068da93ac
Lazy activation for the configuration objects (final concept)
wizard
parents:
58
diff
changeset
|
153 ) unless $this->Exists('DataSource'); |
49 | 154 } |
155 | |
73 | 156 # using application object |
58 | 157 |
73 | 158 my $app = spawn MyApp('default.xml'); |
58 | 159 |
160 $app->Run(); | |
161 | |
73 | 162 =end code |
163 | |
164 Ниже приведен пример файла C<default.xml> содержащего настройки приложения | |
165 | |
166 =begin code xml | |
167 | |
168 <app type='MyApp'> | |
169 <SimpleString>The application</SimpleString> | |
170 <DataSource type='IMPL::Config::Activator'> | |
171 <factory>MyDataSourceClass</factory> | |
172 <parameters type='HASH'> | |
173 <host>localhost</host> | |
174 <user>dbuser</user> | |
175 </parameters> | |
176 </DataSource> | |
177 </app> | |
178 | |
179 =end code xml | |
180 | |
49 | 181 =head1 DESCRIPTION |
182 | |
73 | 183 C<[Serializable]> |
184 | |
185 C<[Autofill]> | |
186 | |
187 C<use base IMPL::Object::Accessor> | |
188 | |
189 Базовый класс для приложений. Использует подход, что приложение | |
190 является объектом, состояние которого предтавляет собой конфигурацию, | |
191 а методы - логику. | |
192 | |
193 Данный класс реализует функционал десериализации (и сериализации) экземпляра | |
194 приложения из XML документа. Для этого используется механизм C<IMPL::Serialization>. | |
195 При этом используются опции C<IMPL::Serialization::XmlFormatter> C<IdentOutput> и | |
196 C<SkipWhitespace> для записи документа в легко читаемом виде. | |
197 | |
198 Поскольку в результате восстановления приложения восстанавливаются все элементы | |
199 из файла конфигурации, то это может потребовать значительных ресурсов для | |
200 создания частей, которые могут никогда не понадобиться. Например, не требуется инициализация | |
201 источника данных для передачи пользователю статических данных, сохраненных на диске. | |
202 | |
203 Для решения этой проблемы используются специальные объекты C<IMPL::Config::Activator>. | |
204 | |
205 Если у приложения описано свойство, в котором хранится C<IMPL::Config::Activator>, то | |
206 при первом обращении к такому свойству, будет создан объект вызовом метода | |
207 C<< IMPL::Config::Activator->activate() >> и возвращен как значение этого свойства. | |
208 Таким образом реализуется прозрачная отложенная активация объектов, что позволяет | |
209 экономить ресурсы. | |
49 | 210 |
211 =head1 MEMBERS | |
212 | |
213 =over | |
214 | |
73 | 215 =item C<[static] LoadXMLFile($fileName) > |
60
b0c068da93ac
Lazy activation for the configuration objects (final concept)
wizard
parents:
58
diff
changeset
|
216 |
73 | 217 Создает из XML файла C<$fileName> экземпляр приложения |
49 | 218 |
73 | 219 =item C<SaveXMLFile($fileName)> |
60
b0c068da93ac
Lazy activation for the configuration objects (final concept)
wizard
parents:
58
diff
changeset
|
220 |
73 | 221 Сохраняет приложение в файл C<$fileName> |
222 | |
223 =item C<[get] xml > | |
49 | 224 |
73 | 225 Сохраняет конфигурацию приложения в XML строку. |
60
b0c068da93ac
Lazy activation for the configuration objects (final concept)
wizard
parents:
58
diff
changeset
|
226 |
73 | 227 =item C<[static,operator] spawn($file)> |
49 | 228 |
73 | 229 Синоним для C<LoadXMLFile>, предполагается использование как оператора. |
60
b0c068da93ac
Lazy activation for the configuration objects (final concept)
wizard
parents:
58
diff
changeset
|
230 |
73 | 231 =item C<rawGet($propname,...)> |
232 | |
233 Метод для получения значений свойств приложения. Данный метод позволяет избежать | |
234 использование активации объектов через C<IMPL::Config::Activator>. | |
60
b0c068da93ac
Lazy activation for the configuration objects (final concept)
wizard
parents:
58
diff
changeset
|
235 |
49 | 236 =back |
237 | |
238 =cut |