NIFI-309 - Adding DynamicProperty support
Project: http://git-wip-us.apache.org/repos/asf/incubator-nifi/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-nifi/commit/bae2b406 Tree: http://git-wip-us.apache.org/repos/asf/incubator-nifi/tree/bae2b406 Diff: http://git-wip-us.apache.org/repos/asf/incubator-nifi/diff/bae2b406 Branch: refs/heads/develop Commit: bae2b4069b38e32b4b9243e314597f48633c704d Parents: 72153c9 Author: danbress <dbr...@onyxconsults.com> Authored: Wed Mar 18 13:41:57 2015 -0400 Committer: danbress <dbr...@onyxconsults.com> Committed: Fri Mar 20 09:49:31 2015 -0400 ---------------------------------------------------------------------- .../annotation/behavior/DynamicProperties.java | 26 ++++++++ .../annotation/behavior/DynamicProperty.java | 45 +++++++++++++ .../html/HtmlDocumentationWriter.java | 70 ++++++++++++++++++++ .../example/FullyDocumentedProcessor.java | 2 + 4 files changed, 143 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/bae2b406/nifi/nifi-api/src/main/java/org/apache/nifi/annotation/behavior/DynamicProperties.java ---------------------------------------------------------------------- diff --git a/nifi/nifi-api/src/main/java/org/apache/nifi/annotation/behavior/DynamicProperties.java b/nifi/nifi-api/src/main/java/org/apache/nifi/annotation/behavior/DynamicProperties.java new file mode 100644 index 0000000..4fdfd08 --- /dev/null +++ b/nifi/nifi-api/src/main/java/org/apache/nifi/annotation/behavior/DynamicProperties.java @@ -0,0 +1,26 @@ +package org.apache.nifi.annotation.behavior; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Indicates that a component has more than one dynamic property + * + * @author + * + */ +@Documented +@Target({ ElementType.TYPE }) +@Retention(RetentionPolicy.RUNTIME) +@Inherited +public @interface DynamicProperties { + /** + * A list of the dynamic properties supported by a component + * @return A list of the dynamic properties supported by a component + */ + public DynamicProperty[] value(); +} http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/bae2b406/nifi/nifi-api/src/main/java/org/apache/nifi/annotation/behavior/DynamicProperty.java ---------------------------------------------------------------------- diff --git a/nifi/nifi-api/src/main/java/org/apache/nifi/annotation/behavior/DynamicProperty.java b/nifi/nifi-api/src/main/java/org/apache/nifi/annotation/behavior/DynamicProperty.java new file mode 100644 index 0000000..7b2150d --- /dev/null +++ b/nifi/nifi-api/src/main/java/org/apache/nifi/annotation/behavior/DynamicProperty.java @@ -0,0 +1,45 @@ +package org.apache.nifi.annotation.behavior; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.apache.nifi.components.ConfigurableComponent; + +/** + * An annotation that may be placed on a {@link ConfigurableComponent} to + * indicate that it supports a dynamic property. + * + * @author + * + */ +@Documented +@Target({ ElementType.TYPE }) +@Retention(RetentionPolicy.RUNTIME) +@Inherited +public @interface DynamicProperty { + /** + * A description of what the name of the dynamic property may be + * + * @return A description of what the name of the dynamic property may be + */ + public String name(); + + /** + * Indicates whether or not the dynamic property supports expression + * language + * + * @return whether or not the dynamic property supports expression + * language + */ + public boolean supportsExpressionLanguage() default false; + + /** + * Provides a description of what the meaning of the property is, and what the expected values are + * @return a description of what the meaning of the property is, and what the expected values are + */ + public String description(); +} http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/bae2b406/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-documentation/src/main/java/org/apache/nifi/documentation/html/HtmlDocumentationWriter.java ---------------------------------------------------------------------- diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-documentation/src/main/java/org/apache/nifi/documentation/html/HtmlDocumentationWriter.java b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-documentation/src/main/java/org/apache/nifi/documentation/html/HtmlDocumentationWriter.java index 9856c5d..7def25c 100644 --- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-documentation/src/main/java/org/apache/nifi/documentation/html/HtmlDocumentationWriter.java +++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-documentation/src/main/java/org/apache/nifi/documentation/html/HtmlDocumentationWriter.java @@ -18,6 +18,7 @@ package org.apache.nifi.documentation.html; import java.io.IOException; import java.io.OutputStream; +import java.util.ArrayList; import java.util.List; import javax.xml.stream.FactoryConfigurationError; @@ -26,6 +27,8 @@ import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; import org.apache.commons.lang3.StringUtils; +import org.apache.nifi.annotation.behavior.DynamicProperties; +import org.apache.nifi.annotation.behavior.DynamicProperty; import org.apache.nifi.annotation.documentation.CapabilityDescription; import org.apache.nifi.annotation.documentation.SeeAlso; import org.apache.nifi.annotation.documentation.Tags; @@ -126,6 +129,7 @@ public class HtmlDocumentationWriter implements DocumentationWriter { writeDescription(configurableComponent, xmlStreamWriter, hasAdditionalDetails); writeTags(configurableComponent, xmlStreamWriter); writeProperties(configurableComponent, xmlStreamWriter); + writeDynamicProperties(configurableComponent, xmlStreamWriter); writeAdditionalBodyInfo(configurableComponent, xmlStreamWriter); writeSeeAlso(configurableComponent, xmlStreamWriter); xmlStreamWriter.writeEndElement(); @@ -350,7 +354,73 @@ public class HtmlDocumentationWriter implements DocumentationWriter { writeSimpleElement(xmlStreamWriter, "p", "This component has no required or optional properties."); } } + + /** + * Writes a list of the dynamic properties that a processor supports + * @param configurableComponent + * @param xmlStreamWriter + * @throws XMLStreamException + */ + private void writeDynamicProperties(final ConfigurableComponent configurableComponent, + final XMLStreamWriter xmlStreamWriter) throws XMLStreamException { + + final List<DynamicProperty> dynamicProperties = getDynamicProperties(configurableComponent); + + 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.writeStartElement("tr"); + writeSimpleElement(xmlStreamWriter, "th", "Name"); + writeSimpleElement(xmlStreamWriter, "th", "Description"); + xmlStreamWriter.writeEndElement(); + for (final DynamicProperty dynamicProperty : dynamicProperties) { + xmlStreamWriter.writeStartElement("tr"); + writeSimpleElement(xmlStreamWriter, "td", dynamicProperty.name()); + xmlStreamWriter.writeStartElement("td"); + xmlStreamWriter.writeCharacters(dynamicProperty.description()); + if (dynamicProperty.supportsExpressionLanguage()) { + xmlStreamWriter.writeEmptyElement("br"); + writeSimpleElement(xmlStreamWriter, "strong", "Supports Expression Language: true"); + } + xmlStreamWriter.writeEndElement(); + xmlStreamWriter.writeEndElement(); + } + + xmlStreamWriter.writeEndElement(); + xmlStreamWriter.writeEndElement(); + } + } + /** + * Gets the dynamic properties for a configurable component + * @param configurableComponent + * @return + */ + private List<DynamicProperty> getDynamicProperties(ConfigurableComponent configurableComponent) { + final List<DynamicProperty> dynamicProperties = new ArrayList<>(); + final DynamicProperties dynProps = configurableComponent.getClass().getAnnotation(DynamicProperties.class); + if (dynProps != null) { + for (final DynamicProperty dynProp : dynProps.value()) { + dynamicProperties.add(dynProp); + } + } + + final DynamicProperty dynProp = configurableComponent.getClass().getAnnotation(DynamicProperty.class); + dynamicProperties.add(dynProp); + + return dynamicProperties; + } + + /** + * Writes an info icon with a description. + * + * @param xmlStreamWriter + * @param description the description of the item + * @throws XMLStreamException + */ private void writeValidValueDescription(XMLStreamWriter xmlStreamWriter, String description) throws XMLStreamException { xmlStreamWriter.writeCharacters(" "); http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/bae2b406/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-documentation/src/test/java/org/apache/nifi/documentation/example/FullyDocumentedProcessor.java ---------------------------------------------------------------------- diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-documentation/src/test/java/org/apache/nifi/documentation/example/FullyDocumentedProcessor.java b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-documentation/src/test/java/org/apache/nifi/documentation/example/FullyDocumentedProcessor.java index 84dc88f..1814f51 100644 --- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-documentation/src/test/java/org/apache/nifi/documentation/example/FullyDocumentedProcessor.java +++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-documentation/src/test/java/org/apache/nifi/documentation/example/FullyDocumentedProcessor.java @@ -22,6 +22,7 @@ import java.util.HashSet; import java.util.List; import java.util.Set; +import org.apache.nifi.annotation.behavior.DynamicProperty; import org.apache.nifi.annotation.documentation.CapabilityDescription; import org.apache.nifi.annotation.documentation.ReadsAttribute; import org.apache.nifi.annotation.documentation.SeeAlso; @@ -43,6 +44,7 @@ import org.apache.nifi.processor.util.StandardValidators; @WritesAttributes({@WritesAttribute(attribute="first", description="this is the first attribute i write"), @WritesAttribute(attribute="second")}) @ReadsAttribute(attribute = "incoming", description="this specifies the format of the thing") @SeeAlso(value={FullyDocumentedControllerService.class, FullyDocumentedReportingTask.class}, classNames={"org.apache.nifi.processor.ExampleProcessor"}) +@DynamicProperty(name="the relationship to route to", supportsExpressionLanguage=true, description="some XPath") public class FullyDocumentedProcessor extends AbstractProcessor { public static final PropertyDescriptor DIRECTORY = new PropertyDescriptor.Builder().name("Input Directory")