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