1 //*****************************************************************************
2 // FILE: ossimInit.cpp
3 //
4 // License: MIT
5 //
6 // See LICENSE.txt file in the top level directory for more details.
7 //
8 // DESCRIPTION:
9 //   Contains implementation of class ossimInit. This object handles all
10 //   aspects of initialization for OSSIM applications. These tasks include:
11 //
12 //      1. Parsing the command line.
13 //      2. Instantiating all class factories.
14 //      3. Initializing the "trace" code execution tracing functionality.
15 //      4. Scanning the preferences file for relevant values.
16 //
17 // SOFTWARE HISTORY:
18 //   24Apr2001  Oscar Kramer
19 //              Initial coding.
20 //*****************************************************************************
21 // $Id$
22 
23 #include <ossim/init/ossimInit.h>
24 #include <ossim/ossimVersion.h>
25 
26 #include <ossim/base/ossimArgumentParser.h>
27 #include <ossim/base/ossimApplicationUsage.h>
28 #include <ossim/base/ossimBaseObjectFactory.h>
29 #include <ossim/base/ossimDatumFactoryRegistry.h>
30 #include <ossim/base/ossimDirectory.h>
31 #include <ossim/base/ossimEnvironmentUtility.h>
32 #include <ossim/base/ossimGeoidManager.h>
33 #include <ossim/base/ossimKeywordlist.h>
34 #include <ossim/base/ossimNotify.h>
35 #include <ossim/base/ossimObjectFactoryRegistry.h>
36 #include <ossim/base/ossimPreferences.h>
37 #include <ossim/base/ossimStreamFactoryRegistry.h>
38 #include <ossim/base/ossimTrace.h>
39 #include <ossim/base/ossimTraceManager.h>
40 #include <ossim/base/ossimGeoidEgm96.h>
41 #include <ossim/base/ossim2dTo2dTransformRegistry.h>
42 
43 
44 #include <ossim/elevation/ossimElevManager.h>
45 
46 #include <ossim/font/ossimFontFactoryRegistry.h>
47 
48 #include <ossim/support_data/ImageHandlerStateRegistry.h>
49 #include <ossim/support_data/ImageHandlerStateFactory.h>
50 
51 #include <ossim/imaging/ossimCodecFactoryRegistry.h>
52 #include <ossim/imaging/ossimImageSourceFactoryRegistry.h>
53 #include <ossim/imaging/ossimImageGeometryRegistry.h>
54 #include <ossim/imaging/ossimImageHandlerRegistry.h>
55 #include <ossim/imaging/ossimOverviewBuilderFactoryRegistry.h>
56 #include <ossim/imaging/ossimOverviewBuilderFactory.h>
57 #include <ossim/imaging/ossimImageWriterFactoryRegistry.h>
58 #include <ossim/imaging/ossimImageMetaDataWriterRegistry.h>
59 
60 #include <ossim/plugin/ossimSharedPluginRegistry.h>
61 #include <ossim/plugin/ossimDynamicLibrary.h>
62 
63 #include <ossim/projection/ossimProjectionFactoryRegistry.h>
64 #include <ossim/projection/ossimProjectionViewControllerFactory.h>
65 
66 #include <algorithm>
67 #include <mutex>
68 #include <geos_c.h>
69 #include <cstdio>
70 #include <cstdarg>
71 #include <cstddef>
72 using namespace std;
73 
74 static ossimTrace traceExec = ossimTrace("ossimInit:exec");
75 static ossimTrace traceDebug = ossimTrace("ossimInit:debug");
76 
77 extern "C"
78 {
79    void geosNoticeFunction(const char *fmt, ...);
80    void geosErrorFunction(const char *fmt, ...);
81 }
82 
geosErrorV(const char * fmt,va_list args)83 ossimString geosErrorV(const char *fmt, va_list args)
84 {
85    char temp[2024];
86    if (fmt)
87    {
88       vsprintf(temp, fmt, args);
89    }
90    else
91    {
92       sprintf(temp, "%s", "");
93    }
94 
95    return temp;
96 }
97 
geosNoticeFunction(const char * fmt,...)98 void geosNoticeFunction(const char *fmt, ...)
99 {
100    // NOTE: This code has an infinite loop in it!!! (drb)
101    //std::lock_guard<std::mutex> lock(theMutex);
102    // theMutex.lock();
103    va_list args;
104 
105    va_start(args, fmt);
106    ossimString result = geosErrorV(fmt, args);
107    va_end(args);
108    // theMutex.unlock();
109    ossimNotify(ossimNotifyLevel_WARN) << result << "\n";
110 }
111 
geosErrorFunction(const char * fmt,...)112 void geosErrorFunction(const char *fmt, ...)
113 {
114    va_list args;
115 
116    va_start(args, fmt);
117    ossimString result = geosErrorV(fmt, args);
118    va_end(args);
119    // theMutex.unlock();
120    ossimNotify(ossimNotifyLevel_WARN) << result << "\n";
121 }
122 
123 ossimInit* ossimInit::theInstance = 0;
124 
~ossimInit()125 ossimInit::~ossimInit()
126 {
127    theInstance = 0;
128 }
129 
ossimInit()130 ossimInit::ossimInit()
131     :
132        theInitializedFlag(false),
133        theAppName(),
134        thePreferences(0), // Delay instance() call until stream factory init.
135        theElevEnabledFlag(true),
136        thePluginLoaderEnabledFlag(true)
137 {
138 }
139 
instance()140 ossimInit* ossimInit::instance()
141 {
142    static std::mutex m;
143    std::lock_guard<std::mutex> lock(m);
144    if (!theInstance)
145    {
146       theInstance = new ossimInit();
147    }
148    return theInstance;
149 }
150 
addOptions(ossimArgumentParser & parser)151 void ossimInit::addOptions(ossimArgumentParser& parser)
152 {
153    parser.getApplicationUsage()->addCommandLineOption("--env", "Specify an env variable to set.  Any number of these can appear with format --env VARIABLE=VALUE");
154    parser.getApplicationUsage()->addCommandLineOption("-P", "specify a preference file to load");
155    parser.getApplicationUsage()->addCommandLineOption("-K", "specify individual keywords to add to the preferences keyword list: name=value");
156    parser.getApplicationUsage()->addCommandLineOption("-T", "specify the classes to trace, ex: ossimInit|ossimImage.* \nwill trace ossimInit and all ossimImage classes");
157    parser.getApplicationUsage()->addCommandLineOption("--disable-elev", "Will disable the elevation");
158    parser.getApplicationUsage()->addCommandLineOption("--disable-plugin", "Will disable the plugin loader");
159 
160    parser.getApplicationUsage()->addCommandLineOption("--ossim-logfile", "takes a logfile as an argument.  All output messages are redirected to the specified log file.  By default there is no log file and all messages are enabled.");
161    parser.getApplicationUsage()->addCommandLineOption("--disable-notify", "Takes an argument. Arguments are ALL, WARN, NOTICE, INFO, FATAL, DEBUG.  If you want multiple disables then just do multiple --disable-notify on the command line.  All argument are case insensitive.  Default is all are enabled.");
162 }
163 
164 /*!****************************************************************************
165  * METHOD: ossimInit::initialize()
166  *
167  *  Method called from the OSSIM application main.
168  *
169  *****************************************************************************/
initialize(int & argc,char ** argv)170 void ossimInit::initialize(int& argc, char** argv)
171 {
172    static std::mutex m;
173    std::lock_guard<std::mutex> lock(m);
174    initGEOS(geosNoticeFunction, geosErrorFunction);
175 
176    if( !theInitializedFlag )
177    {
178       ossimArgumentParser argumentParser(&argc, argv);
179       theInstance->initialize(argumentParser);
180    }
181 }
182 
initialize(ossimArgumentParser & parser)183 void ossimInit::initialize(ossimArgumentParser& parser)
184 {
185    static std::mutex m;
186    std::lock_guard<std::mutex> lock(m);
187    if(theInitializedFlag)
188    {
189       if (traceDebug())
190       {
191          ossimNotify(ossimNotifyLevel_DEBUG)
192             << "DEBUG ossimInit::initialize(parser):"
193             << " Already initialized, returning......"
194             << std::endl;
195       }
196       return;
197    }
198    initGEOS(geosNoticeFunction, geosErrorFunction);
199 
200    theInstance->parseEnvOptions(parser);
201    theInstance->parseNotifyOption(parser);
202    theInstance->parsePrefsOptions(parser);
203 
204    theInstance->theAppName  = parser.getApplicationUsage()->getApplicationName();
205 
206    //Parse the command line:
207 
208    theInstance->parseOptions(parser);
209    // we will also support defining a trace pattern from an Environment
210    // variable.  This will make JNI code easier to enable tracing
211    //
212    ossimString traceVariable = ossimEnvironmentUtility::instance()->getEnvironmentVariable("OSSIM_TRACE");
213 
214    if(!traceVariable.empty())
215    {
216       ossimTraceManager::instance()->setTracePattern(traceVariable);
217    }
218 
219    theInstance->initializeDefaultFactories();
220 
221    if ( theElevEnabledFlag )
222    {
223       theInstance->initializeElevation();
224    }
225 
226    theInstance->initializeLogFile();
227 
228    if(thePluginLoaderEnabledFlag)
229    {
230       theInstance->initializePlugins();
231    }
232 
233    if (traceDebug())
234    {
235       ossimNotify(ossimNotifyLevel_DEBUG)
236          << "ossim preferences file: "
237          << theInstance->thePreferences->getPreferencesFilename()
238          << "\nVersion: " << version()
239          << "\nossimInit::initialize(parser): leaving..." << std::endl;
240    }
241 
242    theInitializedFlag = true;
243 }
244 
initialize()245 void ossimInit::initialize()
246 {
247    if(theInitializedFlag)
248    {
249       if (traceDebug())
250       {
251          ossimNotify(ossimNotifyLevel_DEBUG)
252             << "DEBUG ossimInit::initialize(parser):"
253             << " Already initialized, returning......"
254             << std::endl;
255       }
256       return;
257    }
258 
259    int argc = 1;
260    char* argv[1];
261 
262    argv[0] = new char[1];
263    argv[0][0] = '\0';
264    initialize(argc, argv);
265    delete [] argv[0];
266 }
267 
finalize()268 void ossimInit::finalize()
269 {
270    finishGEOS();
271 }
272 /*!****************************************************************************
273  *  Prints to stdout the list of command line options that this object parses.
274  *****************************************************************************/
usage()275 void ossimInit::usage()
276 {
277    ossimNotify(ossimNotifyLevel_INFO)
278       << "INFORMATION ossimInit::usage():\n"
279       << "Additional command-line options available are as follows: "
280       << "\n"
281       << "\n  -P<pref_filename> -- Allows the user to override the loading "
282       << "\n    of the default preferences with their own pref file."
283       << "\n"
284       << "\n  -K<keyword>[=<value>] -- Allows the user to specify additional"
285       << "\n    keyword/value pairs that are added onto the preferences "
286       << "\n    previously loaded. Keywords specified here override those in"
287       << "\n    the preferences file."
288       << "\n"
289       << "\n  -T<trace_tag> -- Lets user turn on specific trace flags."
290       << "\n"
291       << "\n  -S<session_filename> -- Allows user to specify a session file"
292       << "\n    to load."
293       << std::endl;
294    return;
295 }
296 
getElevEnabledFlag() const297 bool ossimInit::getElevEnabledFlag() const
298 {
299    return theElevEnabledFlag;
300 }
301 
setElevEnabledFlag(bool flag)302 void ossimInit::setElevEnabledFlag(bool flag)
303 {
304    theElevEnabledFlag = flag;
305 }
306 
setPluginLoaderEnabledFlag(bool flag)307 void ossimInit::setPluginLoaderEnabledFlag(bool flag)
308 {
309    thePluginLoaderEnabledFlag = flag;
310 }
311 
loadPlugins(const ossimFilename & plugin,const char * options)312 void ossimInit::loadPlugins(const ossimFilename& plugin, const char* options)
313 {
314    if(!thePluginLoaderEnabledFlag) return;
315 
316    if(plugin.exists())
317    {
318       if(plugin.isDir())
319       {
320          ossimDirectory dir;
321          if(dir.open(plugin))
322          {
323             ossimFilename file;
324 
325             if(dir.getFirst(file, ossimDirectory::OSSIM_DIR_FILES))
326             {
327                do
328                {
329                   ossimSharedPluginRegistry::instance()->registerPlugin(file, options);
330                }
331                while(dir.getNext(file));
332             }
333          }
334       }
335       else
336       {
337          ossimSharedPluginRegistry::instance()->registerPlugin(plugin, options);
338       }
339    }
340 }
341 
parsePrefsOptions(ossimArgumentParser & parser)342 void ossimInit::parsePrefsOptions(ossimArgumentParser& parser)
343 {
344    if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG)
345       << "DEBUG ossimInit::parseOptions: entering..." << std::endl;
346 
347 
348    std::string tempString;
349    ossimArgumentParser::ossimParameter stringParameter(tempString);
350 
351    tempString = "";
352    ossimString prefsFile = ossimEnvironmentUtility::instance()->getEnvironmentVariable("OSSIM_PREFS_FILE");
353    theInstance->thePreferences = ossimPreferences::instance();
354    if(!prefsFile.empty())
355    {
356       thePreferences->loadPreferences();// Use the default load
357    }
358    tempString = "";
359    // override ENV with passed in variable
360    while(parser.read("-P", stringParameter));
361 
362    if(tempString != "")
363    {
364       thePreferences->loadPreferences(ossimFilename(tempString));
365    }
366    tempString = "";
367    while(parser.read("-K", stringParameter))
368    {
369       ossimString option = tempString;
370       if (option.contains("=") )
371       {
372          ossimString delimiter = "=";
373          ossimString key (option.before(delimiter));
374          ossimString value = option.after(delimiter);
375          thePreferences->addPreference(key.c_str(), value.c_str());
376       }
377       else
378       {
379          ossimString key (option);
380          thePreferences->addPreference(key, "");
381       }
382    }
383 
384 }
385 
parseOptions(ossimArgumentParser & parser)386 void ossimInit::parseOptions(ossimArgumentParser& parser)
387 {
388    if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG)
389       << "DEBUG ossimInit::parseOptions: entering..." << std::endl;
390 
391    std::string tempString;
392    ossimArgumentParser::ossimParameter stringParameter(tempString);
393 
394    tempString = "";
395 
396    while(parser.read("-T", stringParameter))
397    {
398       ossimTraceManager::instance()->setTracePattern(ossimString(tempString));
399    }
400 
401    while(parser.read("--ossim-logfile", stringParameter))
402    {
403       ossimSetLogFilename(ossimFilename(tempString));
404    }
405    while(parser.read("--disable-notify", stringParameter))
406    {
407       ossimString tempDownCase = tempString;
408       tempDownCase = tempDownCase.downcase();
409 
410       if(tempDownCase == "warn")
411       {
412          ossimDisableNotify(ossimNotifyFlags_WARN);
413       }
414       else if(tempDownCase == "fatal")
415       {
416          ossimDisableNotify(ossimNotifyFlags_FATAL);
417       }
418       else if(tempDownCase == "debug")
419       {
420          ossimDisableNotify(ossimNotifyFlags_DEBUG);
421       }
422       else if(tempDownCase == "info")
423       {
424          ossimDisableNotify(ossimNotifyFlags_INFO);
425       }
426       else if(tempDownCase == "notice")
427       {
428          ossimDisableNotify(ossimNotifyFlags_NOTICE);
429       }
430       else if(tempDownCase == "all")
431       {
432          ossimDisableNotify(ossimNotifyFlags_ALL);
433       }
434    }
435    if(parser.read("--disable-elev"))
436    {
437       theElevEnabledFlag = false;
438    }
439    if(parser.read("--disable-plugin"))
440    {
441       thePluginLoaderEnabledFlag = false;
442    }
443 }
444 
parseNotifyOption(ossimArgumentParser & parser)445 void ossimInit::parseNotifyOption(ossimArgumentParser& parser)
446 {
447    std::string tempString;
448    ossimArgumentParser::ossimParameter stringParameter(tempString);
449    while(parser.read("--disable-notify", stringParameter))
450    {
451       ossimString tempDownCase = tempString;
452       tempDownCase = tempDownCase.downcase();
453 
454       if(tempDownCase == "warn")
455       {
456          ossimDisableNotify(ossimNotifyFlags_WARN);
457       }
458       else if(tempDownCase == "fatal")
459       {
460          ossimDisableNotify(ossimNotifyFlags_FATAL);
461       }
462       else if(tempDownCase == "debug")
463       {
464          ossimDisableNotify(ossimNotifyFlags_DEBUG);
465       }
466       else if(tempDownCase == "info")
467       {
468          ossimDisableNotify(ossimNotifyFlags_INFO);
469       }
470       else if(tempDownCase == "notice")
471       {
472          ossimDisableNotify(ossimNotifyFlags_NOTICE);
473       }
474       else if(tempDownCase == "all")
475       {
476          ossimDisableNotify(ossimNotifyFlags_ALL);
477       }
478    }
479 }
480 
parseEnvOptions(ossimArgumentParser & parser)481 void ossimInit::parseEnvOptions(ossimArgumentParser& parser)
482 {
483    std::string tempString;
484    ossimArgumentParser::ossimParameter stringParameter(tempString);
485    while(parser.read("--env", stringParameter))
486    {
487       ossimString option = tempString;
488       if (option.contains("=") )
489       {
490          ossimString delimiter = "=";
491          ossimString key (option.before(delimiter));
492          ossimString value = option.after(delimiter);
493          ossimEnvironmentUtility::instance()->setEnvironmentVariable(key.c_str(), value.c_str());
494 
495       }
496       else
497       {
498          ossimString key (option);
499          ossimEnvironmentUtility::instance()->setEnvironmentVariable(key.c_str(), "");
500       }
501    }
502 }
503 /*!****************************************************************************
504  * METHOD: ossimInit::removeOption()
505  *
506  * Removes all characters associated with the indicated option from the
507  * command line string.
508  *
509  *****************************************************************************/
removeOption(int & argc,char ** argv,int argToRemove)510 void ossimInit::removeOption(int& argc,
511                              char** argv,
512                              int argToRemove)
513 {
514    if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG)
515       << "DEBUG ossimInit::removeOption(argc, argv, argToRemove): entering..."
516       << std::endl;
517 
518    // Shift the args up by one position, overwriting the arg being removed:
519    for (int i=argToRemove+1; i<argc;  i++)
520    {
521       argv[i - 1] = argv[i];
522    }
523 
524    argc--;
525    argv[argc] = 0;
526 
527    if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG)
528       << "DEBUG ossimInit::removeOption(argc, argv, argToRemove): leaving..."
529       << std::endl;
530    return;
531 }
532 
initializeDefaultFactories()533 void ossimInit::initializeDefaultFactories()
534 {
535    ossim::StreamFactoryRegistry::instance();
536    ossim::ImageHandlerStateRegistry::instance()->registerFactory(ossim::ImageHandlerStateFactory::instance());
537    ossimObjectFactoryRegistry::instance()->registerFactory(ossimImageSourceFactoryRegistry::instance());
538 
539    //---
540    // Because of how the imagehandlers work off a magic number make sure
541    // we place the writer first if we don't then the imagehandler will
542    // be false and will then try to open the filename and go through a
543    // magic number and if the file already
544    // existed it will open and create a handler instead of a writer.
545    //---
546    ossimCodecFactoryRegistry::instance();
547    ossimImageWriterFactoryRegistry::instance();
548    ossimDatumFactoryRegistry::instance();
549    ossimImageMetaDataWriterRegistry::instance();
550    ossimImageHandlerRegistry::instance();
551    ossim2dTo2dTransformRegistry::instance();
552    ossimImageGeometryRegistry::instance();
553    // Initialize the overview factories.
554    ossimOverviewBuilderFactoryRegistry::instance()->
555       registerFactory(ossimOverviewBuilderFactory::instance(), true);
556 
557    ossimObjectFactoryRegistry::instance()->addFactory(ossimBaseObjectFactory::instance());
558 
559    // initialize. projection factory.
560    ossimProjectionFactoryRegistry::instance();
561 
562    // add the view controllers
563    ossimObjectFactoryRegistry::instance()->registerFactory(ossimProjectionViewControllerFactory::instance());
564 
565    ossimFontFactoryRegistry::instance();
566 }
567 
initializePlugins()568 void ossimInit::initializePlugins()
569 {
570 
571 #if 0
572    // Note: Removed "autoload" code. Commented out below.
573 
574    const ossimKeywordlist& KWL = thePreferences->preferencesKWL();
575 
576    //---
577    // Look for plugins in the form of:
578    // plugin0.file: $(OSSIM_INSTALL_PREFIX)/lib64/ossim/plugins/libossim_png_plugin.so
579    // plugin0.option: front
580    //---
581    ossimString regExp =  ossimString("^(") + "plugin[0-9]+.file)";
582    ossim_uint32 numberOfPlugins = KWL.getNumberOfSubstringKeys( regExp );
583    if ( numberOfPlugins )
584    {
585       const ossim_uint32 MAX_INDEX = numberOfPlugins + 1000; // for skipage...
586       ossim_uint32 index            = 0;
587       ossim_uint32 processedIndexes = 0;
588       const std::string PREFIX_BASE = "plugin";
589       const std::string DOT         = ".";
590       const std::string FILE_KEY    = "file";
591       const std::string OPTIONS_KEY = "options";
592 
593       ossimString prefix;
594       ossimFilename pluginFile;
595       ossimString pluginOptions;
596 
597       // Loop to load plugins in order. Note allows for skipage.
598       while ( processedIndexes < MAX_INDEX )
599       {
600          prefix = PREFIX_BASE + ossimString::toString(index).string() + DOT;
601          pluginFile = KWL.findKey( prefix, FILE_KEY );
602          if ( pluginFile.size() )
603          {
604             if ( pluginFile.exists() )
605             {
606                // Found plugin, look for options:
607                pluginOptions = KWL.findKey( prefix, OPTIONS_KEY );
608 
609                ossimSharedPluginRegistry::instance()->registerPlugin(pluginFile, pluginOptions);
610             }
611             ++processedIndexes;
612          }
613          if ( processedIndexes == numberOfPlugins )
614          {
615             break;
616          }
617          ++index;
618       }
619    }
620 
621    //---
622    // Look for plugins in the form of:
623    // plugin.file0: $(OSSIM_INSTALL_PREFIX)/lib64/ossim/plugins/libossim_png_plugin.so
624    //---
625    regExp =  ossimString("^(") + "plugin.file[0-9]+)";
626    numberOfPlugins = KWL.getNumberOfSubstringKeys( regExp );
627    if ( numberOfPlugins )
628    {
629       const ossim_uint32 MAX_INDEX = numberOfPlugins + 1000; // for skipage...
630       ossim_uint32 index            = 0;
631       ossim_uint32 processedIndexes = 0;
632       const std::string PREFIX_BASE = "plugin.file";
633       std::string fileKey;
634 
635       ossimString prefix;
636       ossimFilename pluginFile;
637       ossimString pluginOptions = ""; // No options:
638 
639       // Loop to load plugins in order. Note allows for skipage.
640       while ( processedIndexes < MAX_INDEX )
641       {
642          fileKey = PREFIX_BASE + ossimString::toString(index).string();
643          pluginFile = KWL.findKey( fileKey );
644          if ( pluginFile.size() )
645          {
646             if ( pluginFile.exists() )
647             {
648                ossimSharedPluginRegistry::instance()->registerPlugin(pluginFile, pluginOptions);
649             }
650             ++processedIndexes;
651          }
652 
653          if ( processedIndexes == numberOfPlugins )
654          {
655             break;
656          }
657          ++index;
658       }
659    }
660 
661 #else  /* Old code that auto loads plugins. */
662    #if 0
663    ossimString regExpressionDir =  ossimString("^(") + "plugin.dir[0-9]+)";
664    ossimString regExpressionFile =  ossimString("^(") + "plugin.file[0-9]+)";
665 
666    const ossimKeywordlist& kwl = thePreferences->preferencesKWL();
667 
668    vector<ossimString> keys = kwl.getSubstringKeyList( regExpressionDir );
669 
670    ossim_uint32 numberOfDirs = (ossim_uint32)keys.size();
671    ossim_uint32 offset = (ossim_uint32)ossimString("plugin.dir").size();
672    int idx = 0;
673 
674    std::vector<int> numberList(numberOfDirs);
675 
676    // register user plugins first
677    ossimFilename userPluginDir = ossimEnvironmentUtility::instance()->getUserOssimPluginDir();
678    loadPlugins(userPluginDir);
679 
680    if(numberList.size()>0)
681    {
682       for(idx = 0; idx < (int)numberList.size();++idx)
683       {
684          ossimString numberStr(keys[idx].begin() + offset,
685                                keys[idx].end());
686          numberList[idx] = numberStr.toInt();
687       }
688 
689       std::sort(numberList.begin(), numberList.end());
690       for(idx=0;idx < (int)numberList.size();++idx)
691       {
692          ossimString newPrefix = "plugin.dir";
693          newPrefix += ossimString::toString(numberList[idx]);
694          const char* directory = kwl.find(newPrefix.c_str());
695 
696          if(directory)
697          {
698             loadPlugins(ossimFilename(directory));
699          }
700       }
701    }
702    keys = kwl.getSubstringKeyList( regExpressionFile );
703 
704    ossim_uint32 numberOfFiles = (ossim_uint32)keys.size();
705    offset = (ossim_uint32)ossimString("plugin.file").size();
706    numberList.resize(numberOfFiles);
707    if(numberList.size()>0)
708    {
709       for(idx = 0; idx < (int)numberList.size();++idx)
710       {
711          ossimString numberStr(keys[idx].begin() + offset,
712                                keys[idx].end());
713          numberList[idx] = numberStr.toInt();
714       }
715 
716       std::sort(numberList.begin(), numberList.end());
717       for(idx=0;idx < (int)numberList.size();++idx)
718       {
719          ossimString newPrefix="plugin.file";
720          newPrefix += ossimString::toString(numberList[idx]);
721          const char* file = kwl.find(newPrefix.c_str());
722 
723          if(file&&ossimFilename(file).exists())
724          {
725             loadPlugins(file);
726 //             ossimSharedPluginRegistry::instance()->registerPlugin(file);
727          }
728       }
729    }
730    #endif
731    // now check new plugin loading that supports passing options to the plugins
732    //
733    const ossimKeywordlist& kwl = thePreferences->preferencesKWL();
734    ossimString regExpressionFile =  ossimString("^(") + "plugin[0-9]+\\.file)";
735    vector<ossimString> keys = kwl.getSubstringKeyList( regExpressionFile );
736 
737    ossim_uint32 numberOfFiles = (ossim_uint32)keys.size();
738    ossim_uint32 offset = (ossim_uint32)ossimString("plugin").size();
739    std::vector<int> numberList(numberOfFiles);
740 
741    if(numberList.size()>0)
742    {
743       ossim_uint32 idx = 0;
744       for(idx = 0; idx < numberList.size();++idx)
745       {
746          ossimString numberStr(keys[idx].begin() + offset,
747                                keys[idx].end());
748          numberList[idx] = numberStr.toInt();
749       }
750       std::sort(numberList.begin(), numberList.end());
751       ossimFilename pluginFile;
752       ossimString options;
753       for(std::vector<ossim_int32>::const_iterator iter = numberList.begin();
754          iter != numberList.end();++iter)
755       {
756          ossimString newPrefix = ossimString("plugin")+ossimString::toString(*iter) + ".";
757 
758          pluginFile = kwl.find((newPrefix+"file").c_str());
759          options    = kwl.find((newPrefix+"options").c_str());
760          if(pluginFile.exists())
761          {
762             ossimSharedPluginRegistry::instance()->registerPlugin(pluginFile, options);
763          }
764       }
765    }
766 
767    regExpressionFile =  ossimString("^(") + "plugin.file[0-9]+)";
768    keys = kwl.getSubstringKeyList( regExpressionFile );
769 
770    numberOfFiles = (ossim_uint32)keys.size();
771    offset = (ossim_uint32)ossimString("plugin.file").size();
772    numberList.resize(numberOfFiles);
773 
774    if(numberList.size()>0)
775    {
776       ossim_uint32 idx = 0;
777       for(idx = 0; idx < numberList.size();++idx)
778       {
779          ossimString numberStr(keys[idx].begin() + offset,
780                                keys[idx].end());
781          numberList[idx] = numberStr.toInt();
782       }
783       std::sort(numberList.begin(), numberList.end());
784       ossimFilename pluginFile;
785       ossimString options;
786       for(std::vector<ossim_int32>::const_iterator iter = numberList.begin();
787          iter != numberList.end();++iter)
788       {
789          ossimString newPrefix = ossimString("plugin.file")+ossimString::toString(*iter);
790 
791          pluginFile = kwl.find(newPrefix.c_str());
792          if(pluginFile.exists())
793          {
794             ossimSharedPluginRegistry::instance()->registerPlugin(pluginFile, options);
795          }
796       }
797    }
798 
799 
800 
801    ossimString auto_load_plugins(ossimPreferences::instance()->findPreference("ossim_init.auto_load_plugins"));
802 
803    if(auto_load_plugins.empty()) auto_load_plugins = "false";
804    // now load any plugins not found in the keywordlist
805    //
806    // check for plugins in the current directory
807    // and load them
808    if(auto_load_plugins.toBool())
809    {
810       ossimFilename ossimpluginsDir = ossimFilename(theAppName).dirCat("ossimplugins");
811       ossimDirectory currentDir(theAppName.path());
812 
813       if(ossimpluginsDir.exists())
814       {
815          currentDir = ossimpluginsDir;
816       }
817       std::vector<ossimFilename> result;
818       currentDir.findAllFilesThatMatch(result, "ossim.*plugin.*", ossimDirectory::OSSIM_DIR_FILES);
819 
820       if(result.size())
821       {
822          ossim_uint32 idx = 0;
823          for(idx = 0; idx < result.size(); ++idx)
824          {
825             ossimSharedPluginRegistry::instance()->registerPlugin(result[idx]);
826          }
827       }
828    }
829 #endif
830 }
831 
initializeElevation()832 void ossimInit::initializeElevation()
833 {
834    if (traceDebug()) ossimNotify(ossimNotifyLevel_DEBUG)
835       << "DEBUG ossimInit::initializeElevation(): Entered..." << std::endl;
836 
837    const ossimKeywordlist& KWL = thePreferences->preferencesKWL();
838 
839 #if 0  /* All autoload stuff disabled. drb 20170408 */
840    ossimFilename appPath = theAppName.path();
841 
842    // look for bundled elevation and geoids
843    {
844       ossimFilename geoid = appPath.dirCat("geoids");
845       geoid = geoid.dirCat("geoid1996");
846       geoid = geoid.dirCat("egm96.grd");
847       if(geoid.exists())
848       {
849          ossimGeoid* geoidPtr = new ossimGeoidEgm96(geoid);
850 
851          if (geoidPtr->getErrorStatus() == ossimErrorCodes::OSSIM_OK)
852          {
853             ossimGeoidManager::instance()->addGeoid(geoidPtr);
854          }
855 
856       }
857    }
858 #endif
859 
860    ossimGeoidManager::instance()->loadState(KWL);
861 
862    //---
863    // Auto load removed to avoid un-wanted directory scanning.
864    // Use ossim preferences.  drb - 28 March 2016.
865    //---
866 #if 0
867    ossimFilename elevation = appPath.dirCat("elevation");
868    if(elevation.exists())
869    {
870       ossimElevManager::instance()->loadElevationPath(elevation);
871    }
872 #endif
873 
874    // lets do backward compatability here
875    //
876    ossimString regExpression =  ossimString("^(") + "elevation_source[0-9]+.)";
877    vector<ossimString> keys =
878    KWL.getSubstringKeyList( regExpression );
879    if(!keys.empty())
880    {
881       ossimNotify(ossimNotifyLevel_WARN) << "Please specify elevation_source keywords with the new prefix\n"
882                                          << "of elevation_manager.elevation_source....\n";
883       thePreferences->preferencesKWL().addPrefixToKeysThatMatch("elevation_manager.", regExpression);
884    }
885    ossimElevManager::instance()->loadState(KWL, "elevation_manager.");
886 
887    if (traceDebug()) ossimNotify(ossimNotifyLevel_DEBUG)
888       << "DEBUG ossimInit::initializeElevation(): leaving..." << std::endl;
889 }
890 
initializeLogFile()891 void ossimInit::initializeLogFile()
892 {
893    //---
894    // Do not set if already as --ossim-logfile take precidence over preferences
895    // file.
896    //---
897    ossimFilename logFile;
898    ossimGetLogFilename(logFile);
899 
900    if ( (logFile.size() == 0) && thePreferences )
901    {
902       const char* lookup =
903          thePreferences->preferencesKWL().find("ossim.log.file");
904       if (lookup)
905       {
906          logFile = lookup;
907          ossimSetLogFilename(logFile);
908       }
909    }
910 }
911 
version() const912 ossimString ossimInit::version() const
913 {
914    ossimString versionString;
915 #ifdef OSSIM_VERSION
916    versionString += OSSIM_VERSION;
917 #else
918    versionString += "Version ?.?.?";
919 #endif
920 
921    versionString += " ";
922 
923 #ifdef OSSIM_BUILD_DATE
924    versionString += OSSIM_BUILD_DATE;
925 #else
926    versionString += "(yyyymmdd)";
927 #endif
928 
929    return versionString;
930 }
931 
appName() const932 ossimFilename ossimInit::appName()const
933 {
934    return theAppName;
935 }
936 
ossimInit(const ossimInit &)937 ossimInit::ossimInit(const ossimInit& /* obj */ )
938 :  theInitializedFlag(false),
939    theAppName(),
940    thePreferences(ossimPreferences::instance()),
941    theElevEnabledFlag(true),
942    thePluginLoaderEnabledFlag(true)
943 {}
944 
operator =(const ossimInit &) const945 void ossimInit::operator=(const ossimInit& /* rhs */) const
946 {}
947