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.
- data/doc/README +88 -0
- data/doc/manual-html/chapter-1.html +454 -0
- data/doc/manual-html/chapter-10.html +399 -0
- data/doc/manual-html/chapter-11.html +600 -0
- data/doc/manual-html/chapter-12.html +406 -0
- data/doc/manual-html/chapter-2.html +382 -0
- data/doc/manual-html/chapter-3.html +424 -0
- data/doc/manual-html/chapter-4.html +432 -0
- data/doc/manual-html/chapter-5.html +381 -0
- data/doc/manual-html/chapter-6.html +364 -0
- data/doc/manual-html/chapter-7.html +434 -0
- data/doc/manual-html/chapter-8.html +373 -0
- data/doc/manual-html/chapter-9.html +324 -0
- data/doc/manual-html/copland.png +0 -0
- data/doc/manual-html/index.html +331 -0
- data/doc/manual-html/manual.css +179 -0
- data/doc/manual-html/tutorial-1.html +407 -0
- data/doc/manual-html/tutorial-2.html +451 -0
- data/doc/manual-html/tutorial-3.html +484 -0
- data/doc/manual-html/tutorial-4.html +446 -0
- data/doc/manual-html/tutorial-5.html +520 -0
- data/doc/manual/chapter.erb +18 -0
- data/doc/manual/example.erb +18 -0
- data/doc/manual/img/copland.png +0 -0
- data/doc/manual/index.erb +30 -0
- data/doc/manual/manual.css +179 -0
- data/doc/manual/manual.rb +239 -0
- data/doc/manual/manual.yml +2643 -0
- data/doc/manual/page.erb +102 -0
- data/doc/manual/tutorial.erb +30 -0
- data/doc/packages/copland.html +764 -0
- data/doc/packages/copland.lib.html +439 -0
- data/doc/packages/copland.remote.html +2096 -0
- data/doc/packages/copland.webrick.html +925 -0
- data/doc/packages/index.html +49 -0
- data/doc/packages/packrat.css +125 -0
- data/examples/calc/calc.rb +47 -0
- data/examples/calc/package.yml +35 -0
- data/examples/calc/services.rb +74 -0
- data/examples/solitaire-cipher/README +11 -0
- data/examples/solitaire-cipher/Rakefile +57 -0
- data/examples/solitaire-cipher/bin/main.rb +14 -0
- data/examples/solitaire-cipher/lib/cipher.rb +230 -0
- data/examples/solitaire-cipher/lib/cli.rb +24 -0
- data/examples/solitaire-cipher/lib/package.yml +106 -0
- data/examples/solitaire-cipher/test/tc_deck.rb +30 -0
- data/examples/solitaire-cipher/test/tc_key-stream.rb +19 -0
- data/examples/solitaire-cipher/test/tc_keying-algorithms.rb +31 -0
- data/examples/solitaire-cipher/test/tc_solitaire-cipher.rb +66 -0
- data/examples/solitaire-cipher/test/tc_unkeyed-algorithm.rb +17 -0
- data/examples/solitaire-cipher/test/tests.rb +2 -0
- data/lib/copland.rb +56 -0
- data/lib/copland/class-factory.rb +95 -0
- data/lib/copland/configuration-point.rb +38 -0
- data/lib/copland/configuration-point/common.rb +203 -0
- data/lib/copland/configuration-point/errors.rb +44 -0
- data/lib/copland/configuration-point/list.rb +59 -0
- data/lib/copland/configuration-point/map.rb +59 -0
- data/lib/copland/configuration/errors.rb +43 -0
- data/lib/copland/configuration/loader.rb +113 -0
- data/lib/copland/configuration/yaml/configuration-point.rb +87 -0
- data/lib/copland/configuration/yaml/implementor.rb +134 -0
- data/lib/copland/configuration/yaml/interceptor.rb +63 -0
- data/lib/copland/configuration/yaml/listener.rb +56 -0
- data/lib/copland/configuration/yaml/loader.rb +122 -0
- data/lib/copland/configuration/yaml/package.rb +125 -0
- data/lib/copland/configuration/yaml/parser.rb +71 -0
- data/lib/copland/configuration/yaml/schema.rb +165 -0
- data/lib/copland/configuration/yaml/service-point.rb +116 -0
- data/lib/copland/configuration/yaml/utils.rb +82 -0
- data/lib/copland/default-schema-processor.rb +144 -0
- data/lib/copland/errors.rb +82 -0
- data/lib/copland/event-producer.rb +95 -0
- data/lib/copland/impl/builder-factory.rb +112 -0
- data/lib/copland/impl/copland-config.yml +1 -0
- data/lib/copland/impl/include-exclude.rb +140 -0
- data/lib/copland/impl/logging-interceptor.rb +106 -0
- data/lib/copland/impl/package.yml +217 -0
- data/lib/copland/impl/startup.rb +116 -0
- data/lib/copland/impl/symbol-source-manager.rb +131 -0
- data/lib/copland/impl/symbol-source.rb +63 -0
- data/lib/copland/instantiator.rb +38 -0
- data/lib/copland/instantiator/abstract.rb +91 -0
- data/lib/copland/instantiator/complex.rb +96 -0
- data/lib/copland/instantiator/identity.rb +58 -0
- data/lib/copland/instantiator/simple.rb +68 -0
- data/lib/copland/interceptor-chain.rb +166 -0
- data/lib/copland/interceptor.rb +139 -0
- data/lib/copland/log-factory.rb +206 -0
- data/lib/copland/models.rb +39 -0
- data/lib/copland/models/abstract.rb +78 -0
- data/lib/copland/models/prototype-deferred.rb +58 -0
- data/lib/copland/models/prototype.rb +58 -0
- data/lib/copland/models/proxy.rb +100 -0
- data/lib/copland/models/singleton-deferred.rb +59 -0
- data/lib/copland/models/singleton.rb +77 -0
- data/lib/copland/models/threaded.rb +65 -0
- data/lib/copland/ordering.rb +123 -0
- data/lib/copland/package.rb +246 -0
- data/lib/copland/registry.rb +368 -0
- data/lib/copland/schema.rb +206 -0
- data/lib/copland/service-point.rb +282 -0
- data/lib/copland/utils.rb +221 -0
- data/lib/copland/version.rb +47 -0
- data/test/conf-test/list-bad-key.yml +30 -0
- data/test/conf-test/list-bad-missing.yml +28 -0
- data/test/conf-test/list-bad-type.yml +28 -0
- data/test/conf-test/list-good.yml +29 -0
- data/test/conf-test/map-bad-key.yml +25 -0
- data/test/conf-test/map-bad-missing.yml +24 -0
- data/test/conf-test/map-bad-type.yml +23 -0
- data/test/conf-test/map-good.yml +25 -0
- data/test/configuration-point/package.yml +52 -0
- data/test/configuration/yaml/config/copland-config.yml +2 -0
- data/test/configuration/yaml/config/module.yml +2 -0
- data/test/configuration/yaml/config/subdir/copland-config.yml +2 -0
- data/test/configuration/yaml/config/subdir/package.yml +4 -0
- data/test/configuration/yaml/defaults/package.yml +5 -0
- data/test/configuration/yaml/defaults/subdir/package.yml +4 -0
- data/test/configuration/yaml/tc_config-loader.rb +86 -0
- data/test/configuration/yaml/tc_configuration-point-processor.rb +134 -0
- data/test/configuration/yaml/tc_implementor-processor.rb +104 -0
- data/test/configuration/yaml/tc_interceptor-processor.rb +85 -0
- data/test/configuration/yaml/tc_listener-processor.rb +69 -0
- data/test/configuration/yaml/tc_loader.rb +74 -0
- data/test/configuration/yaml/tc_package-processor.rb +120 -0
- data/test/configuration/yaml/tc_parser.rb +94 -0
- data/test/configuration/yaml/tc_schema-parser.rb +160 -0
- data/test/configuration/yaml/tc_service-point-processor.rb +104 -0
- data/test/configuration/yaml/tc_type-validator.rb +90 -0
- data/test/custom-logger.yml +3 -0
- data/test/impl/logging/package.yml +44 -0
- data/test/impl/logging/services.rb +84 -0
- data/test/impl/startup/package.yml +46 -0
- data/test/impl/startup/services.rb +47 -0
- data/test/impl/symbols/package.yml +24 -0
- data/test/impl/symbols/services.rb +38 -0
- data/test/impl/tc_builder-factory.rb +173 -0
- data/test/impl/tc_logging-interceptor.rb +148 -0
- data/test/impl/tc_startup.rb +59 -0
- data/test/impl/tc_symbol-sources.rb +61 -0
- data/test/logger.yml +6 -0
- data/test/mock.rb +201 -0
- data/test/schema/bad-package.yml +65 -0
- data/test/schema/package.yml +102 -0
- data/test/schema/services.rb +5 -0
- data/test/services/package.yml +79 -0
- data/test/services/simple.rb +87 -0
- data/test/tc_class-factory.rb +93 -0
- data/test/tc_complex-instantiator.rb +107 -0
- data/test/tc_configuration-point-contrib.rb +74 -0
- data/test/tc_configuration-point-schema.rb +122 -0
- data/test/tc_configuration-point.rb +91 -0
- data/test/tc_default-schema-processor.rb +297 -0
- data/test/tc_identity-instantiator.rb +61 -0
- data/test/tc_interceptors.rb +84 -0
- data/test/tc_logger.rb +131 -0
- data/test/tc_models.rb +176 -0
- data/test/tc_package.rb +165 -0
- data/test/tc_proxy.rb +65 -0
- data/test/tc_registry.rb +141 -0
- data/test/tc_schema.rb +78 -0
- data/test/tc_service-point.rb +178 -0
- data/test/tc_service.rb +70 -0
- data/test/tc_simple-instantiator.rb +61 -0
- data/test/tests.rb +93 -0
- data/tutorial/01/main.rb +7 -0
- data/tutorial/01/package.yml +8 -0
- data/tutorial/01/tutorial.rb +7 -0
- data/tutorial/02/main.rb +10 -0
- data/tutorial/02/package.yml +27 -0
- data/tutorial/02/tutorial.rb +46 -0
- data/tutorial/03/main.rb +24 -0
- data/tutorial/03/package.yml +29 -0
- data/tutorial/03/tutorial.rb +48 -0
- data/tutorial/04/main.rb +24 -0
- data/tutorial/04/package.yml +35 -0
- data/tutorial/04/tutorial.rb +48 -0
- data/tutorial/05/functions/package.yml +16 -0
- data/tutorial/05/functions/services.rb +15 -0
- data/tutorial/05/main.rb +10 -0
- data/tutorial/05/package.yml +35 -0
- data/tutorial/05/tutorial.rb +53 -0
- 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—</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>←</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 “service factory”, 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 “service model”, and shows the difference between “singleton” and “prototype”.</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’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 => point,
|
|
310
|
+
:parms => 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’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—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 “dependency injection” 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—</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>←</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 “service factory”, 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 “service model”, and shows the difference between “singleton” and “prototype”.</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>“Schemas” 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 “trees”. 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’ll get an error. You cannot used schema’s to validate any other type of data. (Arrays are a special case—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 “EmployeeSchema” is exactly like the PersonSchema, except it adds a “department” 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 “any one of a set of keys is required.” 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>
|