diff --git a/nifi-api/src/main/java/org/apache/nifi/documentation/AbstractDocumentationWriter.java b/nifi-api/src/main/java/org/apache/nifi/documentation/AbstractDocumentationWriter.java index c6e793b69c..d3c64d4b55 100644 --- a/nifi-api/src/main/java/org/apache/nifi/documentation/AbstractDocumentationWriter.java +++ b/nifi-api/src/main/java/org/apache/nifi/documentation/AbstractDocumentationWriter.java @@ -48,6 +48,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.Map; import java.util.Set; /** @@ -67,25 +68,7 @@ import java.util.Set; public abstract class AbstractDocumentationWriter implements ExtensionDocumentationWriter { @Override - public final void write(final ConfigurableComponent component) throws IOException { - write(component, null); - } - - @Override - public final void write(final ConfigurableComponent component, final Collection providedServices) throws IOException { - initialize(component); - - writeHeader(component); - writeBody(component); - - if (providedServices != null && component instanceof ControllerService) { - writeProvidedServices(providedServices); - } - - writeFooter(component); - } - - private void initialize(final ConfigurableComponent component) { + public void initialize(final ConfigurableComponent component) { try { if (component instanceof Processor) { initialize((Processor) component); @@ -111,13 +94,30 @@ public abstract class AbstractDocumentationWriter implements ExtensionDocumentat reportingTask.initialize(new DocumentationReportingInitializationContext()); } - protected void writeBody(final ConfigurableComponent component) throws IOException { + @Override + public final void write(final ConfigurableComponent component) throws IOException { + write(component, null, null); + } + + @Override + public final void write(final ConfigurableComponent component, final Collection providedServices, Map propertyServices) throws IOException { + writeHeader(component); + writeBody(component, propertyServices); + + if (providedServices != null && component instanceof ControllerService) { + writeProvidedServices(providedServices); + } + + writeFooter(component); + } + + protected void writeBody(final ConfigurableComponent component, Map propertyServices) throws IOException { writeExtensionName(component.getClass().getName()); writeExtensionType(getExtensionType(component)); writeDeprecationNotice(component.getClass().getAnnotation(DeprecationNotice.class)); writeDescription(getDescription(component)); writeTags(getTags(component)); - writeProperties(component.getPropertyDescriptors()); + writeProperties(component.getPropertyDescriptors(), propertyServices); writeDynamicProperties(getDynamicProperties(component)); if (component instanceof Processor) { @@ -251,7 +251,7 @@ public abstract class AbstractDocumentationWriter implements ExtensionDocumentat protected abstract void writeTags(List tags) throws IOException; - protected abstract void writeProperties(List properties) throws IOException; + protected abstract void writeProperties(List properties, Map propertyServices) throws IOException; protected abstract void writeDynamicProperties(List dynamicProperties) throws IOException; @@ -278,7 +278,7 @@ public abstract class AbstractDocumentationWriter implements ExtensionDocumentat // ControllerService-specific methods - protected abstract void writeProvidedServices(Collection providedServices) throws IOException; + protected abstract void writeProvidedServices(Collection providedServices) throws IOException; protected abstract void writeFooter(ConfigurableComponent component) throws IOException; diff --git a/nifi-api/src/main/java/org/apache/nifi/documentation/ExtensionDocumentationWriter.java b/nifi-api/src/main/java/org/apache/nifi/documentation/ExtensionDocumentationWriter.java index c533e4e7d8..f4b249201d 100644 --- a/nifi-api/src/main/java/org/apache/nifi/documentation/ExtensionDocumentationWriter.java +++ b/nifi-api/src/main/java/org/apache/nifi/documentation/ExtensionDocumentationWriter.java @@ -20,6 +20,7 @@ import org.apache.nifi.components.ConfigurableComponent; import java.io.IOException; import java.util.Collection; +import java.util.Map; /** * Generates documentation for an instance of a ConfigurableComponent. @@ -35,8 +36,29 @@ import java.util.Collection; */ public interface ExtensionDocumentationWriter { + /** + * Calls initialize on the component. Must be called before calling any write methods. + * + * @param component the component to initialize + */ + void initialize(final ConfigurableComponent component); + + /** + * Write the documentation for the given component. + * + * @param component the component to document + * @throws IOException if an error occurs writing the documentation + */ void write(ConfigurableComponent component) throws IOException; - void write(ConfigurableComponent component, Collection provideServices) throws IOException; + /** + * Writes the documentation for the given component. + * + * @param component the component to document + * @param provideServices the service APIs implemented by the component + * @param propertyServiceAPIs the service APIs required by the property descriptors of the component + * @throws IOException if an error occurs writing the documentation + */ + void write(ConfigurableComponent component, Collection provideServices, Map propertyServiceAPIs) throws IOException; } diff --git a/nifi-api/src/main/java/org/apache/nifi/documentation/ProvidedServiceAPI.java b/nifi-api/src/main/java/org/apache/nifi/documentation/ServiceAPI.java similarity index 98% rename from nifi-api/src/main/java/org/apache/nifi/documentation/ProvidedServiceAPI.java rename to nifi-api/src/main/java/org/apache/nifi/documentation/ServiceAPI.java index 04cd425df5..6a4a63b9c1 100644 --- a/nifi-api/src/main/java/org/apache/nifi/documentation/ProvidedServiceAPI.java +++ b/nifi-api/src/main/java/org/apache/nifi/documentation/ServiceAPI.java @@ -28,7 +28,7 @@ package org.apache.nifi.documentation; * NOTE WELL: At this time, while this class is part of nifi-api, it is still evolving and may change in a non-backward-compatible manner or even be * removed from one incremental release to the next. Use at your own risk! */ -public interface ProvidedServiceAPI { +public interface ServiceAPI { /** * @return the fully qualified class name of the interface implemented by the Controller Service */ diff --git a/nifi-api/src/main/java/org/apache/nifi/documentation/StandardProvidedServiceAPI.java b/nifi-api/src/main/java/org/apache/nifi/documentation/StandardServiceAPI.java similarity index 87% rename from nifi-api/src/main/java/org/apache/nifi/documentation/StandardProvidedServiceAPI.java rename to nifi-api/src/main/java/org/apache/nifi/documentation/StandardServiceAPI.java index b86f4cad6e..585f8e477f 100644 --- a/nifi-api/src/main/java/org/apache/nifi/documentation/StandardProvidedServiceAPI.java +++ b/nifi-api/src/main/java/org/apache/nifi/documentation/StandardServiceAPI.java @@ -16,13 +16,13 @@ */ package org.apache.nifi.documentation; -public class StandardProvidedServiceAPI implements ProvidedServiceAPI { +public class StandardServiceAPI implements ServiceAPI { private final String className; private final String groupId; private final String artifactId; private final String version; - public StandardProvidedServiceAPI(final String className, final String groupId, final String artifactId, final String version) { + public StandardServiceAPI(final String className, final String groupId, final String artifactId, final String version) { this.className = className; this.groupId = groupId; this.artifactId = artifactId; diff --git a/nifi-api/src/main/java/org/apache/nifi/documentation/xml/XmlDocumentationWriter.java b/nifi-api/src/main/java/org/apache/nifi/documentation/xml/XmlDocumentationWriter.java index 93dee90022..59813a2a7b 100644 --- a/nifi-api/src/main/java/org/apache/nifi/documentation/xml/XmlDocumentationWriter.java +++ b/nifi-api/src/main/java/org/apache/nifi/documentation/xml/XmlDocumentationWriter.java @@ -33,7 +33,7 @@ import org.apache.nifi.components.PropertyDescriptor; import org.apache.nifi.components.RequiredPermission; import org.apache.nifi.documentation.AbstractDocumentationWriter; import org.apache.nifi.documentation.ExtensionType; -import org.apache.nifi.documentation.ProvidedServiceAPI; +import org.apache.nifi.documentation.ServiceAPI; import org.apache.nifi.processor.Relationship; import javax.xml.stream.XMLOutputFactory; @@ -46,6 +46,7 @@ import java.util.Collection; import java.util.Collections; import java.util.LinkedHashSet; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.function.Function; @@ -132,19 +133,44 @@ public class XmlDocumentationWriter extends AbstractDocumentationWriter { } @Override - protected void writeProperties(final List properties) throws IOException { - writeArray("properties", properties, this::writeProperty); + protected void writeProperties(final List properties, Map propertyServices) throws IOException { + writeStartElement("properties"); + if (properties != null) { + for (final PropertyDescriptor property : properties) { + writeProperty(property, propertyServices); + } + } + writeEndElement(); } - private void writeProperty(final PropertyDescriptor property) throws IOException { + private void writeProperty(final PropertyDescriptor property, Map propertyServices) throws IOException { writeStartElement("property"); writeTextElement("name", property.getName()); writeTextElement("displayName", property.getDisplayName()); writeTextElement("description", property.getDescription()); writeTextElement("defaultValue", property.getDefaultValue()); - writeTextElement("controllerServiceDefinition", property.getControllerServiceDefinition() == null ? null : property.getControllerServiceDefinition().getName()); - writeTextArray("allowableValues", "allowableValue", property.getAllowableValues(), AllowableValue::getDisplayName); + + if (property.getControllerServiceDefinition() != null) { + writeStartElement("controllerServiceDefinition"); + + final ServiceAPI serviceAPI = propertyServices.get(property.getName()); + if (serviceAPI != null) { + writeTextElement("className", serviceAPI.getClassName()); + writeTextElement("groupId", serviceAPI.getGroupId()); + writeTextElement("artifactId", serviceAPI.getArtifactId()); + writeTextElement("version", serviceAPI.getVersion()); + } else { + writeTextElement("className", property.getControllerServiceDefinition().getName()); + writeTextElement("groupId", "unknown"); + writeTextElement("artifactId", "unknown"); + writeTextElement("version", "unknown"); + } + + writeEndElement(); + } + + writeArray("allowableValues", property.getAllowableValues(), this::writeAllowableValue); writeBooleanElement("required", property.isRequired()); writeBooleanElement("sensitive", property.isSensitive()); writeBooleanElement("expressionLanguageSupported", property.isExpressionLanguageSupported()); @@ -155,9 +181,17 @@ public class XmlDocumentationWriter extends AbstractDocumentationWriter { writeEndElement(); } + private void writeAllowableValue(final AllowableValue allowableValue) throws IOException { + writeStartElement("allowableValue"); + writeTextElement("displayName", allowableValue.getDisplayName()); + writeTextElement("value", allowableValue.getValue()); + writeTextElement("description", allowableValue.getDescription()); + writeEndElement(); + } + @Override protected void writeDynamicProperties(final List dynamicProperties) throws IOException { - writeArray("dynamicProperty", dynamicProperties, this::writeDynamicProperty); + writeArray("dynamicProperties", dynamicProperties, this::writeDynamicProperty); } private void writeDynamicProperty(final DynamicProperty property) throws IOException { @@ -189,7 +223,9 @@ public class XmlDocumentationWriter extends AbstractDocumentationWriter { writeStartElement("restricted"); if (restricted != null) { - writeTextElement("generalRestrictionExplanation", restricted.value()); + if (restricted.value() != null && !restricted.value().isEmpty()) { + writeTextElement("generalRestrictionExplanation", restricted.value()); + } final Restriction[] restrictions = restricted.restrictions(); if (restrictions != null) { @@ -222,7 +258,7 @@ public class XmlDocumentationWriter extends AbstractDocumentationWriter { } private void writeSystemResourceConsideration(final SystemResourceConsideration consideration) throws IOException { - writeStartElement("consideration"); + writeStartElement("systemResourceConsideration"); writeTextElement("resource", consideration.resource() == null ? null : consideration.resource().name()); writeTextElement("description", consideration.description()); @@ -285,7 +321,7 @@ public class XmlDocumentationWriter extends AbstractDocumentationWriter { } private void writeReadsAttribute(final ReadsAttribute attribute) throws IOException { - writeStartElement("attribute"); + writeStartElement("readsAttribute"); writeTextElement("name", attribute.attribute()); writeTextElement("description", attribute.description()); writeEndElement(); @@ -297,7 +333,7 @@ public class XmlDocumentationWriter extends AbstractDocumentationWriter { } private void writeWritesAttribute(final WritesAttribute attribute) throws IOException { - writeStartElement("attribute"); + writeStartElement("writesAttribute"); writeTextElement("name", attribute.attribute()); writeTextElement("description", attribute.description()); writeEndElement(); @@ -309,17 +345,19 @@ public class XmlDocumentationWriter extends AbstractDocumentationWriter { } @Override - protected void writeProvidedServices(final Collection providedServices) throws IOException { - writeStartElement("providedServiceAPIs"); - writeArray("service", providedServices, this::writeProvidedService); - writeEndElement(); + protected void writeProvidedServices(final Collection providedServices) throws IOException { + writeArray("providedServiceAPIs", providedServices, this::writeProvidedService); } - private void writeProvidedService(final ProvidedServiceAPI service) throws IOException { + private void writeProvidedService(final ServiceAPI service) throws IOException { + writeStartElement("providedServiceAPI"); + writeTextElement("className",service.getClassName()); writeTextElement("groupId",service.getGroupId()); writeTextElement("artifactId",service.getArtifactId()); writeTextElement("version",service.getVersion()); + + writeEndElement(); } private void writeArray(final String tagName, final Collection values, final ElementWriter writer) throws IOException {