copland 0.8.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. data/doc/manual-html/chapter-1.html +227 -36
  2. data/doc/manual-html/chapter-10.html +155 -82
  3. data/doc/manual-html/chapter-11.html +90 -267
  4. data/doc/manual-html/chapter-12.html +289 -71
  5. data/doc/manual-html/chapter-13.html +430 -0
  6. data/doc/manual-html/chapter-2.html +45 -21
  7. data/doc/manual-html/chapter-3.html +45 -21
  8. data/doc/manual-html/chapter-4.html +45 -21
  9. data/doc/manual-html/chapter-5.html +45 -21
  10. data/doc/manual-html/chapter-6.html +49 -21
  11. data/doc/manual-html/chapter-7.html +45 -21
  12. data/doc/manual-html/chapter-8.html +66 -26
  13. data/doc/manual-html/chapter-9.html +48 -24
  14. data/doc/manual-html/index.html +54 -22
  15. data/doc/manual-html/manual.css +12 -0
  16. data/doc/manual-html/tutorial-1.html +45 -21
  17. data/doc/manual-html/tutorial-2.html +45 -21
  18. data/doc/manual-html/tutorial-3.html +45 -21
  19. data/doc/manual-html/tutorial-4.html +45 -21
  20. data/doc/manual-html/tutorial-5.html +45 -21
  21. data/doc/manual/manual.css +12 -0
  22. data/doc/manual/manual.rb +1 -1
  23. data/doc/manual/manual.yml +426 -20
  24. data/doc/packages/copland.html +41 -9
  25. data/doc/packages/copland.lib.html +36 -8
  26. data/doc/packages/copland.remote.html +46 -10
  27. data/doc/packages/copland.webrick.html +16 -65
  28. data/doc/packages/index.html +1 -1
  29. data/doc/presentation/copland.mgp +1083 -0
  30. data/doc/presentation/to_html.rb +52 -0
  31. data/lib/copland/configuration-point/common.rb +32 -1
  32. data/lib/copland/configuration/yaml/service-point.rb +10 -1
  33. data/lib/copland/log-factory.rb +28 -12
  34. data/lib/copland/logger.rb +155 -0
  35. data/lib/copland/models/singleton.rb +8 -2
  36. data/lib/copland/package.rb +32 -14
  37. data/lib/copland/service-point.rb +7 -0
  38. data/lib/copland/thread.rb +104 -0
  39. data/lib/copland/utils.rb +10 -3
  40. data/lib/copland/version.rb +2 -2
  41. data/test/configuration/yaml/tc_service-point-processor.rb +8 -0
  42. data/test/custom-logger.yml +2 -1
  43. data/test/impl/tc_logging-interceptor.rb +12 -12
  44. data/test/logger.yml +1 -1
  45. data/test/mock.rb +2 -0
  46. data/test/tc_logger.rb +19 -6
  47. data/test/tc_package.rb +25 -0
  48. data/test/tc_queryable-mutex.rb +75 -0
  49. data/test/tc_registry.rb +8 -4
  50. metadata +9 -2
@@ -1,6 +1,6 @@
1
1
  <html>
2
2
  <head>
3
- <title>Copland Manual :: Chapter 11: Schemas</title>
3
+ <title>Copland Manual :: Chapter 11: Service Factories</title>
4
4
  <link type="text/css" rel="stylesheet" href="manual.css" />
5
5
  </head>
6
6
 
@@ -14,8 +14,8 @@
14
14
  </div>
15
15
  </td><td valign='middle' align='right'>
16
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>
17
+ Copland Version: <strong>1.0.0</strong><br />
18
+ Manual Last Updated: <strong>2004-10-12 02:22 GMT</strong>
19
19
  </div>
20
20
  </td></tr>
21
21
  </table>
@@ -39,13 +39,21 @@
39
39
 
40
40
  <li><a href="chapter-1.html#s1">What is Copland?</a></li>
41
41
 
42
- <li><a href="chapter-1.html#s2">Features</a></li>
42
+ <li><a href="chapter-1.html#s2">What Can Copland Do For Me?</a></li>
43
43
 
44
- <li><a href="chapter-1.html#s3">Getting Copland</a></li>
44
+ <li><a href="chapter-1.html#s3">Copland <em>sans</em> Buzzwords</a></li>
45
45
 
46
- <li><a href="chapter-1.html#s4">License Information</a></li>
46
+ <li><a href="chapter-1.html#s4">Copland <em>avec</em> Buzzwords</a></li>
47
47
 
48
- <li><a href="chapter-1.html#s5">Support</a></li>
48
+ <li><a href="chapter-1.html#s5">The Buzzwords Themselves</a></li>
49
+
50
+ <li><a href="chapter-1.html#s6">Features</a></li>
51
+
52
+ <li><a href="chapter-1.html#s7">Getting Copland</a></li>
53
+
54
+ <li><a href="chapter-1.html#s8">License Information</a></li>
55
+
56
+ <li><a href="chapter-1.html#s9">Support</a></li>
49
57
 
50
58
  </ol>
51
59
  </li>
@@ -149,7 +157,9 @@
149
157
 
150
158
  <li><a href="chapter-8.html#s1">Descriptor Syntax</a></li>
151
159
 
152
- <li><a href="chapter-8.html#s2">DefaultSymbolSource</a></li>
160
+ <li><a href="chapter-8.html#s2">FactoryDefaults</a></li>
161
+
162
+ <li><a href="chapter-8.html#s3">ApplicationDefaults</a></li>
153
163
 
154
164
  </ol>
155
165
  </li>
@@ -166,54 +176,68 @@
166
176
 
167
177
  <li>
168
178
  <a href="chapter-10.html">
169
- Service Factories
179
+ Logging
170
180
  </a>
171
181
 
172
182
  <ol type="1">
173
183
 
174
- <li><a href="chapter-10.html#s1">Schemas</a></li>
184
+ <li><a href="chapter-10.html#s1">Log Factory</a></li>
175
185
 
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>
186
+ <li><a href="chapter-10.html#s2">Configuration</a></li>
179
187
 
180
188
  </ol>
181
189
  </li>
182
190
 
183
191
  <li><strong>
184
192
  <a href="chapter-11.html">
185
- Schemas
193
+ Service Factories
186
194
  </a>
187
195
  </strong> <big>&larr;</big>
188
196
  <ol type="1">
189
197
 
190
- <li><a href="chapter-11.html#s1">Basic Format</a></li>
198
+ <li><a href="chapter-11.html#s1">Schemas</a></li>
199
+
200
+ <li><a href="chapter-11.html#s2">How do they work?</a></li>
201
+
202
+ <li><a href="chapter-11.html#s3">BuilderFactory</a></li>
203
+
204
+ </ol>
205
+ </li>
206
+
207
+ <li>
208
+ <a href="chapter-12.html">
209
+ Schemas
210
+ </a>
211
+
212
+ <ol type="1">
213
+
214
+ <li><a href="chapter-12.html#s1">Basic Format</a></li>
191
215
 
192
- <li><a href="chapter-11.html#s2">Subschemas</a></li>
216
+ <li><a href="chapter-12.html#s2">Subschemas</a></li>
193
217
 
194
- <li><a href="chapter-11.html#s3">Arrays</a></li>
218
+ <li><a href="chapter-12.html#s3">Arrays</a></li>
195
219
 
196
- <li><a href="chapter-11.html#s4">Named vs. Anonymous Schemas</a></li>
220
+ <li><a href="chapter-12.html#s4">Named vs. Anonymous Schemas</a></li>
197
221
 
198
- <li><a href="chapter-11.html#s5">Extending Schemas</a></li>
222
+ <li><a href="chapter-12.html#s5">Extending Schemas</a></li>
199
223
 
200
- <li><a href="chapter-11.html#s6">Limitations</a></li>
224
+ <li><a href="chapter-12.html#s6">Limitations</a></li>
201
225
 
202
226
  </ol>
203
227
  </li>
204
228
 
205
229
  <li>
206
- <a href="chapter-12.html">
230
+ <a href="chapter-13.html">
207
231
  Listeners and Event Producers
208
232
  </a>
209
233
 
210
234
  <ol type="1">
211
235
 
212
- <li><a href="chapter-12.html#s1">Event Producers</a></li>
236
+ <li><a href="chapter-13.html#s1">Event Producers</a></li>
213
237
 
214
- <li><a href="chapter-12.html#s2">Listeners</a></li>
238
+ <li><a href="chapter-13.html#s2">Listeners</a></li>
215
239
 
216
- <li><a href="chapter-12.html#s3">The Registry as an Event Producer</a></li>
240
+ <li><a href="chapter-13.html#s3">The Registry as an Event Producer</a></li>
217
241
 
218
242
  </ol>
219
243
  </li>
@@ -291,302 +315,101 @@
291
315
 
292
316
  <div id="content">
293
317
 
294
- <h1>11. Schemas</h1>
318
+ <h1>11. Service Factories</h1>
295
319
 
296
320
 
297
321
 
298
322
  <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>
323
+ <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>
302
324
 
325
+ <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>
303
326
 
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>
327
+ <p>Here is an example that implements a trivial service factory:</p>
314
328
 
315
329
  <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
-
330
+ class ExampleServiceFactory
358
331
 
359
- <div class="section">
360
- <p>Schemas may be nested, to allow for arbitrarily deep schema &#8220;trees&#8221;. Consider the following example:</p>
332
+ def create_instance( point, parms )
333
+ return { :point =&gt; point,
334
+ :parms =&gt; parms }
335
+ end
361
336
 
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
337
+ end
386
338
  </pre>
387
339
 
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
-
340
+ <p>This service would be introduced into Copland via the following package descriptor:</p>
393
341
 
342
+ <pre>
343
+ ---
344
+ id: example
394
345
 
395
- <h2>
396
- <a name="s3"></a>
397
- 11.3. Arrays
398
- </h2>
346
+ service-points:
399
347
 
400
-
348
+ ExampleServiceFactory:
349
+ implementor: some/file/ExampleServiceFactory
350
+ </pre>
401
351
 
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>
352
+ <p>And it would be employed like this:</p>
404
353
 
405
354
  <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>
355
+ ---
356
+ id: demo
426
357
 
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>
358
+ service-points:
428
359
 
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
360
+ ExampleService:
361
+ implementor:
362
+ factory: example.ExampleServiceFactory
451
363
  </pre>
364
+
365
+ <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 />
366
+ </p>
452
367
  </div>
453
368
 
454
369
 
455
370
 
456
371
  <h2>
457
- <a name="s4"></a>
458
- 11.4. Named vs. Anonymous Schemas
372
+ <a name="s1"></a>
373
+ 11.1. Schemas
459
374
  </h2>
460
375
 
461
376
 
462
377
 
463
378
  <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>
379
+ <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 />
380
+ </p>
530
381
  </div>
531
382
 
532
383
 
533
384
 
534
385
  <h2>
535
- <a name="s5"></a>
536
- 11.5. Extending Schemas
386
+ <a name="s2"></a>
387
+ 11.2. How do they work?
537
388
  </h2>
538
389
 
539
390
 
540
391
 
541
392
  <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>
393
+ <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>
543
394
 
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>
395
+ <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 />
396
+ </p>
569
397
  </div>
570
398
 
571
399
 
572
400
 
573
401
  <h2>
574
- <a name="s6"></a>
575
- 11.6. Limitations
402
+ <a name="s3"></a>
403
+ 11.3. BuilderFactory
576
404
  </h2>
577
405
 
578
406
 
579
407
 
580
408
  <div class="section">
581
- <p>The existing schema implementation is sufficient for most purposes, but it has some limitations:</p>
409
+ <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>
582
410
 
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>
411
+ <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 />
412
+ </p>
590
413
  </div>
591
414
 
592
415