copland 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
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,424 @@
1
+ <html>
2
+ <head>
3
+ <title>Copland Manual :: Chapter 3: Getting Started</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><strong>
70
+ <a href="chapter-3.html">
71
+ Getting Started
72
+ </a>
73
+ </strong> <big>&larr;</big>
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>
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>3. Getting Started</h1>
295
+
296
+
297
+
298
+ <h2>
299
+ <a name="s1"></a>
300
+ 3.1. Terminology
301
+ </h2>
302
+
303
+
304
+
305
+ <div class="section">
306
+ <p>In the tutorials and examples that follow, you&#8217;ll see a lot of (potentially) new terminology. Here is a brief glossary of some of the more prominant terms, to help you get started. Don&#8217;t feel like you need to read and understand each term before proceeding through this manual; just know that you can refer back to these if you need to.</p>
307
+
308
+ <ul>
309
+ <li><strong>configuration point</strong>: This is either a list or a map (configurable) which packages may contribute to, and which services may read from to initialize themselves. Packages may define multiple configuration points.</li>
310
+ <li><strong>contribution</strong>: This is how a package contributes to a <em>configuration point</em>. A package may have any number of contributions, to any number of configuration points. Contributions may be made to configuration points both inside and outside of the current package.</li>
311
+ <li><strong>dependency injection</strong>: A design pattern in which the dependencies of an object are managed independently of the object, usually by some &#8220;container&#8221; framework. See &#8220;inversion of control&#8221;.</li>
312
+ <li><strong>event producer</strong>: A service that other services may listen to in order to obtain notifications of various service-specific events.</li>
313
+ <li><strong>interceptor</strong>: An interceptor is a special object that is attached to a service. A <em>chain</em> of interceptors may wrap the methods of a service and act as filters for any invocations of those methods. This is the means by which <span class="caps">AOP</span>-like &#8220;pre&#8221; and &#8220;post&#8221; hooks are implemented in Copland.</li>
314
+ <li><strong>inversion of control</strong>: A general design pattern in which various types of control are delegated (&#8220;inverted&#8221;) to some enclosing framework, called a &#8220;container&#8221;, &#8220;Dependency injection&#8221; is one form of control inversion, though the two terms are sometimes used interchangeably.</li>
315
+ <li><strong>listener</strong>: A service that has been registered with another service point in order to receive events produced by the latter service.</li>
316
+ <li><strong>package</strong>: The unit of organization in Copland. All <em>service points</em>, <em>configuration points</em>, and <em>contributions</em> are grouped into <em>packages</em>. Each <em>package</em> is defined in its own <em>package descriptor</em>.</li>
317
+ <li><strong>package descriptor</strong>: The file that contains the definition of single package. This always called <code>package.yml</code> and contains <span class="caps">YAML</span>.</li>
318
+ <li><strong>multicast service</strong>: A special kind of service that, by itself does nothing, but which other services may register themselves with. Then, when a method on the multicast service is invoked, the corresponding methods of all registered services will be invoked.</li>
319
+ <li><strong>registry</strong>: This is the primary interface into Copland, used by clients. It is the broker that returns <em>services</em> requested by clients.</li>
320
+ <li><strong>service</strong>: This is the basic unit of activity in Copland. The <em>service model</em> determines how the service is instantiated, such as whether it is a singleton or not. Some services are actually <em>service factories</em> which may in turn be used to help create more complex services. Another special type of service is the <em>interceptor factory</em>, which is used to create interceptor instances. An application&#8217;s components will typically be implemented as services.</li>
321
+ <li><strong>service factory</strong>: A service factory is a special kind of service, which may be used to bootstrap the creation of more complex services. Copland comes with several predefined service factories, most notably the &#8220;BuilderFactory&#8221; (which may be used to create the vast majority of the services you will need).</li>
322
+ <li><strong>service model</strong>: A service model defines how and when a service is instantiated. There are six predefined service models, allowing for simple instantiation (one instance per request, created at the time of the request), singleton instantiation (only one instance of the service is ever created, and it will be returned every time the service is requested), deferred instantiation (the service will be created the first time a method is invoked on it), and even combinations of these. The default model is &#8220;singleton deferred&#8221;.</li>
323
+ <li><strong>service point</strong>: A definition of a service. A service point is to a service as a class is to an object. The service point contains the configuration of interceptors, event producers, service model, service factory, and so forth that will be used to construct its corresponding service.</li>
324
+ </ul>
325
+ </div>
326
+
327
+
328
+
329
+ <h2>
330
+ <a name="s2"></a>
331
+ 3.2. Quickstart
332
+ </h2>
333
+
334
+
335
+
336
+ <div class="section">
337
+ <p>This &#8220;Quickstart&#8221; is designed to show you the &#8220;look&#8221; of a simple Copland application. It is not intended to teach you how to use Copland, nor to be an example of application design in Copland. Very little time will be spent on explanation. If you wish to actually learn how to use Copland, refer instead to the Tutorials section, and the Examples section.</p>
338
+
339
+ <h3>Service Implementation</h3>
340
+
341
+ <p>A service is typically backed by a simple, ordinary Ruby object, instantiated from a class. You don&#8217;t have to do anything special to your definition of the class (unless you want it to interact with other services&#8212;but that&#8217;s beyond the scope of this &#8220;quickstart&#8221;).</p>
342
+
343
+ <pre>
344
+ class ASimpleService
345
+ def do_something
346
+ ...
347
+ end
348
+
349
+ def do_something_complicated( a, b, opts={}, &#38;block )
350
+ ...
351
+ end
352
+ end
353
+ </pre>
354
+
355
+ <p>For the rest of this example, we&#8217;ll assume the above implementation is contained in a file called <code>simple-service.rb</code>.</p>
356
+
357
+ <h3>Service Definition</h3>
358
+
359
+ <p>The services are always defined in a package descriptor file. This file is always named <code>package.yml</code>, which means you can only have one per directory. It is a <span class="caps">YAML</span>-formatted description of a package, which will include all of the service points (service definitions) for that package.</p>
360
+
361
+ <pre>
362
+ ---
363
+ id: quickstart
364
+
365
+ service-points:
366
+
367
+ SimpleService:
368
+ implementor: simple-service/ASimpleService
369
+ </pre>
370
+
371
+ <h3>Registry Initialization</h3>
372
+
373
+ <p>Creating a registry is simple: just invoke <code>build</code> on the Registry class.</p>
374
+
375
+ <pre>
376
+ require 'copland'
377
+
378
+ registry = Copland::Registry.build
379
+ </pre>
380
+
381
+ <p>The <code>build</code> method is a convenience method. It takes care of searching subdirectories for package descriptors and adding them to the new registry.</p>
382
+
383
+ <h3>Getting Services</h3>
384
+
385
+ <p>Services are queried through the registry. The name of a service is the name of it&#8217;s package (the &#8216;id&#8217; in the package descriptor), followed by a dot &#8217;.&#8217;, followed by the id of the service.</p>
386
+
387
+ <p>Once you have a reference to the service, you can invoke its methods just as if it were a plain-old Ruby object.</p>
388
+
389
+ <pre>
390
+ service = registry.service( "quickstart.SimpleService" )
391
+ service.do_something
392
+ service.do_something_complex( 1, 2, :name=&gt;"Jim" ) { |a| puts "#{a}: here" }
393
+ </pre>
394
+
395
+ <h3>Service Initialization</h3>
396
+
397
+ <p>Sometimes (especially for &#8220;prototype&#8221; services&#8212;see the prototype service model for more info) you want to be able to pass some kind of initialization data to the new service the first time it is initialized. You <em>could</em> do this with a method that you explicitly call after obtaining a reference to the service&#8212;but then the service needs to keep track of whether the method has already been invoked or not, to prevent the initialization from occurring more than once per service instance.</p>
398
+
399
+ <p>To make this simpler, Copland 0.8 introduced the concept of an <em>initialization block</em>. When you call <code>Registry#service</code>, you can attach a block to it, and that block will be passed to <code>instance_eval</code> on the new service every time that service is instantiated.</p>
400
+
401
+ <p>Something like this:</p>
402
+
403
+ <pre>
404
+ service = registry.service( "quickstart.SimpleService" ) do
405
+ ...
406
+ # put your initialization code here, to be executed every
407
+ # time this service is instantiated.
408
+ ...
409
+ end
410
+ </pre>
411
+
412
+ <p>If the service was instantiated previously (i.e., it is a singleton service and was requested earlier), then the initialization block will be ignored.<br />
413
+ </p>
414
+ </div>
415
+
416
+
417
+
418
+
419
+ </div>
420
+
421
+ </td></tr>
422
+ </table>
423
+ </body>
424
+ </html>
@@ -0,0 +1,432 @@
1
+ <html>
2
+ <head>
3
+ <title>Copland Manual :: Chapter 4: Copland's Design</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><strong>
84
+ <a href="chapter-4.html">
85
+ Copland's Design
86
+ </a>
87
+ </strong> <big>&larr;</big>
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>
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>4. Copland's Design</h1>
295
+
296
+
297
+
298
+ <div class="section">
299
+ <p>Here you&#8217;ll read about various issues regarding Copland&#8217;s design. These will probably not be interesting to anyone except those who want to dig into Copland&#8217;s internals.<br />
300
+ </p>
301
+ </div>
302
+
303
+
304
+
305
+ <h2>
306
+ <a name="s1"></a>
307
+ 4.1. HiveMind
308
+ </h2>
309
+
310
+
311
+
312
+ <div class="section">
313
+ <p>Copland borrows much of its design from the <a href="http://jakarta.apache.org/hivemind">HiveMind</a> IoC container for Java. However, Copland was written without significant experience with HiveMind&#8217;s internals, so although they may look similar on the outside, their implementations will differ significantly.</p>
314
+
315
+ <h3>Similarities</h3>
316
+
317
+ <p>Copland uses HiveMind&#8217;s concepts of &#8220;modules&#8221; (but calls them &#8220;packages&#8221;), &#8220;service points&#8221;, &#8220;configuration points&#8221;, and &#8220;contributions&#8221;. Also, a &#8220;service models&#8221; are borrowed from HiveMmind, although Copland implements them in a more flexible (and extensible) manner.</p>
318
+
319
+ <p>The idea of a <em>service factory</em> was also borrowed from Copland. HiveMind supports digester-like &#8220;rules&#8221; for processing descriptor files, but because of Ruby&#8217;s highly dynamic nature, such complexity was not necessary.</p>
320
+
321
+ <p>Interceptors, and the way they get created (via special &#8220;interceptor factories&#8221;) are identical to HiveMind&#8217;s interface.</p>
322
+
323
+ <h3>Differences</h3>
324
+
325
+ <p>HiveMind uses <span class="caps">XML</span> for it&#8217;s module descriptors. Copland uses <span class="caps">YAML</span>.</p>
326
+
327
+ <p>HiveMind&#8217;s configuration points revolve around <span class="caps">XML</span>&#8212;you define a configuration point and a schema to go with it, and all contributions to that configuration point must match that schema. Copland&#8217;s approach is simpler: simply declare whether a configuration point is a list or a map, and then all contributions must be either in the form of list elements to append to the configuration point, or map elements to merge into it.</p>
328
+
329
+ <p>Copland names the service models differently:</p>
330
+
331
+ <table>
332
+ <tr>
333
+ <td> <strong>HiveMind</strong> </td>
334
+ <td> <strong>Copland</strong> </td>
335
+ </tr>
336
+ <tr>
337
+ <td style="text-align:center;">&#8212;- </td>
338
+ <td style="text-align:left;">prototype </td>
339
+ </tr>
340
+ <tr>
341
+ <td style="text-align:center;">&#8212;- </td>
342
+ <td style="text-align:left;">prototype-deferred </td>
343
+ </tr>
344
+ <tr>
345
+ <td> primitive </td>
346
+ <td> singleton </td>
347
+ </tr>
348
+ <tr>
349
+ <td> singleton </td>
350
+ <td> singleton-deferred </td>
351
+ </tr>
352
+ <tr>
353
+ <td> threaded </td>
354
+ <td> threaded </td>
355
+ </tr>
356
+ <tr>
357
+ <td> pooled </td>
358
+ <td style="text-align:center;">&#8212;- </td>
359
+ </tr>
360
+ </table>
361
+
362
+ <p>Events and listeners exist in HiveMind, too, but because of Ruby&#8217;s dynamic nature they can be implemented much more simply in Copland. Therefore, the way they are declared and used is different in Copland.</p>
363
+
364
+ <p>Multicast services do not exist in HiveMind, nor do services that are backed by anything other than objects. Copland allows services to be backed by classes and singletons, as well as objects.<br />
365
+ </p>
366
+ </div>
367
+
368
+
369
+
370
+ <h2>
371
+ <a name="s2"></a>
372
+ 4.2. Registry Initialization
373
+ </h2>
374
+
375
+
376
+
377
+ <div class="section">
378
+ <p>The initialization process for the registry consists of two phases. The first phase is where the package descriptors are loaded and parsed. Once all of the packages have been loaded the the second phase is started, which causes all of the packages to process those parts of themselves that refer to other packages. This includes contributions to configuration points and processing any referenced parameter schema definitions.</p>
379
+
380
+ <p>One the initialization has been completed, the registry (which is itself exported as a service) loads the copland.Startup service and instructs it to start any services that have registered themselves with it (via its configuration point).<br />
381
+ </p>
382
+ </div>
383
+
384
+
385
+
386
+ <h2>
387
+ <a name="s3"></a>
388
+ 4.3. Service Instantiation
389
+ </h2>
390
+
391
+
392
+
393
+ <div class="section">
394
+ <p>The way a service is instantiated depends on two things: it&#8217;s <em>service model</em>, and its <em>instantiator</em> (or <em>implementor</em>).</p>
395
+
396
+ <p>The <em>instantiator</em> defines <em>how</em> the service is instantiated. It may either be a string (in which case the service is created simply by calling &#8216;new&#8217; on the class described by that string), or a map, in which case the creation of the class is delegated to a service factory. These two approaches are defined inside Copland as &#8220;instantiation factories&#8221;, with the first being <code>Copland::Instantiator::Simple</code>, and the second being <code>Copland::Instantiator::Complex</code>.</p>
397
+
398
+ <p>The <em>service models</em> define <em>when</em> the service is instantiated. For example, the &#8220;singleton&#8221; model says that a service is only instantiated the first time it is requested, with subsequent requests returning the cached instance. The &#8220;singleton-deferred&#8221; model indicates that a service should only be instantiated the first time any of its methods are invoked (this level of granularity is achieved via a proxy object that defers instantiation of its wrapped service).</p>
399
+
400
+ <p>Thus, when a user requests a service, the registry calls the <code>#instance</code> method of the corresponding service point. This calls the <code>#instance</code> method for the service point&#8217;s model, and the service model may then either call the service point&#8217;s <code>#instantiate</code> method (to actually instantiate the service point) or return a cached instance.</p>
401
+
402
+ <p>The service point&#8217;s <code>#instantiate</code> method will call the <code>#instantiate</code> method for the instantiation factory for this service point. The <code>Simple</code> factory simply calls <code>#new</code> on the service point&#8217;s backing class, but the <code>Complex</code> factory will basically &#8220;execute&#8221; the parameter scheme for the service factory that was specified, and then invoke the <code>#create_instance</code> method of the service factory. Either way, the backing object for the service is returned.</p>
403
+
404
+ <p>Then, any interceptors that were specified are added to the new service, the new service is added as a listener to any requested event producers, and the new service is returned.<br />
405
+ </p>
406
+ </div>
407
+
408
+
409
+
410
+ <h2>
411
+ <a name="s4"></a>
412
+ 4.4. Interceptor Chains
413
+ </h2>
414
+
415
+
416
+
417
+ <div class="section">
418
+ <p>Interceptor chains are implemented as chains of proxy objects, each of which wraps an interceptor instance. Each method of the service that is being intercepted is then renamed and replaced with a new method, which just executes the <code>#process_next</code> method on the first element in the chain. When the last element of the chain invokes the <code>#process_next</code> element on what it believes to be the next link, the renamed method of the service is invoked.</p>
419
+
420
+ <p>This makes it look to each interceptor as if they are a filter for the message invocation, which indeed they are. Each interceptor may invoke the <code>#process_next</code> method of the next link in the chain, if they desire, or not, if they desire.<br />
421
+ </p>
422
+ </div>
423
+
424
+
425
+
426
+
427
+ </div>
428
+
429
+ </td></tr>
430
+ </table>
431
+ </body>
432
+ </html>