| /* |
| * 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. |
| */ |
| package org.apache.nifi.registry.service.extension.docs; |
| |
| import org.apache.commons.lang3.StringUtils; |
| import org.apache.nifi.registry.extension.bundle.BundleInfo; |
| import org.apache.nifi.registry.extension.component.ExtensionMetadata; |
| import org.apache.nifi.registry.extension.component.manifest.AllowableValue; |
| import org.apache.nifi.registry.extension.component.manifest.ControllerServiceDefinition; |
| import org.apache.nifi.registry.extension.component.manifest.DeprecationNotice; |
| import org.apache.nifi.registry.extension.component.manifest.DynamicProperty; |
| import org.apache.nifi.registry.extension.component.manifest.ExpressionLanguageScope; |
| import org.apache.nifi.registry.extension.component.manifest.Extension; |
| import org.apache.nifi.registry.extension.component.manifest.InputRequirement; |
| import org.apache.nifi.registry.extension.component.manifest.Property; |
| import org.apache.nifi.registry.extension.component.manifest.ProvidedServiceAPI; |
| import org.apache.nifi.registry.extension.component.manifest.Restricted; |
| import org.apache.nifi.registry.extension.component.manifest.Restriction; |
| import org.apache.nifi.registry.extension.component.manifest.Stateful; |
| import org.apache.nifi.registry.extension.component.manifest.SystemResourceConsideration; |
| import org.springframework.stereotype.Service; |
| |
| import javax.xml.stream.FactoryConfigurationError; |
| import javax.xml.stream.XMLOutputFactory; |
| import javax.xml.stream.XMLStreamException; |
| import javax.xml.stream.XMLStreamWriter; |
| import java.io.IOException; |
| import java.io.OutputStream; |
| import java.util.List; |
| import java.util.Optional; |
| import java.util.stream.Collectors; |
| import java.util.stream.Stream; |
| |
| import static org.apache.nifi.registry.service.extension.docs.DocumentationConstants.CSS_PATH; |
| |
| @Service |
| public class HtmlExtensionDocWriter implements ExtensionDocWriter { |
| |
| @Override |
| public void write(final ExtensionMetadata extensionMetadata, final Extension extension, final OutputStream outputStream) throws IOException { |
| try { |
| final XMLStreamWriter xmlStreamWriter = XMLOutputFactory.newInstance().createXMLStreamWriter(outputStream, "UTF-8"); |
| xmlStreamWriter.writeDTD("<!DOCTYPE html>"); |
| xmlStreamWriter.writeStartElement("html"); |
| xmlStreamWriter.writeAttribute("lang", "en"); |
| writeHead(extensionMetadata, xmlStreamWriter); |
| writeBody(extensionMetadata, extension, xmlStreamWriter); |
| xmlStreamWriter.writeEndElement(); |
| xmlStreamWriter.close(); |
| outputStream.flush(); |
| } catch (XMLStreamException | FactoryConfigurationError e) { |
| throw new IOException("Unable to create XMLOutputStream", e); |
| } |
| } |
| |
| private void writeHead(final ExtensionMetadata extensionMetadata, final XMLStreamWriter xmlStreamWriter) throws XMLStreamException { |
| xmlStreamWriter.writeStartElement("head"); |
| xmlStreamWriter.writeStartElement("meta"); |
| xmlStreamWriter.writeAttribute("charset", "utf-8"); |
| xmlStreamWriter.writeEndElement(); |
| writeSimpleElement(xmlStreamWriter, "title", extensionMetadata.getDisplayName()); |
| |
| final String componentUsageCss = CSS_PATH + "component-usage.css"; |
| xmlStreamWriter.writeStartElement("link"); |
| xmlStreamWriter.writeAttribute("rel", "stylesheet"); |
| xmlStreamWriter.writeAttribute("href", componentUsageCss); |
| xmlStreamWriter.writeAttribute("type", "text/css"); |
| xmlStreamWriter.writeEndElement(); |
| xmlStreamWriter.writeEndElement(); |
| |
| xmlStreamWriter.writeStartElement("script"); |
| xmlStreamWriter.writeAttribute("type", "text/javascript"); |
| xmlStreamWriter.writeCharacters("window.onload = function(){if(self==top) { " + |
| "document.getElementById('nameHeader').style.display = \"inherit\"; } }" ); |
| xmlStreamWriter.writeEndElement(); |
| } |
| |
| private void writeBody(final ExtensionMetadata extensionMetadata, final Extension extension, |
| final XMLStreamWriter xmlStreamWriter) throws XMLStreamException { |
| xmlStreamWriter.writeStartElement("body"); |
| |
| writeHeader(extensionMetadata, extension, xmlStreamWriter); |
| writeBundleInfo(extensionMetadata, xmlStreamWriter); |
| writeDeprecationWarning(extension, xmlStreamWriter); |
| writeDescription(extensionMetadata, extension, xmlStreamWriter); |
| writeTags(extension, xmlStreamWriter); |
| writeProperties(extension, xmlStreamWriter); |
| writeDynamicProperties(extension, xmlStreamWriter); |
| writeAdditionalBodyInfo(extension, xmlStreamWriter); |
| writeStatefulInfo(extension, xmlStreamWriter); |
| writeRestrictedInfo(extension, xmlStreamWriter); |
| writeInputRequirementInfo(extension, xmlStreamWriter); |
| writeSystemResourceConsiderationInfo(extension, xmlStreamWriter); |
| writeProvidedServiceApis(extension, xmlStreamWriter); |
| writeSeeAlso(extension, xmlStreamWriter); |
| |
| // end body |
| xmlStreamWriter.writeEndElement(); |
| } |
| |
| /** |
| * This method may be overridden by sub classes to write additional |
| * information to the body of the documentation. |
| * |
| * @param extension the component to describe |
| * @param xmlStreamWriter the stream writer |
| * @throws XMLStreamException thrown if there was a problem writing to the XML stream |
| */ |
| protected void writeAdditionalBodyInfo(final Extension extension, final XMLStreamWriter xmlStreamWriter) throws XMLStreamException { |
| |
| } |
| |
| private void writeHeader(final ExtensionMetadata extensionMetadata, final Extension extension, |
| final XMLStreamWriter xmlStreamWriter) throws XMLStreamException { |
| xmlStreamWriter.writeStartElement("h1"); |
| xmlStreamWriter.writeAttribute("id", "nameHeader"); |
| xmlStreamWriter.writeAttribute("style", "display: none;"); |
| xmlStreamWriter.writeCharacters(extensionMetadata.getDisplayName()); |
| xmlStreamWriter.writeEndElement(); |
| } |
| |
| private void writeBundleInfoString(final ExtensionMetadata extensionMetadata, final XMLStreamWriter xmlStreamWriter) throws XMLStreamException { |
| final BundleInfo bundleInfo = extensionMetadata.getBundleInfo(); |
| final String bundleInfoText = bundleInfo.getGroupId() + "-" + bundleInfo.getArtifactId() + "-" + bundleInfo.getVersion(); |
| xmlStreamWriter.writeStartElement("p"); |
| xmlStreamWriter.writeStartElement("i"); |
| xmlStreamWriter.writeCharacters(bundleInfoText); |
| xmlStreamWriter.writeEndElement(); |
| xmlStreamWriter.writeEndElement(); |
| } |
| |
| private void writeBundleInfo(final ExtensionMetadata extensionMetadata, final XMLStreamWriter xmlStreamWriter) throws XMLStreamException { |
| final BundleInfo bundleInfo = extensionMetadata.getBundleInfo(); |
| |
| final String extenstionType; |
| switch (extensionMetadata.getType()) { |
| case PROCESSOR: |
| extenstionType = "Processor"; |
| break; |
| case CONTROLLER_SERVICE: |
| extenstionType = "Controller Service"; |
| break; |
| case REPORTING_TASK: |
| extenstionType = "Reporting Task"; |
| break; |
| default: |
| throw new IllegalArgumentException("Unknown extension type: " + extensionMetadata.getType()); |
| } |
| |
| xmlStreamWriter.writeStartElement("table"); |
| |
| xmlStreamWriter.writeStartElement("tr"); |
| writeSimpleElement(xmlStreamWriter, "th", "Extension Info"); |
| writeSimpleElement(xmlStreamWriter, "th", "Value"); |
| xmlStreamWriter.writeEndElement(); |
| |
| xmlStreamWriter.writeStartElement("tr"); |
| writeSimpleElement(xmlStreamWriter, "td", "Full Name", true, "bundle-info"); |
| writeSimpleElement(xmlStreamWriter, "td", extensionMetadata.getName()); |
| xmlStreamWriter.writeEndElement(); |
| |
| xmlStreamWriter.writeStartElement("tr"); |
| writeSimpleElement(xmlStreamWriter, "td", "Type", true, "bundle-info"); |
| writeSimpleElement(xmlStreamWriter, "td", extenstionType); |
| xmlStreamWriter.writeEndElement(); |
| |
| xmlStreamWriter.writeStartElement("tr"); |
| writeSimpleElement(xmlStreamWriter, "td", "Bundle Group", true, "bundle-info"); |
| writeSimpleElement(xmlStreamWriter, "td", bundleInfo.getGroupId()); |
| xmlStreamWriter.writeEndElement(); |
| |
| xmlStreamWriter.writeStartElement("tr"); |
| writeSimpleElement(xmlStreamWriter, "td", "Bundle Artifact", true, "bundle-info"); |
| writeSimpleElement(xmlStreamWriter, "td", bundleInfo.getArtifactId()); |
| xmlStreamWriter.writeEndElement(); |
| |
| xmlStreamWriter.writeStartElement("tr"); |
| writeSimpleElement(xmlStreamWriter, "td", "Bundle Version", true, "bundle-info"); |
| writeSimpleElement(xmlStreamWriter, "td", bundleInfo.getVersion()); |
| xmlStreamWriter.writeEndElement(); |
| |
| xmlStreamWriter.writeStartElement("tr"); |
| writeSimpleElement(xmlStreamWriter, "td", "Bundle Type", true, "bundle-info"); |
| writeSimpleElement(xmlStreamWriter, "td", bundleInfo.getBundleType().toString()); |
| xmlStreamWriter.writeEndElement(); |
| |
| xmlStreamWriter.writeStartElement("tr"); |
| writeSimpleElement(xmlStreamWriter, "td", "System API Version", true, "bundle-info"); |
| writeSimpleElement(xmlStreamWriter, "td", bundleInfo.getSystemApiVersion()); |
| xmlStreamWriter.writeEndElement(); |
| |
| xmlStreamWriter.writeEndElement(); // end table |
| } |
| |
| private void writeDeprecationWarning(final Extension extension, final XMLStreamWriter xmlStreamWriter) throws XMLStreamException { |
| final DeprecationNotice deprecationNotice = extension.getDeprecationNotice(); |
| if (deprecationNotice != null) { |
| xmlStreamWriter.writeStartElement("h2"); |
| xmlStreamWriter.writeCharacters("Deprecation notice: "); |
| xmlStreamWriter.writeEndElement(); |
| |
| xmlStreamWriter.writeStartElement("p"); |
| xmlStreamWriter.writeCharacters(""); |
| if (!StringUtils.isEmpty(deprecationNotice.getReason())) { |
| xmlStreamWriter.writeCharacters(deprecationNotice.getReason()); |
| } else { |
| xmlStreamWriter.writeCharacters("Please be aware this processor is deprecated and may be removed in the near future."); |
| } |
| xmlStreamWriter.writeEndElement(); |
| |
| xmlStreamWriter.writeStartElement("p"); |
| xmlStreamWriter.writeCharacters("Please consider using one the following alternatives: "); |
| |
| final List<String> alternatives = deprecationNotice.getAlternatives(); |
| if (alternatives != null && alternatives.size() > 0) { |
| xmlStreamWriter.writeStartElement("ul"); |
| for (final String alternative : alternatives) { |
| xmlStreamWriter.writeStartElement("li"); |
| xmlStreamWriter.writeCharacters(alternative); |
| xmlStreamWriter.writeEndElement(); |
| } |
| xmlStreamWriter.writeEndElement(); |
| } else { |
| xmlStreamWriter.writeCharacters("No alternative components suggested."); |
| } |
| |
| xmlStreamWriter.writeEndElement(); |
| } |
| } |
| |
| private void writeDescription(final ExtensionMetadata extensionMetadata, final Extension extension, final XMLStreamWriter xmlStreamWriter) |
| throws XMLStreamException { |
| final String description = StringUtils.isBlank(extension.getDescription()) |
| ? "No description provided." : extension.getDescription(); |
| writeSimpleElement(xmlStreamWriter, "h2", "Description: "); |
| writeSimpleElement(xmlStreamWriter, "p", description); |
| |
| if (extensionMetadata.getHasAdditionalDetails()) { |
| xmlStreamWriter.writeStartElement("p"); |
| final BundleInfo bundleInfo = extensionMetadata.getBundleInfo(); |
| final String bucketName = bundleInfo.getBucketName(); |
| final String groupId = bundleInfo.getGroupId(); |
| final String artifactId = bundleInfo.getArtifactId(); |
| final String version = bundleInfo.getVersion(); |
| final String extensionName = extensionMetadata.getName(); |
| |
| final String additionalDetailsPath = "/nifi-registry-api/extension-repository/" |
| + bucketName + "/" + groupId + "/" + artifactId + "/" + version |
| + "/extensions/" + extensionName + "/docs/additional-details"; |
| |
| writeLink(xmlStreamWriter, "Additional Details...", additionalDetailsPath); |
| xmlStreamWriter.writeEndElement(); |
| } |
| } |
| |
| private void writeTags(final Extension extension, final XMLStreamWriter xmlStreamWriter) throws XMLStreamException { |
| final List<String> tags = extension.getTags(); |
| xmlStreamWriter.writeStartElement("h3"); |
| xmlStreamWriter.writeCharacters("Tags: "); |
| xmlStreamWriter.writeEndElement(); |
| xmlStreamWriter.writeStartElement("p"); |
| if (tags != null) { |
| final String tagString = StringUtils.join(tags, ", "); |
| xmlStreamWriter.writeCharacters(tagString); |
| } else { |
| xmlStreamWriter.writeCharacters("No tags provided."); |
| } |
| xmlStreamWriter.writeEndElement(); |
| } |
| |
| protected void writeProperties(final Extension extension, final XMLStreamWriter xmlStreamWriter) throws XMLStreamException { |
| |
| final List<Property> properties = extension.getProperties(); |
| writeSimpleElement(xmlStreamWriter, "h3", "Properties: "); |
| |
| if (properties != null && properties.size() > 0) { |
| final boolean containsExpressionLanguage = containsExpressionLanguage(extension); |
| final boolean containsSensitiveProperties = containsSensitiveProperties(extension); |
| xmlStreamWriter.writeStartElement("p"); |
| xmlStreamWriter.writeCharacters("In the list below, the names of required properties appear in "); |
| writeSimpleElement(xmlStreamWriter, "strong", "bold"); |
| xmlStreamWriter.writeCharacters(". Any other properties (not in bold) are considered optional. " + |
| "The table also indicates any default values"); |
| if (containsExpressionLanguage) { |
| if (!containsSensitiveProperties) { |
| xmlStreamWriter.writeCharacters(", and "); |
| } else { |
| xmlStreamWriter.writeCharacters(", "); |
| } |
| xmlStreamWriter.writeCharacters("whether a property supports the NiFi Expression Language"); |
| } |
| if (containsSensitiveProperties) { |
| xmlStreamWriter.writeCharacters(", and whether a property is considered " + "\"sensitive\", meaning that its value will be encrypted"); |
| } |
| xmlStreamWriter.writeCharacters("."); |
| xmlStreamWriter.writeEndElement(); |
| |
| xmlStreamWriter.writeStartElement("table"); |
| xmlStreamWriter.writeAttribute("id", "properties"); |
| |
| // write the header row |
| xmlStreamWriter.writeStartElement("tr"); |
| writeSimpleElement(xmlStreamWriter, "th", "Name"); |
| writeSimpleElement(xmlStreamWriter, "th", "Default Value"); |
| writeSimpleElement(xmlStreamWriter, "th", "Allowable Values"); |
| writeSimpleElement(xmlStreamWriter, "th", "Description"); |
| xmlStreamWriter.writeEndElement(); |
| |
| // write the individual properties |
| for (Property property : properties) { |
| xmlStreamWriter.writeStartElement("tr"); |
| xmlStreamWriter.writeStartElement("td"); |
| xmlStreamWriter.writeAttribute("id", "name"); |
| if (property.isRequired()) { |
| writeSimpleElement(xmlStreamWriter, "strong", property.getDisplayName()); |
| } else { |
| xmlStreamWriter.writeCharacters(property.getDisplayName()); |
| } |
| |
| xmlStreamWriter.writeEndElement(); |
| writeSimpleElement(xmlStreamWriter, "td", property.getDefaultValue(), false, "default-value"); |
| xmlStreamWriter.writeStartElement("td"); |
| xmlStreamWriter.writeAttribute("id", "allowable-values"); |
| writeValidValues(xmlStreamWriter, property); |
| xmlStreamWriter.writeEndElement(); |
| xmlStreamWriter.writeStartElement("td"); |
| xmlStreamWriter.writeAttribute("id", "description"); |
| if (property.getDescription() != null && property.getDescription().trim().length() > 0) { |
| xmlStreamWriter.writeCharacters(property.getDescription()); |
| } else { |
| xmlStreamWriter.writeCharacters("No Description Provided."); |
| } |
| |
| if (property.isSensitive()) { |
| xmlStreamWriter.writeEmptyElement("br"); |
| writeSimpleElement(xmlStreamWriter, "strong", "Sensitive Property: true"); |
| } |
| |
| if (property.isExpressionLanguageSupported()) { |
| xmlStreamWriter.writeEmptyElement("br"); |
| String text = "Supports Expression Language: true"; |
| final String perFF = " (will be evaluated using flow file attributes and variable registry)"; |
| final String registry = " (will be evaluated using variable registry only)"; |
| final InputRequirement inputRequirement = extension.getInputRequirement(); |
| |
| switch(property.getExpressionLanguageScope()) { |
| case FLOWFILE_ATTRIBUTES: |
| if(inputRequirement != null && inputRequirement.equals(InputRequirement.INPUT_FORBIDDEN)) { |
| text += registry; |
| } else { |
| text += perFF; |
| } |
| break; |
| case VARIABLE_REGISTRY: |
| text += registry; |
| break; |
| case NONE: |
| default: |
| // in case legacy/deprecated method has been used to specify EL support |
| text += " (undefined scope)"; |
| break; |
| } |
| |
| writeSimpleElement(xmlStreamWriter, "strong", text); |
| } |
| xmlStreamWriter.writeEndElement(); |
| |
| xmlStreamWriter.writeEndElement(); |
| } |
| |
| xmlStreamWriter.writeEndElement(); |
| |
| } else { |
| writeSimpleElement(xmlStreamWriter, "p", "This component has no required or optional properties."); |
| } |
| } |
| |
| private boolean containsExpressionLanguage(final Extension extension) { |
| for (Property property : extension.getProperties()) { |
| if (property.isExpressionLanguageSupported()) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| private boolean containsSensitiveProperties(final Extension extension) { |
| for (Property property : extension.getProperties()) { |
| if (property.isSensitive()) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| protected void writeValidValues(final XMLStreamWriter xmlStreamWriter, final Property property) throws XMLStreamException { |
| if (property.getAllowableValues() != null && property.getAllowableValues().size() > 0) { |
| xmlStreamWriter.writeStartElement("ul"); |
| for (AllowableValue value : property.getAllowableValues()) { |
| xmlStreamWriter.writeStartElement("li"); |
| xmlStreamWriter.writeCharacters(value.getDisplayName()); |
| |
| if (!StringUtils.isBlank(value.getDescription())) { |
| writeValidValueDescription(xmlStreamWriter, value.getDescription()); |
| } |
| xmlStreamWriter.writeEndElement(); |
| } |
| xmlStreamWriter.writeEndElement(); |
| } else if (property.getControllerServiceDefinition() != null) { |
| final ControllerServiceDefinition serviceDefinition = property.getControllerServiceDefinition(); |
| final String controllerServiceClass = getSimpleName(serviceDefinition.getClassName()); |
| |
| final String group = serviceDefinition.getGroupId() == null ? "unknown" : serviceDefinition.getGroupId(); |
| final String artifact = serviceDefinition.getArtifactId() == null ? "unknown" : serviceDefinition.getArtifactId(); |
| final String version = serviceDefinition.getVersion() == null ? "unknown" : serviceDefinition.getVersion(); |
| |
| writeSimpleElement(xmlStreamWriter, "strong", "Controller Service API: "); |
| xmlStreamWriter.writeEmptyElement("br"); |
| xmlStreamWriter.writeCharacters(controllerServiceClass); |
| |
| writeValidValueDescription(xmlStreamWriter, group + "-" + artifact + "-" + version); |
| |
| // xmlStreamWriter.writeEmptyElement("br"); |
| // xmlStreamWriter.writeCharacters(group); |
| // xmlStreamWriter.writeEmptyElement("br"); |
| // xmlStreamWriter.writeCharacters(artifact); |
| // xmlStreamWriter.writeEmptyElement("br"); |
| // xmlStreamWriter.writeCharacters(version); |
| } |
| } |
| |
| private String getSimpleName(final String extensionName) { |
| int index = extensionName.lastIndexOf('.'); |
| if (index > 0 && (index < (extensionName.length() - 1))) { |
| return extensionName.substring(index + 1); |
| } else { |
| return extensionName; |
| } |
| } |
| |
| private void writeValidValueDescription(final XMLStreamWriter xmlStreamWriter, final String description) throws XMLStreamException { |
| xmlStreamWriter.writeCharacters(" "); |
| xmlStreamWriter.writeStartElement("img"); |
| xmlStreamWriter.writeAttribute("src", "/nifi-registry-docs/images/iconInfo.png"); |
| xmlStreamWriter.writeAttribute("alt", description); |
| xmlStreamWriter.writeAttribute("title", description); |
| xmlStreamWriter.writeEndElement(); |
| } |
| |
| private void writeDynamicProperties(final Extension extension, final XMLStreamWriter xmlStreamWriter) throws XMLStreamException { |
| |
| final List<DynamicProperty> dynamicProperties = extension.getDynamicProperties(); |
| |
| if (dynamicProperties != null && dynamicProperties.size() > 0) { |
| writeSimpleElement(xmlStreamWriter, "h3", "Dynamic Properties: "); |
| xmlStreamWriter.writeStartElement("p"); |
| xmlStreamWriter.writeCharacters("Dynamic Properties allow the user to specify both the name and value of a property."); |
| xmlStreamWriter.writeStartElement("table"); |
| xmlStreamWriter.writeAttribute("id", "dynamic-properties"); |
| xmlStreamWriter.writeStartElement("tr"); |
| writeSimpleElement(xmlStreamWriter, "th", "Name"); |
| writeSimpleElement(xmlStreamWriter, "th", "Value"); |
| writeSimpleElement(xmlStreamWriter, "th", "Description"); |
| xmlStreamWriter.writeEndElement(); |
| |
| for (final DynamicProperty dynamicProperty : dynamicProperties) { |
| final String name = StringUtils.isBlank(dynamicProperty.getName()) ? "Not Specified" : dynamicProperty.getName(); |
| final String value = StringUtils.isBlank(dynamicProperty.getValue()) ? "Not Specified" : dynamicProperty.getValue(); |
| final String description = StringUtils.isBlank(dynamicProperty.getDescription()) ? "Not Specified" : dynamicProperty.getDescription(); |
| |
| xmlStreamWriter.writeStartElement("tr"); |
| writeSimpleElement(xmlStreamWriter, "td", name, false, "name"); |
| writeSimpleElement(xmlStreamWriter, "td", value, false, "value"); |
| xmlStreamWriter.writeStartElement("td"); |
| xmlStreamWriter.writeCharacters(description); |
| xmlStreamWriter.writeEmptyElement("br"); |
| |
| final ExpressionLanguageScope elScope = dynamicProperty.getExpressionLanguageScope() == null |
| ? ExpressionLanguageScope.NONE : dynamicProperty.getExpressionLanguageScope(); |
| |
| String text; |
| if(elScope.equals(ExpressionLanguageScope.NONE)) { |
| if(dynamicProperty.isExpressionLanguageSupported()) { |
| text = "Supports Expression Language: true (undefined scope)"; |
| } else { |
| text = "Supports Expression Language: false"; |
| } |
| } else { |
| switch(elScope) { |
| case FLOWFILE_ATTRIBUTES: |
| text = "Supports Expression Language: true (will be evaluated using flow file attributes and variable registry)"; |
| break; |
| case VARIABLE_REGISTRY: |
| text = "Supports Expression Language: true (will be evaluated using variable registry only)"; |
| break; |
| case NONE: |
| default: |
| text = "Supports Expression Language: false"; |
| break; |
| } |
| } |
| |
| writeSimpleElement(xmlStreamWriter, "strong", text); |
| xmlStreamWriter.writeEndElement(); |
| xmlStreamWriter.writeEndElement(); |
| } |
| |
| xmlStreamWriter.writeEndElement(); |
| xmlStreamWriter.writeEndElement(); |
| } |
| } |
| |
| private void writeStatefulInfo(final Extension extension, final XMLStreamWriter xmlStreamWriter) |
| throws XMLStreamException { |
| final Stateful stateful = extension.getStateful(); |
| writeSimpleElement(xmlStreamWriter, "h3", "State management: "); |
| |
| if(stateful != null) { |
| final List<String> scopes = Optional.ofNullable(stateful.getScopes()) |
| .map(List::stream) |
| .orElseGet(Stream::empty) |
| .map(s -> s.toString()) |
| .collect(Collectors.toList()); |
| |
| final String description = StringUtils.isBlank(stateful.getDescription()) ? "Not Specified" : stateful.getDescription(); |
| |
| xmlStreamWriter.writeStartElement("table"); |
| xmlStreamWriter.writeAttribute("id", "stateful"); |
| xmlStreamWriter.writeStartElement("tr"); |
| writeSimpleElement(xmlStreamWriter, "th", "Scope"); |
| writeSimpleElement(xmlStreamWriter, "th", "Description"); |
| xmlStreamWriter.writeEndElement(); |
| |
| xmlStreamWriter.writeStartElement("tr"); |
| writeSimpleElement(xmlStreamWriter, "td", StringUtils.join(scopes, ", ")); |
| writeSimpleElement(xmlStreamWriter, "td", description); |
| xmlStreamWriter.writeEndElement(); |
| |
| xmlStreamWriter.writeEndElement(); |
| } else { |
| xmlStreamWriter.writeCharacters("This component does not store state."); |
| } |
| } |
| |
| private void writeRestrictedInfo(final Extension extension, final XMLStreamWriter xmlStreamWriter) |
| throws XMLStreamException { |
| final Restricted restricted = extension.getRestricted(); |
| writeSimpleElement(xmlStreamWriter, "h3", "Restricted: "); |
| |
| if(restricted != null) { |
| final String generalRestrictionExplanation = restricted.getGeneralRestrictionExplanation(); |
| if (!StringUtils.isBlank(generalRestrictionExplanation)) { |
| xmlStreamWriter.writeCharacters(generalRestrictionExplanation); |
| } |
| |
| final List<Restriction> restrictions = restricted.getRestrictions(); |
| if (restrictions != null && restrictions.size() > 0) { |
| xmlStreamWriter.writeStartElement("table"); |
| xmlStreamWriter.writeAttribute("id", "restrictions"); |
| xmlStreamWriter.writeStartElement("tr"); |
| writeSimpleElement(xmlStreamWriter, "th", "Required Permission"); |
| writeSimpleElement(xmlStreamWriter, "th", "Explanation"); |
| xmlStreamWriter.writeEndElement(); |
| |
| for (Restriction restriction : restrictions) { |
| final String permission = StringUtils.isBlank(restriction.getRequiredPermission()) |
| ? "Not Specified" : restriction.getRequiredPermission(); |
| |
| final String explanation = StringUtils.isBlank(restriction.getExplanation()) |
| ? "Not Specified" : restriction.getExplanation(); |
| |
| xmlStreamWriter.writeStartElement("tr"); |
| writeSimpleElement(xmlStreamWriter, "td", permission); |
| writeSimpleElement(xmlStreamWriter, "td", explanation); |
| xmlStreamWriter.writeEndElement(); |
| } |
| |
| xmlStreamWriter.writeEndElement(); |
| } else { |
| xmlStreamWriter.writeCharacters("This component requires access to restricted components regardless of restriction."); |
| } |
| } else { |
| xmlStreamWriter.writeCharacters("This component is not restricted."); |
| } |
| } |
| |
| private void writeInputRequirementInfo(final Extension extension, final XMLStreamWriter xmlStreamWriter) |
| throws XMLStreamException { |
| final InputRequirement inputRequirement = extension.getInputRequirement(); |
| if(inputRequirement != null) { |
| writeSimpleElement(xmlStreamWriter, "h3", "Input requirement: "); |
| switch (inputRequirement) { |
| case INPUT_FORBIDDEN: |
| xmlStreamWriter.writeCharacters("This component does not allow an incoming relationship."); |
| break; |
| case INPUT_ALLOWED: |
| xmlStreamWriter.writeCharacters("This component allows an incoming relationship."); |
| break; |
| case INPUT_REQUIRED: |
| xmlStreamWriter.writeCharacters("This component requires an incoming relationship."); |
| break; |
| default: |
| xmlStreamWriter.writeCharacters("This component does not have input requirement."); |
| break; |
| } |
| } |
| } |
| |
| private void writeSystemResourceConsiderationInfo(final Extension extension, final XMLStreamWriter xmlStreamWriter) |
| throws XMLStreamException { |
| |
| List<SystemResourceConsideration> systemResourceConsiderations = extension.getSystemResourceConsiderations(); |
| |
| writeSimpleElement(xmlStreamWriter, "h3", "System Resource Considerations:"); |
| if (systemResourceConsiderations != null && systemResourceConsiderations.size() > 0) { |
| xmlStreamWriter.writeStartElement("table"); |
| xmlStreamWriter.writeAttribute("id", "system-resource-considerations"); |
| xmlStreamWriter.writeStartElement("tr"); |
| writeSimpleElement(xmlStreamWriter, "th", "Resource"); |
| writeSimpleElement(xmlStreamWriter, "th", "Description"); |
| xmlStreamWriter.writeEndElement(); |
| |
| for (SystemResourceConsideration systemResourceConsideration : systemResourceConsiderations) { |
| final String resource = StringUtils.isBlank(systemResourceConsideration.getResource()) |
| ? "Not Specified" : systemResourceConsideration.getResource(); |
| final String description = StringUtils.isBlank(systemResourceConsideration.getDescription()) |
| ? "Not Specified" : systemResourceConsideration.getDescription(); |
| |
| xmlStreamWriter.writeStartElement("tr"); |
| writeSimpleElement(xmlStreamWriter, "td", resource); |
| writeSimpleElement(xmlStreamWriter, "td", description); |
| xmlStreamWriter.writeEndElement(); |
| } |
| xmlStreamWriter.writeEndElement(); |
| |
| } else { |
| xmlStreamWriter.writeCharacters("None specified."); |
| } |
| } |
| |
| private void writeProvidedServiceApis(final Extension extension, final XMLStreamWriter xmlStreamWriter) throws XMLStreamException { |
| final List<ProvidedServiceAPI> serviceAPIS = extension.getProvidedServiceAPIs(); |
| if (serviceAPIS != null && serviceAPIS.size() > 0) { |
| writeSimpleElement(xmlStreamWriter, "h3", "Provided Service APIs:"); |
| |
| xmlStreamWriter.writeStartElement("ul"); |
| |
| for (final ProvidedServiceAPI serviceAPI : serviceAPIS) { |
| final String name = getSimpleName(serviceAPI.getClassName()); |
| final String bundleInfo = " (" + serviceAPI.getGroupId() + "-" + serviceAPI.getArtifactId() + "-" + serviceAPI.getVersion() + ")"; |
| |
| xmlStreamWriter.writeStartElement("li"); |
| xmlStreamWriter.writeCharacters(name); |
| xmlStreamWriter.writeStartElement("i"); |
| xmlStreamWriter.writeCharacters(bundleInfo); |
| xmlStreamWriter.writeEndElement(); |
| xmlStreamWriter.writeEndElement(); |
| } |
| |
| xmlStreamWriter.writeEndElement(); |
| } |
| } |
| |
| private void writeSeeAlso(final Extension extension, final XMLStreamWriter xmlStreamWriter) |
| throws XMLStreamException { |
| final List<String> seeAlsos = extension.getSeeAlso(); |
| if (seeAlsos != null && seeAlsos.size() > 0) { |
| writeSimpleElement(xmlStreamWriter, "h3", "See Also:"); |
| |
| xmlStreamWriter.writeStartElement("ul"); |
| for (final String seeAlso : seeAlsos) { |
| writeSimpleElement(xmlStreamWriter, "li", seeAlso); |
| } |
| xmlStreamWriter.writeEndElement(); |
| } |
| } |
| |
| /** |
| * Writes a begin element, then text, then end element for the element of a |
| * users choosing. Example: <p>text</p> |
| * |
| * @param writer the stream writer to use |
| * @param elementName the name of the element |
| * @param characters the characters to insert into the element |
| * @throws XMLStreamException thrown if there was a problem writing to the |
| * stream |
| */ |
| protected final static void writeSimpleElement(final XMLStreamWriter writer, final String elementName, |
| final String characters) throws XMLStreamException { |
| writeSimpleElement(writer, elementName, characters, false); |
| } |
| |
| /** |
| * Writes a begin element, then text, then end element for the element of a |
| * users choosing. Example: <p>text</p> |
| * |
| * @param writer the stream writer to use |
| * @param elementName the name of the element |
| * @param characters the characters to insert into the element |
| * @param strong whether the characters should be strong or not. |
| * @throws XMLStreamException thrown if there was a problem writing to the |
| * stream. |
| */ |
| protected final static void writeSimpleElement(final XMLStreamWriter writer, final String elementName, |
| final String characters, boolean strong) throws XMLStreamException { |
| writeSimpleElement(writer, elementName, characters, strong, null); |
| } |
| |
| /** |
| * Writes a begin element, an id attribute(if specified), then text, then |
| * end element for element of the users choosing. Example: <p |
| * id="p-id">text</p> |
| * |
| * @param writer the stream writer to use |
| * @param elementName the name of the element |
| * @param characters the text of the element |
| * @param strong whether to bold the text of the element or not |
| * @param id the id of the element. specifying null will cause no element to |
| * be written. |
| * @throws XMLStreamException xse |
| */ |
| protected final static void writeSimpleElement(final XMLStreamWriter writer, final String elementName, |
| final String characters, boolean strong, String id) throws XMLStreamException { |
| writer.writeStartElement(elementName); |
| if (id != null) { |
| writer.writeAttribute("id", id); |
| } |
| if (strong) { |
| writer.writeStartElement("strong"); |
| } |
| writer.writeCharacters(characters); |
| if (strong) { |
| writer.writeEndElement(); |
| } |
| writer.writeEndElement(); |
| } |
| |
| /** |
| * A helper method to write a link |
| * |
| * @param xmlStreamWriter the stream to write to |
| * @param text the text of the link |
| * @param location the location of the link |
| * @throws XMLStreamException thrown if there was a problem writing to the |
| * stream |
| */ |
| protected void writeLink(final XMLStreamWriter xmlStreamWriter, final String text, final String location) |
| throws XMLStreamException { |
| xmlStreamWriter.writeStartElement("a"); |
| xmlStreamWriter.writeAttribute("href", location); |
| xmlStreamWriter.writeCharacters(text); |
| xmlStreamWriter.writeEndElement(); |
| } |
| |
| } |