summaryrefslogtreecommitdiff
path: root/include/swmgr.h
blob: 9ddc4aa67a3a98262b1f35363886f16d98a6bc17 (plain)
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
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
/******************************************************************************
 *
 *  swmgr.h -	definition of class SWMgr used to interact with an install
 *		base of sword modules.
 *
 * $Id: swmgr.h 3541 2017-12-03 18:40:33Z scribe $
 *
 * Copyright 1997-2014 CrossWire Bible Society (http://www.crosswire.org)
 *	CrossWire Bible Society
 *	P. O. Box 2528
 *	Tempe, AZ  85280-2528
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation version 2.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 */

/** @mainpage The SWORD Project - API documentation
 * This is the API documentation for The SWORD Project.
 * It describes the structure of the SWORD library and documents the functions of the classes.
 * From time to time this documentation gives programming examples, too.
 *
 * SWORD provides a simple to use engine for working with many types of texts including Bibles,
 *	commentaries, lexicons, glossaries, daily devotionals, and others.
 *
 * Some main classes:
 *
 * SWMgr gives access to an installed library of modules (books).
 * SWModule represents an individual module
 * SWKey represents a location into a module (e.g. "John 3:16")
 *
 * An API Primer can be found at:
 *
 * http://crosswire.org/sword/develop/swordapi/apiprimer.jsp
 *
 * If you're interested in working on a client which uses SWORD, please first have a look at
 *	some of the existing ones.  They can always use help, and will also prove to be good examples
 *	if you decide to start a new project.
 *
 * Well known frontends are:
 *	-BibleTime
 *	-BPBible
 *	-Eloquent
 *	-PocketSword
 *	-The SWORD Projectfor Windows
 *	-Xiphos
 * See http://crosswire.org/applications.jsp for links to each and a more
 * complete list.
 */

#ifndef SWMGR_H
#define SWMGR_H

#include <map>
#include <list>
#include <swbuf.h>
#include <swconfig.h>

#include <defs.h>

SWORD_NAMESPACE_START

class SWModule;
class SWFilter;
class SWOptionFilter;
class SWFilterMgr;
class SWBuf;
class SWKey;

typedef std::map < SWBuf, SWModule *, std::less < SWBuf > >ModMap;
typedef std::map < SWBuf, SWFilter * >FilterMap;
typedef std::map < SWBuf, SWOptionFilter * >OptionFilterMap;
typedef std::list < SWBuf >StringList;
typedef std::list < SWFilter* >FilterList;
typedef std::list < SWOptionFilter* >OptionFilterList;

class FileDesc;
class SWOptionFilter;

/** SWMgr exposes an installed module set
 *
 * SWMgr exposes an installed module set and can be asked to configure the desired
 *	markup and options which modules will produce.
 *
 * @version $Id: swmgr.h 3541 2017-12-03 18:40:33Z scribe $
 */
class SWDLLEXPORT SWMgr {
private:
	bool mgrModeMultiMod;
	bool augmentHome;
	void commonInit(SWConfig *iconfig, SWConfig *isysconfig, bool autoload, SWFilterMgr *filterMgr, bool multiMod = false);

protected:
	SWFilterMgr *filterMgr;		//made protected because because BibleTime needs it
	SWConfig *myconfig;		//made protected because because BibleTime needs it
	SWConfig *mysysconfig;
	SWConfig *homeConfig;
	/**
	 * Deprecated. Use createAllModules instead
	 */
	SWDEPRECATED void CreateMods(bool multiMod = false) { createAllModules(multiMod); };
	SWDEPRECATED void DeleteMods() { deleteAllModules(); }
	char configType;		// 0 = file; 1 = directory
	OptionFilterMap optionFilters;
	FilterMap cipherFilters;
	SWFilter *gbfplain;
	SWFilter *thmlplain;
	SWFilter *osisplain;
	SWFilter *teiplain;
	SWOptionFilter *transliterator;
	FilterList cleanupFilters;
	FilterMap extraFilters;
	StringList options;
	/**
	 * method to create all modules from configuration.
	 *
	 * Override to add any special processing before or after
	 * calling SWMgr::createAllModules
	 *
	 * e.g., augmenting a localConfig.conf to SWMgr::config
	 * that might store CipheyKey or Font preferences per module
	 * before actual construction of modules
	 *
	 */
	virtual void createAllModules(bool multiMod = false);
	/**
	 * called to delete all contructed modules.  Undoes createAllModules
	 * override to clean anything up before or after all modules are
	 * deleted
	 */
	virtual void deleteAllModules();

	/**
	 * called to create exactly one module from a config entry
	 * override to do any extra work before or after each module
	 * is created
	 */
	virtual SWModule *createModule(const char *name, const char *driver, ConfigEntMap &section);

	/**
	 * call by every constructor to initialize SWMgr object
	 * override to include any addition common initialization
	 */
	virtual void init();


	/**
	 * Deprecated.  Use addGlobalOptionFilters instead.
	 */
	SWDEPRECATED virtual void AddGlobalOptions(SWModule *module, ConfigEntMap &section, ConfigEntMap::iterator start, ConfigEntMap::iterator end) { addGlobalOptionFilters(module, section); }
	/**
	 * Adds appropriate global option filters to a module.  Override to add any special
	 *	global option filters. Global option filters typically update SourceType markup
	 *	to turn on and off specific features of a text when a user has optionally chosen
	 *	to show or hide that feature, e.g. Strongs, Footnotes, Headings, etc.
	 *	Global options can also have more than On and Off values, but these are the most
	 *	common.
	 *	A set of all global options included from an entire library of installed modules
	 *	can be obtained from getGlobalOptions and presented to the user.  Values to
	 *	which each global option may be set can be obtain from getGlobalOptionValues,
	 *	and similar.  See that family of methods for more information.
	 * See the module.conf GlobalOptionFilter= entries.
	 * @param module module to which to add encoding filters
	 * @param section configuration information for module
	 */
	virtual void addGlobalOptionFilters(SWModule *module, ConfigEntMap &section);

	/**
	 * Deprecated.  Use addLocalOptionFilters instead.
	 */
	SWDEPRECATED virtual void AddLocalOptions(SWModule *module, ConfigEntMap &section, ConfigEntMap::iterator start, ConfigEntMap::iterator end) { addLocalOptionFilters(module, section); }
	/**
	 * Adds appropriate local option filters to a module.  Override to add any special
	 *	local option filters.  Local options are similar to global options in that
	 *	they may be toggled on or off or set to some value from a range of choices
	 *	but local option
	 * See the module.conf LocalOptionFilter= entries.
	 * @param module module to which to add encoding filters
	 * @param section configuration information for module
	 */
	virtual void addLocalOptionFilters(SWModule *module, ConfigEntMap &section);

	/**
	 * Deprecated.  Use addEncodingFilters instead
	 */
	SWDEPRECATED virtual void AddEncodingFilters(SWModule *module, ConfigEntMap &section) { addEncodingFilters(module, section); }
	/**
	 * Adds appropriate encoding filters to a module.  Override to add any special
	 *	encoding filters.
	 * See the module.conf Encoding= entry.
	 * @param module module to which to add encoding filters
	 * @param section configuration information for module
	 */
	virtual void addEncodingFilters(SWModule *module, ConfigEntMap &section);

	/**
	 * Deprecated.  Use addRenderFilters instead.
	 */
	SWDEPRECATED virtual void AddRenderFilters(SWModule *module, ConfigEntMap &section) { addRenderFilters(module, section); }
	/**
	 * Add appropriate render filters to a module.  Override to add any special
	 *	render filters. Render filters are used for preparing a text for
	 *	display and typically convert markup from SourceType
	 *	to desired display markup.
	 * See the module.conf SourceType= entry.
	 * @param module module to which to add render filters
	 * @param section configuration information for module
	 */
	virtual void addRenderFilters(SWModule *module, ConfigEntMap &section);

	/**
	 * Deprecated.  Use addStripFilters instead.
	 */
	SWDEPRECATED virtual void AddStripFilters(SWModule *module, ConfigEntMap &section) { addStripFilters(module, section); }
	/**
	 * Adds appropriate strip filters to a module.  Override to add any special
	 *	strip filters. Strip filters are used for preparing text for searching
	 *	and typically strip out all markup and leave only searchable words
	 * See the module.conf SourceType= entry.
	 * @param module module to which to add strip filters
	 * @param section configuration information for module
	 */
	virtual void addStripFilters(SWModule *module, ConfigEntMap &section);

	/**
	 * Deprecated.  Use addLocalStripFilters instead.
	 */
	SWDEPRECATED virtual void AddStripFilters(SWModule *module, ConfigEntMap &section, ConfigEntMap::iterator start, ConfigEntMap::iterator end) { addLocalStripFilters(module, section); }
	/**
	 * Adds manually specified strip filters specified in module configuration
	 * as LocalStripFilters.  These might take care of special cases of preparation
	 * for searching, e.g., removing ()[] and underdot symbols from manuscript modules
	 * @param module module to which to add local strip filters
	 * @param section configuration information for module
	 */
	virtual void addLocalStripFilters(SWModule *module, ConfigEntMap &section);

	/**
	 * Deprecated.  Use addRawFilters instead.
	 */
	SWDEPRECATED virtual void AddRawFilters(SWModule *module, ConfigEntMap &section) { addRawFilters(module, section); }
	/**
	 * Add appropriate raw filters to a module.  Override to add any special
	 *	raw filters.  Raw filters are used to manipulate a buffer
	 *	immediately after it has been read from storage.  For example,
	 *	any decryption that might need to be done.
	 * See the module.conf CipherKey= entry.
	 * @param module module to which to add raw filters
	 * @param section configuration information for module
	 */
	virtual void addRawFilters(SWModule *module, ConfigEntMap &section);


	// still to be normalized below ...
	//
	StringList augPaths;
	virtual char AddModToConfig(FileDesc *conffd, const char *fname);
	virtual void loadConfigDir(const char *ipath);

public:

	// constants which represent module types used in SWModule::getType
	static const char *MODTYPE_BIBLES;
	static const char *MODTYPE_COMMENTARIES;
	static const char *MODTYPE_LEXDICTS;
	static const char *MODTYPE_GENBOOKS;
	static const char *MODTYPE_DAILYDEVOS;


	static bool isICU;
	static const char *globalConfPath;

	/**
	 * Deprecated.  Used FileMgr::getSystemFileMgr()->getHomeDir() instead.
	 */
	SWDEPRECATED static SWBuf getHomeDir();

	/**
	 * Perform all the logic to discover a SWORD configuration and libraries on a system
	 */
	static void findConfig(char *configType, char **prefixPath, char **configPath, StringList *augPaths = 0, SWConfig **providedSysConf = 0);

	/**
	 * The configuration of a loaded library of SWORD modules
	 * e.g., from /usr/share/sword/mods.d/
	 * 	augmented with ~/.sword/mods.d/
	 * 
	 * This represents all discovered modules and their configuration
	 * compiled into a single SWConfig object with each [section]
	 * representing each module. e.g. [KJV]
	 */
	SWConfig *config;

	/**
	 * The configuration file for SWORD
	 * e.g., /etc/sword.conf
	 */
	SWConfig *sysConfig;

	/** The path to main module set and locales
	 */
	char *prefixPath;

	/** path to main module set configuration 
	 */
	char *configPath;


	/**
	 * Deprecated.  Use getModules instead.
	 */
	ModMap Modules;
	/** The map of available modules.
	 *	This map exposes the installed modules.
	 *
	 *	Here's an example how to iterate over all
	 *	the installed modules and check the module name
	 *	and type of each module and do something special
	 *	if the module type is a Bible.
	 *
	 * @code
	 *
	 * for (ModMap::iterator it = getModules().begin(); it != getModules().end(); ++it) {
	 *
	 * 	SWBuf modName = it->first;
	 * 	SWModule *mod = it->second;
	 *
	 * 	SWBuf modType = mod->getType();
	 *
	 * 	if (modType == SWMgr::MODTYPE_BIBLES) {
	 * 		// do something with mod
	 * 	}
	 * }
	 * @endcode
	 */
	ModMap &getModules();
	const ModMap &getModules() const { return const_cast<SWMgr *>(this)->getModules(); }

	/** Gets a specific module by name.  e.g. SWModule *kjv = myManager.getModule("KJV");
	 * @param modName the name of the module to retrieve
	 * @return the module, if found, otherwise 0
	 */
	SWModule *getModule(const char *modName) { ModMap::iterator it = getModules().find(modName); return ((it != getModules().end()) ? it->second : 0); }
	const SWModule *getModule(const char *modName) const { ModMap::const_iterator it = getModules().find(modName); return ((it != getModules().end()) ? it->second : 0); }


	/** Constructs an instance of SWMgr
	 *
	 * @param iconfig manually supply a configuration.  If not supplied, SWMgr will look on the system
	 *	using a complex hierarchical search.  See README for detailed specifics.
	 * @param isysconfig manually supply a an isysconfig (e.g. /etc/sword.conf)
	 * @param autoload whether or not to immediately load modules on construction of this SWMgr.
	 *	If you reimplemented SWMgr you can set this to false and call SWMgr::load() after you have
	 *	completed the contruction and setup of your SWMgr subclass.
	 * @param filterMgr an SWFilterMgr subclass to use to manager filters on modules
	 *	SWMgr TAKES OWNERSHIP FOR DELETING THIS OBJECT
	 *	For example, this will create an SWMgr and cause its modules to produce HTMLHREF formatted output
	 *	when asked for renderable text:
	 *
	 *	SWMgr *myMgr = new SWMgr(0, 0, true, new MarkupFilterMgr(FMT_HTMLHREF));
	 */
	SWMgr(SWConfig *iconfig = 0, SWConfig *isysconfig = 0, bool autoload = true, SWFilterMgr *filterMgr = 0, bool multiMod = false);

	/**
	 */
	SWMgr(SWFilterMgr *filterMgr, bool multiMod = false);

	/**
	 * @param iConfigPath provide a custom path to use for module set location, instead of
	 *	searching the system for it.
	 */
	SWMgr(const char *iConfigPath, bool autoload = true, SWFilterMgr *filterMgr = 0, bool multiMod = false, bool augmentHome = true);

	/** The destructor of SWMgr.
	 * This function cleans up the modules and deletes the created object.
	 * Destroying the SWMgr causes all retrieved SWModule object to be invalid, so
	 *	be sure to destroy only when retrieved objects are no longer needed.
	 */
	virtual ~SWMgr();

	/**
	 * Adds books from a new path to the library
	 * @param path the path in which to search for books
	 * @param multiMod whether or not to keep multiple copies of the same book if found in different paths
	 *		default - false, uses last found version of the book
	 */
	virtual void augmentModules(const char *path, bool multiMod = false);

	void deleteModule(const char *);

	/** Looks for any newly installed module.conf file in the path provided,
	 *	displays the copyright information to the user, and then copies the
	 *	module.conf to the main module set's mods.d directory
	 * @param dir where to search for new modules
	 */
	virtual void InstallScan(const char *dir);

	/**
	 * Deprecated.  Use load
	 */
	SWDEPRECATED virtual signed char Load() { return load(); }
	/** Loads installed library of SWORD modules.
	 * Should only be manually called if SWMgr was constructed
	 *	without autoload; otherwise, this will be called on SWMgr construction
	 * Reimplement this function to supply special functionality when modules are
	 * initially loaded. This includes
	 * discovery of config path with SWMgr::fileconfig,
	 * loading of composite SWMgr::config,
	 * and construction of all modules from config using SWMgr::createAllModules
	 */
	virtual signed char load();

	/** Change the values of global options (e.g. Footnotes, Strong's Number, etc.)
	 * @param option The name of the option, for which you want to change the
	 * value. Well known and often used values are "Footnotes" or "Strong's Numbers"
	 * @param value new value. Common values are "On" and "Off"
	 */
	virtual void setGlobalOption(const char *option, const char *value);

	/** Get the current value of the given option
	 * @param option the name of the option, who's value is desired
	 * @return the value of the given option
	 */
	virtual const char *getGlobalOption(const char *option);

	/** Gets a brief description for the given option
	 * @param option the name of the option, who's tip is desired
	 * @return description text
	 * @see setGlobalOption, getGlobalOption, getGlobalOptions
	 */
	virtual const char *getGlobalOptionTip(const char *option);

	/** Gets a list of all available option names
	 * @return list of option names
	 */
	virtual StringList getGlobalOptions();

	/** Gets a list of legal values to which a specific option 
	 *	may be set
	 * @param option the name of the option, who's legal values are desired
	 * @return a list of legal values for the given option
	 */
	virtual StringList getGlobalOptionValues(const char *option);

	/** Filters a buffer thru a named filter
	 * @param filterName
	 * @param text buffer to filter
	 * @param key context key if filter needs this for processing
	 * @param module context module if filter needs this for processing
	 * @return error status
	 */
	virtual char filterText(const char *filterName, SWBuf &text, const SWKey *key = 0, const SWModule *module = 0);

	/**
	 * Sets the cipher key for the given module. This function updates the key
	 * at runtime, but it does not write to the config file.
	 * This method is NOT the recommended means for applying a CipherKey
	 * to a module.
	 *
	 * Typically CipherKey entries and other per module user configuration
	 * settings are all saved in a separate localConfig.conf that is updated
	 * by a UI or other client of the library. e.g.,
	 *
	 *
	 * [KJV]
	 * Font=Arial
	 * LocalOptionFilter=SomeSpecialFilterMyUIAppliesToTheKJV
	 *
	 * [ISV]
	 * CipherKey=xyzzy
	 *
	 * [StrongsGreek]
	 * SomeUISetting=false
	 *
	 *
	 * Then these extra config settings in this separate file are applied
	 * just before module creation by overriding SWMgr::createAllModules and
	 * augmenting SWMgr::config with code like this:
	 *
	 * @code
	 * void createAllModules(bool multiMod) {
	 *
	 * 	// after SWMgr::config is loaded
	 *	// see if we have our own local settings
	 * 	SWBuf myExtraConf = "~/.myapp/localConf.conf";
	 * 	bool exists = FileMgr::existsFile(extraConf);
	 * 	if (exists) {
	 * 		SWConfig addConfig(extraConf);
	 * 		this->config->augment(addConfig);
	 * 	}
	 *
	 * 	// now that we've augmented SWMgr::config with our own custom
	 * 	// settings, proceed on with creating modules
	 *
	 * 	SWMgr::createAllModules(multiMod);
	 *
	 * }
	 * @endcode
	 *
	 * The above convention is preferred to using this setCipherKey method
	 *
	 * @param modName For this module we change the unlockKey
	 * @param key This is the new unlock key we use for the module.
	 */
	virtual signed char setCipherKey(const char *modName, const char *key);
};

SWORD_NAMESPACE_END
#endif