Skip to content

Commit 6130538

Browse files
committed
Allow multiple and implement PR feedback
1 parent 67de9bf commit 6130538

File tree

8 files changed

+83
-58
lines changed

8 files changed

+83
-58
lines changed

src/main/java/org/primeframework/mvc/action/annotation/MessageResources.java renamed to src/main/java/org/primeframework/mvc/action/annotation/AlternateMessageResources.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,18 @@
2121
import java.lang.annotation.Target;
2222

2323
/**
24-
* Tells Prime MVC to customize message resource behavior for an action class
24+
* Customize message resource behavior for an action class
2525
*
2626
* @author Brady Wied
2727
*/
2828
@Retention(RetentionPolicy.RUNTIME)
2929
@Target(ElementType.TYPE)
30-
public @interface MessageResources {
30+
public @interface AlternateMessageResources {
3131
/**
32-
* @return Prime MVC, by default, will look for messages, via the {@link org.primeframework.mvc.message.l10n.MessageProvider}
32+
* @return By default, will look for messages, via the {@link org.primeframework.mvc.message.l10n.MessageProvider}
3333
* interface, in an implementation specific search path (see {@link org.primeframework.mvc.message.l10n.ResourceBundleMessageProvider} for an
3434
* example).
3535
* If you want an additional action's messages in the search path, use this attribute.
3636
*/
37-
Class<?> fallback();
37+
Class<?>[] actions();
3838
}

src/main/java/org/primeframework/mvc/action/config/ActionConfiguration.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ public class ActionConfiguration {
6060

6161
public final Map<HTTPMethod, ExecuteMethodConfiguration> executeMethods;
6262

63-
public final String fallbackMessageResourcesPath;
63+
public final List<String> fallbackActionMessageURIs;
6464

6565
public final Map<String, FileUpload> fileUploadMembers;
6666

@@ -125,15 +125,15 @@ public ActionConfiguration(Class<?> actionClass,
125125
List<Method> preValidationMethods,
126126
Field unknownParametersField,
127127
Set<String> validContentTypes,
128-
String fallbackMessageResourcesPath) {
128+
List<String> fallbackActionMessageURIs) {
129129
Objects.requireNonNull(actionClass);
130130

131131
this.actionClass = actionClass;
132132
this.allowUnknownParameters = allowUnknownParameters;
133133
this.constraintValidationMethods = constraintValidationMethods;
134134
this.formPrepareMethods = formPrepareMethods;
135135
this.authorizationMethods = authorizationMethods;
136-
this.fallbackMessageResourcesPath = fallbackMessageResourcesPath;
136+
this.fallbackActionMessageURIs = fallbackActionMessageURIs;
137137
this.jwtAuthorizationMethods = jwtAuthorizationMethods;
138138
this.preValidationMethods = preValidationMethods;
139139
this.postValidationMethods = postValidationMethods;

src/main/java/org/primeframework/mvc/action/config/DefaultActionConfigurationBuilder.java

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import java.util.HashMap;
2828
import java.util.List;
2929
import java.util.Map;
30+
import java.util.Optional;
3031
import java.util.Set;
3132
import java.util.function.BiFunction;
3233
import java.util.function.Function;
@@ -44,7 +45,7 @@
4445
import org.primeframework.mvc.action.ValidationMethodConfiguration;
4546
import org.primeframework.mvc.action.annotation.Action;
4647
import org.primeframework.mvc.action.annotation.AllowUnknownParameters;
47-
import org.primeframework.mvc.action.annotation.MessageResources;
48+
import org.primeframework.mvc.action.annotation.AlternateMessageResources;
4849
import org.primeframework.mvc.action.result.annotation.ResultAnnotation;
4950
import org.primeframework.mvc.action.result.annotation.ResultContainerAnnotation;
5051
import org.primeframework.mvc.content.ValidContentTypes;
@@ -137,13 +138,13 @@ public ActionConfiguration build(Class<?> actionClass) {
137138
Field unknownParametersField = findUnknownParametersField(actionClass);
138139
Set<String> validContentTypes = findAllowedContentTypes(actionClass);
139140

140-
MessageResources messageResources = actionClass.getAnnotation(MessageResources.class);
141-
String fallbackMessageResourcesPath = null;
142-
if (messageResources != null) {
143-
fallbackMessageResourcesPath = uriBuilder.build(messageResources.fallback());
144-
}
141+
List<String> fallbackActionMessageURIs = Optional.ofNullable(actionClass.getAnnotation(AlternateMessageResources.class))
142+
.map(alternates -> Arrays.stream(alternates.actions())
143+
.map(uriBuilder::build)
144+
.toList())
145+
.orElse(List.of());
145146

146-
return new ActionConfiguration(actionClass, allowKnownParameters, constraintValidationMethods, executeMethods, validationMethods, formPrepareMethods, authorizationMethods, jwtAuthorizationMethods, postValidationMethods, preParameterMethods, postParameterMethods, resultAnnotations, preParameterMembers, preRenderMethodsMap, fileUploadMembers, memberNames, securitySchemes, scopeFields, additionalConfiguration, uri, preValidationMethods, unknownParametersField, validContentTypes, fallbackMessageResourcesPath);
147+
return new ActionConfiguration(actionClass, allowKnownParameters, constraintValidationMethods, executeMethods, validationMethods, formPrepareMethods, authorizationMethods, jwtAuthorizationMethods, postValidationMethods, preParameterMethods, postParameterMethods, resultAnnotations, preParameterMembers, preRenderMethodsMap, fileUploadMembers, memberNames, securitySchemes, scopeFields, additionalConfiguration, uri, preValidationMethods, unknownParametersField, validContentTypes, fallbackActionMessageURIs);
147148
}
148149

149150
/**

src/main/java/org/primeframework/mvc/message/l10n/ResourceBundleMessageProvider.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,15 @@
1818
import java.util.Formatter;
1919
import java.util.LinkedList;
2020
import java.util.MissingResourceException;
21+
import java.util.Objects;
2122
import java.util.Queue;
2223
import java.util.ResourceBundle;
2324
import java.util.ResourceBundle.Control;
2425

2526
import com.google.inject.Inject;
2627
import org.primeframework.mvc.action.ActionInvocation;
2728
import org.primeframework.mvc.action.ActionInvocationStore;
29+
import org.primeframework.mvc.action.annotation.AlternateMessageResources;
2830
import org.primeframework.mvc.action.config.ActionConfiguration;
2931
import org.primeframework.mvc.locale.LocaleProvider;
3032
import org.slf4j.Logger;
@@ -121,7 +123,7 @@ protected Queue<String> determineBundles(String bundle) {
121123

122124
/**
123125
* Finds the message in a resource bundle using the search method described in the class comment.
124-
* If the action was annotated with a {@link org.primeframework.mvc.action.annotation.MessageResources} annotation
126+
* If the action was annotated with a {@link AlternateMessageResources} annotation
125127
* and the message was not found with the request's action, that action will be searched as well.
126128
*
127129
* @param actionInvocation The action invocation.
@@ -135,8 +137,12 @@ protected String findMessage(ActionInvocation actionInvocation, String key) {
135137
}
136138

137139
ActionConfiguration config = actionInvocation.configuration;
138-
if (config != null && config.fallbackMessageResourcesPath != null) {
139-
return findMessage(config.fallbackMessageResourcesPath, key);
140+
if (config != null) {
141+
return config.fallbackActionMessageURIs.stream()
142+
.map(uri -> findMessage(uri, key))
143+
.filter(Objects::nonNull)
144+
.findFirst()
145+
.orElse(null);
140146
}
141147

142148
return null;

src/test/java/org/example/action/MessageResourcesAnnotatedAction.java renamed to src/test/java/org/example/action/AlternateMessageResourcesAnnotatedAction.java

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,37 +18,34 @@
1818
import com.google.inject.Inject;
1919
import org.example.action.nested.NestedMessageAction;
2020
import org.primeframework.mvc.action.annotation.Action;
21-
import org.primeframework.mvc.action.annotation.MessageResources;
21+
import org.primeframework.mvc.action.annotation.AlternateMessageResources;
2222
import org.primeframework.mvc.action.result.annotation.Status;
2323
import org.primeframework.mvc.message.MessageStore;
2424
import org.primeframework.mvc.message.MessageType;
2525
import org.primeframework.mvc.message.SimpleMessage;
2626
import org.primeframework.mvc.message.l10n.MessageProvider;
27-
import org.primeframework.mvc.message.l10n.MissingMessageException;
2827

2928
@Action
3029
@Status
31-
@MessageResources(fallback = NestedMessageAction.class)
32-
public class MessageResourcesAnnotatedAction {
30+
@AlternateMessageResources(actions = NestedMessageAction.class)
31+
public class AlternateMessageResourcesAnnotatedAction {
3332
private final MessageProvider messageProvider;
3433

3534
private final MessageStore messageStore;
3635

36+
public String messageKey;
37+
3738
@Inject
38-
public MessageResourcesAnnotatedAction(MessageProvider messageProvider, MessageStore messageStore) {
39+
public AlternateMessageResourcesAnnotatedAction(MessageProvider messageProvider, MessageStore messageStore) {
3940
this.messageProvider = messageProvider;
4041
this.messageStore = messageStore;
4142
}
4243

4344
public String get() {
4445
try {
45-
// this message exists in a standard path by convention - src/test/web/messages/message-resources-annotated.properties
46-
messageStore.add(new SimpleMessage(MessageType.INFO, "normal_message", messageProvider.getMessage("normal_message")));
47-
// this message only exists in NestedMessageAction's path - in src/test/web/messages/nested/nested-message.properties
48-
messageStore.add(new SimpleMessage(MessageType.INFO, "nested_message", messageProvider.getMessage("nested_message")));
49-
} catch (MissingMessageException e) {
50-
e.printStackTrace();
51-
throw new RuntimeException(e);
46+
messageStore.add(new SimpleMessage(MessageType.INFO, messageKey, messageProvider.getMessage(messageKey)));
47+
} catch (Exception e) {
48+
messageStore.add(new SimpleMessage(MessageType.ERROR, messageKey, "not found"));
5249
}
5350
return "success";
5451
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Copyright (c) 2024, Inversoft Inc., All Rights Reserved
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing,
11+
* software distributed under the License is distributed on an
12+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13+
* either express or implied. See the License for the specific
14+
* language governing permissions and limitations under the License.
15+
*/
16+
package org.primeframework.mvc.message;
17+
18+
import org.primeframework.mvc.PrimeBaseTest;
19+
import org.testng.annotations.Test;
20+
21+
public class AlternateMessageResourcesTest extends PrimeBaseTest {
22+
@Test
23+
public void action_has_message() {
24+
// this message exists in a standard path by convention - src/test/web/messages/message-resources-annotated.properties
25+
simulator.test("/alternate-message-resources-annotated")
26+
.withParameter("messageKey", "normal_message")
27+
.get()
28+
.assertStatusCode(200)
29+
.assertContainsGeneralMessageCodes(MessageType.INFO, "normal_message");
30+
}
31+
32+
@Test
33+
public void none_of_them_have_message() {
34+
simulator.test("/alternate-message-resources-annotated")
35+
.withParameter("messageKey", "foobar")
36+
.get()
37+
.assertStatusCode(200)
38+
.assertContainsGeneralMessageCodes(MessageType.ERROR, "foobar");
39+
}
40+
41+
@Test
42+
public void other_action_has_message() {
43+
// this message only exists in NestedMessageAction's path - in src/test/web/messages/nested/nested-message.properties
44+
simulator.test("/alternate-message-resources-annotated")
45+
.withParameter("messageKey", "nested_message")
46+
.get()
47+
.assertStatusCode(200)
48+
.assertContainsGeneralMessageCodes(MessageType.INFO, "nested_message");
49+
}
50+
}

src/test/java/org/primeframework/mvc/message/MessageResourcesTest.java

Lines changed: 0 additions & 29 deletions
This file was deleted.

0 commit comments

Comments
 (0)