Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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.