Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkAbstractFileWriter.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 <mitkAbstractFileWriter.h>
18 
19 #include <mitkBaseData.h>
20 #include <mitkCustomMimeType.h>
21 #include <mitkExceptionMacro.h>
22 #include <mitkIOUtil.h>
23 
25 
26 #include <usGetModuleContext.h>
27 #include <usModuleContext.h>
29 
30 #include <itksys/SystemTools.hxx>
31 
32 #include <fstream>
33 
34 namespace mitk
35 {
36  struct AbstractFileWriter::LocalFile::Impl
37  {
38  Impl(const std::string &location, std::ostream *os) : m_Location(location), m_Stream(os) {}
39  std::string m_Location;
40  std::string m_TmpFileName;
41  std::ostream *m_Stream;
42  };
43 
44  AbstractFileWriter::LocalFile::LocalFile(IFileWriter *writer)
45  : d(new Impl(writer->GetOutputLocation(), writer->GetOutputStream()))
46  {
47  }
48 
50  {
51  if (d->m_Stream && !d->m_TmpFileName.empty())
52  {
53  std::ifstream ifs(d->m_TmpFileName.c_str(), std::ios_base::binary);
54  *d->m_Stream << ifs.rdbuf();
55  d->m_Stream->flush();
56  ifs.close();
57  std::remove(d->m_TmpFileName.c_str());
58  }
59  }
60 
62  {
63  if (d->m_Stream == NULL)
64  {
65  return d->m_Location;
66  }
67  else if (d->m_TmpFileName.empty())
68  {
69  std::string ext = itksys::SystemTools::GetFilenameExtension(d->m_Location);
70  d->m_TmpFileName = IOUtil::CreateTemporaryFile("XXXXXX" + ext);
71  }
72  return d->m_TmpFileName;
73  }
74 
75  AbstractFileWriter::OutputStream::OutputStream(IFileWriter *writer, std::ios_base::openmode mode)
76  : std::ostream(NULL), m_Stream(NULL)
77  {
78  std::ostream *stream = writer->GetOutputStream();
79  if (stream)
80  {
81  this->init(stream->rdbuf());
82  }
83  else
84  {
85  m_Stream = new std::ofstream(writer->GetOutputLocation().c_str(), mode);
86  this->init(m_Stream->rdbuf());
87  }
88  }
89 
91  class AbstractFileWriter::Impl : public FileReaderWriterBase
92  {
93  public:
94  Impl() : FileReaderWriterBase(), m_BaseData(NULL), m_Stream(NULL), m_PrototypeFactory(NULL) {}
95  Impl(const Impl &other)
96  : FileReaderWriterBase(other),
97  m_BaseDataType(other.m_BaseDataType),
98  m_BaseData(NULL),
99  m_Stream(NULL),
100  m_PrototypeFactory(NULL)
101  {
102  }
103 
104  std::string m_BaseDataType;
105  const BaseData *m_BaseData;
106  std::string m_Location;
107  std::ostream *m_Stream;
108 
109  us::PrototypeServiceFactory *m_PrototypeFactory;
111  };
112 
113  void AbstractFileWriter::SetInput(const BaseData *data) { d->m_BaseData = data; }
114  const BaseData *AbstractFileWriter::GetInput() const { return d->m_BaseData; }
115  void AbstractFileWriter::SetOutputLocation(const std::string &location)
116  {
117  d->m_Location = location;
118  d->m_Stream = NULL;
119  }
120 
121  std::string AbstractFileWriter::GetOutputLocation() const { return d->m_Location; }
122  void AbstractFileWriter::SetOutputStream(const std::string &location, std::ostream *os)
123  {
124  d->m_Location = location;
125  d->m_Stream = os;
126  }
127 
128  std::ostream *AbstractFileWriter::GetOutputStream() const { return d->m_Stream; }
130  {
132 
133  delete d->m_PrototypeFactory;
134  }
135 
136  AbstractFileWriter::AbstractFileWriter(const AbstractFileWriter &other) : IFileWriter(), d(new Impl(*other.d.get()))
137  {
138  }
139 
140  AbstractFileWriter::AbstractFileWriter(const std::string &baseDataType) : d(new Impl)
141  {
142  d->m_BaseDataType = baseDataType;
143  }
144 
145  AbstractFileWriter::AbstractFileWriter(const std::string &baseDataType,
146  const CustomMimeType &mimeType,
147  const std::string &description)
148  : d(new Impl)
149  {
150  d->m_BaseDataType = baseDataType;
151  d->SetMimeType(mimeType);
152  d->SetDescription(description);
153  }
154 
156 
158  {
159  if (d->m_BaseData == NULL)
160  return Unsupported;
161 
162  std::vector<std::string> classHierarchy = d->m_BaseData->GetClassHierarchy();
163  if (std::find(classHierarchy.begin(), classHierarchy.end(), d->m_BaseDataType) == classHierarchy.end())
164  {
165  return Unsupported;
166  }
167  return Supported;
168  }
169 
170  MimeType AbstractFileWriter::GetRegisteredMimeType() const { return d->GetRegisteredMimeType(); }
172 
174  {
175  if (d->m_PrototypeFactory)
177 
178  if (context == NULL)
179  {
180  context = us::GetModuleContext();
181  }
182 
183  d->RegisterMimeType(context);
184 
185  if (this->GetMimeType()->GetName().empty())
186  {
187  MITK_WARN << "Not registering writer due to empty MIME type.";
189  }
190 
191  struct PrototypeFactory : public us::PrototypeServiceFactory
192  {
193  AbstractFileWriter *const m_Prototype;
194 
195  PrototypeFactory(AbstractFileWriter *prototype) : m_Prototype(prototype) {}
196  us::InterfaceMap GetService(us::Module * /*module*/,
197  const us::ServiceRegistrationBase & /*registration*/) override
198  {
199  return us::MakeInterfaceMap<IFileWriter>(m_Prototype->Clone());
200  }
201 
202  void UngetService(us::Module * /*module*/,
203  const us::ServiceRegistrationBase & /*registration*/,
204  const us::InterfaceMap &service) override
205  {
206  delete us::ExtractInterface<IFileWriter>(service);
207  }
208  };
209 
210  d->m_PrototypeFactory = new PrototypeFactory(this);
212  d->m_Reg = context->RegisterService<IFileWriter>(d->m_PrototypeFactory, props);
213  return d->m_Reg;
214  }
215 
217  {
218  try
219  {
220  d->m_Reg.Unregister();
221  }
222  catch (const std::exception &)
223  {
224  }
225  }
226 
228  {
229  us::ServiceProperties result;
230  result[IFileWriter::PROP_DESCRIPTION()] = this->GetDescription();
231  result[IFileWriter::PROP_MIMETYPE()] = this->GetMimeType()->GetName();
232  result[IFileWriter::PROP_BASEDATA_TYPE()] = d->m_BaseDataType;
234 
235  // for (IFileWriter::OptionList::const_iterator it = d->m_Options.begin(); it != d->m_Options.end(); ++it)
236  // {
237  // result[it->first] = std::string("true");
238  // }
239  return result;
240  }
241 
242  const CustomMimeType *AbstractFileWriter::GetMimeType() const { return d->GetMimeType(); }
243  void AbstractFileWriter::SetMimeTypePrefix(const std::string &prefix) { d->SetMimeTypePrefix(prefix); }
244  std::string AbstractFileWriter::GetMimeTypePrefix() const { return d->GetMimeTypePrefix(); }
246  {
247  return d->RegisterMimeType(context);
248  }
249 
250  void AbstractFileWriter::SetMimeType(const CustomMimeType &mimeType) { d->SetMimeType(mimeType); }
251  void AbstractFileWriter::SetRanking(int ranking) { d->SetRanking(ranking); }
253 
255  {
256  d->SetDefaultOptions(defaultOptions);
257  }
258 
259  IFileWriter::Options AbstractFileWriter::GetDefaultOptions() const { return d->GetDefaultOptions(); }
260  IFileWriter::Options AbstractFileWriter::GetOptions() const { return d->GetOptions(); }
261  us::Any AbstractFileWriter::GetOption(const std::string &name) const { return d->GetOption(name); }
262  void AbstractFileWriter::SetOption(const std::string &name, const us::Any &value) { d->SetOption(name, value); }
263  void AbstractFileWriter::SetOptions(const Options &options) { d->SetOptions(options); }
265 
266  void AbstractFileWriter::AddProgressCallback(const ProgressCallback &callback) { d->AddProgressCallback(callback); }
268  {
269  d->RemoveProgressCallback(callback);
270  }
271 
273 
274  int AbstractFileWriter::GetRanking() const { return d->GetRanking(); }
275  void AbstractFileWriter::SetBaseDataType(const std::string &baseDataType) { d->m_BaseDataType = baseDataType; }
276  std::string AbstractFileWriter::GetDescription() const { return d->GetDescription(); }
277  std::string AbstractFileWriter::GetBaseDataType() const { return d->m_BaseDataType; }
279  {
280  if (this->GetOutputStream() == NULL)
281  {
282  // check if a file name is set and if we can write to it
283  const std::string fileName = this->GetOutputLocation();
284  if (fileName.empty())
285  {
286  mitkThrow() << "No output location or stream specified";
287  }
288  }
289  }
290 
291  void AbstractFileWriter::SetDescription(const std::string &description) { d->SetDescription(description); }
292 }
AbstractFileWriter(const AbstractFileWriter &other)
virtual void SetInput(const BaseData *data) override
Set the input data for writing.
US_Core_EXPORT const std::string & SERVICE_RANKING()
Base of all data objects.
Definition: mitkBaseData.h:39
virtual Options GetOptions() const override
returns a list of the supported options
std::map< std::string, void * > InterfaceMap
static std::string PROP_DESCRIPTION()
Service property name for a description.
Definition: mitkIFileIO.cpp:22
virtual us::ServiceProperties GetServiceProperties() const
STL namespace.
DataCollection - Class to facilitate loading/accessing structured data.
virtual std::string GetOutputLocation() const =0
Get the current output location.
std::map< std::string, us::Any > Options
Options for reading or writing data.
Definition: mitkIFileIO.h:73
virtual us::ServiceRegistration< CustomMimeType > RegisterMimeType(us::ModuleContext *context)
static std::string PROP_MIMETYPE()
Service property name for the mime-type associated with this file writer.
Definition: mitkIFileIO.cpp:28
void SetDefaultOptions(const Options &defaultOptions)
const CustomMimeType * GetMimeType() const
virtual ConfidenceLevel GetConfidenceLevel() const override
The confidence level of the reader or writer implementation.
The CustomMimeType class represents a custom mime-type which may be registered as a service object...
virtual std::string GetBaseDataType() const
void SetRanking(int ranking)
Set the service ranking for this file writer.
#define MITK_WARN
Definition: mitkLogMacros.h:23
virtual void SetOutputStream(const std::string &location, std::ostream *os) override
Set an output stream for writing.
#define mitkThrow()
virtual const BaseData * GetInput() const override
Get the input data set via SetInput().
Definition: usAny.h:163
void SetBaseDataType(const std::string &baseDataType)
Sets the name of the mitk::Basedata that this writer is able to handle.
std::string GetName() const
Returns the unique name for the MimeType.
virtual void SetOutputLocation(const std::string &location) override
Set the output location.
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
virtual std::ostream * GetOutputStream() const =0
Get the output stream.
virtual std::ostream * GetOutputStream() const override
Get the output stream.
virtual void SetOption(const std::string &name, const us::Any &value) override
static std::string PROP_BASEDATA_TYPE()
Service property name for the supported mitk::BaseData sub-class.
static std::string CreateTemporaryFile(std::ofstream &tmpStream, const std::string &templateName="XXXXXX", std::string path=std::string())
Definition: mitkIOUtil.cpp:407
us::ServiceRegistration< IFileWriter > RegisterService(us::ModuleContext *context=us::GetModuleContext())
void SetMimeType(const CustomMimeType &mimeType)
static std::string GetName(std::string fileName, std::string suffix)
OutputStream(IFileWriter *writer, std::ios_base::openmode mode=std::ios_base::trunc|std::ios_base::out)
virtual void SetOptions(const Options &options) override
virtual std::string GetOutputLocation() const override
Get the current output location.
ConfidenceLevel
A confidence level describing the confidence of the reader or writer in handling the given data...
Definition: mitkIFileIO.h:49
void SetMimeTypePrefix(const std::string &prefix)
The common interface of all MITK file writers.
Base class for writing mitk::BaseData objects to files or streams.
void SetDescription(const std::string &description)
Sets a human readable description of this writer.
virtual us::Any GetOption(const std::string &name) const override
static ModuleContext * GetModuleContext()
Returns the module context of the calling module.
virtual void AddProgressCallback(const ProgressCallback &callback) override
std::string GetMimeTypePrefix() const
virtual void RemoveProgressCallback(const ProgressCallback &callback) override
std::string GetDescription() const