1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
|
/*-------------------------------------------------------------------------
* C-Pluff, a plug-in framework for C
* Copyright 2007 Johannes Lehtinen
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*-----------------------------------------------------------------------*/
/**
* @page plugin Plug-in
*
* @section pluginOverview Overview
*
* Plug-in is the core element of an extensible application. The extensions and
* also the main application logic are implemented as plug-ins. Plug-ins can
* be developed, distributed and deployed independently, subject to
* inter-plugin dependencies. Deploying a new plug-in does not require
* recompilation or relinking if the operating system platform supports
* required dynamic linking facilities.
*
* @section pluginStructure Structure
*
* A plug-in includes the following structural elements.
*
* - @ref pluginDescriptor "Plug-in descriptor"
* - @ref pluginRuntime "Plug-in runtime library"
* - @ref pluginData "Static plug-in data"
*
* @subsection pluginDescriptor Plug-in descriptor
*
* A plug-in descriptor is an XML document describing a plug-in. It includes
* information about the contents of the plug-in, the features provided by
* the plug-in, plug-in version information and static dependencies of the
* plug-in. Most of the elements are optional. Most of the descriptor
* information described here is available to software via
* @ref cp_plugin_info_t structure. The plug-in descriptor must be located
* in the plug-in directory as @c plugin.xml.
*
* The formal declaration of plug-in descriptor is available as
* XML Schema Definition in @c plugin.xsd located in the top level source
* directory. Currently there is no namespace associated with the plug-in
* descriptor. Here is an example of a plug-in descriptor. Click element name
* to jump into documentation for that element.
*
* <div class="fragment">
* <pre class="fragment">
* <<a class="code" href="#pluginDescPlugin">plugin</a> id=<span class="charliteral">"org.c-pluff.example"</span> name=<span class="charliteral">"Example Plug-in"</span> version=<span class="charliteral">"0.3.2"</span> provider-name=<span class="charliteral">"Johannes Lehtinen"</span>>
* <<a class="code" href="#pluginDescPluginBWC">backwards-compatibility</a> abi=<span class="charliteral">"0.3"</span> api=<span class="charliteral">"0.2.8"</span>/>
* <<a class="code" href="#pluginDescPluginRequires">requires</a>>
* <<a class="code" href="#pluginDescPluginReqCP">c-pluff</a> version=<span class="charliteral">"0.1"</span>/>
* <<a class="code" href="#pluginDescPluginReqImport">import</a> plugin=<span class="charliteral">"org.c-pluff.util"</span> version=<span class="charliteral">"0.2"</span>/>
* <<a class="code" href="#pluginDescPluginReqImport">import</a> plugin=<span class="charliteral">"org.c-pluff.extra"</span> optional=<span class="charliteral">"true"</span>/>
* </<a class="code" href="#pluginDescPluginRequires">requires</a>>
* <<a class="code" href="#pluginDescPluginRuntime">runtime</a> library=<span class="charliteral">"libruntime"</span> funcs=<span class="charliteral">"org_cpluff_example_funcs"</span>/>
* <<a class="code" href="#pluginDescPluginEP">extension-point</a> id=<span class="charliteral">"editors"</span> name=<span class="charliteral">"Text Editors"</span> schema=<span class="charliteral">"editors_schema.xsd"</span>/>
* <<a class="code" href="#pluginDescPluginEP">extension-point</a> id=<span class="charliteral">"url-families"</span>/>
* <<a class="code" href="#pluginDescPluginE">extension</a> point=<span class="charliteral">"org.c-pluff.util.archivers"</span> id=<span class="charliteral">"tar"</span> name=<span class="charliteral">"Tar Archiver Support"</span>>
* <type random-access=<span class="charliteral">"false"</span>/>
* <exec bin=<span class="charliteral">"tar"</span>/>
* </<a class="code" href="#pluginDescPluginE">extension</a>>
* <<a class="code" href="#pluginDescPluginE">extension</a> point=<span class="charliteral">"org.c-pluff.example.editors</span>>
* <editor name=<span class="charliteral">"Text Editor"</span> runtime=<span class="charliteral">"org_cpluff_example_txteditor_runtime"</span>>
* <file-types>
* <file-type mime-type=<span class="charliteral">"text/plain"</span>/>
* </file-types>
* </editor>
* </<a class="code" href="#pluginDescPluginE">extension</a>>
* </<a class="code" href="#pluginDescPlugin">plugin</a>></pre>
* </div>
*
* A descriptor can also be much simpler, depending on the plug-in.
* Here is an example of a minimal descriptor (of a useless plug-in).
*
* <div class="fragment">
* <pre class="fragment">
* <<a class="code" href="#pluginDescPlugin">plugin</a> id=<span class="charliteral">"org.c-pluff.useless"</span>/></pre>
* </div>
*
* @subsubsection pluginDescPlugin plugin
*
* This is the top level element of the plug-in descriptor. It can have
* following attributes.
*
* - @a id: A mandatory unique identifier for the plug-in. Plug-in identifiers
* should preferably be generated using a reversed DNS domain name as
* prefix to prevent identifier conflicts.
* - @a name: An optional human-readable name for the plug-in.
* - @a version: An optional version number for the plug-in. Version numbers
* are used for checking compatibility when resolving versioned plug-in
* dependencies. See also information about
* @ref pluginVersions "plug-in versions".
* - @a provider-name: The name of the plug-in provider or author. Optional.
*
* This element can contain following elements.
*
* - @ref pluginDescPluginBWC "backwards-compatibility": Optional information about backwards
* compatibility of this plug-in version.
* - @ref pluginDescPluginRequires "requires": Information about static plug-in dependencies. Can be omitted
* if the plug-in does not have static dependencies.
* - @ref pluginDescPluginRuntime "runtime": Information about the plug-in runtime library. Can be omitted
* if the plug-in does not have a runtime library but only data.
* - @ref pluginDescPluginEP "extension-point": Information about extension points provided by the
* plug-in. This element is repeated if there are multiple extension points
* and omitted if there are none.
* - @ref pluginDescPluginE "extension": Information about extensions provided by the plug-in.
* This element is repeated if there are multiple extensions and omitted
* if there are none.
*
* @subsubsection pluginDescPluginBWC backwards-compatibility
*
* This element includes optional information about the backwards compatibility
* of this plug-in version. It can have following attributes.
*
* - @a abi: Backwards compatibility of the application binary interface (ABI)
* of the plug-in. ABI includes any public symbols exported by the plug-in,
* data structures associated with exported symbols and any extension points
* provided by the plug-in. The ABI of the current plug-in version is
* backwards compatible with any plug-in version from the version specified
* here to the current version. This information is used when resolving
* versioned plug-in dependencies. See also information about
* @ref pluginVersions "plug-in versions".
* - @a api: Backwards compatibility of the application programming interface
* (API) of the plug-in. API compatibility means that source code developed
* against one version of the plug-in also compiles against another version
* of the plug-in. This information is not used by framework but it can be
* used by a developer developing dependent plug-ins.
*
* These apply to plug-ins that provide header files and runtime libraries.
* For example, a plug-in might export global functions to other plug-ins or it
* might provide an extension point where an extension installed by other
* plug-in must conform to data structures defined by the plug-in.
* Both attributes are optional.
*
* @subsubsection pluginDescPluginRequires requires
*
* This element includes information about static plug-in dependencies.
* It can be omitted if there are no dependencies. It can contain following
* elements.
*
* - @ref pluginDescPluginReqCP "c-pluff": An optional version dependency
* on the C-Pluff implementation.
* - @ref pluginDescPluginReqImport "import": Declares a static dependency
* on other plug-in. This element is repeated if there are multiple
* dependencies and omitted if there are none.
*
* @subsubsection pluginDescPluginReqCP c-pluff
*
* This element declares a version dependency on the C-Pluff
* implementation. It can be used to ensure that the plug-in is not loaded by
* incompatible C-Pluff version. It has the following attribute.
*
* - @a version: The required version of the C-Pluff implementation.
* This is used when resolving the plug-in. It is checked that the used
* C-Pluff implementation is backwards compatible with the version specified
* here when it comes to the application binary interface (ABI) of C-Pluff.
*
* @subsubsection pluginDescPluginReqImport import
*
* This element declares a static dependency on other plug-in. It must be
* used when a plug-in uses global symbols or data from other plug-in or when
* a plug-in uses an extension point defined by other plug-in or whenever some
* other plug-in needs to be there for the plug-in to work. The framework takes
* care of resolving and starting the dependencies whenever the plug-in is
* resolved or started.
*
* This element can have following attributes.
*
* - @a plugin: The identifier of the imported plug-in.
* - @a version: An optional version dependency on the imported plug-in.
* The plug-in can be resolved only if the version of the imported plug-in
* is backwards compatible with the version specified here when it comes
* to the application binary interface (ABI) of the imported plug-in.
* - @a optional: Is the import optional or not ("true" or "false"). Default is
* false, a mandatory import.
* An optional import behaves just like the mandatory import as long as the
* imported plug-in is present. However, if it is not present then the
* import is ignored. Optional import can be used if the plug-in works
* in limited capacity even without the specified plug-in.
*
* @subsubsection pluginDescPluginRuntime runtime
*
* This element contains information about the plug-in runtime library. It is
* omitted if the plug-in does not have a runtime library but contains only
* data. It can have following attributes.
*
* - @a library: The name of the plug-in runtime library in the plug-in
* directory. A platform specific extension (for example, ".so" or ".dll")
* is added to the value specified here when loading the library.
* - @a funcs: The functions to be used to create an instance of the plug-in
* runtime. This attribute is optional. It is needed if the plug-in has
* a start or stop function. The value specified here is a name of an
* exported symbol which contains a pointer to @ref cp_plugin_runtime_t
* structure.
*
* @subsubsection pluginDescPluginEP extension-point
*
* This element defines an extension point provided by the plug-in.
* It can have following attributes.
*
* - @a id: The local identifier of the extension point. The value specified
* here is prefixed with the identifier of the plug-in and dot to construct
* the global identifier of the extension point.
* - @a name: An optional human-readable name describing the use of the
* extension point.
* - @a schema: An optional path to the extension point XML schema in
* the plug-in directory. This information is not currently used by the
* framework. But it can be used by a developer to determine what information
* should be provided by extensions attached to this extension point.
*
* @subsubsection pluginDescPluginE extension
*
* This element defines an extension installed into a specified extension
* point provided by the defining plug-in or some other plug-in.
* It can have following attributes.
*
* - @a point: The global identifier of the associated extension point.
* - @a id: An optional local identifier for the extension. The value specified
* here is prefixed with the identifier of the plug-in and dot to construct
* the global identifier for the extension.
* - @a name: An optional human-readable name describing the extension.
*
* The extension element can contain XML elements specific to the associated
* extension point (conforming to the schema defined by the extension point).
*
* @subsection pluginRuntime Plug-in runtime library
*
* A plug-in runtime library is an optional plug-in element. Plug-ins only
* supplying static data in form of XML data and files do not need a runtime
* library. However, a typical plug-in does provide program logic as well.
*
* The plug-in runtime library includes all program logic and program
* data provided by the plug-in. It is simply a shared library, or a
* dynamically linked library, which is linked in to the application when
* the plug-in is started. When plug-in is unloaded, the runtime library is
* unloaded as well. The framework has been designed to manage dependencies
* so that unloading of the runtime library does not cause problems, provided
* that plug-ins behave properly.
*
* A plug-in can expose functionality to other plug-ins either as exported
* global symbols that are directly resolved by other plug-ins or by supplying
* extensions. When other plug-ins are directly using exported symbols the
* plug-in acts just like any standard shared library. Nothing special there.
* The more interesting case is exposing functionality as extensions. Because
* the extension is registered at a specific extension point, the logic in
* other plug-ins can use the extension and the associated program logic even
* if they are not aware of the existence of the extension supplying plug-in.
*
* The extension points accepting program logic as extensions define a way
* to specify the name of the symbol pointing to the supplied logic. This is
* typically an attribute of an XML element contained in the extension
* definition. The plug-in supplying the extension can then export the program
* logic as a global symbol with arbitrary name and then place the name of the
* symbol in extension data. Alternatively, the plug-in can define a virtual
* symbol at runtime using ::cp_define_symbol. Other plug-ins that are using
* extensions registered at the extension point can then resolve the named
* symbol using ::cp_resolve_symbol at runtime. The framework automatically
* creates a dependency from the symbol using plug-in to the symbol supplying
* plug-in to prevent failures in case the symbol supplying plug-in is stopped
* or unloaded.
*
* @subsection pluginData Static plug-in data
*
* Plug-in can supply static data to other plug-ins using at least two
* different mechanisms. A plug-in can easily provide static XML data as part
* of extension elements. Additionally, a plug-in directory can contain
* files that may be accessed by other plug-ins. Currently the platform does
* not provide assistance in accessing data files provided by other plug-ins.
* However, a plug-in can locate the plug-in directory and thus any included
* data files by using plug-in path available in @ref cp_plugin_info_t
* structure of the data providing plug-in.
*/
|