| /** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You 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 |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * 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. |
| */ |
| |
| #include "AgentDocs.h" |
| #include <vector> |
| #include <algorithm> |
| #include <iostream> |
| #include <iterator> |
| #include <fstream> |
| #include <set> |
| #include <memory> |
| #include <string> |
| #include "core/ClassLoader.h" |
| #include "core/ConfigurableComponent.h" |
| #include "core/Core.h" |
| #include "core/Processor.h" |
| #include "core/Property.h" |
| #include "core/PropertyValidation.h" |
| #include "core/Relationship.h" |
| #include "io/validation.h" |
| #include "utils/file/FileUtils.h" |
| #include "agent/build_description.h" |
| #include "agent/agent_version.h" |
| |
| namespace org { |
| namespace apache { |
| namespace nifi { |
| namespace minifi { |
| namespace docs { |
| |
| std::string AgentDocs::extractClassName(const std::string &processor) const { |
| auto lastOfIdx = processor.find_last_of("."); |
| if (lastOfIdx != std::string::npos) { |
| lastOfIdx++; // if a value is found, increment to move beyond the . |
| int nameLength = processor.length() - lastOfIdx; |
| std::string processorName = processor.substr(lastOfIdx, nameLength); |
| return processorName; |
| } |
| return processor; |
| |
| } |
| |
| void AgentDocs::generate(const std::string &docsdir, std::ostream &genStream) { |
| std::map<std::string, ClassDescription> processorSet; |
| for (const auto &group : minifi::AgentBuild::getExtensions()) { |
| |
| struct Components descriptions = BuildDescription::getClassDescriptions(group); |
| for (const auto &processorName : descriptions.processors_) { |
| processorSet.insert(std::make_pair(extractClassName(processorName.class_name_), processorName)); |
| } |
| } |
| for (const auto &processor : processorSet) { |
| const std::string &filename = docsdir + utils::file::FileUtils::get_separator() + processor.first; |
| std::ofstream outfile(filename); |
| |
| std::string description; |
| |
| bool foundDescription = minifi::AgentDocs::getDescription(processor.first, description); |
| |
| if (!foundDescription) { |
| foundDescription = minifi::AgentDocs::getDescription(processor.second.class_name_, description); |
| } |
| |
| outfile << "## " << processor.first << std::endl << std::endl; |
| if (foundDescription) { |
| outfile << "### Description " << std::endl << std::endl; |
| outfile << description << std::endl; |
| } |
| |
| outfile << "### Properties " << std::endl << std::endl; |
| outfile |
| << "In the list below, the names of required properties appear in bold. Any other properties (not in bold) are considered optional. The table also indicates any default values, and whether a property supports the NiFi Expression Language." |
| << std::endl<< std::endl; |
| |
| outfile << "| Name | Default Value | Allowable Values | Description | " << std::endl << "| - | - | - | - | " << std::endl; |
| for (const auto &prop : processor.second.class_properties_) { |
| bool supportsEl = prop.second.supportsExpressionLangauge(); |
| outfile << "|"; |
| if (prop.second.getRequired()) { |
| outfile << "**"; |
| } |
| outfile << prop.first; |
| if (prop.second.getRequired()) { |
| outfile << "**"; |
| } |
| const auto allowableValues = prop.second.getAllowedValues(); |
| std::stringstream s; |
| std::copy(allowableValues.begin(),allowableValues.end(), std::ostream_iterator<std::string>(s,"<br>")); |
| outfile << "|"; |
| const auto defaultValue = prop.second.getDefaultValue().to_string(); |
| if (defaultValue.size() == 1 && (int)defaultValue.c_str()[0] == 0x0a){ |
| outfile << "\\n"; |
| } |
| else{ |
| outfile << defaultValue; |
| } |
| outfile << "|" << s.str() << "|" << prop.second.getDescription(); |
| if (supportsEl){ |
| outfile << "<br/>**Supports Expression Language: true**"; |
| } |
| outfile << "|" << std::endl; |
| } |
| outfile << "### Properties " << std::endl << std::endl; |
| outfile << "| Name | Description |" << std::endl << "| - | - |" << std::endl; |
| for (const auto &rel : processor.second.class_relationships_) { |
| outfile << "|" << rel.getName() << "|" << rel.getDescription() << "|" << std::endl; |
| } |
| |
| outfile << std::endl; |
| |
| } |
| |
| std::map<std::string,std::string> fileList; |
| |
| auto fileFind = [&fileList,this](const std::string& base_path, const std::string& file) -> bool { |
| if (file.find(".extra") == std::string::npos) |
| fileList.insert( std::make_pair(file, base_path + utils::file::FileUtils::get_separator() + file) ); |
| return true; |
| }; |
| |
| // shortened with list_dir |
| utils::file::FileUtils::list_dir(docsdir, fileFind, logging::LoggerFactory<AgentDocs>::getLogger()); |
| genStream << "<!--" |
| "Licensed to the Apache Software Foundation (ASF) under one or more" |
| "contributor license agreements. See the NOTICE file distributed with" |
| "this work for additional information regarding copyright ownership." |
| "The ASF licenses this file to You 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" |
| " http://www.apache.org/licenses/LICENSE-2.0" |
| "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." |
| "-->"<<std::endl; |
| genStream << "# Processors" << std::endl << std::endl; |
| genStream << "## Table of Contents" << std::endl << std::endl; |
| |
| for(const auto &file : fileList){ |
| std::string lcfile=file.first; |
| std::transform(lcfile.begin(), lcfile.end(), lcfile.begin(), ::tolower); |
| genStream << "- [" << file.first << "](#" << lcfile << ")" << std::endl; |
| } |
| |
| for(const auto &file : fileList){ |
| std::ifstream filestream(file.second); |
| genStream << filestream.rdbuf() << std::endl; |
| std::ifstream filestreamExtra(file.second + ".extra"); |
| if (filestreamExtra.good()){ |
| genStream << filestreamExtra.rdbuf()<< std::endl; |
| } |
| } |
| } |
| |
| } /* namespace docs */ |
| } /* namespace minifi */ |
| } /* namespace nifi */ |
| } /* namespace apache */ |
| } /* namespace org */ |