This is an automated email from the ASF dual-hosted git repository.

markap14 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nifi-api.git


The following commit(s) were added to refs/heads/main by this push:
     new f05eea8  NIFI-15812 - Support CapabilityTag annotation in 
Documentation Writer (#84)
f05eea8 is described below

commit f05eea8d5e031d24c523dee5caf6ba963275b632
Author: Pierre Villard <[email protected]>
AuthorDate: Thu May 14 18:09:47 2026 +0200

    NIFI-15812 - Support CapabilityTag annotation in Documentation Writer (#84)
---
 .../AbstractConnectorDocumentationWriter.java      | 12 +++++
 .../documentation/AbstractDocumentationWriter.java | 13 ++++++
 .../xml/XmlConnectorDocumentationWriter.java       | 16 +++++++
 .../documentation/xml/XmlDocumentationWriter.java  | 16 +++++++
 .../xml/XmlConnectorDocumentationWriterTest.java   | 47 +++++++++++++++++++
 .../xml/XmlDocumentationWriterTest.java            | 52 ++++++++++++++++++++++
 6 files changed, 156 insertions(+)

diff --git 
a/src/main/java/org/apache/nifi/documentation/AbstractConnectorDocumentationWriter.java
 
b/src/main/java/org/apache/nifi/documentation/AbstractConnectorDocumentationWriter.java
index f10fcd1..9fba49d 100644
--- 
a/src/main/java/org/apache/nifi/documentation/AbstractConnectorDocumentationWriter.java
+++ 
b/src/main/java/org/apache/nifi/documentation/AbstractConnectorDocumentationWriter.java
@@ -17,6 +17,7 @@
 package org.apache.nifi.documentation;
 
 import org.apache.nifi.annotation.documentation.CapabilityDescription;
+import org.apache.nifi.annotation.documentation.CapabilityTag;
 import org.apache.nifi.annotation.documentation.DeprecationNotice;
 import org.apache.nifi.annotation.documentation.SeeAlso;
 import org.apache.nifi.annotation.documentation.Tags;
@@ -63,6 +64,7 @@ public abstract class AbstractConnectorDocumentationWriter 
implements ConnectorD
         
writeDeprecationNotice(connector.getClass().getAnnotation(DeprecationNotice.class));
         writeDescription(getDescription(connector));
         writeTags(getTags(connector));
+        writeCapabilityTags(getCapabilityTags(connector));
         writeConfigurationSteps(connector.getConfigurationSteps());
         writeSeeAlso(connector.getClass().getAnnotation(SeeAlso.class));
     }
@@ -84,6 +86,14 @@ public abstract class AbstractConnectorDocumentationWriter 
implements ConnectorD
         return tagValues == null ? Collections.emptyList() : 
Arrays.asList(tagValues);
     }
 
+    protected List<CapabilityTag> getCapabilityTags(final Connector connector) 
{
+        final CapabilityTag[] capabilityTags = 
connector.getClass().getAnnotationsByType(CapabilityTag.class);
+        if (capabilityTags.length == 0) {
+            return Collections.emptyList();
+        }
+        return Arrays.asList(capabilityTags);
+    }
+
     protected abstract void writeHeader(Connector connector) throws 
IOException;
 
     protected abstract void writeExtensionName(String extensionName) throws 
IOException;
@@ -96,6 +106,8 @@ public abstract class AbstractConnectorDocumentationWriter 
implements ConnectorD
 
     protected abstract void writeTags(List<String> tags) throws IOException;
 
+    protected abstract void writeCapabilityTags(List<CapabilityTag> 
capabilityTags) throws IOException;
+
     protected abstract void writeConfigurationSteps(List<ConfigurationStep> 
configurationSteps) throws IOException;
 
     protected abstract void writeSeeAlso(SeeAlso seeAlso) throws IOException;
diff --git 
a/src/main/java/org/apache/nifi/documentation/AbstractDocumentationWriter.java 
b/src/main/java/org/apache/nifi/documentation/AbstractDocumentationWriter.java
index 9dedd1b..c126cf7 100644
--- 
a/src/main/java/org/apache/nifi/documentation/AbstractDocumentationWriter.java
+++ 
b/src/main/java/org/apache/nifi/documentation/AbstractDocumentationWriter.java
@@ -37,6 +37,7 @@ import org.apache.nifi.annotation.behavior.WritesAttributes;
 import org.apache.nifi.annotation.configuration.DefaultSchedule;
 import org.apache.nifi.annotation.configuration.DefaultSettings;
 import org.apache.nifi.annotation.documentation.CapabilityDescription;
+import org.apache.nifi.annotation.documentation.CapabilityTag;
 import org.apache.nifi.annotation.documentation.DeprecationNotice;
 import org.apache.nifi.annotation.documentation.MultiProcessorUseCase;
 import org.apache.nifi.annotation.documentation.SeeAlso;
@@ -153,6 +154,7 @@ public abstract class AbstractDocumentationWriter 
implements ExtensionDocumentat
         
writeDeprecationNotice(component.getClass().getAnnotation(DeprecationNotice.class));
         writeDescription(getDescription(component));
         writeTags(getTags(component));
+        writeCapabilityTags(getCapabilityTags(component));
         writeProperties(component.getPropertyDescriptors(), propertyServices);
         writeDynamicProperties(getDynamicProperties(component));
         
writeSupportsSensitiveDynamicProperties(component.getClass().getAnnotation(SupportsSensitiveDynamicProperties.class));
@@ -288,6 +290,15 @@ public abstract class AbstractDocumentationWriter 
implements ExtensionDocumentat
         return Arrays.asList(useCases);
     }
 
+    private List<CapabilityTag> getCapabilityTags(final ConfigurableComponent 
component) {
+        final CapabilityTag[] capabilityTags = 
component.getClass().getAnnotationsByType(CapabilityTag.class);
+        if (capabilityTags.length == 0) {
+            return Collections.emptyList();
+        }
+
+        return Arrays.asList(capabilityTags);
+    }
+
     protected ExtensionType getExtensionType(final ConfigurableComponent 
component) {
         if (component instanceof Processor) {
             return ExtensionType.PROCESSOR;
@@ -324,6 +335,8 @@ public abstract class AbstractDocumentationWriter 
implements ExtensionDocumentat
 
     protected abstract void writeTags(List<String> tags) throws IOException;
 
+    protected abstract void writeCapabilityTags(List<CapabilityTag> 
capabilityTags) throws IOException;
+
     protected abstract void writeProperties(List<PropertyDescriptor> 
properties, Map<String, ServiceAPI> propertyServices) throws IOException;
 
     protected abstract void writeDynamicProperties(List<DynamicProperty> 
dynamicProperties) throws IOException;
diff --git 
a/src/main/java/org/apache/nifi/documentation/xml/XmlConnectorDocumentationWriter.java
 
b/src/main/java/org/apache/nifi/documentation/xml/XmlConnectorDocumentationWriter.java
index 9fdcc19..86712cd 100644
--- 
a/src/main/java/org/apache/nifi/documentation/xml/XmlConnectorDocumentationWriter.java
+++ 
b/src/main/java/org/apache/nifi/documentation/xml/XmlConnectorDocumentationWriter.java
@@ -27,6 +27,7 @@ import java.util.function.Function;
 import javax.xml.stream.XMLOutputFactory;
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamWriter;
+import org.apache.nifi.annotation.documentation.CapabilityTag;
 import org.apache.nifi.annotation.documentation.DeprecationNotice;
 import org.apache.nifi.annotation.documentation.SeeAlso;
 import org.apache.nifi.components.DescribedValue;
@@ -114,6 +115,21 @@ public class XmlConnectorDocumentationWriter extends 
AbstractConnectorDocumentat
         writeTextArray("tags", "tag", tags);
     }
 
+    @Override
+    protected void writeCapabilityTags(final List<CapabilityTag> 
capabilityTags) throws IOException {
+        if (capabilityTags == null || capabilityTags.isEmpty()) {
+            return;
+        }
+        writeStartElement("capabilityTags");
+        for (final CapabilityTag capabilityTag : capabilityTags) {
+            writeStartElement("capabilityTag");
+            writeTextElement("key", capabilityTag.key());
+            writeTextElement("value", capabilityTag.value());
+            writeEndElement();
+        }
+        writeEndElement();
+    }
+
     @Override
     protected void writeConfigurationSteps(final List<ConfigurationStep> 
configurationSteps) throws IOException {
         if (configurationSteps == null || configurationSteps.isEmpty()) {
diff --git 
a/src/main/java/org/apache/nifi/documentation/xml/XmlDocumentationWriter.java 
b/src/main/java/org/apache/nifi/documentation/xml/XmlDocumentationWriter.java
index b9acd56..f0f67a0 100644
--- 
a/src/main/java/org/apache/nifi/documentation/xml/XmlDocumentationWriter.java
+++ 
b/src/main/java/org/apache/nifi/documentation/xml/XmlDocumentationWriter.java
@@ -34,6 +34,7 @@ import org.apache.nifi.annotation.behavior.TriggerWhenEmpty;
 import org.apache.nifi.annotation.behavior.WritesAttribute;
 import org.apache.nifi.annotation.configuration.DefaultSchedule;
 import org.apache.nifi.annotation.configuration.DefaultSettings;
+import org.apache.nifi.annotation.documentation.CapabilityTag;
 import org.apache.nifi.annotation.documentation.DeprecationNotice;
 import org.apache.nifi.annotation.documentation.MultiProcessorUseCase;
 import org.apache.nifi.annotation.documentation.ProcessorConfiguration;
@@ -149,6 +150,21 @@ public class XmlDocumentationWriter extends 
AbstractDocumentationWriter {
         writeTextArray("tags", "tag", tags);
     }
 
+    @Override
+    protected void writeCapabilityTags(final List<CapabilityTag> 
capabilityTags) throws IOException {
+        if (capabilityTags == null || capabilityTags.isEmpty()) {
+            return;
+        }
+        writeArray("capabilityTags", capabilityTags, this::writeCapabilityTag);
+    }
+
+    private void writeCapabilityTag(final CapabilityTag capabilityTag) throws 
IOException {
+        writeStartElement("capabilityTag");
+        writeTextElement("key", capabilityTag.key());
+        writeTextElement("value", capabilityTag.value());
+        writeEndElement();
+    }
+
     @Override
     protected void writeProperties(final List<PropertyDescriptor> properties, 
Map<String, ServiceAPI> propertyServices) throws IOException {
         if (properties == null || properties.isEmpty()) {
diff --git 
a/src/test/java/org/apache/nifi/documentation/xml/XmlConnectorDocumentationWriterTest.java
 
b/src/test/java/org/apache/nifi/documentation/xml/XmlConnectorDocumentationWriterTest.java
index dc5912d..3b911fd 100644
--- 
a/src/test/java/org/apache/nifi/documentation/xml/XmlConnectorDocumentationWriterTest.java
+++ 
b/src/test/java/org/apache/nifi/documentation/xml/XmlConnectorDocumentationWriterTest.java
@@ -17,6 +17,7 @@
 package org.apache.nifi.documentation.xml;
 
 import org.apache.nifi.annotation.documentation.CapabilityDescription;
+import org.apache.nifi.annotation.documentation.CapabilityTag;
 import org.apache.nifi.annotation.documentation.DeprecationNotice;
 import org.apache.nifi.annotation.documentation.SeeAlso;
 import org.apache.nifi.annotation.documentation.Tags;
@@ -410,6 +411,47 @@ class XmlConnectorDocumentationWriterTest {
         assertEquals("BOOLEAN", propertyTypeNode.getTextContent());
     }
 
+    @Test
+    void testWriteConnectorWithCapabilityTags() throws Exception {
+        final Connector connector = new CapabilityTagConnector();
+        final Document document = writeDocumentation(connector);
+
+        assertExtensionNameTypeFound(connector, ExtensionType.CONNECTOR, 
document);
+
+        final Node capabilityTagsNode = findNode("/extension/capabilityTags", 
document);
+        assertNotNull(capabilityTagsNode);
+
+        final NodeList capabilityTagNodes = capabilityTagsNode.getChildNodes();
+        assertEquals(2, capabilityTagNodes.getLength());
+
+        final Node firstTag = capabilityTagNodes.item(0);
+        assertEquals("capabilityTag", firstTag.getNodeName());
+        final Node firstKey = firstTag.getFirstChild();
+        assertEquals("key", firstKey.getNodeName());
+        assertEquals("vendor", firstKey.getTextContent());
+        final Node firstValue = firstKey.getNextSibling();
+        assertEquals("value", firstValue.getNodeName());
+        assertEquals("Acme Corp", firstValue.getTextContent());
+
+        final Node secondTag = capabilityTagNodes.item(1);
+        assertEquals("capabilityTag", secondTag.getNodeName());
+        final Node secondKey = secondTag.getFirstChild();
+        assertEquals("key", secondKey.getNodeName());
+        assertEquals("category", secondKey.getTextContent());
+        final Node secondValue = secondKey.getNextSibling();
+        assertEquals("value", secondValue.getNodeName());
+        assertEquals("networking", secondValue.getTextContent());
+    }
+
+    @Test
+    void testWriteConnectorWithNoCapabilityTags() throws Exception {
+        final Connector connector = new MinimalConnector();
+        final Document document = writeDocumentation(connector);
+
+        final Node capabilityTagsNode = findNode("/extension/capabilityTags", 
document);
+        assertNull(capabilityTagsNode);
+    }
+
     private Node findNode(final String expression, final Node node) throws 
XPathExpressionException {
         final XPathFactory factory = XPathFactory.newInstance();
         final XPath path = factory.newXPath();
@@ -862,5 +904,10 @@ class XmlConnectorDocumentationWriterTest {
             );
         }
     }
+
+    @CapabilityTag(key = "vendor", value = "Acme Corp")
+    @CapabilityTag(key = "category", value = "networking")
+    private static class CapabilityTagConnector extends MinimalConnector {
+    }
 }
 
diff --git 
a/src/test/java/org/apache/nifi/documentation/xml/XmlDocumentationWriterTest.java
 
b/src/test/java/org/apache/nifi/documentation/xml/XmlDocumentationWriterTest.java
index e2ea473..9627c12 100644
--- 
a/src/test/java/org/apache/nifi/documentation/xml/XmlDocumentationWriterTest.java
+++ 
b/src/test/java/org/apache/nifi/documentation/xml/XmlDocumentationWriterTest.java
@@ -16,6 +16,7 @@
  */
 package org.apache.nifi.documentation.xml;
 
+import org.apache.nifi.annotation.documentation.CapabilityTag;
 import org.apache.nifi.annotation.documentation.DeprecationNotice;
 import org.apache.nifi.components.ConfigurableComponent;
 import org.apache.nifi.components.PropertyDescriptor;
@@ -203,6 +204,47 @@ class XmlDocumentationWriterTest {
         assertListenPortPropertiesMatched(document);
     }
 
+    @Test
+    void testWriteCapabilityTags() throws Exception {
+        final Processor processor = new CapabilityTagProcessor();
+        final Document document = writeDocumentation(processor);
+
+        assertExtensionNameTypeFound(processor, ExtensionType.PROCESSOR, 
document);
+
+        final Node capabilityTagsNode = findNode("/extension/capabilityTags", 
document);
+        assertNotNull(capabilityTagsNode);
+
+        final NodeList capabilityTagNodes = capabilityTagsNode.getChildNodes();
+        assertEquals(2, capabilityTagNodes.getLength());
+
+        final Node firstTag = capabilityTagNodes.item(0);
+        assertEquals("capabilityTag", firstTag.getNodeName());
+        final Node firstKey = firstTag.getFirstChild();
+        assertEquals("key", firstKey.getNodeName());
+        assertEquals("vendor", firstKey.getTextContent());
+        final Node firstValue = firstKey.getNextSibling();
+        assertEquals("value", firstValue.getNodeName());
+        assertEquals("Acme Corp", firstValue.getTextContent());
+
+        final Node secondTag = capabilityTagNodes.item(1);
+        assertEquals("capabilityTag", secondTag.getNodeName());
+        final Node secondKey = secondTag.getFirstChild();
+        assertEquals("key", secondKey.getNodeName());
+        assertEquals("category", secondKey.getTextContent());
+        final Node secondValue = secondKey.getNextSibling();
+        assertEquals("value", secondValue.getNodeName());
+        assertEquals("networking", secondValue.getTextContent());
+    }
+
+    @Test
+    void testWriteNoCapabilityTags() throws Exception {
+        final Processor processor = new MinimalProcessor();
+        final Document document = writeDocumentation(processor);
+
+        final Node capabilityTagsNode = findNode("/extension/capabilityTags", 
document);
+        assertNull(capabilityTagsNode);
+    }
+
     private void assertRelationshipsMatched(final Document document) throws 
XPathExpressionException {
         final Node relationshipsNode = findNode("/extension/relationships", 
document);
         assertNotNull(relationshipsNode);
@@ -400,4 +442,14 @@ class XmlDocumentationWriterTest {
             return PROPERTY_DESCRIPTORS;
         }
     }
+
+    @CapabilityTag(key = "vendor", value = "Acme Corp")
+    @CapabilityTag(key = "category", value = "networking")
+    private static class CapabilityTagProcessor extends AbstractProcessor {
+
+        @Override
+        public void onTrigger(final ProcessContext context, final 
ProcessSession session) throws ProcessException {
+
+        }
+    }
 }

Reply via email to