copland 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (184) hide show
  1. data/doc/README +88 -0
  2. data/doc/manual-html/chapter-1.html +454 -0
  3. data/doc/manual-html/chapter-10.html +399 -0
  4. data/doc/manual-html/chapter-11.html +600 -0
  5. data/doc/manual-html/chapter-12.html +406 -0
  6. data/doc/manual-html/chapter-2.html +382 -0
  7. data/doc/manual-html/chapter-3.html +424 -0
  8. data/doc/manual-html/chapter-4.html +432 -0
  9. data/doc/manual-html/chapter-5.html +381 -0
  10. data/doc/manual-html/chapter-6.html +364 -0
  11. data/doc/manual-html/chapter-7.html +434 -0
  12. data/doc/manual-html/chapter-8.html +373 -0
  13. data/doc/manual-html/chapter-9.html +324 -0
  14. data/doc/manual-html/copland.png +0 -0
  15. data/doc/manual-html/index.html +331 -0
  16. data/doc/manual-html/manual.css +179 -0
  17. data/doc/manual-html/tutorial-1.html +407 -0
  18. data/doc/manual-html/tutorial-2.html +451 -0
  19. data/doc/manual-html/tutorial-3.html +484 -0
  20. data/doc/manual-html/tutorial-4.html +446 -0
  21. data/doc/manual-html/tutorial-5.html +520 -0
  22. data/doc/manual/chapter.erb +18 -0
  23. data/doc/manual/example.erb +18 -0
  24. data/doc/manual/img/copland.png +0 -0
  25. data/doc/manual/index.erb +30 -0
  26. data/doc/manual/manual.css +179 -0
  27. data/doc/manual/manual.rb +239 -0
  28. data/doc/manual/manual.yml +2643 -0
  29. data/doc/manual/page.erb +102 -0
  30. data/doc/manual/tutorial.erb +30 -0
  31. data/doc/packages/copland.html +764 -0
  32. data/doc/packages/copland.lib.html +439 -0
  33. data/doc/packages/copland.remote.html +2096 -0
  34. data/doc/packages/copland.webrick.html +925 -0
  35. data/doc/packages/index.html +49 -0
  36. data/doc/packages/packrat.css +125 -0
  37. data/examples/calc/calc.rb +47 -0
  38. data/examples/calc/package.yml +35 -0
  39. data/examples/calc/services.rb +74 -0
  40. data/examples/solitaire-cipher/README +11 -0
  41. data/examples/solitaire-cipher/Rakefile +57 -0
  42. data/examples/solitaire-cipher/bin/main.rb +14 -0
  43. data/examples/solitaire-cipher/lib/cipher.rb +230 -0
  44. data/examples/solitaire-cipher/lib/cli.rb +24 -0
  45. data/examples/solitaire-cipher/lib/package.yml +106 -0
  46. data/examples/solitaire-cipher/test/tc_deck.rb +30 -0
  47. data/examples/solitaire-cipher/test/tc_key-stream.rb +19 -0
  48. data/examples/solitaire-cipher/test/tc_keying-algorithms.rb +31 -0
  49. data/examples/solitaire-cipher/test/tc_solitaire-cipher.rb +66 -0
  50. data/examples/solitaire-cipher/test/tc_unkeyed-algorithm.rb +17 -0
  51. data/examples/solitaire-cipher/test/tests.rb +2 -0
  52. data/lib/copland.rb +56 -0
  53. data/lib/copland/class-factory.rb +95 -0
  54. data/lib/copland/configuration-point.rb +38 -0
  55. data/lib/copland/configuration-point/common.rb +203 -0
  56. data/lib/copland/configuration-point/errors.rb +44 -0
  57. data/lib/copland/configuration-point/list.rb +59 -0
  58. data/lib/copland/configuration-point/map.rb +59 -0
  59. data/lib/copland/configuration/errors.rb +43 -0
  60. data/lib/copland/configuration/loader.rb +113 -0
  61. data/lib/copland/configuration/yaml/configuration-point.rb +87 -0
  62. data/lib/copland/configuration/yaml/implementor.rb +134 -0
  63. data/lib/copland/configuration/yaml/interceptor.rb +63 -0
  64. data/lib/copland/configuration/yaml/listener.rb +56 -0
  65. data/lib/copland/configuration/yaml/loader.rb +122 -0
  66. data/lib/copland/configuration/yaml/package.rb +125 -0
  67. data/lib/copland/configuration/yaml/parser.rb +71 -0
  68. data/lib/copland/configuration/yaml/schema.rb +165 -0
  69. data/lib/copland/configuration/yaml/service-point.rb +116 -0
  70. data/lib/copland/configuration/yaml/utils.rb +82 -0
  71. data/lib/copland/default-schema-processor.rb +144 -0
  72. data/lib/copland/errors.rb +82 -0
  73. data/lib/copland/event-producer.rb +95 -0
  74. data/lib/copland/impl/builder-factory.rb +112 -0
  75. data/lib/copland/impl/copland-config.yml +1 -0
  76. data/lib/copland/impl/include-exclude.rb +140 -0
  77. data/lib/copland/impl/logging-interceptor.rb +106 -0
  78. data/lib/copland/impl/package.yml +217 -0
  79. data/lib/copland/impl/startup.rb +116 -0
  80. data/lib/copland/impl/symbol-source-manager.rb +131 -0
  81. data/lib/copland/impl/symbol-source.rb +63 -0
  82. data/lib/copland/instantiator.rb +38 -0
  83. data/lib/copland/instantiator/abstract.rb +91 -0
  84. data/lib/copland/instantiator/complex.rb +96 -0
  85. data/lib/copland/instantiator/identity.rb +58 -0
  86. data/lib/copland/instantiator/simple.rb +68 -0
  87. data/lib/copland/interceptor-chain.rb +166 -0
  88. data/lib/copland/interceptor.rb +139 -0
  89. data/lib/copland/log-factory.rb +206 -0
  90. data/lib/copland/models.rb +39 -0
  91. data/lib/copland/models/abstract.rb +78 -0
  92. data/lib/copland/models/prototype-deferred.rb +58 -0
  93. data/lib/copland/models/prototype.rb +58 -0
  94. data/lib/copland/models/proxy.rb +100 -0
  95. data/lib/copland/models/singleton-deferred.rb +59 -0
  96. data/lib/copland/models/singleton.rb +77 -0
  97. data/lib/copland/models/threaded.rb +65 -0
  98. data/lib/copland/ordering.rb +123 -0
  99. data/lib/copland/package.rb +246 -0
  100. data/lib/copland/registry.rb +368 -0
  101. data/lib/copland/schema.rb +206 -0
  102. data/lib/copland/service-point.rb +282 -0
  103. data/lib/copland/utils.rb +221 -0
  104. data/lib/copland/version.rb +47 -0
  105. data/test/conf-test/list-bad-key.yml +30 -0
  106. data/test/conf-test/list-bad-missing.yml +28 -0
  107. data/test/conf-test/list-bad-type.yml +28 -0
  108. data/test/conf-test/list-good.yml +29 -0
  109. data/test/conf-test/map-bad-key.yml +25 -0
  110. data/test/conf-test/map-bad-missing.yml +24 -0
  111. data/test/conf-test/map-bad-type.yml +23 -0
  112. data/test/conf-test/map-good.yml +25 -0
  113. data/test/configuration-point/package.yml +52 -0
  114. data/test/configuration/yaml/config/copland-config.yml +2 -0
  115. data/test/configuration/yaml/config/module.yml +2 -0
  116. data/test/configuration/yaml/config/subdir/copland-config.yml +2 -0
  117. data/test/configuration/yaml/config/subdir/package.yml +4 -0
  118. data/test/configuration/yaml/defaults/package.yml +5 -0
  119. data/test/configuration/yaml/defaults/subdir/package.yml +4 -0
  120. data/test/configuration/yaml/tc_config-loader.rb +86 -0
  121. data/test/configuration/yaml/tc_configuration-point-processor.rb +134 -0
  122. data/test/configuration/yaml/tc_implementor-processor.rb +104 -0
  123. data/test/configuration/yaml/tc_interceptor-processor.rb +85 -0
  124. data/test/configuration/yaml/tc_listener-processor.rb +69 -0
  125. data/test/configuration/yaml/tc_loader.rb +74 -0
  126. data/test/configuration/yaml/tc_package-processor.rb +120 -0
  127. data/test/configuration/yaml/tc_parser.rb +94 -0
  128. data/test/configuration/yaml/tc_schema-parser.rb +160 -0
  129. data/test/configuration/yaml/tc_service-point-processor.rb +104 -0
  130. data/test/configuration/yaml/tc_type-validator.rb +90 -0
  131. data/test/custom-logger.yml +3 -0
  132. data/test/impl/logging/package.yml +44 -0
  133. data/test/impl/logging/services.rb +84 -0
  134. data/test/impl/startup/package.yml +46 -0
  135. data/test/impl/startup/services.rb +47 -0
  136. data/test/impl/symbols/package.yml +24 -0
  137. data/test/impl/symbols/services.rb +38 -0
  138. data/test/impl/tc_builder-factory.rb +173 -0
  139. data/test/impl/tc_logging-interceptor.rb +148 -0
  140. data/test/impl/tc_startup.rb +59 -0
  141. data/test/impl/tc_symbol-sources.rb +61 -0
  142. data/test/logger.yml +6 -0
  143. data/test/mock.rb +201 -0
  144. data/test/schema/bad-package.yml +65 -0
  145. data/test/schema/package.yml +102 -0
  146. data/test/schema/services.rb +5 -0
  147. data/test/services/package.yml +79 -0
  148. data/test/services/simple.rb +87 -0
  149. data/test/tc_class-factory.rb +93 -0
  150. data/test/tc_complex-instantiator.rb +107 -0
  151. data/test/tc_configuration-point-contrib.rb +74 -0
  152. data/test/tc_configuration-point-schema.rb +122 -0
  153. data/test/tc_configuration-point.rb +91 -0
  154. data/test/tc_default-schema-processor.rb +297 -0
  155. data/test/tc_identity-instantiator.rb +61 -0
  156. data/test/tc_interceptors.rb +84 -0
  157. data/test/tc_logger.rb +131 -0
  158. data/test/tc_models.rb +176 -0
  159. data/test/tc_package.rb +165 -0
  160. data/test/tc_proxy.rb +65 -0
  161. data/test/tc_registry.rb +141 -0
  162. data/test/tc_schema.rb +78 -0
  163. data/test/tc_service-point.rb +178 -0
  164. data/test/tc_service.rb +70 -0
  165. data/test/tc_simple-instantiator.rb +61 -0
  166. data/test/tests.rb +93 -0
  167. data/tutorial/01/main.rb +7 -0
  168. data/tutorial/01/package.yml +8 -0
  169. data/tutorial/01/tutorial.rb +7 -0
  170. data/tutorial/02/main.rb +10 -0
  171. data/tutorial/02/package.yml +27 -0
  172. data/tutorial/02/tutorial.rb +46 -0
  173. data/tutorial/03/main.rb +24 -0
  174. data/tutorial/03/package.yml +29 -0
  175. data/tutorial/03/tutorial.rb +48 -0
  176. data/tutorial/04/main.rb +24 -0
  177. data/tutorial/04/package.yml +35 -0
  178. data/tutorial/04/tutorial.rb +48 -0
  179. data/tutorial/05/functions/package.yml +16 -0
  180. data/tutorial/05/functions/services.rb +15 -0
  181. data/tutorial/05/main.rb +10 -0
  182. data/tutorial/05/package.yml +35 -0
  183. data/tutorial/05/tutorial.rb +53 -0
  184. metadata +260 -0
@@ -0,0 +1,399 @@
1
+ <html>
2
+ <head>
3
+ <title>Copland Manual :: Chapter 10: Service Factories</title>
4
+ <link type="text/css" rel="stylesheet" href="manual.css" />
5
+ </head>
6
+
7
+ <body>
8
+ <div id="banner">
9
+ <table border='0' cellpadding='0' cellspacing='0' width='100%'>
10
+ <tr><td valign='top' align='left'>
11
+ <div class="title">
12
+ <span class="product">Copland&mdash;</span><br />
13
+ <span class="tagline">compose yourself...</span>
14
+ </div>
15
+ </td><td valign='middle' align='right'>
16
+ <div class="info">
17
+ Copland Version: <strong>0.8.0</strong><br />
18
+ Manual Last Updated: <strong>2004-09-27 03:37 GMT</strong>
19
+ </div>
20
+ </td></tr>
21
+ </table>
22
+ </div>
23
+
24
+ <table border='0' width='100%' cellpadding='0' cellspacing='0'>
25
+ <tr><td valign='top'>
26
+
27
+ <div id="navigation">
28
+ <h1>Copland Manual</h1>
29
+
30
+ <h2>Chapters</h2>
31
+ <ol type="I">
32
+
33
+ <li>
34
+ <a href="chapter-1.html">
35
+ Introduction
36
+ </a>
37
+
38
+ <ol type="1">
39
+
40
+ <li><a href="chapter-1.html#s1">What is Copland?</a></li>
41
+
42
+ <li><a href="chapter-1.html#s2">Features</a></li>
43
+
44
+ <li><a href="chapter-1.html#s3">Getting Copland</a></li>
45
+
46
+ <li><a href="chapter-1.html#s4">License Information</a></li>
47
+
48
+ <li><a href="chapter-1.html#s5">Support</a></li>
49
+
50
+ </ol>
51
+ </li>
52
+
53
+ <li>
54
+ <a href="chapter-2.html">
55
+ Justification
56
+ </a>
57
+
58
+ <ol type="1">
59
+
60
+ <li><a href="chapter-2.html#s1">IoC in One Paragraph</a></li>
61
+
62
+ <li><a href="chapter-2.html#s2">Why IoC?</a></li>
63
+
64
+ <li><a href="chapter-2.html#s3">A Case Study</a></li>
65
+
66
+ </ol>
67
+ </li>
68
+
69
+ <li>
70
+ <a href="chapter-3.html">
71
+ Getting Started
72
+ </a>
73
+
74
+ <ol type="1">
75
+
76
+ <li><a href="chapter-3.html#s1">Terminology</a></li>
77
+
78
+ <li><a href="chapter-3.html#s2">Quickstart</a></li>
79
+
80
+ </ol>
81
+ </li>
82
+
83
+ <li>
84
+ <a href="chapter-4.html">
85
+ Copland's Design
86
+ </a>
87
+
88
+ <ol type="1">
89
+
90
+ <li><a href="chapter-4.html#s1">HiveMind</a></li>
91
+
92
+ <li><a href="chapter-4.html#s2">Registry Initialization</a></li>
93
+
94
+ <li><a href="chapter-4.html#s3">Service Instantiation</a></li>
95
+
96
+ <li><a href="chapter-4.html#s4">Interceptor Chains</a></li>
97
+
98
+ </ol>
99
+ </li>
100
+
101
+ <li>
102
+ <a href="chapter-5.html">
103
+ Packages
104
+ </a>
105
+
106
+ <ol type="1">
107
+
108
+ <li><a href="chapter-5.html#s1">Descriptor Syntax</a></li>
109
+
110
+ <li><a href="chapter-5.html#s2">Tips</a></li>
111
+
112
+ </ol>
113
+ </li>
114
+
115
+ <li>
116
+ <a href="chapter-6.html">
117
+ Service Points
118
+ </a>
119
+
120
+ <ol type="1">
121
+
122
+ <li><a href="chapter-6.html#s1">Descriptor Syntax</a></li>
123
+
124
+ </ol>
125
+ </li>
126
+
127
+ <li>
128
+ <a href="chapter-7.html">
129
+ Service Models
130
+ </a>
131
+
132
+ <ol type="1">
133
+
134
+ <li><a href="chapter-7.html#s1">Standard Models</a></li>
135
+
136
+ <li><a href="chapter-7.html#s2">Deferred Instantiation</a></li>
137
+
138
+ <li><a href="chapter-7.html#s3">Custom Service Models</a></li>
139
+
140
+ </ol>
141
+ </li>
142
+
143
+ <li>
144
+ <a href="chapter-8.html">
145
+ Configuration Points
146
+ </a>
147
+
148
+ <ol type="1">
149
+
150
+ <li><a href="chapter-8.html#s1">Descriptor Syntax</a></li>
151
+
152
+ <li><a href="chapter-8.html#s2">DefaultSymbolSource</a></li>
153
+
154
+ </ol>
155
+ </li>
156
+
157
+ <li>
158
+ <a href="chapter-9.html">
159
+ Contributions
160
+ </a>
161
+
162
+ <ol type="1">
163
+
164
+ </ol>
165
+ </li>
166
+
167
+ <li><strong>
168
+ <a href="chapter-10.html">
169
+ Service Factories
170
+ </a>
171
+ </strong> <big>&larr;</big>
172
+ <ol type="1">
173
+
174
+ <li><a href="chapter-10.html#s1">Schemas</a></li>
175
+
176
+ <li><a href="chapter-10.html#s2">How do they work?</a></li>
177
+
178
+ <li><a href="chapter-10.html#s3">BuilderFactory</a></li>
179
+
180
+ </ol>
181
+ </li>
182
+
183
+ <li>
184
+ <a href="chapter-11.html">
185
+ Schemas
186
+ </a>
187
+
188
+ <ol type="1">
189
+
190
+ <li><a href="chapter-11.html#s1">Basic Format</a></li>
191
+
192
+ <li><a href="chapter-11.html#s2">Subschemas</a></li>
193
+
194
+ <li><a href="chapter-11.html#s3">Arrays</a></li>
195
+
196
+ <li><a href="chapter-11.html#s4">Named vs. Anonymous Schemas</a></li>
197
+
198
+ <li><a href="chapter-11.html#s5">Extending Schemas</a></li>
199
+
200
+ <li><a href="chapter-11.html#s6">Limitations</a></li>
201
+
202
+ </ol>
203
+ </li>
204
+
205
+ <li>
206
+ <a href="chapter-12.html">
207
+ Listeners and Event Producers
208
+ </a>
209
+
210
+ <ol type="1">
211
+
212
+ <li><a href="chapter-12.html#s1">Event Producers</a></li>
213
+
214
+ <li><a href="chapter-12.html#s2">Listeners</a></li>
215
+
216
+ <li><a href="chapter-12.html#s3">The Registry as an Event Producer</a></li>
217
+
218
+ </ol>
219
+ </li>
220
+
221
+ </ol>
222
+
223
+ <h2>API Reference</h2>
224
+
225
+ <ul>
226
+ <li><a href="http://copland.rubyforge.org/api/index.html">Copland API</a></li>
227
+ <li><a href="http://copland.rubyforge.org/packrat/index.html">Package Reference</a></li>
228
+ </ul>
229
+
230
+ <h2>Tutorials</h2>
231
+ <ol>
232
+
233
+ <li>
234
+ <a href="tutorial-1.html">
235
+ Creating Services
236
+ </a>
237
+ <br />
238
+ <p>The basics of creating new services in Copland.</p>
239
+ </li>
240
+
241
+ <li>
242
+ <a href="tutorial-2.html">
243
+ Service Factories
244
+ </a>
245
+ <br />
246
+ <p>Introduces the concept of a &#8220;service factory&#8221;, and shows how to use them to create complex services.</p>
247
+ </li>
248
+
249
+ <li>
250
+ <a href="tutorial-3.html">
251
+ Service Models
252
+ </a>
253
+ <br />
254
+ <p>Introduces the concept of the &#8220;service model&#8221;, and shows the difference between &#8220;singleton&#8221; and &#8220;prototype&#8221;.</p>
255
+ </li>
256
+
257
+ <li>
258
+ <a href="tutorial-4.html">
259
+ Logging Interceptor
260
+ </a>
261
+ <br />
262
+ <p>Shows how to use the logging interceptor to add logging for method invocations on any service.</p>
263
+ </li>
264
+
265
+ <li>
266
+ <a href="tutorial-5.html">
267
+ Configuration Points
268
+ </a>
269
+ <br />
270
+ <p>Demonstrates the use of configuration points for decentralizing service configuration.</p>
271
+ </li>
272
+
273
+ </ol>
274
+
275
+ <p align="center"><strong>More To Come...</strong></p>
276
+
277
+ <!--
278
+ <h2>Examples</h2>
279
+ <ol>
280
+
281
+ </ol>
282
+ -->
283
+
284
+ <div class="license">
285
+ <a href="http://creativecommons.org/licenses/by-sa/2.0/"><img alt="Creative Commons License" border="0" src="http://creativecommons.org/images/public/somerights" /></a><br />
286
+ This manual is licensed under a <a href="http://creativecommons.org/licenses/by-sa/2.0/">Creative Commons License</a>.
287
+ </div>
288
+ </div>
289
+
290
+ </td><td valign='top' width="100%">
291
+
292
+ <div id="content">
293
+
294
+ <h1>10. Service Factories</h1>
295
+
296
+
297
+
298
+ <div class="section">
299
+ <p>Sometimes it requires a little more effort (or a lot more effort) to instantiate and initialize a service than simply calling <code>#new</code> on it&#8217;s associated class. In such cases, you need to rely on a <em>service factory</em> to instantiate the service.</p>
300
+
301
+ <p>A service factory is just a regular service as far as Copland is concerned. It is declared in the usual way. However, a service that will be used as a service factory must implement at least one method: <code>#create_instance</code>. This method should accept two parameters, the <em>service point</em> to instantiate, and the <em>parameters</em> associated with this instantiation. (The <code>parameters</code> parameter will always be a hash.)</p>
302
+
303
+ <p>Here is an example that implements a trivial service factory:</p>
304
+
305
+ <pre>
306
+ class ExampleServiceFactory
307
+
308
+ def create_instance( point, parms )
309
+ return { :point =&gt; point,
310
+ :parms =&gt; parms }
311
+ end
312
+
313
+ end
314
+ </pre>
315
+
316
+ <p>This service would be introduced into Copland via the following package descriptor:</p>
317
+
318
+ <pre>
319
+ ---
320
+ id: example
321
+
322
+ service-points:
323
+
324
+ ExampleServiceFactory:
325
+ implementor: some/file/ExampleServiceFactory
326
+ </pre>
327
+
328
+ <p>And it would be employed like this:</p>
329
+
330
+ <pre>
331
+ ---
332
+ id: demo
333
+
334
+ service-points:
335
+
336
+ ExampleService:
337
+ implementor:
338
+ factory: example.ExampleServiceFactory
339
+ </pre>
340
+
341
+ <p>This service factory, when used to instantiate a service, would always return a new Hash object consisting of the service point and its parameters. Thus, the <code>ExampleService</code> service point would, when instantiated, always consist of a hash containing its own service point, and any parameters that were given when it was instantiated (none, in this case). Not a very useful service factory, but it demonstrates what it ought to do.<br />
342
+ </p>
343
+ </div>
344
+
345
+
346
+
347
+ <h2>
348
+ <a name="s1"></a>
349
+ 10.1. Schemas
350
+ </h2>
351
+
352
+
353
+
354
+ <div class="section">
355
+ <p>As mentioned in the chapter on service points, a service point may be associated with a <em>schema</em>. More will be said on schemas (and specifically, on their formats) in the next chapter, but suffice it to say here that the schema allows a service point to specify what parameters it accepts when invoked as a factory service.<br />
356
+ </p>
357
+ </div>
358
+
359
+
360
+
361
+ <h2>
362
+ <a name="s2"></a>
363
+ 10.2. How do they work?
364
+ </h2>
365
+
366
+
367
+
368
+ <div class="section">
369
+ <p>When you specify a factory service as the implementor of another service, Copland automatically marks that service point as needing a <em>complex instantiator</em>. Thus, when it comes time to instantiate the service point, the parameters are collected, and if the factory has a schema, the parameters are validated against that schema. Then, the parameters are preprocessed (to translate values to their appropriate and expected types), and the factory&#8217;s <code>#create_instance</code> method is called. The result of that call is then treated as the new service.</p>
370
+
371
+ <p>Contrast this with the <em>simple instantiator</em>. When the simple instantiator is used, all it does (more or less) is invoke <code>#new</code> on the named class and return the result. The existence of factory services allows for much more complex (and powerful) behavior.<br />
372
+ </p>
373
+ </div>
374
+
375
+
376
+
377
+ <h2>
378
+ <a name="s3"></a>
379
+ 10.3. BuilderFactory
380
+ </h2>
381
+
382
+
383
+
384
+ <div class="section">
385
+ <p>Copland comes with one predefined factory service: <code>copland.BuilderFactory</code>. With this factory you can implement most of the more common types of services. (There are always special cases, though&#8212;the <code>copland.lib</code>, <code>copland.remote</code> and <code>copland.webrick</code> libraries all define additional factory services for specialized uses.)</p>
386
+
387
+ <p>The BuilderFactory allows you to not only instantiate a class, but to specify constructor parameters and set properties on the new object. It also allows you to specify methods that should be invoked in order to initialize a service. It is by this means that the &#8220;dependency injection&#8221; aspect of Copland comes into play.<br />
388
+ </p>
389
+ </div>
390
+
391
+
392
+
393
+
394
+ </div>
395
+
396
+ </td></tr>
397
+ </table>
398
+ </body>
399
+ </html>
@@ -0,0 +1,600 @@
1
+ <html>
2
+ <head>
3
+ <title>Copland Manual :: Chapter 11: Schemas</title>
4
+ <link type="text/css" rel="stylesheet" href="manual.css" />
5
+ </head>
6
+
7
+ <body>
8
+ <div id="banner">
9
+ <table border='0' cellpadding='0' cellspacing='0' width='100%'>
10
+ <tr><td valign='top' align='left'>
11
+ <div class="title">
12
+ <span class="product">Copland&mdash;</span><br />
13
+ <span class="tagline">compose yourself...</span>
14
+ </div>
15
+ </td><td valign='middle' align='right'>
16
+ <div class="info">
17
+ Copland Version: <strong>0.8.0</strong><br />
18
+ Manual Last Updated: <strong>2004-09-27 03:37 GMT</strong>
19
+ </div>
20
+ </td></tr>
21
+ </table>
22
+ </div>
23
+
24
+ <table border='0' width='100%' cellpadding='0' cellspacing='0'>
25
+ <tr><td valign='top'>
26
+
27
+ <div id="navigation">
28
+ <h1>Copland Manual</h1>
29
+
30
+ <h2>Chapters</h2>
31
+ <ol type="I">
32
+
33
+ <li>
34
+ <a href="chapter-1.html">
35
+ Introduction
36
+ </a>
37
+
38
+ <ol type="1">
39
+
40
+ <li><a href="chapter-1.html#s1">What is Copland?</a></li>
41
+
42
+ <li><a href="chapter-1.html#s2">Features</a></li>
43
+
44
+ <li><a href="chapter-1.html#s3">Getting Copland</a></li>
45
+
46
+ <li><a href="chapter-1.html#s4">License Information</a></li>
47
+
48
+ <li><a href="chapter-1.html#s5">Support</a></li>
49
+
50
+ </ol>
51
+ </li>
52
+
53
+ <li>
54
+ <a href="chapter-2.html">
55
+ Justification
56
+ </a>
57
+
58
+ <ol type="1">
59
+
60
+ <li><a href="chapter-2.html#s1">IoC in One Paragraph</a></li>
61
+
62
+ <li><a href="chapter-2.html#s2">Why IoC?</a></li>
63
+
64
+ <li><a href="chapter-2.html#s3">A Case Study</a></li>
65
+
66
+ </ol>
67
+ </li>
68
+
69
+ <li>
70
+ <a href="chapter-3.html">
71
+ Getting Started
72
+ </a>
73
+
74
+ <ol type="1">
75
+
76
+ <li><a href="chapter-3.html#s1">Terminology</a></li>
77
+
78
+ <li><a href="chapter-3.html#s2">Quickstart</a></li>
79
+
80
+ </ol>
81
+ </li>
82
+
83
+ <li>
84
+ <a href="chapter-4.html">
85
+ Copland's Design
86
+ </a>
87
+
88
+ <ol type="1">
89
+
90
+ <li><a href="chapter-4.html#s1">HiveMind</a></li>
91
+
92
+ <li><a href="chapter-4.html#s2">Registry Initialization</a></li>
93
+
94
+ <li><a href="chapter-4.html#s3">Service Instantiation</a></li>
95
+
96
+ <li><a href="chapter-4.html#s4">Interceptor Chains</a></li>
97
+
98
+ </ol>
99
+ </li>
100
+
101
+ <li>
102
+ <a href="chapter-5.html">
103
+ Packages
104
+ </a>
105
+
106
+ <ol type="1">
107
+
108
+ <li><a href="chapter-5.html#s1">Descriptor Syntax</a></li>
109
+
110
+ <li><a href="chapter-5.html#s2">Tips</a></li>
111
+
112
+ </ol>
113
+ </li>
114
+
115
+ <li>
116
+ <a href="chapter-6.html">
117
+ Service Points
118
+ </a>
119
+
120
+ <ol type="1">
121
+
122
+ <li><a href="chapter-6.html#s1">Descriptor Syntax</a></li>
123
+
124
+ </ol>
125
+ </li>
126
+
127
+ <li>
128
+ <a href="chapter-7.html">
129
+ Service Models
130
+ </a>
131
+
132
+ <ol type="1">
133
+
134
+ <li><a href="chapter-7.html#s1">Standard Models</a></li>
135
+
136
+ <li><a href="chapter-7.html#s2">Deferred Instantiation</a></li>
137
+
138
+ <li><a href="chapter-7.html#s3">Custom Service Models</a></li>
139
+
140
+ </ol>
141
+ </li>
142
+
143
+ <li>
144
+ <a href="chapter-8.html">
145
+ Configuration Points
146
+ </a>
147
+
148
+ <ol type="1">
149
+
150
+ <li><a href="chapter-8.html#s1">Descriptor Syntax</a></li>
151
+
152
+ <li><a href="chapter-8.html#s2">DefaultSymbolSource</a></li>
153
+
154
+ </ol>
155
+ </li>
156
+
157
+ <li>
158
+ <a href="chapter-9.html">
159
+ Contributions
160
+ </a>
161
+
162
+ <ol type="1">
163
+
164
+ </ol>
165
+ </li>
166
+
167
+ <li>
168
+ <a href="chapter-10.html">
169
+ Service Factories
170
+ </a>
171
+
172
+ <ol type="1">
173
+
174
+ <li><a href="chapter-10.html#s1">Schemas</a></li>
175
+
176
+ <li><a href="chapter-10.html#s2">How do they work?</a></li>
177
+
178
+ <li><a href="chapter-10.html#s3">BuilderFactory</a></li>
179
+
180
+ </ol>
181
+ </li>
182
+
183
+ <li><strong>
184
+ <a href="chapter-11.html">
185
+ Schemas
186
+ </a>
187
+ </strong> <big>&larr;</big>
188
+ <ol type="1">
189
+
190
+ <li><a href="chapter-11.html#s1">Basic Format</a></li>
191
+
192
+ <li><a href="chapter-11.html#s2">Subschemas</a></li>
193
+
194
+ <li><a href="chapter-11.html#s3">Arrays</a></li>
195
+
196
+ <li><a href="chapter-11.html#s4">Named vs. Anonymous Schemas</a></li>
197
+
198
+ <li><a href="chapter-11.html#s5">Extending Schemas</a></li>
199
+
200
+ <li><a href="chapter-11.html#s6">Limitations</a></li>
201
+
202
+ </ol>
203
+ </li>
204
+
205
+ <li>
206
+ <a href="chapter-12.html">
207
+ Listeners and Event Producers
208
+ </a>
209
+
210
+ <ol type="1">
211
+
212
+ <li><a href="chapter-12.html#s1">Event Producers</a></li>
213
+
214
+ <li><a href="chapter-12.html#s2">Listeners</a></li>
215
+
216
+ <li><a href="chapter-12.html#s3">The Registry as an Event Producer</a></li>
217
+
218
+ </ol>
219
+ </li>
220
+
221
+ </ol>
222
+
223
+ <h2>API Reference</h2>
224
+
225
+ <ul>
226
+ <li><a href="http://copland.rubyforge.org/api/index.html">Copland API</a></li>
227
+ <li><a href="http://copland.rubyforge.org/packrat/index.html">Package Reference</a></li>
228
+ </ul>
229
+
230
+ <h2>Tutorials</h2>
231
+ <ol>
232
+
233
+ <li>
234
+ <a href="tutorial-1.html">
235
+ Creating Services
236
+ </a>
237
+ <br />
238
+ <p>The basics of creating new services in Copland.</p>
239
+ </li>
240
+
241
+ <li>
242
+ <a href="tutorial-2.html">
243
+ Service Factories
244
+ </a>
245
+ <br />
246
+ <p>Introduces the concept of a &#8220;service factory&#8221;, and shows how to use them to create complex services.</p>
247
+ </li>
248
+
249
+ <li>
250
+ <a href="tutorial-3.html">
251
+ Service Models
252
+ </a>
253
+ <br />
254
+ <p>Introduces the concept of the &#8220;service model&#8221;, and shows the difference between &#8220;singleton&#8221; and &#8220;prototype&#8221;.</p>
255
+ </li>
256
+
257
+ <li>
258
+ <a href="tutorial-4.html">
259
+ Logging Interceptor
260
+ </a>
261
+ <br />
262
+ <p>Shows how to use the logging interceptor to add logging for method invocations on any service.</p>
263
+ </li>
264
+
265
+ <li>
266
+ <a href="tutorial-5.html">
267
+ Configuration Points
268
+ </a>
269
+ <br />
270
+ <p>Demonstrates the use of configuration points for decentralizing service configuration.</p>
271
+ </li>
272
+
273
+ </ol>
274
+
275
+ <p align="center"><strong>More To Come...</strong></p>
276
+
277
+ <!--
278
+ <h2>Examples</h2>
279
+ <ol>
280
+
281
+ </ol>
282
+ -->
283
+
284
+ <div class="license">
285
+ <a href="http://creativecommons.org/licenses/by-sa/2.0/"><img alt="Creative Commons License" border="0" src="http://creativecommons.org/images/public/somerights" /></a><br />
286
+ This manual is licensed under a <a href="http://creativecommons.org/licenses/by-sa/2.0/">Creative Commons License</a>.
287
+ </div>
288
+ </div>
289
+
290
+ </td><td valign='top' width="100%">
291
+
292
+ <div id="content">
293
+
294
+ <h1>11. Schemas</h1>
295
+
296
+
297
+
298
+ <div class="section">
299
+ <p>&#8220;Schemas&#8221; are the mechanism by which you can restrict what values are contributed to configuration points, or which parameters are acceptable to a service constructed via a factory service.<br />
300
+ </p>
301
+ </div>
302
+
303
+
304
+
305
+ <h2>
306
+ <a name="s1"></a>
307
+ 11.1. Basic Format
308
+ </h2>
309
+
310
+
311
+
312
+ <div class="section">
313
+ <p>In <span class="caps">YAML</span> terminology, a schema is simply a map that follows a special format. Consider the following configuration point:</p>
314
+
315
+ <pre>
316
+ MyConfigurationPoint:
317
+ type: map
318
+ schema:
319
+ definition:
320
+ user.name:
321
+ type: string
322
+ required: true
323
+ home.directory:
324
+ type: string
325
+ user.groups:
326
+ type: array
327
+ </pre>
328
+
329
+ <p>This configuration point is a map that only allows three keys: <code>user.name</code>, <code>home.directory</code>, and <code>user.groups</code>. Any contribution made to this configuration point <em>must not</em> contain any keys other than these values. And since the <code>user.name</code> key is marked as required, any contribution to this configuration point <em>must</em> contain at least that key.</p>
330
+
331
+ <p>Note the type definitions as well. The recognized types are:</p>
332
+
333
+ <ul>
334
+ <li><code>any</code></li>
335
+ <li><code>array</code></li>
336
+ <li><code>configuration</code></li>
337
+ <li><code>integer</code></li>
338
+ <li><code>log</code></li>
339
+ <li><code>hash</code></li>
340
+ <li><code>real</code></li>
341
+ <li><code>service</code></li>
342
+ <li><code>string</code></li>
343
+ </ul>
344
+
345
+ <p>If the type is left out, it defaults to <code>any</code>. If a value is contributed to that key that is not of the required type, a validation error results.</p>
346
+
347
+ <p>Note that schemas may be applied to service points as well, in identical fashion to that of configuration points. (That is to say, they are introduced by the <code>schema</code> descriptor element.) In that case, the schema applies to the parameters of any service point that uses this service point as its factory service.</p>
348
+ </div>
349
+
350
+
351
+
352
+ <h2>
353
+ <a name="s2"></a>
354
+ 11.2. Subschemas
355
+ </h2>
356
+
357
+
358
+
359
+ <div class="section">
360
+ <p>Schemas may be nested, to allow for arbitrarily deep schema &#8220;trees&#8221;. Consider the following example:</p>
361
+
362
+ <pre>
363
+ MyConfigurationPoint:
364
+ type: map
365
+ schema:
366
+ definition:
367
+ user.name:
368
+ type: string
369
+ required: true
370
+ home.directory:
371
+ type: string
372
+ user.groups:
373
+ type: array
374
+ user.address:
375
+ definition:
376
+ line1:
377
+ type: string
378
+ line2:
379
+ type: string
380
+ city:
381
+ type: string
382
+ state:
383
+ type: string
384
+ zip:
385
+ type: string
386
+ </pre>
387
+
388
+ <p>In this case, the <code>user.address</code> element of the schema is itself <em>another schema</em>. That is to say, any element that it matches must be a hash, which may be empty, but which may contain no keys other than those specified (<code>line1</code>, <code>line2</code>, <code>city</code>, <code>state</code>, and <code>zip</code>).</p>
389
+
390
+ <p>If you specify a subschema definintion (via the <code>definition</code> keyword), and the same element is of any type other than <code>hash</code> or <code>array</code>, you&#8217;ll get an error. You cannot used schema&#8217;s to validate any other type of data. (Arrays are a special case&#8212;see the next section.)</p>
391
+ </div>
392
+
393
+
394
+
395
+ <h2>
396
+ <a name="s3"></a>
397
+ 11.3. Arrays
398
+ </h2>
399
+
400
+
401
+
402
+ <div class="section">
403
+ <p>When you specify a schema for an array (or for a configuration point of type <code>list</code>), the schema will be applied to every element of any array that is contributed. For example, consider this:</p>
404
+
405
+ <pre>
406
+ MoviesILike:
407
+ type: list
408
+ schema:
409
+ definition:
410
+ name:
411
+ type: string
412
+ required: true
413
+ genre:
414
+ type: string
415
+ actors:
416
+ type: array
417
+ definition:
418
+ name:
419
+ type: string
420
+ required: true
421
+ gender:
422
+ type: string
423
+ birthdate:
424
+ type: string
425
+ </pre>
426
+
427
+ <p>This configuration point is a <code>list</code>. Every element that is contributed to it must conform to the given schema. Note, too, that the <code>actors</code> element of the schema expects an array, and that each element of <em>that</em> array must conform to the given subschema.</p>
428
+
429
+ <p>Given that schema, the following contribution would be valid:</p>
430
+
431
+ <pre>
432
+ contributions:
433
+
434
+ MoviesILike:
435
+ - name: Twelve Angry Men
436
+ genre: Drama
437
+ actors:
438
+ - name: Henry Fonda
439
+ gender: male
440
+ birthdate: 16 May 1905
441
+ - name: Jack Klugman
442
+ birthdate: 27 Apr 1922
443
+ - name: Ed Binns
444
+ - name: John Fiedler
445
+ - name: Lawrence of Arabia
446
+ actors:
447
+ - name: Peter O'Toole
448
+ - name: Alec Guinness
449
+ birthdate: 2 Apr 1914
450
+ - name: Remains of the Day
451
+ </pre>
452
+ </div>
453
+
454
+
455
+
456
+ <h2>
457
+ <a name="s4"></a>
458
+ 11.4. Named vs. Anonymous Schemas
459
+ </h2>
460
+
461
+
462
+
463
+ <div class="section">
464
+ <p>The schemas that have been shown so far have been <em>anonymous</em>. This is fine for schemas that are very specific and have a very special purpose. However, sometimes, you want several configuration points of service points to have the same schema. To accomplish this, you need to give your schemas names.</p>
465
+
466
+ <p>Named schemas are owned by the package in which they are defined, but once named they may be used in any package (just like service points and configuration points).</p>
467
+
468
+ <p>To name a schema, just add a <code>name</code> element at the same level as the <code>definition</code> element:</p>
469
+
470
+ <pre>
471
+ MoviesILike:
472
+ type: list
473
+ schema:
474
+ name: MovieDefinition
475
+ definition:
476
+ ...
477
+ </pre>
478
+
479
+ <p>Then, you can reuse the schema by putting the schema name after the <code>schema</code> element, instead of a hash:</p>
480
+
481
+ <pre>
482
+ MoviesIHate:
483
+ type: list
484
+ schema: MovieDefinition
485
+ </pre>
486
+
487
+ <p>This second configuration point will reuse the <code>MovieDefinition</code> schema. Note that you can specify an existing schema (or name a schema) at any level of a schema definition:</p>
488
+
489
+ <pre>
490
+ MoviesILike:
491
+ type: list
492
+ schema:
493
+ name: MovieDefinition
494
+ definition:
495
+ name:
496
+ type: string
497
+ required: true
498
+ genre:
499
+ type: string
500
+ actors:
501
+ name: ActorDefinition
502
+ type: array
503
+ definition:
504
+ name:
505
+ type: string
506
+ required: true
507
+ gender:
508
+ type: string
509
+ birthdate:
510
+ type: string
511
+
512
+ MoviesIHate:
513
+ type: list
514
+ schema: MovieDefinition
515
+
516
+ FavoriteActors:
517
+ type: list
518
+ schema: ActorDefinition
519
+
520
+ PartiesAttended:
521
+ type: list
522
+ schema:
523
+ definition:
524
+ place:
525
+ type: string
526
+ host:
527
+ type: string
528
+ attendees: ActorDefinition
529
+ </pre>
530
+ </div>
531
+
532
+
533
+
534
+ <h2>
535
+ <a name="s5"></a>
536
+ 11.5. Extending Schemas
537
+ </h2>
538
+
539
+
540
+
541
+ <div class="section">
542
+ <p>Sometimes it happens that you want to create a schema that is <em>almost</em> like an existing schema, but adds one or two new elements. You can do this in Copland by <em>extending</em> the existing schema:</p>
543
+
544
+ <pre>
545
+ People:
546
+ type: list
547
+ schema:
548
+ name: PersonSchema
549
+ definition:
550
+ name:
551
+ required: true
552
+ type: string
553
+ gender:
554
+ required: true
555
+ type: string
556
+
557
+ Employees:
558
+ type: list
559
+ schema:
560
+ name: EmployeeSchema
561
+ extend: PersonSchema
562
+ definition:
563
+ department:
564
+ required: true
565
+ type: string
566
+ </pre>
567
+
568
+ <p>In the above instance, the &#8220;EmployeeSchema&#8221; is exactly like the PersonSchema, except it adds a &#8220;department&#8221; key.</p>
569
+ </div>
570
+
571
+
572
+
573
+ <h2>
574
+ <a name="s6"></a>
575
+ 11.6. Limitations
576
+ </h2>
577
+
578
+
579
+
580
+ <div class="section">
581
+ <p>The existing schema implementation is sufficient for most purposes, but it has some limitations:</p>
582
+
583
+ <ul>
584
+ <li>You cannot specify a format for a non-hash value.</li>
585
+ <li>You cannot specify whether a subschema that reuses an existing schema is required or not.</li>
586
+ <li>You cannot enforce the constraint &#8220;any one of a set of keys is required.&#8221; The schema subsystem only understands a single key being required or not.</li>
587
+ </ul>
588
+
589
+ <p>For most purposes, however, it is sufficient.</p>
590
+ </div>
591
+
592
+
593
+
594
+
595
+ </div>
596
+
597
+ </td></tr>
598
+ </table>
599
+ </body>
600
+ </html>