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 2022/06/03 00:05:40 UTC

[tapestry-5] 01/04: TAP5-2727: add @InjectComponent optional()

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

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

commit c56255e8a4e3078bc40413af4278448ea7b7da6e
Author: Ben Weidig <be...@netzgut.net>
AuthorDate: Sat May 28 16:30:51 2022 +0200

    TAP5-2727: add @InjectComponent optional()
---
 .../tapestry5/annotations/InjectComponent.java     |  5 +++++
 .../internal/transform/InjectComponentWorker.java  | 13 ++++++++++--
 tapestry-core/src/test/app1/Index.tml              | 10 +++++++++
 .../integration/app1/CoreBehaviorsTests.java       | 16 +++++++++++++++
 .../app1/pages/InjectComponentOptional.java        | 24 ++++++++++++++++++++++
 .../pages/InjectComponentOptionalException.java    | 24 ++++++++++++++++++++++
 .../app1/pages/InjectComponentOptional.tml         |  5 +++++
 .../pages/InjectComponentOptionalException.tml     |  5 +++++
 .../apache/tapestry5/test/SeleniumTestCase.java    | 11 ++++++++++
 9 files changed, 111 insertions(+), 2 deletions(-)

diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/annotations/InjectComponent.java b/tapestry-core/src/main/java/org/apache/tapestry5/annotations/InjectComponent.java
index acf95660f..cc69d9d51 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/annotations/InjectComponent.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/annotations/InjectComponent.java
@@ -36,4 +36,9 @@ public @interface InjectComponent
      * The name of the component to inject. Defaults to the name of the annotated field.
      */
     String value() default "";
+
+    /**
+     * If true, allows the component to be missing without throwing an exception.
+     */
+    boolean optional() default false;
 }
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/InjectComponentWorker.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/InjectComponentWorker.java
index 022385e2d..96525242f 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/InjectComponentWorker.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/InjectComponentWorker.java
@@ -40,8 +40,10 @@ public class InjectComponentWorker implements ComponentClassTransformWorker2
 
         private Component embedded;
 
+        private boolean optional; 
+
         private InjectedComponentFieldValueConduit(ComponentResources resources, String fieldName, String type,
-                                                   String componentId)
+                                                   String componentId, boolean optional)
         {
             super(resources, fieldName);
 
@@ -49,6 +51,7 @@ public class InjectComponentWorker implements ComponentClassTransformWorker2
             this.fieldName = fieldName;
             this.componentId = componentId;
             this.type = type;
+            this.optional = optional;
 
             resources.getPageLifecycleCallbackHub().addPageAttachedCallback(new Runnable()
             {
@@ -66,6 +69,10 @@ public class InjectComponentWorker implements ComponentClassTransformWorker2
                 embedded = resources.getEmbeddedComponent(componentId);
             } catch (UnknownValueException ex)
             {
+                if (this.optional) {
+                    return;
+                }
+
                 throw new RuntimeException(String.format("Unable to inject component into field %s of class %s: %s",
                         fieldName, getComponentClassName(), ex.getMessage()), ex);
             }
@@ -112,6 +119,8 @@ public class InjectComponentWorker implements ComponentClassTransformWorker2
             final String componentId = getComponentId(field, annotation);
 
             final String fieldName = field.getName();
+            
+            final boolean optional = annotation.optional();
 
             ComputedValue<FieldConduit<Object>> provider = new ComputedValue<FieldConduit<Object>>()
             {
@@ -119,7 +128,7 @@ public class InjectComponentWorker implements ComponentClassTransformWorker2
                 {
                     ComponentResources resources = context.get(ComponentResources.class);
 
-                    return new InjectedComponentFieldValueConduit(resources, fieldName, type, componentId);
+                    return new InjectedComponentFieldValueConduit(resources, fieldName, type, componentId, optional);
                 }
             };
 
diff --git a/tapestry-core/src/test/app1/Index.tml b/tapestry-core/src/test/app1/Index.tml
index 1e7ca7983..36a8fbf7c 100644
--- a/tapestry-core/src/test/app1/Index.tml
+++ b/tapestry-core/src/test/app1/Index.tml
@@ -76,6 +76,16 @@
         doesn't match actual field type
     </li>
 
+    <li>
+        <a href="injectcomponentoptional">InjectComponentOptional</a>
+        -- check optional @InjectComponent is not throwing an exception
+    </li>
+
+    <li>
+        <a href="injectcomponentoptionalexception">InjectComponentOptionalException</a>
+        -- check missing non-optional @InjectComponent is throwing an exception
+    </li>
+
     <li>
         <a href="recursivedemo">Recursive Demo</a>
         -- check for handling of recursive components
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java
index 5e51f9c5a..7bbb063e1 100644
--- a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java
@@ -177,6 +177,22 @@ public class CoreBehaviorsTests extends App1TestCase
         assertTextPresent("Unable to inject component 'form' into field form of org.apache.tapestry5.integration.app1.pages.InjectComponentMismatch. Class org.apache.tapestry5.corelib.components.BeanEditForm is not assignable to a field of type org.apache.tapestry5.corelib.components.Form.");
     }
 
+    @Test
+    public void inject_component_optional() throws Exception
+    {
+        openLinks("InjectComponentOptional");
+
+        assertTextNotPresent("Unable to inject component 'form' into field form of org.apache.tapestry5.integration.app1.pages.InjectComponentOptional.");
+    }
+
+    @Test
+    public void inject_component_optional_exception() throws Exception
+    {
+        openLinks("InjectComponentOptionalException");
+
+        assertTextPresent("Unable to inject component into field form of class org.apache.tapestry5.integration.app1.pages.InjectComponentOptionalException");
+    }
+
     @Test
     public void injection() throws Exception
     {
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/InjectComponentOptional.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/InjectComponentOptional.java
new file mode 100644
index 000000000..a83cc94cc
--- /dev/null
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/InjectComponentOptional.java
@@ -0,0 +1,24 @@
+// Copyright  2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.integration.app1.pages;
+
+import org.apache.tapestry5.annotations.InjectComponent;
+import org.apache.tapestry5.corelib.components.Form;
+
+public class InjectComponentOptional
+{
+    @InjectComponent(optional = true)
+    private Form form;
+}
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/InjectComponentOptionalException.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/InjectComponentOptionalException.java
new file mode 100644
index 000000000..e91cd2f99
--- /dev/null
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/InjectComponentOptionalException.java
@@ -0,0 +1,24 @@
+// Copyright  2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.integration.app1.pages;
+
+import org.apache.tapestry5.annotations.InjectComponent;
+import org.apache.tapestry5.corelib.components.Form;
+
+public class InjectComponentOptionalException
+{
+    @InjectComponent(optional=false)
+    private Form form;
+}
diff --git a/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/InjectComponentOptional.tml b/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/InjectComponentOptional.tml
new file mode 100644
index 000000000..10da58bef
--- /dev/null
+++ b/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/InjectComponentOptional.tml
@@ -0,0 +1,5 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <t:beaneditform t:id="otherForm" object="this"/>
+
+</html>
diff --git a/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/InjectComponentOptionalException.tml b/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/InjectComponentOptionalException.tml
new file mode 100644
index 000000000..10da58bef
--- /dev/null
+++ b/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/InjectComponentOptionalException.tml
@@ -0,0 +1,5 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <t:beaneditform t:id="otherForm" object="this"/>
+
+</html>
diff --git a/tapestry-test/src/main/java/org/apache/tapestry5/test/SeleniumTestCase.java b/tapestry-test/src/main/java/org/apache/tapestry5/test/SeleniumTestCase.java
index 11a495c85..6baec9a01 100644
--- a/tapestry-test/src/main/java/org/apache/tapestry5/test/SeleniumTestCase.java
+++ b/tapestry-test/src/main/java/org/apache/tapestry5/test/SeleniumTestCase.java
@@ -1536,6 +1536,17 @@ public abstract class SeleniumTestCase extends Assert implements Selenium
         }
     }
 
+    protected final void assertTextNotPresent(String... text)
+    {
+        for (String item : text)
+        {
+            if (isTextPresent(item))
+            {
+                reportAndThrowAssertionError("Page did contain '" + item + "'.");
+            }
+        }
+    }
+
     /**
      * Assets that each string provided is present somewhere in the current document.
      *