DefaultMessageResolver.java 4.7 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/*
 * 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.Locale;
19
import java.util.Map;
20 21 22 23

import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceResolvable;
import org.springframework.core.style.ToStringCreator;
24 25 26 27 28 29 30 31 32 33
import org.springframework.expression.AccessException;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.EvaluationException;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.ParseException;
import org.springframework.expression.ParserContext;
import org.springframework.expression.PropertyAccessor;
import org.springframework.expression.TypedValue;
import org.springframework.expression.spel.support.StandardEvaluationContext;
34

K
Keith Donald 已提交
35
final class DefaultMessageResolver implements MessageResolver, MessageSourceResolvable {
36 37 38 39 40

	private Severity severity;

	private String[] codes;

41
	private Map<String, Object> args;
42

43 44
	private String defaultText;

45 46
	private ExpressionParser expressionParser;

47 48
	public DefaultMessageResolver(Severity severity, String[] codes, Map<String, Object> args, String defaultText,
			ExpressionParser expressionParser) {
49 50 51 52
		this.severity = severity;
		this.codes = codes;
		this.args = args;
		this.defaultText = defaultText;
53
		this.expressionParser = expressionParser;
54
	}
55

56 57 58
	// implementing MessageResolver

	public Message resolveMessage(MessageSource messageSource, Locale locale) {
59 60 61 62 63 64 65 66 67 68
		String messageString = messageSource.getMessage(this, locale);
		Expression message;
		try {
			message = expressionParser.parseExpression(messageString, ParserContext.TEMPLATE_EXPRESSION);
		} catch (ParseException e) {
			throw new MessageResolutionException("Failed to parse message expression", e);
		}
		try {
			StandardEvaluationContext context = new StandardEvaluationContext();
			context.setRootObject(args);
69
			context.addPropertyAccessor(new MessageArgumentAccessor(messageSource, locale));
70 71 72 73 74
			String text = (String) message.getValue(context);
			return new TextMessage(severity, text);
		} catch (EvaluationException e) {
			throw new MessageResolutionException("Failed to evaluate expression to generate message text", e);
		}
75 76 77 78 79 80 81 82 83
	}

	// implementing MessageSourceResolver

	public String[] getCodes() {
		return codes;
	}

	public Object[] getArguments() {
84
		return null;
85 86 87 88 89 90 91
	}

	public String getDefaultMessage() {
		return defaultText;
	}

	public String toString() {
92 93
		return new ToStringCreator(this).append("severity", severity).append("codes", codes).append("defaultText",
				defaultText).toString();
94
	}
95

K
javadoc  
Keith Donald 已提交
96
	private static class TextMessage implements Message {
97 98

		private Severity severity;
99

100
		private String text;
101

102 103 104 105
		public TextMessage(Severity severity, String text) {
			this.severity = severity;
			this.text = text;
		}
106

107 108 109 110 111 112 113
		public Severity getSeverity() {
			return severity;
		}

		public String getText() {
			return text;
		}
114 115 116

	}

117
	static class MessageArgumentAccessor implements PropertyAccessor {
118 119 120 121

		private MessageSource messageSource;
		
		private Locale locale;
122 123

		public MessageArgumentAccessor(MessageSource messageSource, Locale locale) {
124 125 126 127 128
			this.messageSource = messageSource;
			this.locale = locale;
		}

		public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException {
129
			return (((Map) target).containsKey(name));
130 131 132
		}

		public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException {
133 134 135 136 137 138 139
			Object o = ((Map) target).get(name);
			if (o instanceof MessageSourceResolvable) {
				String message = messageSource.getMessage((MessageSourceResolvable) o, locale);
				return new TypedValue(message);
			} else {
				return new TypedValue(o);
			}
140
		}
141
		
142 143 144 145
		public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException {
			return false;
		}

146 147
		public void write(EvaluationContext context, Object target, String name, Object newValue)
				throws AccessException {
148 149
			throw new UnsupportedOperationException("Should not be called");
		}
150
		
151 152 153 154
		public Class[] getSpecificTargetClasses() {
			return new Class[] { Map.class };
		}

155
	}
156

157
}