copland 0.8.0 → 1.0.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 (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