You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by th...@apache.org on 2021/10/22 22:21:46 UTC

[tapestry-5] branch rest updated: TAP5-2696: fixing NPE in OpenAPI generation

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

thiagohp pushed a commit to branch rest
in repository https://gitbox.apache.org/repos/asf/tapestry-5.git


The following commit(s) were added to refs/heads/rest by this push:
     new ce38612  TAP5-2696: fixing NPE in OpenAPI generation
ce38612 is described below

commit ce38612c6e2cb43412d0344d36d2f0399a75cc7a
Author: Thiago H. de Paula Figueiredo <th...@arsmachina.com.br>
AuthorDate: Fri Oct 22 19:21:36 2021 -0300

    TAP5-2696: fixing NPE in OpenAPI generation
    
    when a superclass has no REST event handler methods
---
 .../DefaultOpenApiDescriptionGenerator.java        | 37 +++++++++++-----------
 .../app1/base/AbstractRestDemoPage.java            |  3 +-
 ...tractRestDemoPage.java => EmptySuperclass.java} | 18 ++++-------
 3 files changed, 27 insertions(+), 31 deletions(-)

diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/DefaultOpenApiDescriptionGenerator.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/DefaultOpenApiDescriptionGenerator.java
index 9a26f95..653bed5 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/DefaultOpenApiDescriptionGenerator.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/DefaultOpenApiDescriptionGenerator.java
@@ -20,10 +20,8 @@ import java.lang.reflect.Method;
 import java.lang.reflect.Parameter;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Optional;
-import java.util.Set;
 import java.util.stream.Collectors;
 
 import javax.servlet.http.HttpServletResponse;
@@ -76,8 +74,6 @@ public class DefaultOpenApiDescriptionGenerator implements OpenApiDescriptionGen
     
     final private ComponentClassResolver componentClassResolver;
     
-    final private Set<String> failedPageNames;
-    
     final private PageRenderLinkSource pageRenderLinkSource;
     
     final private Request request;
@@ -104,7 +100,6 @@ public class DefaultOpenApiDescriptionGenerator implements OpenApiDescriptionGen
         this.pageRenderLinkSource = pageRenderLinkSource;
         this.request = request;
         messages = new ThreadLocal<>();
-        failedPageNames = new HashSet<>();
     }
 
     @Override
@@ -114,18 +109,18 @@ public class DefaultOpenApiDescriptionGenerator implements OpenApiDescriptionGen
         // Making sure all pages have been loaded and transformed
         for (String pageName : componentClassResolver.getPageNames())
         {
-            if (!failedPageNames.contains(pageName))
+            try
             {
-                try
-                {
-                    pageSource.getPage(pageName);
-                }
-                catch (Exception e)
-                {
-                    // Ignoring exception, since some classes may not
-                    // be instantiable.
-                    failedPageNames.add(pageName);
-                }
+                pageSource.getPage(pageName);
+            }
+            catch (Exception e)
+            {
+                // Ignoring exception, since some classes may not
+                // be instantiable.
+                LOGGER.warn(String.format(
+                        "Exception while intantiating page %s for OpenAPI description generation,", 
+                        pageName), e);
+                e.printStackTrace();
             }
         }
 
@@ -218,9 +213,13 @@ public class DefaultOpenApiDescriptionGenerator implements OpenApiDescriptionGen
         JSONArray methodsAsJson = new JSONArray();
         while (model != null)
         {
-            JSONArray thisMethodArray = new JSONArray(model.getMeta(
-                    InternalConstants.REST_ENDPOINT_EVENT_HANDLER_METHODS));
-            addElementsIfNotPresent(methodsAsJson, thisMethodArray);
+            final String meta = model.getMeta(
+                    InternalConstants.REST_ENDPOINT_EVENT_HANDLER_METHODS);
+            if (meta != null)
+            {
+                JSONArray thisMethodArray = new JSONArray(meta);
+                addElementsIfNotPresent(methodsAsJson, thisMethodArray);
+            }
             model = model.getParentModel();
         }
         return methodsAsJson;
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/base/AbstractRestDemoPage.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/base/AbstractRestDemoPage.java
index ca419a5..a0898e0 100644
--- a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/base/AbstractRestDemoPage.java
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/base/AbstractRestDemoPage.java
@@ -16,7 +16,8 @@ import org.apache.tapestry5.annotations.OnEvent;
 import org.apache.tapestry5.annotations.StaticActivationContextValue;
 import org.apache.tapestry5.util.TextStreamResponse;
 
-public class AbstractRestDemoPage {
+public class AbstractRestDemoPage extends EmptySuperclass
+{
     
     @OnEvent(EventConstants.HTTP_GET)
     protected Object abstractSuperclassEndpoint(@StaticActivationContextValue("abstract") String abstractValue)
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/base/AbstractRestDemoPage.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/base/EmptySuperclass.java
similarity index 55%
copy from tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/base/AbstractRestDemoPage.java
copy to tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/base/EmptySuperclass.java
index ca419a5..4f295aa 100644
--- a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/base/AbstractRestDemoPage.java
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/base/EmptySuperclass.java
@@ -11,17 +11,13 @@
 // limitations under the License.
 package org.apache.tapestry5.integration.app1.base;
 
-import org.apache.tapestry5.EventConstants;
-import org.apache.tapestry5.annotations.OnEvent;
-import org.apache.tapestry5.annotations.StaticActivationContextValue;
-import org.apache.tapestry5.util.TextStreamResponse;
+import org.apache.tapestry5.internal.services.DefaultOpenApiDescriptionGenerator;
 
-public class AbstractRestDemoPage {
+/**
+ * Just to make sure {@link DefaultOpenApiDescriptionGenerator} handles superclasses
+ * without any REST methods correctly (it didn't at first).
+ */
+public class EmptySuperclass 
+{
     
-    @OnEvent(EventConstants.HTTP_GET)
-    protected Object abstractSuperclassEndpoint(@StaticActivationContextValue("abstract") String abstractValue)
-    {
-        return new TextStreamResponse("text/plain", abstractValue);
-    }
-
 }