Medical Imaging Interaction Toolkit  2018.4.99-b20efe7f
Medical Imaging Interaction Toolkit
mitkFileReaderSelector.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 "mitkFileReaderSelector.h"
14 
15 #include <mitkCoreServices.h>
16 #include <mitkFileReaderRegistry.h>
17 #include <mitkIMimeTypeProvider.h>
18 
19 #include <usAny.h>
20 #include <usServiceProperties.h>
21 #include <usServiceReference.h>
22 
23 #include <itksys/SystemTools.hxx>
24 
25 namespace mitk
26 {
27  struct FileReaderSelector::Item::Impl : us::SharedData
28  {
29  Impl() : m_FileReader(nullptr), m_ConfidenceLevel(IFileReader::Unsupported), m_Id(-1) {}
30  us::ServiceReference<IFileReader> m_FileReaderRef;
31  IFileReader *m_FileReader;
32  IFileReader::ConfidenceLevel m_ConfidenceLevel;
33  MimeType m_MimeType;
34  long m_Id;
35  };
36 
37  struct FileReaderSelector::Impl : us::SharedData
38  {
39  Impl() : m_BestId(-1), m_SelectedId(m_BestId) {}
40  Impl(const Impl &other) : us::SharedData(other), m_BestId(-1), m_SelectedId(m_BestId) {}
41  FileReaderRegistry m_ReaderRegistry;
42  std::map<long, FileReaderSelector::Item> m_Items;
43  std::vector<MimeType> m_MimeTypes;
44  long m_BestId;
45  long m_SelectedId;
46  };
47 
48  FileReaderSelector::FileReaderSelector(const FileReaderSelector &other) : m_Data(other.m_Data) {}
49  FileReaderSelector::FileReaderSelector(const std::string &path) : m_Data(new Impl)
50  {
51  if (!itksys::SystemTools::FileExists(path.c_str()))
52  {
53  return;
54  }
55 
57 
58  // Get all mime types and associated readers for the given file path
59 
60  m_Data->m_MimeTypes = mimeTypeProvider->GetMimeTypesForFile(path);
61  if (m_Data->m_MimeTypes.empty())
62  return;
63 
64  for (std::vector<MimeType>::const_iterator mimeTypeIter = m_Data->m_MimeTypes.begin(),
65  mimeTypeIterEnd = m_Data->m_MimeTypes.end();
66  mimeTypeIter != mimeTypeIterEnd;
67  ++mimeTypeIter)
68  {
69  std::vector<FileReaderRegistry::ReaderReference> refs = m_Data->m_ReaderRegistry.GetReferences(*mimeTypeIter);
70  for (std::vector<FileReaderRegistry::ReaderReference>::const_iterator readerIter = refs.begin(),
71  iterEnd = refs.end();
72  readerIter != iterEnd;
73  ++readerIter)
74  {
75  IFileReader *reader = m_Data->m_ReaderRegistry.GetReader(*readerIter);
76  if (reader == nullptr)
77  continue;
78  try
79  {
80  reader->SetInput(path);
81  IFileReader::ConfidenceLevel confidenceLevel = reader->GetConfidenceLevel();
82  if (confidenceLevel == IFileReader::Unsupported)
83  {
84  continue;
85  }
86 
87  Item item;
88  item.d->m_FileReaderRef = *readerIter;
89  item.d->m_FileReader = reader;
90  item.d->m_ConfidenceLevel = confidenceLevel;
91  item.d->m_MimeType = *mimeTypeIter;
92  item.d->m_Id = us::any_cast<long>(readerIter->GetProperty(us::ServiceConstants::SERVICE_ID()));
93  m_Data->m_Items.insert(std::make_pair(item.d->m_Id, item));
94  // m_Data->m_MimeTypes.insert(mimeType);
95  }
96  catch (const us::BadAnyCastException &e)
97  {
98  MITK_WARN << "Unexpected: " << e.what();
99  }
100  catch (const std::exception &e)
101  {
102  // Log the error but continue
103  MITK_WARN << "IFileWriter::GetConfidenceLevel exception: " << e.what();
104  }
105  }
106  }
107 
108  // get the "best" reader
109 
110  if (!m_Data->m_Items.empty())
111  {
112  std::set<Item> sortedItems;
113  for (std::map<long, Item>::const_iterator iter = m_Data->m_Items.begin(), iterEnd = m_Data->m_Items.end();
114  iter != iterEnd;
115  ++iter)
116  {
117  sortedItems.insert(iter->second);
118  }
119  m_Data->m_BestId = sortedItems.rbegin()->GetServiceId();
120  m_Data->m_SelectedId = m_Data->m_BestId;
121  }
122  }
123 
126  {
127  m_Data = other.m_Data;
128  return *this;
129  }
130 
131  bool FileReaderSelector::IsEmpty() const { return m_Data->m_Items.empty(); }
132  std::vector<MimeType> FileReaderSelector::GetMimeTypes() const { return m_Data->m_MimeTypes; }
133  std::vector<FileReaderSelector::Item> FileReaderSelector::Get() const
134  {
135  std::vector<Item> result;
136  for (std::map<long, Item>::const_iterator iter = m_Data->m_Items.begin(), iterEnd = m_Data->m_Items.end();
137  iter != iterEnd;
138  ++iter)
139  {
140  result.push_back(iter->second);
141  }
142  std::sort(result.begin(), result.end());
143  return result;
144  }
145 
147  {
148  std::map<long, Item>::const_iterator iter = m_Data->m_Items.find(id);
149  if (iter != m_Data->m_Items.end())
150  {
151  return iter->second;
152  }
153  return Item();
154  }
155 
156  FileReaderSelector::Item FileReaderSelector::GetDefault() const { return Get(m_Data->m_BestId); }
157  long FileReaderSelector::GetDefaultId() const { return m_Data->m_BestId; }
158  FileReaderSelector::Item FileReaderSelector::GetSelected() const { return Get(m_Data->m_SelectedId); }
159  long FileReaderSelector::GetSelectedId() const { return m_Data->m_SelectedId; }
160  bool FileReaderSelector::Select(const FileReaderSelector::Item &item) { return Select(item.d->m_Id); }
162  {
163  if (id > -1)
164  {
165  if (m_Data->m_Items.find(id) == m_Data->m_Items.end())
166  {
167  return false;
168  }
169  m_Data->m_SelectedId = id;
170  return true;
171  }
172  return false;
173  }
174 
175  void FileReaderSelector::Swap(FileReaderSelector &fws) { m_Data.Swap(fws.m_Data); }
176  FileReaderSelector::Item::Item(const FileReaderSelector::Item &other) : d(other.d) {}
179  {
180  d = other.d;
181  return *this;
182  }
183 
184  IFileReader *FileReaderSelector::Item::GetReader() const { return d->m_FileReader; }
186  {
187  us::Any descr = d->m_FileReaderRef.GetProperty(IFileReader::PROP_DESCRIPTION());
188  if (descr.Empty())
189  return std::string();
190  return descr.ToString();
191  }
192 
194  MimeType FileReaderSelector::Item::GetMimeType() const { return d->m_MimeType; }
196  long FileReaderSelector::Item::GetServiceId() const { return d->m_Id; }
198  {
199  // sort by confidence level first (ascending)
200  if (d->m_ConfidenceLevel == other.d->m_ConfidenceLevel)
201  {
202  // sort by mime-type ranking
203  if (d->m_MimeType < other.d->m_MimeType)
204  {
205  return true;
206  }
207  else if (other.d->m_MimeType < d->m_MimeType)
208  {
209  return false;
210  }
211  else
212  {
213  // sort by file writer service ranking
214  return d->m_FileReaderRef < other.d->m_FileReaderRef;
215  }
216  }
217  return d->m_ConfidenceLevel < other.d->m_ConfidenceLevel;
218  }
219 
220  FileReaderSelector::Item::Item() : d(new Impl()) {}
221  void swap(FileReaderSelector &frs1, FileReaderSelector &frs2) { frs1.Swap(frs2); }
222 }
virtual ConfidenceLevel GetConfidenceLevel() const =0
The confidence level of the reader or writer implementation.
static IMimeTypeProvider * GetMimeTypeProvider(us::ModuleContext *context=us::GetModuleContext())
Get an IMimeTypeProvider instance.
static std::string PROP_DESCRIPTION()
Service property name for a description.
Definition: mitkIFileIO.cpp:18
DataCollection - Class to facilitate loading/accessing structured data.
ValueType * any_cast(Any *operand)
Definition: usAny.h:377
std::vector< MimeType > GetMimeTypes() const
bool Empty() const
Definition: usAny.h:246
std::string ToString() const
Definition: usAny.h:257
std::vector< Item > Get() const
Get a sorted list of file reader items.
const char * what() const override
Definition: usAny.h:352
FileReaderSelector(const FileReaderSelector &other)
void Swap(ExplicitlySharedDataPointer &other)
Definition: usSharedData.h:210
us::ServiceReference< IFileReader > GetReference() const
#define MITK_WARN
Definition: mitkLogMacros.h:19
virtual void SetInput(const std::string &location)=0
Set the input location.
ConfidenceLevel
A confidence level describing the confidence of the reader or writer in handling the given data...
Definition: mitkIFileIO.h:45
Definition: usAny.h:163
void swap(CustomMimeType &l, CustomMimeType &r)
The MimeType class represens a registered mime-type. It is an immutable wrapper for mitk::CustomMimeT...
Definition: mitkMimeType.h:36
IFileReader::ConfidenceLevel GetConfidenceLevel() const
void Swap(FileReaderSelector &fws)
A RAII helper class for core service objects.
The common interface for all MITK file readers.
US_Core_EXPORT const std::string & SERVICE_ID()
FileReaderSelector & operator=(const FileReaderSelector &other)
bool operator<(const Item &other) const
virtual std::vector< MimeType > GetMimeTypesForFile(const std::string &filePath) const =0