Browse Source
git-svn-id: https://src.springframework.org/svn/spring-framework/trunk@1397 50f2f4bb-b051-0410-bef5-90022cba6387pull/1/head
25 changed files with 515 additions and 545 deletions
@ -0,0 +1,48 @@
@@ -0,0 +1,48 @@
|
||||
/* |
||||
* Copyright 2004-2009 the original author or authors. |
||||
* |
||||
* 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.springframework.ui.alert; |
||||
|
||||
/** |
||||
* Communicates an event of interest to the user. |
||||
* For example, an alert may inform a user of a web application a business rule was violated. |
||||
* TODO - should we introduce detail messages here |
||||
* @author Keith Donald |
||||
* @since 3.0 |
||||
*/ |
||||
public interface Alert { |
||||
|
||||
/** |
||||
* The user interface element this alert is associated with; for example, "registration.password" |
||||
*/ |
||||
public String getElement(); |
||||
|
||||
/** |
||||
* The code uniquely identifying this kind of alert; for example, "weakPassword". |
||||
* May be used as a key to lookup additional alert details. |
||||
*/ |
||||
public String getCode(); |
||||
|
||||
/** |
||||
* The level of impact this alert has on the user. |
||||
*/ |
||||
public Severity getSeverity(); |
||||
|
||||
/** |
||||
* The localized message to display to the user; for example, "Please enter a stronger password". |
||||
*/ |
||||
public String getMessage(); |
||||
|
||||
} |
||||
@ -0,0 +1,48 @@
@@ -0,0 +1,48 @@
|
||||
/* |
||||
* Copyright 2004-2009 the original author or authors. |
||||
* |
||||
* 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.springframework.ui.alert; |
||||
|
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* A context for adding and getting alerts for display in a user interface. |
||||
* @author Keith Donald |
||||
* @since 3.0 |
||||
*/ |
||||
public interface AlertContext { |
||||
|
||||
/** |
||||
* Return all alerts in this context indexed by the UI element they are associated with. |
||||
* @return the message map |
||||
*/ |
||||
public Map<String, List<Alert>> getAlerts(); |
||||
|
||||
/** |
||||
* Get all alerts on the UI element provided. |
||||
* Returns an empty list if no alerts have been added for the element. |
||||
* Alerts are returned in the order they were added. |
||||
* @param element the id of the element to lookup alerts against |
||||
*/ |
||||
public List<Alert> getAlerts(String element); |
||||
|
||||
/** |
||||
* Add an alert to this context. |
||||
* @param alert the alert to add |
||||
*/ |
||||
public void add(Alert alert); |
||||
|
||||
} |
||||
@ -0,0 +1,7 @@
@@ -0,0 +1,7 @@
|
||||
<html> |
||||
<body> |
||||
<p> |
||||
An API for alerts to display in a user interface. |
||||
</p> |
||||
</body> |
||||
</html> |
||||
@ -0,0 +1,66 @@
@@ -0,0 +1,66 @@
|
||||
/* |
||||
* Copyright 2004-2009 the original author or authors. |
||||
* |
||||
* 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.springframework.ui.alert.support; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.Collections; |
||||
import java.util.LinkedHashMap; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
import org.springframework.core.style.ToStringCreator; |
||||
import org.springframework.ui.alert.Alert; |
||||
import org.springframework.ui.alert.AlertContext; |
||||
import org.springframework.util.CachingMapDecorator; |
||||
|
||||
/** |
||||
* The default alert context implementation. |
||||
* @author Keith Donald |
||||
* @since 3.0 |
||||
*/ |
||||
public class DefaultAlertContext implements AlertContext { |
||||
|
||||
@SuppressWarnings("serial") |
||||
private Map<String, List<Alert>> alertsByElement = new CachingMapDecorator<String, List<Alert>>(new LinkedHashMap<String, List<Alert>>()) { |
||||
protected List<Alert> create(String element) { |
||||
return new ArrayList<Alert>(); |
||||
} |
||||
}; |
||||
|
||||
// implementing AlertContext
|
||||
|
||||
public Map<String, List<Alert>> getAlerts() { |
||||
return Collections.unmodifiableMap(alertsByElement); |
||||
} |
||||
|
||||
public List<Alert> getAlerts(String element) { |
||||
List<Alert> messages = alertsByElement.get(element); |
||||
if (messages.isEmpty()) { |
||||
return Collections.emptyList(); |
||||
} |
||||
return Collections.unmodifiableList(messages); |
||||
} |
||||
|
||||
public void add(Alert alert) { |
||||
List<Alert> alerts = alertsByElement.get(alert.getElement()); |
||||
alerts.add(alert); |
||||
} |
||||
|
||||
public String toString() { |
||||
return new ToStringCreator(this).append("alertsByElement", alertsByElement).toString(); |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,7 @@
@@ -0,0 +1,7 @@
|
||||
<html> |
||||
<body> |
||||
<p> |
||||
Support implementation of the Alert API. |
||||
</p> |
||||
</body> |
||||
</html> |
||||
@ -0,0 +1,14 @@
@@ -0,0 +1,14 @@
|
||||
package org.springframework.ui.binding; |
||||
|
||||
import java.lang.annotation.Documented; |
||||
import java.lang.annotation.ElementType; |
||||
import java.lang.annotation.Retention; |
||||
import java.lang.annotation.RetentionPolicy; |
||||
import java.lang.annotation.Target; |
||||
|
||||
@Target({ElementType.METHOD}) |
||||
@Retention(RetentionPolicy.RUNTIME) |
||||
@Documented |
||||
public @interface Bound { |
||||
|
||||
} |
||||
@ -0,0 +1,25 @@
@@ -0,0 +1,25 @@
|
||||
package org.springframework.ui.binding; |
||||
|
||||
import java.lang.annotation.Documented; |
||||
import java.lang.annotation.ElementType; |
||||
import java.lang.annotation.Retention; |
||||
import java.lang.annotation.RetentionPolicy; |
||||
import java.lang.annotation.Target; |
||||
|
||||
@Target({ElementType.TYPE}) |
||||
@Retention(RetentionPolicy.RUNTIME) |
||||
@Documented |
||||
public @interface Model { |
||||
|
||||
/** |
||||
* The name of the model |
||||
*/ |
||||
String value() default ""; |
||||
|
||||
/** |
||||
* Configures strict model binding. |
||||
* @see Binder#setStrict(boolean) |
||||
*/ |
||||
boolean strict() default false; |
||||
|
||||
} |
||||
@ -1,41 +0,0 @@
@@ -1,41 +0,0 @@
|
||||
/* |
||||
* Copyright 2004-2009 the original author or authors. |
||||
* |
||||
* 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.springframework.ui.message; |
||||
|
||||
/** |
||||
* Communicates information of interest to the user. |
||||
* For example, a error message may inform a user of a web application a business rule was violated. |
||||
* TODO - should we introduce summary/detail fields instead of just text |
||||
* @author Keith Donald |
||||
* @since 3.0 |
||||
*/ |
||||
public interface Message { |
||||
|
||||
/** |
||||
* The severity of this message. |
||||
* The severity indicates the intensity or priority of the message. |
||||
* @return the message severity |
||||
*/ |
||||
public Severity getSeverity(); |
||||
|
||||
/** |
||||
* The message text. |
||||
* The text is the message's communication payload. |
||||
* @return the message text |
||||
*/ |
||||
public String getText(); |
||||
|
||||
} |
||||
@ -1,49 +0,0 @@
@@ -1,49 +0,0 @@
|
||||
/* |
||||
* Copyright 2004-2009 the original author or authors. |
||||
* |
||||
* 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.springframework.ui.message; |
||||
|
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* A context for recording and retrieving messages for display in a user interface. |
||||
* @author Keith Donald |
||||
* @since 3.0 |
||||
*/ |
||||
public interface MessageContext { |
||||
|
||||
/** |
||||
* Return all messages in this context indexed by the UI element they are associated with. |
||||
* @return the message map |
||||
*/ |
||||
public Map<String, List<Message>> getMessages(); |
||||
|
||||
/** |
||||
* Get all messages on the UI element provided. |
||||
* Returns an empty list if no messages have been recorded against the element. |
||||
* Messages are returned in the order they were added. |
||||
* @param element the id of the element to lookup messages against |
||||
*/ |
||||
public List<Message> getMessages(String element); |
||||
|
||||
/** |
||||
* Add a new message to an element. |
||||
* @param message the resolver that will resolve the message to be added; typically constructed by a {@link MessageBuilder}. |
||||
* @param element the id of the UI element the message should be associated with |
||||
*/ |
||||
public void add(MessageResolver message, String element); |
||||
|
||||
} |
||||
@ -1,7 +1,7 @@
@@ -1,7 +1,7 @@
|
||||
<html> |
||||
<body> |
||||
<p> |
||||
An API for creating and managing localized messages to display in a UI. |
||||
An API for creating localized messages to display in a user interface. |
||||
</p> |
||||
</body> |
||||
</html> |
||||
@ -1,118 +0,0 @@
@@ -1,118 +0,0 @@
|
||||
/* |
||||
* Copyright 2004-2009 the original author or authors. |
||||
* |
||||
* 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.springframework.ui.message.support; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.Collections; |
||||
import java.util.LinkedHashMap; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
import org.springframework.context.MessageSource; |
||||
import org.springframework.context.i18n.LocaleContextHolder; |
||||
import org.springframework.core.style.ToStringCreator; |
||||
import org.springframework.ui.message.Message; |
||||
import org.springframework.ui.message.MessageContext; |
||||
import org.springframework.ui.message.MessageResolver; |
||||
import org.springframework.ui.message.Severity; |
||||
import org.springframework.util.Assert; |
||||
import org.springframework.util.CachingMapDecorator; |
||||
|
||||
/** |
||||
* The default message context implementation. |
||||
* Uses a {@link MessageSource} to resolve messages that are added by callers. |
||||
* @author Keith Donald |
||||
* @since 3.0 |
||||
*/ |
||||
public class DefaultMessageContext implements MessageContext { |
||||
|
||||
private final MessageSource messageSource; |
||||
|
||||
@SuppressWarnings("serial") |
||||
private Map<String, List<Message>> messagesByElement = new CachingMapDecorator<String, List<Message>>(new LinkedHashMap<String, List<Message>>()) { |
||||
protected List<Message> create(String element) { |
||||
return new ArrayList<Message>(); |
||||
} |
||||
}; |
||||
|
||||
/** |
||||
* Creates a new default message context. |
||||
* @param messageSource the message source to resolve messages added to this context |
||||
*/ |
||||
public DefaultMessageContext(MessageSource messageSource) { |
||||
Assert.notNull(messageSource, "The MessageSource is required"); |
||||
this.messageSource = messageSource; |
||||
} |
||||
|
||||
/** |
||||
* The message source configured to resolve message text. |
||||
* @return the message source |
||||
*/ |
||||
public MessageSource getMessageSource() { |
||||
return messageSource; |
||||
} |
||||
|
||||
// implementing message context
|
||||
|
||||
public Map<String, List<Message>> getMessages() { |
||||
return Collections.unmodifiableMap(messagesByElement); |
||||
} |
||||
|
||||
public List<Message> getMessages(String element) { |
||||
List<Message> messages = messagesByElement.get(element); |
||||
if (messages.isEmpty()) { |
||||
return Collections.emptyList(); |
||||
} |
||||
return Collections.unmodifiableList(messages); |
||||
} |
||||
|
||||
public void add(MessageResolver messageResolver, String element) { |
||||
List<Message> messages = messagesByElement.get(element); |
||||
messages.add(new ResolvableMessage(messageResolver)); |
||||
} |
||||
|
||||
public String toString() { |
||||
return new ToStringCreator(this).append("messagesByElement", messagesByElement).toString(); |
||||
} |
||||
|
||||
// internal helpers
|
||||
|
||||
class ResolvableMessage implements Message { |
||||
|
||||
private MessageResolver resolver; |
||||
|
||||
private Message resolvedMessage; |
||||
|
||||
public ResolvableMessage(MessageResolver resolver) { |
||||
this.resolver = resolver; |
||||
} |
||||
|
||||
public Severity getSeverity() { |
||||
return getMessage().getSeverity(); |
||||
} |
||||
|
||||
public String getText() { |
||||
return getMessage().getText(); |
||||
} |
||||
|
||||
public Message getMessage() { |
||||
if (resolvedMessage == null) { |
||||
resolvedMessage = resolver.resolveMessage(messageSource, LocaleContextHolder.getLocale()); |
||||
} |
||||
return resolvedMessage; |
||||
} |
||||
} |
||||
} |
||||
@ -1,7 +0,0 @@
@@ -1,7 +0,0 @@
|
||||
<html> |
||||
<body> |
||||
<p> |
||||
Support implementation of the MessageContext API. |
||||
</p> |
||||
</body> |
||||
</html> |
||||
@ -0,0 +1,43 @@
@@ -0,0 +1,43 @@
|
||||
package org.springframework.ui.alert; |
||||
|
||||
import static org.junit.Assert.assertEquals; |
||||
|
||||
import org.junit.Before; |
||||
import org.junit.Test; |
||||
import org.springframework.ui.alert.Alert; |
||||
import org.springframework.ui.alert.Severity; |
||||
import org.springframework.ui.alert.support.DefaultAlertContext; |
||||
|
||||
public class DefaultMessageContextTests { |
||||
|
||||
private DefaultAlertContext context; |
||||
|
||||
@Before |
||||
public void setUp() { |
||||
context = new DefaultAlertContext(); |
||||
} |
||||
|
||||
@Test |
||||
public void addAlert() { |
||||
Alert alert = new Alert() { |
||||
public String getElement() { |
||||
return "form.property"; |
||||
} |
||||
|
||||
public String getCode() { |
||||
return "invalidFormat"; |
||||
} |
||||
|
||||
public String getMessage() { |
||||
return "Please enter a value in format yyy-dd-mm"; |
||||
} |
||||
|
||||
public Severity getSeverity() { |
||||
return Severity.ERROR; |
||||
} |
||||
}; |
||||
context.add(alert); |
||||
assertEquals(1, context.getAlerts().size()); |
||||
assertEquals("invalidFormat", context.getAlerts("form.property").get(0).getCode()); |
||||
} |
||||
} |
||||
@ -1,49 +0,0 @@
@@ -1,49 +0,0 @@
|
||||
package org.springframework.ui.message.support; |
||||
|
||||
import static org.junit.Assert.assertEquals; |
||||
|
||||
import java.util.List; |
||||
import java.util.Locale; |
||||
import java.util.Map; |
||||
|
||||
import org.junit.After; |
||||
import org.junit.Before; |
||||
import org.junit.Test; |
||||
import org.springframework.context.i18n.LocaleContextHolder; |
||||
import org.springframework.ui.message.ResolvableArgument; |
||||
import org.springframework.ui.message.Message; |
||||
import org.springframework.ui.message.MessageBuilder; |
||||
import org.springframework.ui.message.MessageResolver; |
||||
import org.springframework.ui.message.MockMessageSource; |
||||
import org.springframework.ui.message.Severity; |
||||
|
||||
public class DefaultMessageContextTests { |
||||
|
||||
private DefaultMessageContext context; |
||||
|
||||
@Before |
||||
public void setUp() { |
||||
MockMessageSource messageSource = new MockMessageSource(); |
||||
messageSource.addMessage("invalidFormat", Locale.US, "#{label} must be in format #{format}"); |
||||
messageSource.addMessage("mathForm.decimalField", Locale.US, "Decimal Field"); |
||||
context = new DefaultMessageContext(messageSource); |
||||
LocaleContextHolder.setLocale(Locale.US); |
||||
} |
||||
|
||||
@After |
||||
public void tearDown() { |
||||
LocaleContextHolder.setLocale(null); |
||||
} |
||||
|
||||
@Test |
||||
public void addMessage() { |
||||
MessageBuilder builder = new MessageBuilder(); |
||||
MessageResolver message = builder.severity(Severity.ERROR).code("invalidFormat").arg("label", new ResolvableArgument("mathForm.decimalField")). |
||||
arg("format", "#,###.##").defaultText("Field must be in format #,###.##").build(); |
||||
context.add(message, "mathForm.decimalField"); |
||||
Map<String, List<Message>> messages = context.getMessages(); |
||||
assertEquals(1, messages.size()); |
||||
assertEquals("Decimal Field must be in format #,###.##", messages.get("mathForm.decimalField").get(0).getText()); |
||||
assertEquals("Decimal Field must be in format #,###.##", context.getMessages("mathForm.decimalField").get(0).getText()); |
||||
} |
||||
} |
||||
Loading…
Reference in new issue