1 /*
2 * $Id$
3 *
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
19 * under the License.
20 */
21
22 package org.apache.struts.faces.util;
23
24
25 import java.util.Collection;
26 import java.util.Locale;
27 import java.util.Map;
28 import java.util.Objects;
29 import java.util.Set;
30
31 import org.apache.struts.util.MessageResources;
32
33
34 /**
35 * A limited immutable {@code Map} implementation that wraps the
36 * {@code MessageResources} instance for the specified {@code Locale}.
37 * Exposing the messages as a {@code Map} makes them easily accessible
38 * via value binding expressions, as well as JSP 2.0 expression
39 * language expressions.
40 */
41 public class MessagesMap implements Map<String, String> {
42
43
44 // ------------------------------------------------------ Instance Variables
45
46
47 /**
48 * The {@code Locale} for which to return messages, or
49 * {@code null} for the system default {@code Locale}.
50 */
51 private final Locale locale;
52
53
54 /**
55 * The {@code MessageResources} being wrapped by this
56 * {@link MessagesMap}.
57 */
58 private final MessageResources messages;
59
60
61 // ------------------------------------------------------------ Constructors
62
63
64 /**
65 * Construct a new {@link MessagesMap} instance that wraps the specified
66 * {@code MessageResources} instance, and returns messages for the
67 * specified {@code Locale}.
68 *
69 * @param messages {@code MessageResources} instance to wrap
70 * @param locale {@code Locale} for which to retrieve messages, or
71 * {@code null} for the system default {@code Locale}
72 *
73 * @throws NullPointerException if {@code messages} is {@code null}
74 */
75 public MessagesMap(MessageResources messages, Locale locale) {
76 super();
77 if (messages == null) {
78 throw new NullPointerException();
79 }
80 this.messages = messages;
81 this.locale = locale;
82 }
83
84
85 // ---------------------------------------------------------- Public Methods
86
87
88 /**
89 * The {@code clear()} method is not supported.
90 */
91 public void clear() {
92 throw new UnsupportedOperationException();
93 }
94
95
96 /**
97 * Return {@code true} if there is a message for the specified key.
98 *
99 * @param key Message key to evaluate
100 */
101 public boolean containsKey(Object key) {
102 return key != null && messages.isPresent(locale, key.toString());
103 }
104
105
106 /**
107 * The {@code containsValue()} method is not supported.
108 *
109 * @param value Value to evaluate
110 */
111 public boolean containsValue(Object value) {
112 throw new UnsupportedOperationException();
113 }
114
115
116 /**
117 * The {@code entrySet()} method is not supported.
118 */
119 public Set<Map.Entry<String, String>> entrySet() {
120 throw new UnsupportedOperationException();
121 }
122
123
124 /**
125 * The {@code equals} method checks whether equal
126 * {@code MessageResources} and {@code Locale} are
127 * being wrapped.
128 *
129 * @param o The object to be compared
130 */
131 public boolean equals(Object o) {
132 if (this == o) {
133 return true;
134 }
135
136 if (o == null) {
137 return false;
138 }
139
140 if (getClass() != o.getClass()) {
141 return (false);
142 }
143
144 final MessagesMap other = (MessagesMap) o;
145 if (!messages.equals(other.getMessages())) {
146 return false;
147 }
148
149 return Objects.equals(locale, other.locale);
150 }
151
152
153 /**
154 * Return the message string for the specified key.
155 *
156 * @param key Key for message to return
157 */
158 public String get(Object key) {
159 if (key == null) {
160 return "??????";
161 } else {
162 return messages.getMessage(locale, key.toString());
163 }
164 }
165
166
167 /**
168 * The {@code hashCode()} method returns values that will be
169 * identical if the {@code equals} method returns {@code true}.
170 */
171 @Override
172 public int hashCode() {
173 int value = messages.hashCode();
174 if (locale != null) {
175 value = value ^ locale.hashCode();
176 }
177 return value;
178 }
179
180
181 /**
182 * The {@code isEmpty()} method returns {@code false}, on the
183 * assumption that there is always at least one message available.
184 */
185 public boolean isEmpty() {
186 return false;
187 }
188
189
190 /**
191 * The {@code keySet()} method is not supported.
192 */
193 public Set<String> keySet() {
194 throw new UnsupportedOperationException();
195 }
196
197
198 /**
199 * The {@code put()} method is not supported.
200 *
201 * @param key Key to store
202 * @param value Value to store
203 */
204 public String put(String key, String value) {
205 throw new UnsupportedOperationException();
206 }
207
208
209 /**
210 * The {@code putAll()} method is not supported.
211 *
212 * @param map Keys and values to store
213 */
214 public void putAll(Map<? extends String, ? extends String> map) {
215 throw new UnsupportedOperationException();
216 }
217
218
219 /**
220 * The {@code remove()} method is not supported.
221 *
222 * @param key Key to remove
223 */
224 public String remove(Object key) {
225 throw new UnsupportedOperationException();
226 }
227
228
229 /**
230 * The {@code size()} method is not supported.
231 */
232 public int size() {
233 throw new UnsupportedOperationException();
234 }
235
236
237 /**
238 * The {@code values()} method is not supported.
239 */
240 public Collection<String> values() {
241 throw new UnsupportedOperationException();
242 }
243
244
245 // --------------------------------------------------------- Package Methods
246
247
248 /**
249 * Return the {@code Locale} we object we are wrapping.
250 */
251 Locale getLocale() {
252 return this.locale;
253 }
254
255
256 /**
257 * Return the {@code MessageResources} object we are wrapping.
258 */
259 MessageResources getMessages() {
260 return this.messages;
261 }
262
263
264 }