diff --git a/Core/Code/IO/mitkFileReaderRegistry.cpp b/Core/Code/IO/mitkFileReaderRegistry.cpp index 69e92b5622..acfae6240a 100644 --- a/Core/Code/IO/mitkFileReaderRegistry.cpp +++ b/Core/Code/IO/mitkFileReaderRegistry.cpp @@ -1,238 +1,241 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkFileReaderRegistry.h" #include "mitkIMimeTypeProvider.h" #include "mitkCoreServices.h" // Microservices #include #include #include #include #include "itksys/SystemTools.hxx" mitk::FileReaderRegistry::FileReaderRegistry() { } mitk::FileReaderRegistry::~FileReaderRegistry() { for (std::map >::iterator iter = m_ServiceObjects.begin(), end = m_ServiceObjects.end(); iter != end; ++iter) { iter->second.UngetService(iter->first); } } //////////////////// READING DIRECTLY //////////////////// std::vector< mitk::BaseData::Pointer > mitk::FileReaderRegistry::Read(const std::string& path, us::ModuleContext* context) { // Find extension std::string extension = itksys::SystemTools::GetFilenameExtension(path); - extension = extension.substr(1, extension.size()-1); + if (!extension.empty()) + { + extension = extension.substr(1, extension.size()-1); + } // Get best Reader FileReaderRegistry readerRegistry; mitk::IFileReader* reader = readerRegistry.GetReader(extension, context); // Throw exception if no compatible reader was found - if (reader == NULL) mitkThrow() << "Tried to directly read a file of type '" + extension + "' via FileReaderRegistry, but no reader supporting this filetype was found."; + if (reader == NULL) mitkThrow() << "Tried to directly read a file with extension '" + extension + "' via FileReaderRegistry, but no reader supporting this file type was found."; return reader->Read(path); } std::vector< mitk::BaseData::Pointer > mitk::FileReaderRegistry::ReadAll( const std::vector& paths, std::vector* unreadableFiles, us::ModuleContext* context) { FileReaderRegistry readerRegistry; std::vector< mitk::BaseData::Pointer > result; for (std::vector::const_iterator iterator = paths.begin(), end = paths.end(); iterator != end; ++iterator) { try { std::string extension = itksys::SystemTools::GetFilenameExtension(*iterator); - extension = extension.substr(1, extension.size()-1); + if (!extension.empty()) + { + extension = extension.substr(1, extension.size()-1); + } mitk::IFileReader* reader = readerRegistry.GetReader(extension, context); // Throw exception if no compatible reader was found if (reader == NULL) throw; std::vector baseDataList = reader->Read( *iterator ); result.insert(result.end(), baseDataList.begin(), baseDataList.end()); } catch (...) { if (unreadableFiles) unreadableFiles->push_back( *iterator ); } } return result; } //////////////////// GETTING READERS //////////////////// mitk::FileReaderRegistry::ReaderReference mitk::FileReaderRegistry::GetReaderReference(const std::string& mimeType, us::ModuleContext* context) { std::vector refs = GetReaderReferences(mimeType, context); if (refs.empty()) return ReaderReference(); std::sort(refs.begin(), refs.end()); return refs.back(); } std::vector mitk::FileReaderRegistry::GetReaderReferences(const std::string& mimeType, us::ModuleContext* context) { std::string filter = us::LDAPProp(us::ServiceConstants::OBJECTCLASS()) == us_service_interface_iid() && us::LDAPProp(IFileReader::PROP_MIMETYPE()) == mimeType; return context->GetServiceReferences(filter); } mitk::IFileReader* mitk::FileReaderRegistry::GetReader(const mitk::FileReaderRegistry::ReaderReference& ref, us::ModuleContext* context) { us::ServiceObjects serviceObjects = context->GetServiceObjects(ref); mitk::IFileReader* reader = serviceObjects.GetService(); m_ServiceObjects.insert(std::make_pair(reader, serviceObjects)); return reader; } mitk::IFileReader* mitk::FileReaderRegistry::GetReader(const std::string& extension, us::ModuleContext* context ) { std::vector results = GetReaders(extension, context); if (results.empty()) return NULL; return results.front(); } std::vector mitk::FileReaderRegistry::GetReaders(const std::string& extension, us::ModuleContext* context ) { std::vector result; const std::vector > refs = GetReaderList(extension, context); result.reserve(refs.size()); // Translate List of ServiceRefs to List of Pointers for (std::vector >::const_iterator iter = refs.begin(), end = refs.end(); iter != end; ++iter) { us::ServiceObjects serviceObjects = context->GetServiceObjects(*iter); mitk::IFileReader* reader = serviceObjects.GetService(); m_ServiceObjects.insert(std::make_pair(reader, serviceObjects)); result.push_back(reader); } return result; } mitk::IFileReader* mitk::FileReaderRegistry::GetReader( const std::string& extension, const mitk::IFileReader::OptionNames& options, us::ModuleContext* context ) { std::vector matching = mitk::FileReaderRegistry::GetReaders(extension, options, context); if (matching.empty()) return NULL; return matching.front(); } std::vector mitk::FileReaderRegistry::GetReaders( const std::string& extension, const mitk::IFileReader::OptionNames& options, us::ModuleContext* context ) { const std::vector allReaders = mitk::FileReaderRegistry::GetReaders(extension, context); std::vector result; result.reserve(allReaders.size()); // the list is already sorted by priority. Now find reader that supports all options for (std::vector ::const_iterator iter = allReaders.begin(), end = allReaders.end(); iter != end; ++iter) { mitk::IFileReader * currentReader = *iter; // Now see if this reader supports all options. If yes, push to results if ( mitk::FileReaderRegistry::ReaderSupportsOptions(currentReader, options) ) { result.push_back(currentReader); } } return result; } void mitk::FileReaderRegistry::UngetReader(mitk::IFileReader* reader) { std::map >::iterator readerIter = m_ServiceObjects.find(reader); if (readerIter != m_ServiceObjects.end()) { readerIter->second.UngetService(reader); m_ServiceObjects.erase(readerIter); } } void mitk::FileReaderRegistry::UngetReaders(const std::vector& readers) { for (std::vector::const_iterator iter = readers.begin(), end = readers.end(); iter != end; ++iter) { this->UngetReader(*iter); } } //////////////////// INTERNAL CODE //////////////////// bool mitk::FileReaderRegistry::ReaderSupportsOptions(mitk::IFileReader* reader, const mitk::IFileReader::OptionNames& options ) { const mitk::IFileReader::OptionList readerOptions = reader->GetOptions(); if (options.empty()) return true; // if no options were requested, return true unconditionally if (readerOptions.empty()) return false; // if options were requested and reader supports no options, return false // For each of the strings in requested options, check if option is available in reader for(mitk::IFileReader::OptionNames::const_iterator options_i = options.begin(), i_end = options.end(); options_i != i_end; ++options_i) { { bool optionFound = false; // Iterate over each available option from reader to check if one of them matches the current option for(mitk::IFileReader::OptionList::const_iterator options_j = readerOptions.begin(), j_end = readerOptions.end(); options_j != j_end; ++options_j) { if ( *options_i == options_j->first ) optionFound = true; } if (optionFound == false) return false; // If one option was not found, leave method and return false } } return true; // if all options have been found, return true } //////////////////// uS-INTERACTION //////////////////// std::vector< us::ServiceReference > mitk::FileReaderRegistry::GetReaderList(const std::string& extension, us::ModuleContext* context ) { std::vector > result; // filter for mime type std::string filter; - if (!extension.empty()) + mitk::IMimeTypeProvider* mimeTypeProvider = mitk::CoreServices::GetMimeTypeProvider(context); + std::vector mimeTypes = mimeTypeProvider->GetMimeTypesForExtension(extension); + if (mimeTypes.empty()) { - mitk::IMimeTypeProvider* mimeTypeProvider = mitk::CoreServices::GetMimeTypeProvider(context); - std::vector mimeTypes = mimeTypeProvider->GetMimeTypesForExtension(extension); - if (mimeTypes.empty()) - { - MITK_WARN << "No mime-type information for extension " << extension << " available."; - return result; - } - filter = us::LDAPProp(mitk::IFileReader::PROP_MIMETYPE()) == mimeTypes.front(); + MITK_WARN << "No mime-type information for extension " << extension << " available."; + return result; } + filter = us::LDAPProp(mitk::IFileReader::PROP_MIMETYPE()) == mimeTypes.front(); result = context->GetServiceReferences(filter); std::sort(result.begin(), result.end()); std::reverse(result.begin(), result.end()); return result; } diff --git a/Core/Code/IO/mitkFileWriterRegistry.cpp b/Core/Code/IO/mitkFileWriterRegistry.cpp index 7d2981936d..d91c3974fc 100644 --- a/Core/Code/IO/mitkFileWriterRegistry.cpp +++ b/Core/Code/IO/mitkFileWriterRegistry.cpp @@ -1,209 +1,212 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkFileWriterRegistry.h" // MITK #include // ITK #include // Microservices #include #include #include #include mitk::FileWriterRegistry::FileWriterRegistry() { } mitk::FileWriterRegistry::~FileWriterRegistry() { for (std::map >::iterator iter = m_ServiceObjects.begin(), end = m_ServiceObjects.end(); iter != end; ++iter) { iter->second.UngetService(iter->first); } } //////////////////// WRITING DIRECTLY //////////////////// void mitk::FileWriterRegistry::Write(const mitk::BaseData* data, const std::string& path, us::ModuleContext* context) { // Find extension std::string extension = itksys::SystemTools::GetFilenameExtension(path); - extension = extension.substr(1, extension.size()-1); + if (!extension.empty()) + { + extension = extension.substr(1, extension.size()-1); + } // Get best Writer FileWriterRegistry writerRegistry; mitk::IFileWriter* writer = writerRegistry.GetWriter(data, extension, mitk::IFileWriter::OptionNames(), context); // Throw exception if no compatible Writer was found if (writer == NULL) { mitkThrow() << "Tried to directly write a file of type '" << data->GetNameOfClass() << "' and extension '" << extension - << "' via FileWriterRegistry, but no writer supporting this filetype was found."; + << "' via FileWriterRegistry, but no writer supporting this file type was found."; } writer->Write(data, path); } void mitk::FileWriterRegistry::Write(const mitk::BaseData* data, std::ostream& os, us::ModuleContext* context) { // Get best Writer FileWriterRegistry writerRegistry; mitk::IFileWriter* writer = writerRegistry.GetWriter(data, std::string(), mitk::IFileWriter::OptionNames(), context); // Throw exception if no compatible Writer was found if (writer == NULL) { mitkThrow() << "Tried to directly write a file of type '" << data->GetNameOfClass() << "' to a std::ostream via FileWriterRegistry, but no writer supporting this BaseData type was found."; } writer->Write(data, os); } //////////////////// GETTING WRITERS //////////////////// mitk::IFileWriter* mitk::FileWriterRegistry::GetWriter( const mitk::BaseData* baseData, const std::string& extension, const mitk::IFileWriter::OptionNames& options, us::ModuleContext* context) { return GetWriter(baseData->GetNameOfClass(), extension, options, context); } mitk::IFileWriter* mitk::FileWriterRegistry::GetWriter( const std::string& baseDataType, const std::string& extension, const mitk::IFileWriter::OptionNames& options, us::ModuleContext* context) { std::vector results = GetWriters(baseDataType, extension, options, context); if (results.empty()) return NULL; return results.front(); } std::vector mitk::FileWriterRegistry::GetWriters( const mitk::BaseData* baseData, const std::string& extension, const mitk::IFileWriter::OptionNames& options, us::ModuleContext* context) { return GetWriters(baseData->GetNameOfClass(), extension, options, context); } std::vector mitk::FileWriterRegistry::GetWriters( const std::string& baseDataType, const std::string& extension, const mitk::IFileWriter::OptionNames& options, us::ModuleContext* context) { // filter for class and extension std::string filter = us::LDAPProp(mitk::IFileWriter::PROP_BASEDATA_TYPE()) == baseDataType && us::LDAPProp(mitk::IFileWriter::PROP_EXTENSION()) == extension; std::vector > refs = context->GetServiceReferences(filter); std::sort(refs.begin(), refs.end()); std::reverse(refs.begin(), refs.end()); std::vector result; result.reserve(refs.size()); // Translate List of ServiceRefs to List of Pointers for (std::vector >::const_iterator iter = refs.begin(), end = refs.end(); iter != end; ++iter) { us::ServiceObjects serviceObjects = context->GetServiceObjects(*iter); mitk::IFileWriter* writer = serviceObjects.GetService(); // Now see if this Writer supports all options. If yes, push to results if (mitk::FileWriterRegistry::WriterSupportsOptions(writer, options)) { m_ServiceObjects.insert(std::make_pair(writer, serviceObjects)); result.push_back(writer); } } return result; } //////////////////// GENERIC INFORMATION //////////////////// std::string mitk::FileWriterRegistry::GetSupportedExtensions(const std::string& extension, us::ModuleContext* context) { std::string filter = us::LDAPProp(mitk::IFileWriter::PROP_EXTENSION()) == extension; const std::vector > refs = context->GetServiceReferences(filter); return CreateFileDialogString(refs); } std::string mitk::FileWriterRegistry::GetSupportedWriters(const std::string& baseDataType, us::ModuleContext* context) { std::string filter = us::LDAPProp(mitk::IFileWriter::PROP_BASEDATA_TYPE()) == baseDataType; const std::vector > refs = context->GetServiceReferences(filter); return CreateFileDialogString(refs); } //////////////////// INTERNAL CODE //////////////////// bool mitk::FileWriterRegistry::WriterSupportsOptions(mitk::IFileWriter* writer, const mitk::IFileWriter::OptionNames& options ) { const mitk::IFileWriter::OptionList writerOptions = writer->GetOptions(); if (options.empty()) return true; // if no options were requested, return true unconditionally if (writerOptions.empty()) return false; // if options were requested and reader supports no options, return false // For each of the strings in requested options, check if option is available in reader for(mitk::IFileWriter::OptionNames::const_iterator options_i = options.begin(), i_end = options.end(); options_i != i_end; ++options_i) { { bool optionFound = false; // Iterate over each available option from reader to check if one of them matches the current option for(mitk::IFileWriter::OptionList::const_iterator options_j = writerOptions.begin(), j_end = writerOptions.end(); options_j != j_end; ++options_j) { if ( *options_i == options_j->first ) optionFound = true; } if (optionFound == false) return false; // If one option was not found, leave method and return false } } return true; // if all options have been found, return true } std::string mitk::FileWriterRegistry::CreateFileDialogString(const std::vector >& refs) { std::vector entries; // Will contain Description + Extension (Human readable) entries.reserve(refs.size()); std::string knownExtensions; // Will contain plain list of all known extensions (for the QFileDialog entry "All Known Extensions") for (std::vector >::const_iterator iterator = refs.begin(), end = refs.end(); iterator != end; ++iterator) { // Generate List of Extensions if (iterator == refs.begin()) // First entry without semicolon knownExtensions += "*" + iterator->GetProperty(mitk::IFileWriter::PROP_EXTENSION()).ToString(); else // Ad semicolon for each following entry knownExtensions += "; *" + iterator->GetProperty(mitk::IFileWriter::PROP_EXTENSION()).ToString(); // Generate List of human readable entries composed of Description + Extension std::string entry = iterator->GetProperty(mitk::IFileWriter::PROP_DESCRIPTION()).ToString() + "(*" + iterator->GetProperty(mitk::IFileWriter::PROP_EXTENSION()).ToString() + ");;"; entries.push_back(entry); } std::sort(entries.begin(), entries.end()); std::string result = "Known Extensions (" + knownExtensions + ");;All (*)"; for (std::vector::const_iterator iterator = entries.begin(), end = entries.end(); iterator != end; ++iterator) { result += ";;" + *iterator; } return result; } diff --git a/Core/Code/IO/mitkMimeTypeProvider.cpp b/Core/Code/IO/mitkMimeTypeProvider.cpp index 869e42536b..d535c1091d 100644 --- a/Core/Code/IO/mitkMimeTypeProvider.cpp +++ b/Core/Code/IO/mitkMimeTypeProvider.cpp @@ -1,196 +1,199 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkMimeTypeProvider.h" #include #include #include #ifdef _MSC_VER #pragma warning(disable:4503) // decorated name length exceeded, name was truncated #pragma warning(disable:4355) #endif namespace mitk { MimeTypeProvider::MimeTypeProvider() : m_Tracker(NULL) { } void MimeTypeProvider::Start() { if (m_Tracker == NULL) { m_Tracker = new us::ServiceTracker(us::GetModuleContext(), this); } m_Tracker->Open(); } void MimeTypeProvider::Stop() { m_Tracker->Close(); } std::vector MimeTypeProvider::GetMimeTypes() const { std::vector result; for (MapType::const_iterator iter = m_MimeTypeToRefs.begin(), end = m_MimeTypeToRefs.end(); iter != end; ++iter) { result.push_back(iter->first); } return result; } std::vector MimeTypeProvider::GetMimeTypesForFile(const std::string& filePath) const { // For now, just use the file extension to look-up the registered mime-types. std::string extension = itksys::SystemTools::GetFilenameExtension(filePath); - extension = extension.substr(1, extension.size()-1); + if (!extension.empty()) + { + extension = extension.substr(1, extension.size()-1); + } return this->GetMimeTypesForExtension(extension); } std::vector MimeTypeProvider::GetMimeTypesForExtension(const std::string& extension) const { std::vector result; std::vector > mimeTypeRefs; for (MapType::const_iterator iter = m_MimeTypeToRefs.begin(), end = m_MimeTypeToRefs.end(); iter != end; ++iter) { us::Any any = iter->second.rbegin()->GetProperty(IMimeType::PROP_EXTENSIONS()); if (!any.Empty() && any.Type() == typeid(std::vector)) { const std::vector& extensions = us::ref_any_cast >(any); if (std::find(extensions.begin(), extensions.end(), extension) != extensions.end()) { mimeTypeRefs.push_back(*(iter->second.rbegin())); } } } std::sort(mimeTypeRefs.begin(), mimeTypeRefs.end()); for (std::vector >::reverse_iterator iter = mimeTypeRefs.rbegin(); iter != mimeTypeRefs.rend(); ++iter) { result.push_back(us::ref_any_cast(iter->GetProperty(IMimeType::PROP_ID()))); } return result; } std::vector MimeTypeProvider::GetMimeTypesForCategory(const std::string& category) const { std::vector result; for (MapType::const_iterator iter = m_MimeTypeToRefs.begin(), end = m_MimeTypeToRefs.end(); iter != end; ++iter) { us::Any cat = iter->second.rbegin()->GetProperty(IMimeType::PROP_CATEGORY()); if (!cat.Empty() && cat.Type() == typeid(std::string) && us::ref_any_cast(cat) == category) { result.push_back(iter->first); } } return result; } std::string MimeTypeProvider::GetDescription(const std::string& mimeType) const { MapType::const_iterator iter = m_MimeTypeToRefs.find(mimeType); if (iter == m_MimeTypeToRefs.end()) return std::string(); us::Any description = iter->second.rbegin()->GetProperty(IMimeType::PROP_DESCRIPTION()); if (!description.Empty() && description.Type() == typeid(std::string)) { return us::ref_any_cast(description); } return std::string(); } std::vector MimeTypeProvider::GetExtensions(const std::string& mimeType) const { MapType::const_iterator iter = m_MimeTypeToRefs.find(mimeType); if (iter == m_MimeTypeToRefs.end()) return std::vector(); us::Any extensions = iter->second.rbegin()->GetProperty(IMimeType::PROP_EXTENSIONS()); if (!extensions.Empty() && extensions.Type() == typeid(std::vector)) { return us::ref_any_cast >(extensions); } return std::vector(); } std::string MimeTypeProvider::GetCategory(const std::string& mimeType) const { MapType::const_iterator iter = m_MimeTypeToRefs.find(mimeType); if (iter == m_MimeTypeToRefs.end()) return std::string(); us::Any category = iter->second.rbegin()->GetProperty(IMimeType::PROP_CATEGORY()); if (!category.Empty() && category.Type() == typeid(std::string)) { return us::ref_any_cast(category); } return std::string(); } std::vector MimeTypeProvider::GetCategories() const { std::vector result; for (MapType::const_iterator iter = m_MimeTypeToRefs.begin(), end = m_MimeTypeToRefs.end(); iter != end; ++iter) { us::Any category = iter->second.rbegin()->GetProperty(IMimeType::PROP_CATEGORY()); if (!category.Empty() && category.Type() == typeid(std::string)) { std::string s = us::ref_any_cast(category); if (!s.empty()) { result.push_back(s); } } } result.erase(std::unique(result.begin(), result.end()), result.end()); return result; } us::ServiceReference MimeTypeProvider::AddingService(const ServiceReferenceType& reference) { us::Any id = reference.GetProperty(IMimeType::PROP_ID()); if (!id.Empty() && id.Type() == typeid(std::string)) { m_MimeTypeToRefs[us::ref_any_cast(id)].insert(reference); return reference; } return ServiceReferenceType(); } void MimeTypeProvider::ModifiedService(const ServiceReferenceType& /*reference*/, ServiceReferenceType /*service*/) { } void MimeTypeProvider::RemovedService(const ServiceReferenceType& /*reference*/, ServiceReferenceType service) { std::string id = us::ref_any_cast(service.GetProperty(IMimeType::PROP_ID())); std::set& refs = m_MimeTypeToRefs[id]; refs.erase(service); if (refs.empty()) { m_MimeTypeToRefs.erase(id); } } } diff --git a/Core/Code/Testing/mitkFileReaderRegistryTest.cpp b/Core/Code/Testing/mitkFileReaderRegistryTest.cpp index ed78dd21b5..d324d86d4e 100644 --- a/Core/Code/Testing/mitkFileReaderRegistryTest.cpp +++ b/Core/Code/Testing/mitkFileReaderRegistryTest.cpp @@ -1,208 +1,208 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkTestingMacros.h" #include "mitkAbstractFileReader.h" #include "mitkIFileReader.h" #include "mitkFileReaderRegistry.h" #include #include class DummyReader : public mitk::AbstractFileReader { public: DummyReader(const DummyReader& other) : mitk::AbstractFileReader(other) { } - DummyReader(const std::string& extension, int priority) - : mitk::AbstractFileReader("application/dummy", extension, "This is a dummy description") + DummyReader(const std::string& mimeType, const std::string& extension, int priority) + : mitk::AbstractFileReader(mimeType, extension, "This is a dummy description") { this->SetPriority(priority); m_ServiceReg = this->RegisterService(); } ~DummyReader() { if (m_ServiceReg) m_ServiceReg.Unregister(); } using mitk::AbstractFileReader::Read; virtual std::vector< itk::SmartPointer > Read(std::istream& /*stream*/) { std::vector result; return result; } private: DummyReader* Clone() const { return new DummyReader(*this); } us::ServiceRegistration m_ServiceReg; }; // End of internal dummy reader class DummyReader2 : public mitk::AbstractFileReader { public: DummyReader2(const DummyReader2& other) : mitk::AbstractFileReader(other) { } - DummyReader2(const std::string& extension, int priority) - : mitk::AbstractFileReader("application/dummy", extension, "This is a second dummy description") + DummyReader2(const std::string& mimeType, const std::string& extension, int priority) + : mitk::AbstractFileReader(mimeType, extension, "This is a second dummy description") { this->SetPriority(priority); m_ServiceReg = this->RegisterService(); } ~DummyReader2() { if (m_ServiceReg) m_ServiceReg.Unregister(); } using mitk::AbstractFileReader::Read; virtual std::vector< itk::SmartPointer > Read(std::istream& /*stream*/) { std::vector result; return result; } private: DummyReader2* Clone() const { return new DummyReader2(*this); } us::ServiceRegistration m_ServiceReg; }; // End of internal dummy reader 2 /** * TODO */ int mitkFileReaderRegistryTest(int /*argc*/ , char* /*argv*/[]) { // always start with this! MITK_TEST_BEGIN("FileReaderRegistry"); // mitk::FileReaderRegistry::Pointer frm = mitk::FileReaderRegistry::New(); // MITK_TEST_CONDITION_REQUIRED(argc == 2,"Testing FileReaderRegistry instantiation"); - DummyReader testDR("test",1); - DummyReader otherDR("other",1); + DummyReader testDR("application/dummy", "test",1); + DummyReader otherDR("application/dummy2", "other",1); MITK_TEST_CONDITION_REQUIRED(!testDR.CanRead("/this/is/a/folder/file.tes"),"Negative test of default CanRead() implementation"); mitk::FileReaderRegistry* readerRegistry = new mitk::FileReaderRegistry; mitk::IFileReader* returned = readerRegistry->GetReader("test"); MITK_TEST_CONDITION_REQUIRED(returned && &static_cast(testDR) != returned,"Testing correct retrieval of FileReader 1/2"); returned = readerRegistry->GetReader("other"); MITK_TEST_CONDITION_REQUIRED(returned && &static_cast(otherDR) != returned,"Testing correct retrieval of FileReader 2/2"); - DummyReader mediocreTestDR("test", 20); - DummyReader prettyFlyTestDR("test", 50); - DummyReader2 awesomeTestDR("test", 100); + DummyReader mediocreTestDR("application/dummy", "test", 20); + DummyReader prettyFlyTestDR("application/dummy", "test", 50); + DummyReader2 awesomeTestDR("application/dummy", "test", 100); returned = readerRegistry->GetReader("test"); MITK_TEST_CONDITION_REQUIRED(dynamic_cast(returned), "Testing correct priorized retrieval of FileReader: Best reader"); // Now to give those readers some options, then we will try again mitk::IFileReader::OptionList options; options.push_back(std::make_pair("isANiceGuy", true)); mediocreTestDR.SetOptions(options); options.clear(); options.push_back(std::make_pair("canFly", true)); prettyFlyTestDR.SetOptions(options); options.push_back(std::make_pair("isAwesome", true)); awesomeTestDR.SetOptions(options); //note: awesomeReader canFly and isAwesome // Reset Options, use to define what we want the reader to do options.clear(); mitk::IFileReader::OptionNames optionsFilter; optionsFilter.push_back("canFly"); returned = readerRegistry->GetReader("test", optionsFilter); MITK_TEST_CONDITION_REQUIRED(returned && &static_cast(awesomeTestDR) != returned, "Testing correct retrieval of FileReader with Options: Best reader with options"); optionsFilter.push_back("isAwesome"); returned = readerRegistry->GetReader("test", optionsFilter); MITK_TEST_CONDITION_REQUIRED(returned && &static_cast(awesomeTestDR) != returned, "Testing correct retrieval of FileReader with multiple Options: Best reader with options"); optionsFilter.clear(); optionsFilter.push_back("isANiceGuy"); returned = readerRegistry->GetReader("test", optionsFilter); MITK_TEST_CONDITION_REQUIRED(returned && &static_cast(mediocreTestDR) != returned, "Testing correct retrieval of specific FileReader with Options: Low priority reader with specific option"); optionsFilter.push_back("canFly"); returned = readerRegistry->GetReader("test", optionsFilter); MITK_TEST_CONDITION_REQUIRED(returned == NULL, "Testing correct return of 0 value when no matching reader was found"); // Onward to test the retrieval of multiple readers std::vector< mitk::IFileReader* > returnedList; returnedList = readerRegistry->GetReaders("test", optionsFilter); MITK_TEST_CONDITION_REQUIRED(returnedList.empty(), "Testing correct return of zero readers when no matching reader was found, asking for all compatibles"); optionsFilter.clear(); optionsFilter.push_back("canFly"); returnedList = readerRegistry->GetReaders("test", optionsFilter); MITK_TEST_CONDITION_REQUIRED(returnedList.size() == 2, "Testing correct return of two readers when two matching reader was found, asking for all compatibles"); MITK_TEST_CONDITION_REQUIRED(dynamic_cast(returnedList.front()), "Testing correct priorization of returned Readers with options 1/2"); optionsFilter.clear(); optionsFilter.push_back("isAwesome"); returnedList = readerRegistry->GetReaders("test", optionsFilter); MITK_TEST_CONDITION_REQUIRED(returnedList.size() == 1, "Testing correct return of one readers when one matching reader was found, asking for all compatibles"); MITK_TEST_CONDITION_REQUIRED(dynamic_cast(returnedList.front()), "Testing correctness of result from former query"); // And now to verify a working read chain for a mps file: //mitk::PointSetReader::Pointer psr = mitk::PointSetReader::New(); //std::vector basedata; //basedata = mitk::FileReaderRegistry::Read("F://Build//MITK-Data//pointSet.mps"); //MITK_TEST_CONDITION_REQUIRED(basedata.size() > 0, "Testing correct read of PointSet"); // Testing templated call to ReaderRegistry //mitk::PointSet::Pointer pointset = mitk::FileReaderRegistry::Read< mitk::PointSet >("F://Build//MITK-Data//pointSet.mps"); //MITK_TEST_CONDITION_REQUIRED(pointset.IsNotNull(), "Testing templated call of Read()"); // And now for something completely different... (Debug) // mitk::LegacyFileReaderService::Pointer lfr = mitk::LegacyFileReaderService::New(".nrrd", "Nearly Raw Raster Data"); //returned = mitk::FileReaderRegistry::GetReader(".nrrd"); //MITK_TEST_CONDITION_REQUIRED(lfr == returned, "Testing correct retrieval of specific FileReader with Options: Low priority reader with specific option"); //std::vector image = mitk::FileReaderRegistry::Read("F://Build//MITK-Data//Pic2DplusT.nrrd"); //MITK_TEST_CONDITION_REQUIRED(image.size() > 0, "Testing whether image was returned or not"); //mitk::Image::Pointer image2 = dynamic_cast (image.front().GetPointer()); //MITK_TEST_CONDITION_REQUIRED(image2.IsNotNull(), "Testing if BaseData is an image"); // Delete this here because it will call the PrototypeServiceFactory::Unget() method // of the dummy readers. delete readerRegistry; // always end with this! MITK_TEST_END(); } diff --git a/Core/Code/Testing/mitkFileWriterRegistryTest.cpp b/Core/Code/Testing/mitkFileWriterRegistryTest.cpp index 2eff6b00fa..588e3c8797 100644 --- a/Core/Code/Testing/mitkFileWriterRegistryTest.cpp +++ b/Core/Code/Testing/mitkFileWriterRegistryTest.cpp @@ -1,307 +1,303 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include #include #include #include #include #include #include class DummyBaseData : public mitk::BaseData { public: mitkClassMacro(DummyBaseData, mitk::BaseData) itkNewMacro(Self) void SetRequestedRegion(const itk::DataObject * /*data*/) {} void SetRequestedRegionToLargestPossibleRegion() {} bool RequestedRegionIsOutsideOfTheBufferedRegion() { return false; } bool VerifyRequestedRegion() { return true; } }; class DummyWriter : public mitk::AbstractFileWriter { public: DummyWriter(const DummyWriter& other) : mitk::AbstractFileWriter(other) , m_Content("Hi there stream") { } DummyWriter(const std::string& basedataType, const std::string& extension, int priority) : mitk::AbstractFileWriter(basedataType, extension, "This is a dummy description") , m_Content("Hi there stream") { m_Priority = priority; m_ServiceReg = this->RegisterService(); } ~DummyWriter() { if (m_ServiceReg) m_ServiceReg.Unregister(); } using AbstractFileWriter::Write; virtual void Write(const mitk::BaseData* data, std::ostream& stream) { MITK_TEST_CONDITION_REQUIRED(dynamic_cast(data), "Correct data type") stream << m_Content; } std::string m_Content; private: DummyWriter* Clone() const { return new DummyWriter(*this); } us::ServiceRegistration m_ServiceReg; }; // End of internal dummy Writer class DummyWriter2 : public mitk::AbstractFileWriter { public: DummyWriter2(const DummyWriter2& other) : mitk::AbstractFileWriter(other) , m_Content("hi there file path") { } DummyWriter2(const std::string& basedataType, const std::string& extension, int priority) : mitk::AbstractFileWriter(basedataType, extension, "This is a dummy description") , m_Content("hi there file path") { m_Priority = priority; m_ServiceReg = this->RegisterService(); } ~DummyWriter2() { if (m_ServiceReg) m_ServiceReg.Unregister(); } using AbstractFileWriter::Write; virtual void Write(const mitk::BaseData* data, const std::string& filePath ) { MITK_TEST_CONDITION_REQUIRED(dynamic_cast(data), "Correct data type") std::ofstream fileStream(filePath.c_str()); fileStream << m_Content; } virtual void Write(const mitk::BaseData* data, std::ostream& stream ) { mitk::AbstractFileWriter::Write(data, stream); } virtual bool CanWrite(const mitk::BaseData *data) const { return dynamic_cast(data); } std::string m_Content; private: DummyWriter2* Clone() const { return new DummyWriter2(*this); } us::ServiceRegistration m_ServiceReg; }; // End of internal dummy Writer 2 void TestStreamMethods() { - DummyWriter dummyWriter(DummyBaseData::GetStaticNameOfClass(), ".stream", 100); - DummyWriter2 dummyWriter2(DummyBaseData::GetStaticNameOfClass(), ".file", 50); + DummyWriter dummyWriter(DummyBaseData::GetStaticNameOfClass(), "stream", 100); + DummyWriter2 dummyWriter2(DummyBaseData::GetStaticNameOfClass(), "file", 50); mitk::FileWriterRegistry writerRegistry; // Test DummyWriter, which always uses a ostream for writing, even // when a file path is used DummyBaseData dummyData; std::stringstream oss; writerRegistry.Write(&dummyData, oss); MITK_TEST_CONDITION_REQUIRED(dummyWriter.m_Content == oss.str(), "Dummy stream writer") std::string content; { std::ofstream tmpStream; std::string tmpFileName = mitk::IOUtil::CreateTemporaryFile(tmpStream); writerRegistry.Write(&dummyData, tmpFileName); std::ifstream tmpInput(tmpFileName.c_str()); std::getline(tmpInput, content); tmpInput.close(); tmpStream.close(); std::remove(tmpFileName.c_str()); } MITK_TEST_CONDITION_REQUIRED(dummyWriter.m_Content == content, "Dummy stream writer") // Test DummyWriter2, which always uses a real file for writing, even // when a std::ostream object is given std::stringstream oss2; dummyWriter2.Write(&dummyData, oss2); MITK_TEST_CONDITION_REQUIRED(dummyWriter2.m_Content == oss2.str(), "Dummy 2 stream writer") std::string content2; { std::ofstream tmpStream; - std::string tmpFileName = mitk::IOUtil::CreateTemporaryFile(tmpStream); - tmpStream.close(); - std::remove(tmpFileName.c_str()); - - // This is a work-around to get a temporary file name ending with ".file" - tmpFileName += ".file"; + std::string tmpFileName = mitk::IOUtil::CreateTemporaryFile(tmpStream, "XXXXXX.file"); writerRegistry.Write(&dummyData, tmpFileName); std::ifstream tmpInput(tmpFileName.c_str()); std::getline(tmpInput, content2); tmpInput.close(); std::remove(tmpFileName.c_str()); } MITK_TEST_CONDITION_REQUIRED(dummyWriter2.m_Content == content2, "Dummy 2 stream writer") } /** * TODO */ int mitkFileWriterRegistryTest(int argc , char* argv[]) { // always start with this! - MITK_TEST_BEGIN("FileWriterRegistry"); + //MITK_TEST_BEGIN("FileWriterRegistry"); TestStreamMethods(); // mitk::FileWriterRegistry::Pointer frm = mitk::FileWriterRegistry::New(); // MITK_TEST_CONDITION_REQUIRED(argc == 2,"Testing FileWriterRegistry instantiation"); DummyWriter testDR("testdata", "test", 1); DummyWriter otherDR("testdata", "other", 1); // MITK_TEST_CONDITION_REQUIRED(testDR->CanWrite("/this/is/a/folder/file.test"),"Positive test of default CanRead() implementation"); // MITK_TEST_CONDITION_REQUIRED(!testDR->CanWrite("/this/is/a/folder/file.tes"),"Negative test of default CanRead() implementation"); mitk::FileWriterRegistry* writerRegistry = new mitk::FileWriterRegistry; mitk::IFileWriter* returned = writerRegistry->GetWriter("", "test"); MITK_TEST_CONDITION_REQUIRED(returned && &static_cast(testDR) != returned,"Testing correct retrieval of FileWriter 1/2"); returned = writerRegistry->GetWriter("", "other"); MITK_TEST_CONDITION_REQUIRED(returned && &static_cast(otherDR) != returned,"Testing correct retrieval of FileWriter 2/2"); DummyWriter mediocreTestDR("testdata", "test", 20); DummyWriter prettyFlyTestDR("testdata", "test", 50); DummyWriter2 awesomeTestDR("testdata", "test", 100); returned = writerRegistry->GetWriter("test"); MITK_TEST_CONDITION_REQUIRED(dynamic_cast(&awesomeTestDR), "Testing correct priorized retrieval of FileWriter: Best Writer"); // Now to give those Writers some options, then we will try again mitk::IFileWriter::OptionList options; options.push_back(std::make_pair("isANiceGuy", true)); mediocreTestDR.SetOptions(options); options.clear(); options.push_back(std::make_pair("canFly", true)); prettyFlyTestDR.SetOptions(options); options.push_back(std::make_pair("isAwesome", true)); awesomeTestDR.SetOptions(options); //note: awesomeWriter canFly and isAwesome // Reset Options, use to define what we want the Writer to do mitk::IFileWriter::OptionNames optionFilter; optionFilter.push_back("canFly"); returned = writerRegistry->GetWriter("", "test", optionFilter); MITK_TEST_CONDITION_REQUIRED(returned && &static_cast(awesomeTestDR) != returned, "Testing correct retrieval of FileWriter with Options: Best Writer with options"); optionFilter.push_back("isAwesome"); returned = writerRegistry->GetWriter("", "test", optionFilter); MITK_TEST_CONDITION_REQUIRED(returned && &static_cast(awesomeTestDR) != returned, "Testing correct retrieval of FileWriter with multiple Options: Best Writer with options"); optionFilter.clear(); optionFilter.push_back("isANiceGuy"); returned = writerRegistry->GetWriter("", "test", optionFilter); MITK_TEST_CONDITION_REQUIRED(returned && &static_cast(mediocreTestDR) != returned, "Testing correct retrieval of specific FileWriter with Options: Low priority Writer with specific option"); optionFilter.push_back("canFly"); returned = writerRegistry->GetWriter("", "test", optionFilter); MITK_TEST_CONDITION_REQUIRED(returned == NULL, "Testing correct return of 0 value when no matching Writer was found"); // Onward to test the retrieval of multiple Writers std::vector< mitk::IFileWriter* > returnedList; returnedList = writerRegistry->GetWriters("", "test", optionFilter); MITK_TEST_CONDITION_REQUIRED(returnedList.empty(), "Testing correct return of zero Writers when no matching Writer was found, asking for all compatibles"); optionFilter.clear(); optionFilter.push_back("canFly"); returnedList = writerRegistry->GetWriters("", "test", optionFilter); MITK_TEST_CONDITION_REQUIRED(returnedList.size() == 2, "Testing correct return of two Writers when two matching Writer was found, asking for all compatibles"); MITK_TEST_CONDITION_REQUIRED(dynamic_cast(returnedList.front()), "Testing correct priorization of returned Writers with options 1/2"); optionFilter.clear(); optionFilter.push_back("isAwesome"); returnedList = writerRegistry->GetWriters("", "test", optionFilter); MITK_TEST_CONDITION_REQUIRED(returnedList.size() == 1, "Testing correct return of one Writers when one matching Writer was found, asking for all compatibles"); MITK_TEST_CONDITION_REQUIRED(dynamic_cast(returnedList.front()), "Testing correctness of result from former query"); //mitk::CoreObjectFactory::GetInstance(); //mitk::FileReaderRegistry readerRegistry; //mitk::Image::Pointer image = readerRegistry.Read("F://Build//MITK-Data//Pic2DplusT.nrrd"); //writerRegistry->Write(image.GetPointer(), "F://Build//MITK-Data//Pic2DplusTcopy.nrrd"); //// And now to verify a working read chain for a mps file: //mitk::PointSetWriter::Pointer psr = mitk::PointSetWriter::New(); //mitk::BaseData::Pointer basedata; //basedata = mitk::FileWriterRegistry::Read("F://Build//MITK-Data//pointSet.mps"); //MITK_TEST_CONDITION_REQUIRED(basedata.IsNotNull(), "Testing correct read of PointSet"); //// Testing templated call to WriterRegistry //mitk::PointSet::Pointer pointset = mitk::FileWriterRegistry::Read< mitk::PointSet >("F://Build//MITK-Data//pointSet.mps"); //MITK_TEST_CONDITION_REQUIRED(pointset.IsNotNull(), "Testing templated call of Read()"); //// And now for something completely different... (Debug) //mitk::LegacyFileWriterService::Pointer lfr = mitk::LegacyFileWriterService::New(".nrrd", "Nearly Raw Raster Data"); //returned = mitk::FileWriterRegistry::GetWriter(".nrrd"); //MITK_TEST_CONDITION_REQUIRED(lfr == returned, "Testing correct retrieval of specific FileWriter with Options: Low priority Writer with specific option"); //mitk::BaseData::Pointer image = mitk::FileWriterRegistry::Read("F://Build//MITK-Data//Pic2DplusT.nrrd"); //MITK_TEST_CONDITION_REQUIRED(image.IsNotNull(), "Testing whether BaseData is empty or not"); //mitk::Image::Pointer image2 = dynamic_cast (image.GetPointer()); //MITK_TEST_CONDITION_REQUIRED(image2.IsNotNull(), "Testing if BaseData is an image"); // Delete this here because it will call the PrototypeServiceFactory::Unget() method // of the dummy writers. delete writerRegistry; //// always end with this! - MITK_TEST_END() + //MITK_TEST_END() + return 0; }