/*========================================================================= * * Copyright NumFOCUS * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * https://www.apache.org/licenses/LICENSE-2.0.txt * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *=========================================================================*/ #ifndef itkDOMReader_hxx #define itkDOMReader_hxx #include "itksys/SystemTools.hxx" #include "itkStdStreamLogOutput.h" namespace itk { template DOMReader::DOMReader() : m_Output(nullptr) { // Create the logger. this->m_Logger = LoggerType::New(); // by default logged messages go to the console auto defout = StdStreamLogOutput::New(); defout->SetStream(std::cout); this->m_Logger->AddLogOutput(defout); // settings that may be important this->m_Logger->SetName(this->GetNameOfClass()); this->m_Logger->SetPriorityLevel(Logger::PriorityLevelEnum::NOTSET); // log everything this->m_Logger->SetLevelForFlushing( Logger::PriorityLevelEnum::MUSTFLUSH); // never flush (MUSTFLUSH actually leads to no flush, a bug in Logger) // some other settings this->m_Logger->SetTimeStampFormat(Logger::TimeStampFormatEnum::HUMANREADABLE); this->m_Logger->SetHumanReadableFormat("%Y-%b-%d %H:%M:%S"); // time stamp format } /** * The output object will be created automatically, but the user * can appoint a user object as the output by calling this function. */ template void DOMReader::SetOutput(OutputType * output) { this->m_Output = output; this->m_OutputHolder = dynamic_cast(output); this->Modified(); } /** Get the output object for full access. */ template auto DOMReader::GetOutput() -> OutputType * { return this->m_Output; } /** Get the output object for read-only access. */ template auto DOMReader::GetOutput() const -> const OutputType * { return this->m_Output; } /** * Function called by Update() or end-users to generate the output object from a DOM object. * Some derived readers may accept an incomplete DOM object during the reading process, in those cases * the optional argument 'userdata' can be used to provide the missed information. */ template void DOMReader::Update(const DOMNodeType * inputdom, const void * userdata) { if (inputdom == nullptr) { itkExceptionMacro("read from an invalid DOM object"); } // group subsequent logging under this reader this->GetLogger()->SetName(this->GetNameOfClass()); // variable/info needed for logging FancyString info; FancyString tagname = inputdom->GetName(); // log start of reading info << ClearContent << "Reading \"" << tagname << "\" ...\n"; this->GetLogger()->Info(info); // perform actual reading this->GenerateData(inputdom, userdata); // log end of reading info << ClearContent << "Reading \"" << tagname << "\" done!\n"; this->GetLogger()->Info(info); if (this->GetOutput() == nullptr) { itkExceptionMacro("no valid output object was generated"); } } /** * Function called by end-users to generate the output object from the input XML file. */ template void DOMReader::Update() { // create the intermediate DOM object if it is not set if (this->m_IntermediateDOM.IsNull()) { DOMNodePointer node = DOMNodeType::New(); this->SetIntermediateDOM(node); } FancyString fn(this->m_FileName); // remove previous data from the DOM object this->m_IntermediateDOM->RemoveAllAttributesAndChildren(); // read the input XML file and update the DOM object auto reader = DOMNodeXMLReader::New(); reader->SetDOMNodeXML(this->m_IntermediateDOM); reader->SetFileName(fn.ToString()); reader->Update(); // save the current working directory (WD), and change the WD to where the XML file is located FancyString sOldWorkingDir = itksys::SystemTools::GetCurrentWorkingDirectory(); FancyString sNewWorkingDir = itksys::SystemTools::GetFilenamePath(fn); itksys::SystemTools::ChangeDirectory(sNewWorkingDir); this->Update(this->m_IntermediateDOM); // change the WD back to the previously saved itksys::SystemTools::ChangeDirectory(sOldWorkingDir); } } // namespace itk #endif // itkDOMReader_hxx