Orfeo Toolbox  3.16
itkObjectFactoryBase.cxx
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Insight Segmentation & Registration Toolkit
4  Module: $RCSfile: itkObjectFactoryBase.cxx,v $
5  Language: C++
6  Date: $Date: 2009-12-23 14:55:37 $
7  Version: $Revision: 1.60 $
8 
9  Copyright (c) Insight Software Consortium. All rights reserved.
10  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
11 
12  Portions of this code are covered under the VTK copyright.
13  See VTKCopyright.txt or http://www.kitware.com/VTKCopyright.htm for details.
14 
15  This software is distributed WITHOUT ANY WARRANTY; without even
16  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
17  PURPOSE. See the above copyright notices for more information.
18 
19 =========================================================================*/
20 #if defined(_MSC_VER)
21 #pragma warning ( disable : 4786 )
22 #endif
23 
24 #include "itkObjectFactoryBase.h"
25 #include "itkDynamicLoader.h"
26 #include "itkDirectory.h"
27 #include "itkVersion.h"
28 #include <stdlib.h>
29 #include <ctype.h>
30 #include <string.h>
31 #include <algorithm>
32 #include <map>
33 
34 namespace
35 {
36 
37 class CleanUpObjectFactory
38 {
39 public:
40  inline void Use()
41  {
42  }
43  ~CleanUpObjectFactory()
44  {
46  }
47 };
48 static CleanUpObjectFactory CleanUpObjectFactoryGlobal;
49 }
50 
51 namespace itk
52 {
53 
60 {
61  return (rhs.m_Description == lhs.m_Description
63 }
64 
71 {
72  return (rhs.m_Description < lhs.m_Description
74 }
75 
76 
85 typedef std::multimap<std::string, ObjectFactoryBase::OverrideInformation>
87 
92 {
93 public:
94 };
95 
99 std::list<ObjectFactoryBase*>*
101 
102 
109 ::CreateInstance(const char* itkclassname)
110 {
112  {
114  }
115 
116  for ( std::list<ObjectFactoryBase*>::iterator
117  i = m_RegisteredFactories->begin();
118  i != m_RegisteredFactories->end(); ++i )
119  {
120  LightObject::Pointer newobject = (*i)->CreateObject(itkclassname);
121  if(newobject)
122  {
123  newobject->Register();
124  return newobject;
125  }
126  }
127  return 0;
128 }
129 
130 
131 std::list<LightObject::Pointer>
133 ::CreateAllInstance(const char* itkclassname)
134 {
136  {
138  }
139  std::list<LightObject::Pointer> created;
140  for ( std::list<ObjectFactoryBase*>::iterator
141  i = m_RegisteredFactories->begin();
142  i != m_RegisteredFactories->end(); ++i )
143  {
144  std::list<LightObject::Pointer> moreObjects = (*i)->CreateAllObject( itkclassname );
145  created.splice( created.end(), moreObjects );
146  }
147  return created;
148 }
149 
150 
154 void
157 {
158  CleanUpObjectFactoryGlobal.Use();
163  {
164  return;
165  }
166 
168  new std::list<ObjectFactoryBase*>;
171 }
172 
173 
178 void
181 {
182 }
183 
187 void
190 {
194 #ifdef _WIN32
195  char PathSeparator = ';';
196 #else
197  char PathSeparator = ':';
198 #endif
199 
200  std::string LoadPath;
201  if (getenv("ITK_AUTOLOAD_PATH"))
202  {
203  LoadPath = getenv("ITK_AUTOLOAD_PATH");
204  }
205  else
206  {
207  return;
208  }
209 
210  if(LoadPath.size() == 0)
211  {
212  return;
213  }
214  std::string::size_type EndSeparatorPosition = 0;
215  std::string::size_type StartSeparatorPosition = 0;
216 
217  while ( StartSeparatorPosition != std::string::npos )
218  {
219  StartSeparatorPosition = EndSeparatorPosition;
220 
224  EndSeparatorPosition = LoadPath.find(PathSeparator,
225  StartSeparatorPosition);
226  if(EndSeparatorPosition == std::string::npos)
227  {
228  EndSeparatorPosition = LoadPath.size() + 1; // Add 1 to simulate
229  // having a separator
230  }
231  std::string CurrentPath =
232  LoadPath.substr(StartSeparatorPosition,
233  EndSeparatorPosition - StartSeparatorPosition);
234 
235  ObjectFactoryBase::LoadLibrariesInPath(CurrentPath.c_str());
236 
240  if(EndSeparatorPosition > LoadPath.size())
241  {
242  StartSeparatorPosition = std::string::npos;
243  }
244  else
245  {
246  EndSeparatorPosition++; // Skip the separator
247  }
248  }
249 }
250 
251 
256 static std::string
257 CreateFullPath(const char* path, const char* file)
258 {
259  std::string ret;
260 #ifdef _WIN32
261  const char sep = '\\';
262 #else
263  const char sep = '/';
264 #endif
265 
268  ret = path;
269  if ( !ret.empty() && ret[ret.size()-1] != sep )
270  {
271  ret += sep;
272  }
273  ret += file;
274  return ret;
275 }
276 
277 
282 typedef ObjectFactoryBase* (* ITK_LOAD_FUNCTION)();
283 
284 
291 inline bool
292 NameIsSharedLibrary(const char* name)
293 {
294  std::string extension = itksys::DynamicLoader::LibExtension();
295 
296 #ifdef __APPLE__
297  // possible bug: CMake generated build file on the Mac makes
298  // libraries with a .dylib extension. kwsys guesses the extension
299  // should be ".so"
300  extension = ".dylib";
301 #endif
302 
303  std::string sname = name;
304  size_t extensionpos = sname.rfind(extension);
305  if ( extensionpos != std::string::npos && extensionpos == sname.size() - extension.size() )
306  {
307  return true;
308  }
309  return false;
310 }
311 
315 void
317 ::LoadLibrariesInPath(const char* path)
318 {
320  if ( !dir->Load(path) )
321  {
322  return;
323  }
324 
328  for ( unsigned int i = 0; i < dir->GetNumberOfFiles(); i++ )
329  {
330  const char* file = dir->GetFile(i);
335  if ( NameIsSharedLibrary(file) )
336  {
337  std::string fullpath = CreateFullPath(path, file);
338  LibHandle lib = DynamicLoader::OpenLibrary(fullpath.c_str());
339  if ( lib )
340  {
344  ITK_LOAD_FUNCTION loadfunction
350  if ( loadfunction )
351  {
352  ObjectFactoryBase* newfactory = (*loadfunction)();
353 
357  newfactory->m_LibraryHandle = (void*)lib;
358  newfactory->m_LibraryPath = fullpath;
359  newfactory->m_LibraryDate = 0; // unused for now...
361  }
362  else
363  {
364  // We would really like to close the lib if it does not
365  // contain the itkLoad symbol. Unfortuantely, it seems that
366  // some systems crash on the call
367  // DynamicLoader::CloseLibrary(lib) if the lib has symbols
368  // that the current executable is using.
369  }
370  }
371  }
372  }
373 }
374 
375 
379 void
382 {
385 }
386 
387 
392 {
393  m_LibraryHandle = 0;
394  m_LibraryDate = 0;
396 }
397 
398 
404 {
405  m_OverrideMap->erase(m_OverrideMap->begin(), m_OverrideMap->end());
406  delete m_OverrideMap;
407 }
408 
409 
413 void
416 {
417  if ( factory->m_LibraryHandle == 0 )
418  {
419  const char nonDynamicName[] = "Non-Dynamicaly loaded factory";
420  factory->m_LibraryPath = nonDynamicName;
421  }
422  if ( strcmp(factory->GetITKSourceVersion(),
424  {
425  itkGenericOutputMacro(<< "Possible incompatible factory load:"
426  << "\nRunning itk version :\n" << Version::GetITKSourceVersion()
427  << "\nLoaded factory version:\n" << factory->GetITKSourceVersion()
428  << "\nLoading factory:\n" << factory->m_LibraryPath << "\n");
429  }
430 
432  ObjectFactoryBase::m_RegisteredFactories->push_back(factory);
433  factory->Register();
434 }
435 
436 
440 void
442 ::PrintSelf(std::ostream& os, Indent indent) const
443 {
444  Superclass::PrintSelf(os, indent);
445 
446  os << indent << "Factory DLL path: " << m_LibraryPath.c_str() << "\n";
447  os << indent << "Factory description: " << this->GetDescription() << std::endl;
448 
449  int num = static_cast<int>( m_OverrideMap->size() );
450  os << indent << "Factory overides " << num << " classes:" << std::endl;
451 
452  indent = indent.GetNextIndent();
453  for(OverRideMap::iterator i = m_OverrideMap->begin();
454  i != m_OverrideMap->end(); ++i)
455  {
456  os << indent << "Class : " << (*i).first.c_str() << "\n";
457  os << indent << "Overriden with: " << (*i).second.m_OverrideWithName.c_str()
458  << std::endl;
459  os << indent << "Enable flag: " << (*i).second.m_EnabledFlag
460  << std::endl;
461  os << indent << "Create object: " << (*i).second.m_CreateObject
462  << std::endl;
463  os << std::endl;
464  }
465 }
466 
467 
471 void
474 {
475  for ( std::list<ObjectFactoryBase*>::iterator i =
476  m_RegisteredFactories->begin();
477  i != m_RegisteredFactories->end(); ++i )
478  {
479  if ( factory == *i )
480  {
481  factory->UnRegister();
482  m_RegisteredFactories->remove(factory);
483  return;
484  }
485  }
486 }
487 
488 
492 void
495 {
496 
498  {
499  // Collect up all the library handles so they can be closed
500  // AFTER the factory has been deleted.
501  std::list<void *> libs;
502  for ( std::list<ObjectFactoryBase*>::iterator i
503  = m_RegisteredFactories->begin();
504  i != m_RegisteredFactories->end(); ++i )
505  {
506  libs.push_back(static_cast<void *>((*i)->m_LibraryHandle));
507  }
508  // Unregister each factory
509  for ( std::list<ObjectFactoryBase*>::iterator f
510  = m_RegisteredFactories->begin();
511  f != m_RegisteredFactories->end(); ++f )
512  {
513  (*f)->UnRegister();
514  }
515  // And delete the library handles all at once
516 #ifndef __CYGWIN__
517  for ( std::list<void *>::iterator lib = libs.begin();
518  lib != libs.end();
519  ++lib)
520  {
521  if((*lib))
522  {
523  DynamicLoader::CloseLibrary(static_cast<LibHandle>(*lib));
524  }
525  }
526 #endif
529  }
530 }
531 
532 
536 void
538 ::RegisterOverride(const char* classOverride,
539  const char* subclass,
540  const char* description,
541  bool enableFlag,
543  createFunction)
544 {
546  info.m_Description = description;
547  info.m_OverrideWithName = subclass;
548  info.m_EnabledFlag = enableFlag;
549  info.m_CreateObject = createFunction;
550 
551  m_OverrideMap->insert(OverRideMap::value_type(classOverride, info));
552 }
553 
554 
557 ::CreateObject(const char* itkclassname)
558 {
559  OverRideMap::iterator start = m_OverrideMap->lower_bound(itkclassname);
560  OverRideMap::iterator end = m_OverrideMap->upper_bound(itkclassname);
561 
562  for ( OverRideMap::iterator i = start; i != end; ++i )
563  {
564  if ( i != m_OverrideMap->end() && (*i).second.m_EnabledFlag)
565  {
566  return (*i).second.m_CreateObject->CreateObject();
567  }
568  }
569  return 0;
570 }
571 
572 
573 std::list<LightObject::Pointer>
575 ::CreateAllObject(const char* itkclassname)
576 {
577  OverRideMap::iterator start = m_OverrideMap->lower_bound(itkclassname);
578  OverRideMap::iterator end = m_OverrideMap->upper_bound(itkclassname);
579 
580  std::list<LightObject::Pointer> created;
581 
582  for ( OverRideMap::iterator i = start; i != end; ++i )
583  {
584  if ( i != m_OverrideMap->end() && (*i).second.m_EnabledFlag)
585  {
586  created.push_back( (*i).second.m_CreateObject->CreateObject() );
587  }
588  }
589  return created;
590 }
591 
595 void
597 ::SetEnableFlag(bool flag,
598  const char* className,
599  const char* subclassName)
600 {
601  OverRideMap::iterator start = m_OverrideMap->lower_bound(className);
602  OverRideMap::iterator end = m_OverrideMap->upper_bound(className);
603  for ( OverRideMap::iterator i = start; i != end; ++i )
604  {
605  if ( (*i).second.m_OverrideWithName == subclassName )
606  {
607  (*i).second.m_EnabledFlag = flag;
608  }
609  }
610 }
611 
612 
616 bool
618 ::GetEnableFlag(const char* className, const char* subclassName)
619 {
620  OverRideMap::iterator start = m_OverrideMap->lower_bound(className);
621  OverRideMap::iterator end = m_OverrideMap->upper_bound(className);
622  for ( OverRideMap::iterator i = start; i != end; ++i )
623  {
624  if ( (*i).second.m_OverrideWithName == subclassName )
625  {
626  return (*i).second.m_EnabledFlag;
627  }
628  }
629  return 0;
630 }
631 
632 
636 void
638 ::Disable(const char* className)
639 {
640  OverRideMap::iterator start = m_OverrideMap->lower_bound(className);
641  OverRideMap::iterator end = m_OverrideMap->upper_bound(className);
642  for ( OverRideMap::iterator i = start; i != end; ++i )
643  {
644  (*i).second.m_EnabledFlag = 0;
645  }
646 }
647 
648 
652 std::list<ObjectFactoryBase*>
655 {
657 }
658 
659 
663 std::list<std::string>
666 {
667  std::list<std::string> ret;
668  for ( OverRideMap::iterator i = m_OverrideMap->begin();
669  i != m_OverrideMap->end(); ++i )
670  {
671  ret.push_back((*i).first);
672  }
673  return ret;
674 }
675 
676 
680 std::list<std::string>
683 {
684  std::list<std::string> ret;
685  for ( OverRideMap::iterator i = m_OverrideMap->begin();
686  i != m_OverrideMap->end(); ++i )
687  {
688  ret.push_back((*i).second.m_OverrideWithName);
689  }
690  return ret;
691 }
692 
693 
697 std::list<std::string>
700 {
701  std::list<std::string> ret;
702  for ( OverRideMap::iterator i = m_OverrideMap->begin();
703  i != m_OverrideMap->end(); ++i )
704  {
705  ret.push_back((*i).second.m_Description);
706  }
707  return ret;
708 }
709 
710 
714 std::list<bool>
717 {
718  std::list<bool> ret;
719  for( OverRideMap::iterator i = m_OverrideMap->begin();
720  i != m_OverrideMap->end(); ++i)
721  {
722  ret.push_back((*i).second.m_EnabledFlag);
723  }
724  return ret;
725 }
726 
729 const char *
732 {
733  return m_LibraryPath.c_str();
734 }
735 
736 } // end namespace itk

Generated at Sat Feb 2 2013 23:56:47 for Orfeo Toolbox with doxygen 1.8.1.1