Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkAbstractFileReader.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 <mitkAbstractFileReader.h>
18 
19 #include <mitkCustomMimeType.h>
20 #include <mitkIOUtil.h>
22 
24 
25 #include <usGetModuleContext.h>
26 #include <usModuleContext.h>
28 
29 #include <itksys/SystemTools.hxx>
30 
31 #include <fstream>
32 
33 namespace mitk
34 {
35  AbstractFileReader::InputStream::InputStream(IFileReader *reader, std::ios_base::openmode mode)
36  : std::istream(NULL), m_Stream(NULL)
37  {
38  std::istream *stream = reader->GetInputStream();
39  if (stream)
40  {
41  this->init(stream->rdbuf());
42  }
43  else
44  {
45  m_Stream = new std::ifstream(reader->GetInputLocation().c_str(), mode);
46  this->init(m_Stream->rdbuf());
47  }
48  }
49 
51  class AbstractFileReader::Impl : public FileReaderWriterBase
52  {
53  public:
54  Impl() : FileReaderWriterBase(), m_Stream(NULL), m_PrototypeFactory(NULL) {}
55  Impl(const Impl &other) : FileReaderWriterBase(other), m_Stream(NULL), m_PrototypeFactory(NULL) {}
56  std::string m_Location;
57  std::string m_TmpFile;
58  std::istream *m_Stream;
59 
60  us::PrototypeServiceFactory *m_PrototypeFactory;
62  };
63 
66  {
68 
69  delete d->m_PrototypeFactory;
70 
71  if (!d->m_TmpFile.empty())
72  {
73  std::remove(d->m_TmpFile.c_str());
74  }
75  }
76 
77  AbstractFileReader::AbstractFileReader(const AbstractFileReader &other) : IFileReader(), d(new Impl(*other.d.get()))
78  {
79  }
80 
81  AbstractFileReader::AbstractFileReader(const CustomMimeType &mimeType, const std::string &description) : d(new Impl)
82  {
83  d->SetMimeType(mimeType);
84  d->SetDescription(description);
85  }
86 
88 
89  std::vector<BaseData::Pointer> AbstractFileReader::Read()
90  {
91  std::vector<BaseData::Pointer> result;
92 
94  this->Read(*ds);
95  DataStorage::SetOfObjects::ConstPointer dataNodes = ds->GetAll();
96  for (DataStorage::SetOfObjects::ConstIterator iter = dataNodes->Begin(), iterEnd = dataNodes->End();
97  iter != iterEnd;
98  ++iter)
99  {
100  result.push_back(iter.Value()->GetData());
101  }
102  return result;
103  }
104 
106  {
108  std::vector<BaseData::Pointer> data = this->Read();
109  for (std::vector<BaseData::Pointer>::iterator iter = data.begin(); iter != data.end(); ++iter)
110  {
112  node->SetData(*iter);
113  this->SetDefaultDataNodeProperties(node, this->GetInputLocation());
114  ds.Add(node);
115  result->InsertElement(result->Size(), node);
116  }
117  return result;
118  }
119 
121  {
122  if (d->m_Stream)
123  {
124  if (*d->m_Stream)
125  return Supported;
126  }
127  else
128  {
129  if (itksys::SystemTools::FileExists(this->GetInputLocation().c_str(), true))
130  {
131  return Supported;
132  }
133  }
134  return Unsupported;
135  }
136 
138 
140  {
141  if (d->m_PrototypeFactory)
143 
144  if (context == NULL)
145  {
146  context = us::GetModuleContext();
147  }
148 
149  d->RegisterMimeType(context);
150 
151  if (this->GetMimeType()->GetName().empty())
152  {
153  MITK_WARN << "Not registering reader due to empty MIME type.";
155  }
156 
157  struct PrototypeFactory : public us::PrototypeServiceFactory
158  {
159  AbstractFileReader *const m_Prototype;
160 
161  PrototypeFactory(AbstractFileReader *prototype) : m_Prototype(prototype) {}
162  us::InterfaceMap GetService(us::Module * /*module*/,
163  const us::ServiceRegistrationBase & /*registration*/) override
164  {
165  return us::MakeInterfaceMap<IFileReader>(m_Prototype->Clone());
166  }
167 
168  void UngetService(us::Module * /*module*/,
169  const us::ServiceRegistrationBase & /*registration*/,
170  const us::InterfaceMap &service) override
171  {
172  delete us::ExtractInterface<IFileReader>(service);
173  }
174  };
175 
176  d->m_PrototypeFactory = new PrototypeFactory(this);
178  d->m_Reg = context->RegisterService<IFileReader>(d->m_PrototypeFactory, props);
179  return d->m_Reg;
180  }
181 
183  {
184  try
185  {
186  d->m_Reg.Unregister();
187  }
188  catch (const std::exception &)
189  {
190  }
191  }
192 
194  {
195  us::ServiceProperties result;
196 
197  result[IFileReader::PROP_DESCRIPTION()] = this->GetDescription();
198  result[IFileReader::PROP_MIMETYPE()] = this->GetMimeType()->GetName();
200  return result;
201  }
202 
204  {
205  return d->RegisterMimeType(context);
206  }
207 
208  void AbstractFileReader::SetMimeType(const CustomMimeType &mimeType) { d->SetMimeType(mimeType); }
209  void AbstractFileReader::SetDescription(const std::string &description) { d->SetDescription(description); }
210  void AbstractFileReader::SetRanking(int ranking) { d->SetRanking(ranking); }
211  int AbstractFileReader::GetRanking() const { return d->GetRanking(); }
213  {
214  std::string localFileName;
215  if (d->m_Stream)
216  {
217  if (d->m_TmpFile.empty())
218  {
219  // write the stream contents to temporary file
220  std::string ext = itksys::SystemTools::GetFilenameExtension(this->GetInputLocation());
221  std::ofstream tmpStream;
222  localFileName = mitk::IOUtil::CreateTemporaryFile(
223  tmpStream, std::ios_base::out | std::ios_base::trunc | std::ios_base::binary, "XXXXXX" + ext);
224  tmpStream << d->m_Stream->rdbuf();
225  d->m_TmpFile = localFileName;
226  }
227  else
228  {
229  localFileName = d->m_TmpFile;
230  }
231  }
232  else
233  {
234  localFileName = d->m_Location;
235  }
236  return localFileName;
237  }
238 
240 
242  {
243  d->SetDefaultOptions(defaultOptions);
244  }
245 
246  IFileReader::Options AbstractFileReader::GetDefaultOptions() const { return d->GetDefaultOptions(); }
247  void AbstractFileReader::SetInput(const std::string &location)
248  {
249  d->m_Location = location;
250  d->m_Stream = NULL;
251  }
252 
253  void AbstractFileReader::SetInput(const std::string &location, std::istream *is)
254  {
255  if (d->m_Stream != is && !d->m_TmpFile.empty())
256  {
257  std::remove(d->m_TmpFile.c_str());
258  d->m_TmpFile.clear();
259  }
260  d->m_Location = location;
261  d->m_Stream = is;
262  }
263 
264  std::string AbstractFileReader::GetInputLocation() const { return d->m_Location; }
265  std::istream *AbstractFileReader::GetInputStream() const { return d->m_Stream; }
266  MimeType AbstractFileReader::GetRegisteredMimeType() const { return d->GetRegisteredMimeType(); }
267  IFileReader::Options AbstractFileReader::GetOptions() const { return d->GetOptions(); }
268  us::Any AbstractFileReader::GetOption(const std::string &name) const { return d->GetOption(name); }
269  void AbstractFileReader::SetOptions(const Options &options) { d->SetOptions(options); }
270  void AbstractFileReader::SetOption(const std::string &name, const us::Any &value) { d->SetOption(name, value); }
272 
273  void AbstractFileReader::AddProgressCallback(const ProgressCallback &callback) { d->AddProgressCallback(callback); }
275  {
276  d->RemoveProgressCallback(callback);
277  }
278 
280 
281  const CustomMimeType *AbstractFileReader::GetMimeType() const { return d->GetMimeType(); }
282  void AbstractFileReader::SetMimeTypePrefix(const std::string &prefix) { d->SetMimeTypePrefix(prefix); }
283  std::string AbstractFileReader::GetMimeTypePrefix() const { return d->GetMimeTypePrefix(); }
284  std::string AbstractFileReader::GetDescription() const { return d->GetDescription(); }
285  void AbstractFileReader::SetDefaultDataNodeProperties(DataNode *node, const std::string &filePath)
286  {
287  // path
288  if (!filePath.empty())
289  {
291  mitk::StringProperty::New(itksys::SystemTools::GetFilenamePath(filePath));
292  node->SetProperty(StringProperty::PATH, pathProp);
293  }
294 
295  // name already defined?
296  mitk::StringProperty::Pointer nameProp = dynamic_cast<mitk::StringProperty *>(node->GetProperty("name"));
297  if (nameProp.IsNull() || (strcmp(nameProp->GetValue(), "No Name!") == 0))
298  {
299  // name already defined in BaseData
300  mitk::StringProperty::Pointer baseDataNameProp =
301  dynamic_cast<mitk::StringProperty *>(node->GetData()->GetProperty("name").GetPointer());
302  if (baseDataNameProp.IsNull() || (strcmp(baseDataNameProp->GetValue(), "No Name!") == 0))
303  {
304  // name neither defined in node, nor in BaseData -> name = filebasename;
305  nameProp = mitk::StringProperty::New(this->GetRegisteredMimeType().GetFilenameWithoutExtension(filePath));
306  node->SetProperty("name", nameProp);
307  }
308  else
309  {
310  // name defined in BaseData!
311  nameProp = mitk::StringProperty::New(baseDataNameProp->GetValue());
312  node->SetProperty("name", nameProp);
313  }
314  }
315 
316  // visibility
317  if (!node->GetProperty("visible"))
318  {
319  node->SetVisibility(true);
320  }
321  }
322 }
virtual us::ServiceProperties GetServiceProperties() const
virtual void Add(mitk::DataNode *node, const mitk::DataStorage::SetOfObjects *parents=nullptr)=0
Adds a DataNode containing a data object to its internal storage.
Data management class that handles 'was created by' relations.
itk::SmartPointer< Self > Pointer
virtual us::Any GetOption(const std::string &name) const override
void SetVisibility(bool visible, const mitk::BaseRenderer *renderer=nullptr, const char *propertyKey="visible")
Convenience method for setting visibility properties (instances of BoolProperty)
US_Core_EXPORT const std::string & SERVICE_RANKING()
virtual void SetOption(const std::string &name, const us::Any &value) override
virtual ConfidenceLevel GetConfidenceLevel() const override
The confidence level of the reader or writer implementation.
std::map< std::string, void * > InterfaceMap
static std::string PROP_DESCRIPTION()
Service property name for a description.
Definition: mitkIFileIO.cpp:22
virtual std::istream * GetInputStream() const override
Get the input stream.
virtual void SetOptions(const Options &options) override
STL namespace.
DataCollection - Class to facilitate loading/accessing structured data.
std::map< std::string, us::Any > Options
Options for reading or writing data.
Definition: mitkIFileIO.h:73
BaseData * GetData() const
Get the data object (instance of BaseData, e.g., an Image) managed by this DataNode.
virtual us::ServiceRegistration< CustomMimeType > RegisterMimeType(us::ModuleContext *context)
mitk::BaseProperty * GetProperty(const char *propertyKey, const mitk::BaseRenderer *renderer=nullptr) const
Get the property (instance of BaseProperty) with key propertyKey from the PropertyList of the rendere...
std::string GetLocalFileName() const
Get a local file name for reading.
static std::string PROP_MIMETYPE()
Service property name for the mime-type associated with this file writer.
Definition: mitkIFileIO.cpp:28
virtual std::vector< itk::SmartPointer< BaseData > > Read() override=0
Reads a path or stream and creates a list of BaseData objects.
itk::SmartPointer< const Self > ConstPointer
virtual void SetDefaultDataNodeProperties(DataNode *node, const std::string &filePath)
std::string GetMimeTypePrefix() const
void SetMimeType(const CustomMimeType &mimeType)
The CustomMimeType class represents a custom mime-type which may be registered as a service object...
void SetMimeTypePrefix(const std::string &prefix)
InputStream(IFileReader *writer, std::ios_base::openmode mode=std::ios_base::in)
void SetDefaultOptions(const Options &defaultOptions)
us::ServiceRegistration< IFileReader > RegisterService(us::ModuleContext *context=us::GetModuleContext())
#define MITK_WARN
Definition: mitkLogMacros.h:23
std::string GetDescription() const
static Pointer New()
void SetDescription(const std::string &description)
Definition: usAny.h:163
std::string GetName() const
Returns the unique name for the MimeType.
const CustomMimeType * GetMimeType() const
virtual Options GetOptions() const override
returns a list of the supported options
virtual void AddProgressCallback(const ProgressCallback &callback) override
static const char * PATH
virtual std::istream * GetInputStream() const =0
Get the input stream.
The MimeType class represens a registered mime-type. It is an immutable wrapper for mitk::CustomMimeT...
Definition: mitkMimeType.h:45
US_UNORDERED_MAP_TYPE< std::string, Any > ServiceProperties
void SetRanking(int ranking)
Set the service ranking for this file reader.
Base class for creating mitk::BaseData objects from files or streams.
static std::string CreateTemporaryFile(std::ofstream &tmpStream, const std::string &templateName="XXXXXX", std::string path=std::string())
Definition: mitkIOUtil.cpp:407
virtual std::string GetInputLocation() const =0
Get the current input location.
static std::string GetName(std::string fileName, std::string suffix)
ConfidenceLevel
A confidence level describing the confidence of the reader or writer in handling the given data...
Definition: mitkIFileIO.h:49
void SetProperty(const char *propertyKey, BaseProperty *property, const mitk::BaseRenderer *renderer=nullptr)
Set the property (instance of BaseProperty) with key propertyKey in the PropertyList of the renderer ...
Property for strings.
virtual std::string GetInputLocation() const override
Get the current input location.
mitk::BaseProperty::Pointer GetProperty(const char *propertyKey) const
Get the property (instance of BaseProperty) with key propertyKey from the PropertyList, and set it to this, respectively;.
The common interface for all MITK file readers.
virtual void SetInput(const std::string &location) override
Set the input location.
static ModuleContext * GetModuleContext()
Returns the module context of the calling module.
static Pointer New()
virtual void RemoveProgressCallback(const ProgressCallback &callback) override
Class for nodes of the DataTree.
Definition: mitkDataNode.h:66
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.