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 <[email protected]> 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. *
