Medical Imaging Interaction Toolkit  2018.4.99-b585543d
Medical Imaging Interaction Toolkit
mitkCoreActivator.cpp
Go to the documentation of this file.
1 /*============================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
13 #include "mitkCoreActivator.h"
14 
15 #include <mitkCoreServices.h>
17 
18 // File IO
22 #include <mitkIOMimeTypes.h>
23 #include <mitkIOUtil.h>
24 #include <mitkImageVtkLegacyIO.h>
25 #include <mitkImageVtkXmlIO.h>
26 #include <mitkItkImageIO.h>
27 #include <mitkMimeTypeProvider.h>
30 #include <mitkRawImageFileReader.h>
31 #include <mitkSurfaceStlIO.h>
32 #include <mitkSurfaceVtkLegacyIO.h>
33 #include <mitkSurfaceVtkXmlIO.h>
34 
36 #include <mitkFileWriter.h>
37 
38 #include <itkGDCMImageIO.h>
39 #include <itkNiftiImageIO.h>
40 
41 // Micro Services
42 #include <usGetModuleContext.h>
43 #include <usModule.h>
44 #include <usModuleActivator.h>
45 #include <usModuleContext.h>
46 #include <usModuleEvent.h>
47 #include <usModuleInitialization.h>
48 #include <usModuleResource.h>
49 #include <usModuleResourceStream.h>
50 #include <usModuleSettings.h>
51 #include <usServiceTracker.h>
52 
53 // ITK "injects" static initialization code for IO factories
54 // via the itkImageIOFactoryRegisterManager.h header (which
55 // is generated in the application library build directory).
56 // To ensure that the code is called *before* the CppMicroServices
57 // static initialization code (which triggers the Activator::Start
58 // method), we include the ITK header here.
60 
61 void HandleMicroServicesMessages(us::MsgType type, const char *msg)
62 {
63  switch (type)
64  {
65  case us::DebugMsg:
66  MITK_DEBUG << msg;
67  break;
68  case us::InfoMsg:
69  MITK_INFO << msg;
70  break;
71  case us::WarningMsg:
72  MITK_WARN << msg;
73  break;
74  case us::ErrorMsg:
75  MITK_ERROR << msg;
76  break;
77  }
78 }
79 
80 void AddMitkAutoLoadPaths(const std::string &programPath)
81 {
83 #ifdef __APPLE__
84  // Walk up three directories since that is where the .dylib files are located
85  // for build trees.
86  std::string additionalPath = programPath;
87  bool addPath = true;
88  for (int i = 0; i < 3; ++i)
89  {
90  std::size_t index = additionalPath.find_last_of('/');
91  if (index != std::string::npos)
92  {
93  additionalPath = additionalPath.substr(0, index);
94  }
95  else
96  {
97  addPath = false;
98  break;
99  }
100  }
101  if (addPath)
102  {
103  us::ModuleSettings::AddAutoLoadPath(additionalPath);
104  }
105 #endif
106 }
107 
109 {
111 
113  if (propPath.IsExplicit())
114  {
115  std::string name = mitk::PropertyKeyPathToPropertyName(propPath);
116  std::string key = name;
117  std::replace(key.begin(), key.end(), '.', '_');
118  info->SetNameAndKey(name, key);
119  }
120  else
121  {
122  std::string key = mitk::PropertyKeyPathToPersistenceKeyRegEx(propPath);
123  std::string keyTemplate = mitk::PropertyKeyPathToPersistenceKeyTemplate(propPath);
124  std::string propRegEx = mitk::PropertyKeyPathToPropertyRegEx(propPath);
125  std::string propTemplate = mitk::PropertyKeyPathToPersistenceNameTemplate(propPath);
126  info->UseRegEx(propRegEx, propTemplate, key, keyTemplate);
127  }
128 
129  persistenceService->AddInfo(info);
130 }
131 
132 class FixedNiftiImageIO : public itk::NiftiImageIO
133 {
134 public:
136  typedef FixedNiftiImageIO Self;
137  typedef itk::NiftiImageIO Superclass;
138  typedef itk::SmartPointer<Self> Pointer;
139 
141  itkNewMacro(Self)
142 
143 
144  itkTypeMacro(FixedNiftiImageIO, Superclass)
145 
146  bool SupportsDimension(unsigned long dim) override
147  {
148  return dim > 1 && dim < 5;
149  }
150 };
151 
152 void MitkCoreActivator::Load(us::ModuleContext *context)
153 {
154  // Handle messages from CppMicroServices
156 
157  this->m_Context = context;
158 
159  // Add the current application directory to the auto-load paths.
160  // This is useful for third-party executables.
161  std::string programPath = mitk::IOUtil::GetProgramPath();
162  if (programPath.empty())
163  {
164  MITK_WARN << "Could not get the program path.";
165  }
166  else
167  {
168  AddMitkAutoLoadPaths(programPath);
169  }
170 
171  // m_RenderingManager = mitk::RenderingManager::New();
172  // context->RegisterService<mitk::RenderingManager>(renderingManager.GetPointer());
173  m_PlanePositionManager.reset(new mitk::PlanePositionManagerService);
174  context->RegisterService<mitk::PlanePositionManagerService>(m_PlanePositionManager.get());
175 
176  m_PropertyAliases.reset(new mitk::PropertyAliases);
177  context->RegisterService<mitk::IPropertyAliases>(m_PropertyAliases.get());
178 
179  m_PropertyDescriptions.reset(new mitk::PropertyDescriptions);
180  context->RegisterService<mitk::IPropertyDescriptions>(m_PropertyDescriptions.get());
181 
182  m_PropertyExtensions.reset(new mitk::PropertyExtensions);
183  context->RegisterService<mitk::IPropertyExtensions>(m_PropertyExtensions.get());
184 
185  m_PropertyFilters.reset(new mitk::PropertyFilters);
186  context->RegisterService<mitk::IPropertyFilters>(m_PropertyFilters.get());
187 
188  m_PropertyPersistence.reset(new mitk::PropertyPersistence);
189  context->RegisterService<mitk::IPropertyPersistence>(m_PropertyPersistence.get());
190 
191  m_PropertyRelations.reset(new mitk::PropertyRelations);
192  context->RegisterService<mitk::IPropertyRelations>(m_PropertyRelations.get());
193 
194  m_MimeTypeProvider.reset(new mitk::MimeTypeProvider);
195  m_MimeTypeProvider->Start();
196  m_MimeTypeProviderReg = context->RegisterService<mitk::IMimeTypeProvider>(m_MimeTypeProvider.get());
197 
198  this->RegisterDefaultMimeTypes();
199  this->RegisterItkReaderWriter();
200  this->RegisterVtkReaderWriter();
201 
202  // Add custom Reader / Writer Services
203  m_FileReaders.push_back(new mitk::PointSetReaderService());
204  m_FileWriters.push_back(new mitk::PointSetWriterService());
205  m_FileReaders.push_back(new mitk::GeometryDataReaderService());
206  m_FileWriters.push_back(new mitk::GeometryDataWriterService());
207  m_FileReaders.push_back(new mitk::RawImageFileReaderService());
208 
209  //add properties that should be persistent (if possible/supported by the writer)
216 
217  /*
218  There IS an option to exchange ALL vtkTexture instances against vtkNeverTranslucentTextureFactory.
219  This code is left here as a reminder, just in case we might need to do that some time.
220 
221  vtkNeverTranslucentTextureFactory* textureFactory = vtkNeverTranslucentTextureFactory::New();
222  vtkObjectFactory::RegisterFactory( textureFactory );
223  textureFactory->Delete();
224  */
225 
226  this->RegisterLegacyWriter();
227 }
228 
229 void MitkCoreActivator::Unload(us::ModuleContext *)
230 {
231  for (auto &elem : m_FileReaders)
232  {
233  delete elem;
234  }
235 
236  for (auto &elem : m_FileWriters)
237  {
238  delete elem;
239  }
240 
241  for (auto &elem : m_FileIOs)
242  {
243  delete elem;
244  }
245 
246  for (auto &elem : m_LegacyWriters)
247  {
248  delete elem;
249  }
250 
251  // The mitk::ModuleContext* argument of the Unload() method
252  // will always be 0 for the Mitk library. It makes no sense
253  // to use it at this stage anyway, since all libraries which
254  // know about the module system have already been unloaded.
255 
256  // we need to close the internal service tracker of the
257  // MimeTypeProvider class here. Otherwise it
258  // would hold on to the ModuleContext longer than it is
259  // actually valid.
260  m_MimeTypeProviderReg.Unregister();
261  m_MimeTypeProvider->Stop();
262 
263  for (std::vector<mitk::CustomMimeType *>::const_iterator mimeTypeIter = m_DefaultMimeTypes.begin(),
264  iterEnd = m_DefaultMimeTypes.end();
265  mimeTypeIter != iterEnd;
266  ++mimeTypeIter)
267  {
268  delete *mimeTypeIter;
269  }
270 }
271 
272 void MitkCoreActivator::RegisterDefaultMimeTypes()
273 {
274  // Register some default mime-types
275 
276  std::vector<mitk::CustomMimeType *> mimeTypes = mitk::IOMimeTypes::Get();
277  for (std::vector<mitk::CustomMimeType *>::const_iterator mimeTypeIter = mimeTypes.begin(), iterEnd = mimeTypes.end();
278  mimeTypeIter != iterEnd;
279  ++mimeTypeIter)
280  {
281  m_DefaultMimeTypes.push_back(*mimeTypeIter);
282  m_Context->RegisterService(m_DefaultMimeTypes.back());
283  }
284 }
285 
286 void MitkCoreActivator::RegisterItkReaderWriter()
287 {
288  std::list<itk::LightObject::Pointer> allobjects = itk::ObjectFactoryBase::CreateAllInstance("itkImageIOBase");
289 
290  for (auto &allobject : allobjects)
291  {
292  auto *io = dynamic_cast<itk::ImageIOBase *>(allobject.GetPointer());
293 
294  // NiftiImageIO does not provide a correct "SupportsDimension()" methods
295  // and the supported read/write extensions are not ordered correctly
296  if (dynamic_cast<itk::NiftiImageIO *>(io))
297  continue;
298 
299  // Use a custom mime-type for GDCMImageIO below
300  if (dynamic_cast<itk::GDCMImageIO *>(allobject.GetPointer()))
301  {
302  // MITK provides its own DICOM reader (which internally uses GDCMImageIO).
303  continue;
304  }
305 
306  if (io)
307  {
308  m_FileIOs.push_back(new mitk::ItkImageIO(io));
309  }
310  else
311  {
312  MITK_WARN << "Error ImageIO factory did not return an ImageIOBase: " << (allobject)->GetNameOfClass();
313  }
314  }
315 
316  FixedNiftiImageIO::Pointer itkNiftiIO = FixedNiftiImageIO::New();
317  mitk::ItkImageIO *niftiIO = new mitk::ItkImageIO(mitk::IOMimeTypes::NIFTI_MIMETYPE(), itkNiftiIO.GetPointer(), 0);
318  m_FileIOs.push_back(niftiIO);
319 }
320 
321 void MitkCoreActivator::RegisterVtkReaderWriter()
322 {
323  m_FileIOs.push_back(new mitk::SurfaceVtkXmlIO());
324  m_FileIOs.push_back(new mitk::SurfaceStlIO());
325  m_FileIOs.push_back(new mitk::SurfaceVtkLegacyIO());
326 
327  m_FileIOs.push_back(new mitk::ImageVtkXmlIO());
328  m_FileIOs.push_back(new mitk::ImageVtkLegacyIO());
329 }
330 
331 void MitkCoreActivator::RegisterLegacyWriter()
332 {
333  std::list<itk::LightObject::Pointer> allobjects = itk::ObjectFactoryBase::CreateAllInstance("IOWriter");
334 
335  for (auto i = allobjects.begin(); i != allobjects.end(); ++i)
336  {
337  mitk::FileWriter::Pointer io = dynamic_cast<mitk::FileWriter *>(i->GetPointer());
338  if (io)
339  {
340  std::string description = std::string("Legacy ") + io->GetNameOfClass() + " Writer";
341  mitk::IFileWriter *writer = new mitk::LegacyFileWriterService(io, description);
342  m_LegacyWriters.push_back(writer);
343  }
344  else
345  {
346  MITK_ERROR << "Error IOWriter override is not of type mitk::FileWriter: " << (*i)->GetNameOfClass() << std::endl;
347  }
348  }
349 }
350 
352 
353 // Call CppMicroservices initialization code at the end of the file.
354 // This especially ensures that VTK object factories have already
355 // been registered (VTK initialization code is injected by implicitly
356 // include VTK header files at the top of this file).
Interface of property relations service.
Interface of property aliases service.
MITKCORE_EXPORT std::string PropertyKeyPathToPropertyName(const PropertyKeyPath &tagPath)
static std::vector< CustomMimeType * > Get()
#define MITK_INFO
Definition: mitkLogMacros.h:18
void Load(us::ModuleContext *context) override
static void AddAutoLoadPath(const std::string &path)
#define MITK_ERROR
Definition: mitkLogMacros.h:20
#define MITK_DEBUG
Definition: mitkLogMacros.h:22
Interface of property extensions service.
static void info(const char *fmt,...)
Definition: svm.cpp:86
#define US_INITIALIZE_MODULE
Creates initialization code for a module.
void Unload(us::ModuleContext *) override
Interface of property descriptions service.
#define MITK_WARN
Definition: mitkLogMacros.h:19
static IPropertyPersistence * GetPropertyPersistence(us::ModuleContext *context=us::GetModuleContext())
Get an IPropertyPersistence instance.
The IMimeTypeProvider service interface allows to query all registered mime types.
void AddPropertyPersistence(const mitk::PropertyKeyPath &propPath)
Interface class of writers that write data to files.
static CustomMimeType NIFTI_MIMETYPE()
MITKCORE_EXPORT std::string PropertyKeyPathToPersistenceNameTemplate(const PropertyKeyPath &tagPath)
static std::string GetProgramPath()
Definition: mitkIOUtil.cpp:356
Interface of property persistence service.
MITKCORE_EXPORT std::string PropertyKeyPathToPersistenceKeyTemplate(const PropertyKeyPath &tagPath)
static const char * replace[]
This is a dictionary to replace long names of classes, modules, etc. to shorter versions in the conso...
MsgHandler installMsgHandler(MsgHandler h)
Definition: usUtils.cpp:263
A RAII helper class for core service objects.
virtual bool AddInfo(const PropertyPersistenceInfo *info, bool overwrite=false)=0
Add persistence info for a specific base data property. If there is already a property info instance ...
void HandleMicroServicesMessages(us::MsgType type, const char *msg)
Interface of property filters service.
void AddMitkAutoLoadPaths(const std::string &programPath)
The common interface of all MITK file writers.
Class that can be used to specify nested or wild carded property keys. E.g. for the use in context of...
#define US_EXPORT_MODULE_ACTIVATOR(_activator_type)
Export a module activator class.
MITKCORE_EXPORT std::string PropertyKeyPathToPropertyRegEx(const PropertyKeyPath &tagPath)
MITKCORE_EXPORT std::string PropertyKeyPathToPersistenceKeyRegEx(const PropertyKeyPath &tagPath)