diff --git a/plugins/convention/src/main/java/org/apache/struts2/convention/DefaultResultMapBuilder.java b/plugins/convention/src/main/java/org/apache/struts2/convention/DefaultResultMapBuilder.java index ffab2f167..2a682247a 100644 --- a/plugins/convention/src/main/java/org/apache/struts2/convention/DefaultResultMapBuilder.java +++ b/plugins/convention/src/main/java/org/apache/struts2/convention/DefaultResultMapBuilder.java @@ -188,21 +188,33 @@ public class DefaultResultMapBuilder implements ResultMapBuilder { actionClass, resultsByExtension); } + //get inherited @Results and @Result + for (Class clazz : ReflectionTools.getClassHierarchy(actionClass)) { + createResultsFromAnnotations(clazz, packageConfig, defaultResultPath, results, resultsByExtension); + } + + return results; + } + + /** + * Creates results from @Results and @Result annotations + */ + protected void createResultsFromAnnotations(Class actionClass, PackageConfig packageConfig, String defaultResultPath, + Map results, Map resultsByExtension) { Results resultsAnn = actionClass.getAnnotation(Results.class); if (resultsAnn != null) { createFromAnnotations(results, defaultResultPath, packageConfig, resultsAnn.value(), - actionClass, resultsByExtension); + actionClass, resultsByExtension); } Result resultAnn = actionClass.getAnnotation(Result.class); if (resultAnn != null) { createFromAnnotations(results, defaultResultPath, packageConfig, new Result[]{resultAnn}, - actionClass, resultsByExtension); + actionClass, resultsByExtension); } - - return results; } + /** * Creates any result types from the resources available in the web application. This scans the * web application resources using the servlet context. diff --git a/plugins/convention/src/main/java/org/apache/struts2/convention/ReflectionTools.java b/plugins/convention/src/main/java/org/apache/struts2/convention/ReflectionTools.java index d9f89c44b..1128635cd 100644 --- a/plugins/convention/src/main/java/org/apache/struts2/convention/ReflectionTools.java +++ b/plugins/convention/src/main/java/org/apache/struts2/convention/ReflectionTools.java @@ -22,6 +22,8 @@ package org.apache.struts2.convention; import java.lang.annotation.Annotation; import java.lang.reflect.Method; +import java.util.List; +import java.util.ArrayList; /** *

@@ -62,4 +64,19 @@ public class ReflectionTools { throw new RuntimeException(e); } } + + /** + * Return the list of parent classes in order (Object will be at index 0) + * @param clazz class to process + * @return hierarchy of classes + */ + public static List> getClassHierarchy(Class clazz) { + List> classes = new ArrayList>(); + while (clazz != null) { + classes.add(0, clazz); + clazz = clazz.getSuperclass(); + } + + return classes; + } } \ No newline at end of file diff --git a/plugins/convention/src/test/java/org/apache/struts2/convention/DefaultResultMapBuilderTest.java b/plugins/convention/src/test/java/org/apache/struts2/convention/DefaultResultMapBuilderTest.java index fb134f386..1a5d5ab14 100644 --- a/plugins/convention/src/test/java/org/apache/struts2/convention/DefaultResultMapBuilderTest.java +++ b/plugins/convention/src/test/java/org/apache/struts2/convention/DefaultResultMapBuilderTest.java @@ -33,6 +33,9 @@ import org.apache.struts2.convention.actions.result.ActionLevelResultAction; import org.apache.struts2.convention.actions.result.ActionLevelResultsAction; import org.apache.struts2.convention.actions.result.ClassLevelResultAction; import org.apache.struts2.convention.actions.result.ClassLevelResultsAction; +import org.apache.struts2.convention.actions.result.InheritedResultExtends; +import org.apache.struts2.convention.actions.result.InheritedResultsExtends; +import org.apache.struts2.convention.actions.result.OverrideInheritedResultExtends; import org.apache.struts2.convention.actions.resultpath.ClassLevelResultPathAction; import org.apache.struts2.convention.annotation.Action; import org.easymock.EasyMock; @@ -109,7 +112,7 @@ public class DefaultResultMapBuilderTest extends TestCase { PackageConfig packageConfig = createPackageConfigBuilder("/namespace"); - this.conventionsService = new ConventionsServiceImpl("/WEB-INF/location"); + this.conventionsService = new ConventionsServiceImpl("/WEB-INF/location"); DefaultResultMapBuilder builder = new DefaultResultMapBuilder(context, container, "dispatcher,velocity,freemarker"); Map results = builder.build(NoAnnotationAction.class, null, "no-annotation", packageConfig); assertEquals(4, results.size()); @@ -153,6 +156,54 @@ public class DefaultResultMapBuilderTest extends TestCase { EasyMock.verify(context); } + public void testClassLevelInheritedSingleResultAnnotation() throws Exception { + ServletContext context = EasyMock.createStrictMock(ServletContext.class); + + // Setup some mock jsps + Set resources = new HashSet(); + EasyMock.expect(context.getResourcePaths("/WEB-INF/location/namespace/")).andReturn(resources); + EasyMock.replay(context); + + PackageConfig packageConfig = createPackageConfigBuilder("/namespace"); + + this.conventionsService = new ConventionsServiceImpl("/WEB-INF/location"); + DefaultResultMapBuilder builder = new DefaultResultMapBuilder(context, container, "dispatcher,velocity,freemarker"); + Map results = builder.build(InheritedResultExtends.class, null, "result-inheritance-extends", packageConfig); + assertEquals(1, results.size()); + assertEquals("error", results.get("error").getName()); + assertEquals(3, results.get("error").getParams().size()); + assertEquals("org.apache.struts2.dispatcher.ServletDispatcherResult", results.get("error").getClassName()); + assertEquals("/WEB-INF/location/namespace/error.jsp", results.get("error").getParams().get("location")); + assertEquals("value", results.get("error").getParams().get("key")); + assertEquals("value1", results.get("error").getParams().get("key1")); + EasyMock.verify(context); + } + + public void testClassLevelOverwriteInheritedSingleResultAnnotation() throws Exception { + ServletContext context = EasyMock.createStrictMock(ServletContext.class); + + // Setup some mock jsps + Set resources = new HashSet(); + EasyMock.expect(context.getResourcePaths("/WEB-INF/location/namespace/")).andReturn(resources); + EasyMock.replay(context); + + PackageConfig packageConfig = createPackageConfigBuilder("/namespace"); + + this.conventionsService = new ConventionsServiceImpl("/WEB-INF/location"); + DefaultResultMapBuilder builder = new DefaultResultMapBuilder(context, container, "dispatcher,velocity,freemarker"); + Map results = builder.build(OverrideInheritedResultExtends.class, null, "result-inheritance-extends", packageConfig); + assertEquals(1, results.size()); + assertEquals("error", results.get("error").getName()); + assertEquals(5, results.get("error").getParams().size()); + assertEquals("org.apache.struts2.dispatcher.ServletDispatcherResult", results.get("error").getClassName()); + assertEquals("/WEB-INF/location/namespace/error.jsp", results.get("error").getParams().get("location")); + assertEquals("value", results.get("error").getParams().get("key")); + assertEquals("value1", results.get("error").getParams().get("key1")); + assertEquals("value-overwritten", results.get("error").getParams().get("key-overwritten")); + assertEquals("value1-overwritten", results.get("error").getParams().get("key1-overwritten")); + EasyMock.verify(context); + } + public void testClassLevelMultipleResultAnnotation() throws Exception { ServletContext context = EasyMock.createStrictMock(ServletContext.class); @@ -192,6 +243,45 @@ public class DefaultResultMapBuilderTest extends TestCase { EasyMock.verify(context); } + public void testClassLevelInheritanceMultipleResultAnnotation() throws Exception { + ServletContext context = EasyMock.createStrictMock(ServletContext.class); + + // Setup some mock jsps + Set resources = new HashSet(); + EasyMock.expect(context.getResourcePaths("/WEB-INF/location/namespace/")).andReturn(resources); + EasyMock.replay(context); + + PackageConfig packageConfig = createPackageConfigBuilder("/namespace"); + + this.conventionsService = new ConventionsServiceImpl("/WEB-INF/location"); + DefaultResultMapBuilder builder = new DefaultResultMapBuilder(context, container, "dispatcher,velocity,freemarker"); + Map results = builder.build(InheritedResultsExtends.class, null, "class-level-results", packageConfig); + assertEquals(4, results.size()); + assertEquals("error", results.get("error").getName()); + assertEquals("input", results.get("input").getName()); + assertEquals("success", results.get("success").getName()); + assertEquals("failure", results.get("failure").getName()); + assertEquals(3, results.get("error").getParams().size()); + assertEquals("org.apache.struts2.dispatcher.ServletDispatcherResult", results.get("error").getClassName()); + assertEquals("/WEB-INF/location/namespace/error.jsp", results.get("error").getParams().get("location")); + assertEquals("ann-value", results.get("error").getParams().get("key")); + assertEquals("ann-value1", results.get("error").getParams().get("key1")); + assertEquals(1, results.get("input").getParams().size()); + assertEquals("foo.action", results.get("input").getParams().get("actionName")); + assertEquals("org.apache.struts2.dispatcher.ServletActionRedirectResult", results.get("input").getClassName()); + assertEquals(3, results.get("failure").getParams().size()); + assertEquals("/WEB-INF/location/namespace/action-failure.jsp", results.get("failure").getParams().get("location")); + assertEquals("org.apache.struts2.dispatcher.ServletDispatcherResult", results.get("failure").getClassName()); + assertEquals("value", results.get("failure").getParams().get("key")); + assertEquals("value1", results.get("failure").getParams().get("key1")); + assertEquals(3, results.get("success").getParams().size()); + assertEquals("/WEB-INF/location/namespace/action-success.jsp", results.get("success").getParams().get("location")); + assertEquals("org.apache.struts2.dispatcher.ServletDispatcherResult", results.get("success").getClassName()); + assertEquals("value", results.get("success").getParams().get("key")); + assertEquals("value1", results.get("success").getParams().get("key1")); + EasyMock.verify(context); + } + public void testActionLevelSingleResultAnnotation() throws Exception { ServletContext context = EasyMock.createStrictMock(ServletContext.class); @@ -254,9 +344,9 @@ public class DefaultResultMapBuilderTest extends TestCase { ServletContext context = EasyMock.createNiceMock(ServletContext.class); ResultTypeConfig resultType = new ResultTypeConfig.Builder("freemarker", "org.apache.struts2.dispatcher.ServletDispatcherResult"). - defaultResultParam("location").build(); + defaultResultParam("location").build(); PackageConfig packageConfig = new PackageConfig.Builder("package"). - defaultResultType("dispatcher").addResultTypeConfig(resultType).build(); + defaultResultType("dispatcher").addResultTypeConfig(resultType).build(); this.conventionsService = new ConventionsServiceImpl("/WEB-INF/component"); DefaultResultMapBuilder builder = new DefaultResultMapBuilder(context, container, "dispatcher,velocity,freemarker"); @@ -278,20 +368,20 @@ public class DefaultResultMapBuilderTest extends TestCase { private PackageConfig createPackageConfigBuilder(String namespace) { ResultTypeConfig resultType = new ResultTypeConfig.Builder("dispatcher", "org.apache.struts2.dispatcher.ServletDispatcherResult"). - addParam("key", "value").addParam("key1", "value1").defaultResultParam("location").build(); + addParam("key", "value").addParam("key1", "value1").defaultResultParam("location").build(); - ResultTypeConfig redirect = new ResultTypeConfig.Builder("redirectAction", - "org.apache.struts2.dispatcher.ServletActionRedirectResult").defaultResultParam("actionName").build(); + ResultTypeConfig redirect = new ResultTypeConfig.Builder("redirectAction", + "org.apache.struts2.dispatcher.ServletActionRedirectResult").defaultResultParam("actionName").build(); ResultTypeConfig ftlResultType = new ResultTypeConfig.Builder("freemarker", - "org.apache.struts2.views.freemarker.FreemarkerResult").defaultResultParam("location").build(); + "org.apache.struts2.views.freemarker.FreemarkerResult").defaultResultParam("location").build(); return new PackageConfig.Builder("package"). - namespace(namespace). - defaultResultType("dispatcher"). - addResultTypeConfig(resultType). - addResultTypeConfig(redirect). - addResultTypeConfig(ftlResultType).build(); + namespace(namespace). + defaultResultType("dispatcher"). + addResultTypeConfig(resultType). + addResultTypeConfig(redirect). + addResultTypeConfig(ftlResultType).build(); } private ServletContext mockServletContext(String resultPath) { @@ -308,7 +398,7 @@ public class DefaultResultMapBuilderTest extends TestCase { } private void verify(ServletContext context, String resultPath, Map results, - boolean redirect) { + boolean redirect) { assertEquals(4, results.size()); assertEquals("success", results.get("success").getName()); assertEquals("input", results.get("input").getName()); diff --git a/plugins/convention/src/test/java/org/apache/struts2/convention/PackageBasedActionConfigBuilderTest.java b/plugins/convention/src/test/java/org/apache/struts2/convention/PackageBasedActionConfigBuilderTest.java index 45f5bf9e7..44202b918 100644 --- a/plugins/convention/src/test/java/org/apache/struts2/convention/PackageBasedActionConfigBuilderTest.java +++ b/plugins/convention/src/test/java/org/apache/struts2/convention/PackageBasedActionConfigBuilderTest.java @@ -28,7 +28,6 @@ import static org.easymock.EasyMock.verify; import java.util.*; import java.net.MalformedURLException; -import java.lang.reflect.Method; import junit.framework.TestCase; @@ -61,6 +60,7 @@ import org.apache.struts2.convention.actions.result.ActionLevelResultAction; import org.apache.struts2.convention.actions.result.ActionLevelResultsAction; import org.apache.struts2.convention.actions.result.ClassLevelResultAction; import org.apache.struts2.convention.actions.result.ClassLevelResultsAction; +import org.apache.struts2.convention.actions.result.InheritedResultExtends; import org.apache.struts2.convention.actions.resultpath.ClassLevelResultPathAction; import org.apache.struts2.convention.actions.resultpath.PackageLevelResultPathAction; import org.apache.struts2.convention.actions.skip.Index; @@ -87,7 +87,6 @@ import com.opensymphony.xwork2.config.impl.DefaultConfiguration; import com.opensymphony.xwork2.inject.Container; import com.opensymphony.xwork2.inject.Scope.Strategy; import com.opensymphony.xwork2.ognl.OgnlReflectionProvider; -import com.opensymphony.xwork2.ognl.OgnlUtil; import javax.servlet.ServletContext; @@ -241,6 +240,7 @@ public class PackageBasedActionConfigBuilderTest extends TestCase { expect(resultMapBuilder.build(ClassLevelResultsAction.class, null, "class-level-results", resultPkg)).andReturn(results); expect(resultMapBuilder.build(ActionLevelResultAction.class, getAnnotation(ActionLevelResultAction.class, "execute", Action.class), "action-level-result", resultPkg)).andReturn(results); expect(resultMapBuilder.build(ActionLevelResultsAction.class, getAnnotation(ActionLevelResultsAction.class, "execute", Action.class), "action-level-results", resultPkg)).andReturn(results); + expect(resultMapBuilder.build(InheritedResultExtends.class, null, "inherited-result-extends", resultPkg)).andReturn(results); /* org.apache.struts2.convention.actions.resultpath */ expect(resultMapBuilder.build(ClassLevelResultPathAction.class, null, "class-level-result-path", resultPathPkg)).andReturn(results); @@ -449,12 +449,13 @@ public class PackageBasedActionConfigBuilderTest extends TestCase { /* org.apache.struts2.convention.actions.result */ pkgConfig = configuration.getPackageConfig("org.apache.struts2.convention.actions.result#struts-default#/result"); assertNotNull(pkgConfig); - assertEquals(4, pkgConfig.getActionConfigs().size()); + assertEquals(5, pkgConfig.getActionConfigs().size()); verifyActionConfig(pkgConfig, "class-level-result", ClassLevelResultAction.class, "execute", pkgConfig.getName()); verifyActionConfig(pkgConfig, "class-level-results", ClassLevelResultsAction.class, "execute", pkgConfig.getName()); verifyActionConfig(pkgConfig, "action-level-result", ActionLevelResultAction.class, "execute", pkgConfig.getName()); verifyActionConfig(pkgConfig, "action-level-results", ActionLevelResultsAction.class, "execute", pkgConfig.getName()); - + verifyActionConfig(pkgConfig, "inherited-result-extends", InheritedResultExtends.class, "execute", pkgConfig.getName()); + /* org.apache.struts2.convention.actions.resultpath */ pkgConfig = configuration.getPackageConfig("org.apache.struts2.convention.actions.resultpath#struts-default#/resultpath"); assertNotNull(pkgConfig); diff --git a/plugins/convention/src/test/java/org/apache/struts2/convention/actions/result/InheritedResultExtends.java b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/result/InheritedResultExtends.java new file mode 100644 index 000000000..ed5eb2b32 --- /dev/null +++ b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/result/InheritedResultExtends.java @@ -0,0 +1,25 @@ +/* + * $Id$ + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.struts2.convention.actions.result; + +public class InheritedResultExtends extends InheritedResultTestBase { + +} \ No newline at end of file diff --git a/plugins/convention/src/test/java/org/apache/struts2/convention/actions/result/InheritedResultTestBase.java b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/result/InheritedResultTestBase.java new file mode 100644 index 000000000..e57e8c393 --- /dev/null +++ b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/result/InheritedResultTestBase.java @@ -0,0 +1,29 @@ +/* + * $Id$ + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.struts2.convention.actions.result; + +import com.opensymphony.xwork2.ActionSupport; +import org.apache.struts2.convention.annotation.Result; + +@Result(name="error", location="error.jsp", params={"key", "value", "key1", "value1"}) +public abstract class InheritedResultTestBase extends ActionSupport { + +} \ No newline at end of file diff --git a/plugins/convention/src/test/java/org/apache/struts2/convention/actions/result/InheritedResultsExtends.java b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/result/InheritedResultsExtends.java new file mode 100644 index 000000000..fc3441c49 --- /dev/null +++ b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/result/InheritedResultsExtends.java @@ -0,0 +1,24 @@ +/* + * $Id$ + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.struts2.convention.actions.result; + +public class InheritedResultsExtends extends InheritedResultsTestBase{ +} diff --git a/plugins/convention/src/test/java/org/apache/struts2/convention/actions/result/InheritedResultsTestBase.java b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/result/InheritedResultsTestBase.java new file mode 100644 index 000000000..0ffa34597 --- /dev/null +++ b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/result/InheritedResultsTestBase.java @@ -0,0 +1,33 @@ +/* + * $Id$ + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.struts2.convention.actions.result; + +import org.apache.struts2.convention.annotation.Results; +import org.apache.struts2.convention.annotation.Result; + +@Results({ + @Result(name="error", location="error.jsp", params={"key", "ann-value", "key1", "ann-value1"}), + @Result(name="input", location="foo.action", type="redirectAction"), + @Result(name="success", location="/WEB-INF/location/namespace/action-success.jsp"), + @Result(name="failure", location="/WEB-INF/location/namespace/action-failure.jsp") +}) +public abstract class InheritedResultsTestBase { +} diff --git a/plugins/convention/src/test/java/org/apache/struts2/convention/actions/result/OverrideInheritedResultExtends.java b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/result/OverrideInheritedResultExtends.java new file mode 100644 index 000000000..d0ed594d4 --- /dev/null +++ b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/result/OverrideInheritedResultExtends.java @@ -0,0 +1,27 @@ +/* + * $Id$ + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.struts2.convention.actions.result; + +import org.apache.struts2.convention.annotation.Result; + +@Result(name="error", location="error.jsp", params={"key-overwritten", "value-overwritten", "key1-overwritten", "value1-overwritten"}) +public class OverrideInheritedResultExtends extends OverrideInheritedResultTestBase { +} diff --git a/plugins/convention/src/test/java/org/apache/struts2/convention/actions/result/OverrideInheritedResultTestBase.java b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/result/OverrideInheritedResultTestBase.java new file mode 100644 index 000000000..7b256f8d4 --- /dev/null +++ b/plugins/convention/src/test/java/org/apache/struts2/convention/actions/result/OverrideInheritedResultTestBase.java @@ -0,0 +1,27 @@ +/* + * $Id$ + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.struts2.convention.actions.result; + +import org.apache.struts2.convention.annotation.Result; + +@Result(name="error", location="error.jsp", params={"key", "value", "key1", "value1"}) +public abstract class OverrideInheritedResultTestBase { +}