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")

Reply via email to