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

kdoran pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nifi-maven.git


The following commit(s) were added to refs/heads/master by this push:
     new 613b37c  NIFI-5859 Modifications to extension manifest generation to 
better support unmarshalling XML into pojos
613b37c is described below

commit 613b37c54a148328e6d045eb3c25e19b365b8946
Author: Bryan Bende <bbe...@apache.org>
AuthorDate: Tue Feb 26 16:36:55 2019 -0500

    NIFI-5859 Modifications to extension manifest generation to better support 
unmarshalling XML into pojos
---
 src/main/java/org/apache/nifi/NarMojo.java         | 97 ++++++++++++++++++----
 .../extraction/ExtensionDefinitionFactory.java     |  2 +-
 2 files changed, 84 insertions(+), 15 deletions(-)

diff --git a/src/main/java/org/apache/nifi/NarMojo.java 
b/src/main/java/org/apache/nifi/NarMojo.java
index 3627adf..0c7ab75 100644
--- a/src/main/java/org/apache/nifi/NarMojo.java
+++ b/src/main/java/org/apache/nifi/NarMojo.java
@@ -49,7 +49,6 @@ import org.apache.maven.plugins.annotations.ResolutionScope;
 import org.apache.maven.project.MavenProject;
 import org.apache.maven.project.MavenProjectHelper;
 import org.apache.maven.project.ProjectBuilder;
-import org.apache.maven.project.ProjectBuildingException;
 import 
org.apache.maven.shared.artifact.filter.collection.ArtifactFilterException;
 import org.apache.maven.shared.artifact.filter.collection.ArtifactIdFilter;
 import org.apache.maven.shared.artifact.filter.collection.ArtifactsFilter;
@@ -66,6 +65,7 @@ import 
org.apache.nifi.extension.definition.ServiceAPIDefinition;
 import org.apache.nifi.extension.definition.extraction.ExtensionClassLoader;
 import 
org.apache.nifi.extension.definition.extraction.ExtensionClassLoaderFactory;
 import 
org.apache.nifi.extension.definition.extraction.ExtensionDefinitionFactory;
+import 
org.apache.nifi.extension.definition.extraction.StandardServiceAPIDefinition;
 import org.codehaus.plexus.archiver.ArchiverException;
 import org.codehaus.plexus.archiver.jar.JarArchiver;
 import org.codehaus.plexus.archiver.jar.ManifestException;
@@ -92,8 +92,10 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Date;
 import java.util.Enumeration;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 import java.util.jar.JarEntry;
 import java.util.jar.JarFile;
@@ -509,7 +511,7 @@ public class NarMojo extends AbstractMojo {
 
     private File getExtensionsDocumentationFile() {
         final File directory = new File(projectBuildDirectory, 
"META-INF/docs");
-        return new File(directory, "extension-docs.xml");
+        return new File(directory, "extension-manifest.xml");
     }
 
     private void generateDocumentation() throws MojoExecutionException {
@@ -546,13 +548,15 @@ public class NarMojo extends AbstractMojo {
 
             final XMLStreamWriter xmlWriter = 
XMLOutputFactory.newInstance().createXMLStreamWriter(out, "UTF-8");
             try {
-                xmlWriter.writeStartElement("extensions");
+                xmlWriter.writeStartElement("extensionManifest");
 
                 final String nifiApiVersion = 
extensionClassLoader.getNiFiApiVersion();
-                xmlWriter.writeStartElement("nifiApiVersion");
+                xmlWriter.writeStartElement("systemApiVersion");
                 xmlWriter.writeCharacters(nifiApiVersion);
                 xmlWriter.writeEndElement();
 
+                xmlWriter.writeStartElement("extensions");
+
                 final Class<?> docWriterClass;
                 try {
                     docWriterClass = 
Class.forName(DOCUMENTATION_WRITER_CLASS_NAME, false, extensionClassLoader);
@@ -584,6 +588,7 @@ public class NarMojo extends AbstractMojo {
                 }
 
                 xmlWriter.writeEndElement();
+                xmlWriter.writeEndElement();
             } finally {
                 xmlWriter.close();
             }
@@ -623,25 +628,89 @@ public class NarMojo extends AbstractMojo {
         final Class<?> extensionClass = 
Class.forName(extensionDefinition.getExtensionName(), false, classLoader);
         final Object extensionInstance = extensionClass.newInstance();
 
-        final Set<ServiceAPIDefinition> serviceDefinitions = 
extensionDefinition.getProvidedServiceAPIs();
+        final Method initMethod = docWriterClass.getMethod("initialize", 
configurableComponentClass);
+        initMethod.invoke(docWriter, extensionInstance);
 
-        if (serviceDefinitions == null || serviceDefinitions.isEmpty()) {
+        final Map<String,ServiceAPIDefinition> propertyServiceDefinitions = 
getRequiredServiceDefinitions(extensionClass, extensionInstance);
+        final Set<ServiceAPIDefinition> providedServiceDefinitions = 
extensionDefinition.getProvidedServiceAPIs();
+
+        if ((providedServiceDefinitions == null || 
providedServiceDefinitions.isEmpty())
+                && (propertyServiceDefinitions == null || 
propertyServiceDefinitions.isEmpty())) {
             final Method writeMethod = docWriterClass.getMethod("write", 
configurableComponentClass);
             writeMethod.invoke(docWriter, extensionInstance);
         } else {
-            final Class<?> providedServiceApiClass = 
Class.forName("org.apache.nifi.documentation.StandardProvidedServiceAPI", 
false, classLoader);
-            final Constructor<?> ctr = 
providedServiceApiClass.getConstructor(String.class, String.class, 
String.class, String.class);
+            final Class<?> serviceApiClass = 
Class.forName("org.apache.nifi.documentation.StandardServiceAPI", false, 
classLoader);
+            final List<Object> providedServices = 
getDocumentationServiceAPIs(serviceApiClass, providedServiceDefinitions);
+            final Map<String,Object> propertyServices = 
getDocumentationServiceAPIs(serviceApiClass, propertyServiceDefinitions);
+
+            final Method writeMethod = docWriterClass.getMethod("write", 
configurableComponentClass, Collection.class, Map.class);
+            writeMethod.invoke(docWriter, extensionInstance, providedServices, 
propertyServices);
+        }
+    }
+
+    private List<Object> getDocumentationServiceAPIs(Class<?> serviceApiClass, 
Set<ServiceAPIDefinition> serviceDefinitions) throws NoSuchMethodException, 
InstantiationException, IllegalAccessException, InvocationTargetException {
+        final Constructor<?> ctr = 
serviceApiClass.getConstructor(String.class, String.class, String.class, 
String.class);
+
+        final List<Object> providedServices = new ArrayList<>();
+
+        for (final ServiceAPIDefinition definition : serviceDefinitions) {
+            final Object serviceApi = 
ctr.newInstance(definition.getServiceAPIClassName(), 
definition.getServiceGroupId(), definition.getServiceArtifactId(), 
definition.getServiceVersion());
+            providedServices.add(serviceApi);
+        }
+        return providedServices;
+    }
+
+    private Map<String,Object> getDocumentationServiceAPIs(Class<?> 
serviceApiClass, Map<String,ServiceAPIDefinition> serviceDefinitions) throws 
NoSuchMethodException, InstantiationException, IllegalAccessException, 
InvocationTargetException {
+        final Constructor<?> ctr = 
serviceApiClass.getConstructor(String.class, String.class, String.class, 
String.class);
 
-            final List<Object> providedServices = new ArrayList<>();
+        final Map<String,Object> providedServices = new HashMap<>();
 
-            for (final ServiceAPIDefinition definition : serviceDefinitions) {
-                final Object serviceApi = 
ctr.newInstance(definition.getServiceAPIClassName(), 
definition.getServiceGroupId(), definition.getServiceArtifactId(), 
definition.getServiceVersion());
-                providedServices.add(serviceApi);
+        for (final Map.Entry<String,ServiceAPIDefinition> entry : 
serviceDefinitions.entrySet()) {
+            final String propName = entry.getKey();
+            final ServiceAPIDefinition definition = entry.getValue();
+
+            final Object serviceApi = 
ctr.newInstance(definition.getServiceAPIClassName(), 
definition.getServiceGroupId(), definition.getServiceArtifactId(), 
definition.getServiceVersion());
+            providedServices.put(propName, serviceApi);
+        }
+        return providedServices;
+    }
+
+    private Map<String,ServiceAPIDefinition> 
getRequiredServiceDefinitions(final Class<?> extensionClass, final Object 
extensionInstance) throws NoSuchMethodException, InvocationTargetException, 
IllegalAccessException {
+        final Map<String,ServiceAPIDefinition> requiredServiceAPIDefinitions = 
new HashMap<>();
+
+        final Method writeMethod = 
extensionClass.getMethod("getPropertyDescriptors");
+        final List<Object> propertyDescriptors = (List<Object>) 
writeMethod.invoke(extensionInstance);
+
+        if (propertyDescriptors == null) {
+            return requiredServiceAPIDefinitions;
+        }
+
+        for (final Object propDescriptor : propertyDescriptors) {
+            final Method nameMethod = 
propDescriptor.getClass().getMethod("getName");
+            final String propName = (String) nameMethod.invoke(propDescriptor);
+
+            final Method serviceDefinitionMethod = 
propDescriptor.getClass().getMethod("getControllerServiceDefinition");
+            final Object serviceDefinition = 
serviceDefinitionMethod.invoke(propDescriptor);
+
+            if (serviceDefinition == null) {
+                continue;
             }
 
-            final Method writeMethod = docWriterClass.getMethod("write", 
configurableComponentClass, Collection.class);
-            writeMethod.invoke(docWriter, extensionInstance, providedServices);
+            final Class<?> serviceDefinitionClass = (Class<?>) 
serviceDefinition;
+            final ExtensionClassLoader extensionClassLoader = 
(ExtensionClassLoader) serviceDefinitionClass.getClassLoader();
+            final Artifact narArtifact = extensionClassLoader.getNarArtifact();
+
+            final ServiceAPIDefinition serviceAPIDefinition = new 
StandardServiceAPIDefinition(
+                    serviceDefinitionClass.getName(),
+                    narArtifact.getGroupId(),
+                    narArtifact.getId(),
+                    narArtifact.getBaseVersion()
+            );
+
+            requiredServiceAPIDefinitions.put(propName, serviceAPIDefinition);
         }
+
+        return requiredServiceAPIDefinitions;
     }
 
     private void writeAdditionalDetails(final ExtensionClassLoader 
classLoader, final Set<String> extensionNames, final File additionalDetailsDir)
diff --git 
a/src/main/java/org/apache/nifi/extension/definition/extraction/ExtensionDefinitionFactory.java
 
b/src/main/java/org/apache/nifi/extension/definition/extraction/ExtensionDefinitionFactory.java
index 6203493..d632d19 100644
--- 
a/src/main/java/org/apache/nifi/extension/definition/extraction/ExtensionDefinitionFactory.java
+++ 
b/src/main/java/org/apache/nifi/extension/definition/extraction/ExtensionDefinitionFactory.java
@@ -91,7 +91,7 @@ public class ExtensionDefinitionFactory {
                     final Artifact interfaceNarArtifact = 
((ExtensionClassLoader) interfaceClassLoader).getNarArtifact();
 
                     final ServiceAPIDefinition serviceDefinition = new 
StandardServiceAPIDefinition(implementedInterface.getName(),
-                        interfaceNarArtifact.getGroupId(), 
interfaceNarArtifact.getArtifactId(), interfaceNarArtifact.getVersion());
+                        interfaceNarArtifact.getGroupId(), 
interfaceNarArtifact.getArtifactId(), interfaceNarArtifact.getBaseVersion());
 
                     serviceApis.add(serviceDefinition);
                 }

Reply via email to