1 /**
2 * Copyright 2005-2013 The Kuali Foundation
3 *
4 * Licensed under the Educational Community 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.opensource.org/licenses/ecl2.php
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.kuali.rice.krad.messages;
17
18 import org.apache.commons.lang.StringUtils;
19 import org.kuali.rice.coreservice.framework.CoreFrameworkServiceLocator;
20 import org.kuali.rice.krad.util.KRADConstants;
21
22 import java.util.ArrayList;
23 import java.util.Collection;
24 import java.util.List;
25
26 /**
27 * Implementation of the {@link MessageService} that allows {@link MessageProvider} implementations
28 * to be configured for exposing external message repositories
29 *
30 * <p>
31 * This message service implementation essentially delegates all calls down to one or more message
32 * providers. When more than one message provider is configured, providers higher up in the chain will
33 * receive priority. That is, when finding a message the first provider that has the message will be used
34 * and no others will be consulted. When finding a collection of messages, if the same message (key) exists
35 * from more than one provider, the message from the first encountered provider (in the List) will
36 * be used.
37 * </p>
38 *
39 * <p>
40 * The default namespace and component are constants of the service implementation and may not be changed.
41 * </p>
42 *
43 * @author Kuali Rice Team (rice.collab@kuali.org)
44 */
45 public class MessageServiceImpl implements MessageService {
46 private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(MessageServiceImpl.class);
47
48 private List<MessageProvider> messageProviders;
49
50 /**
51 * @see MessageService#getMessage(java.lang.String, java.lang.String, java.lang.String)
52 */
53 public Message getMessage(String namespace, String component, String key) {
54 return getMessage(namespace, component, key, getDefaultLocaleCode());
55 }
56
57 /**
58 * @see MessageService#getMessage(java.lang.String, java.lang.String, java.lang.String)
59 */
60 public Message getMessage(String namespace, String component, String key, String locale) {
61 Message message = null;
62
63 // use default namespace and component if not given
64 if (StringUtils.isBlank(namespace)) {
65 namespace = DEFAULT_NAMESPACE_CODE;
66 }
67
68 if (StringUtils.isBlank(component)) {
69 component = DEFAULT_COMPONENT_CODE;
70 }
71
72 if (StringUtils.isBlank(locale)) {
73 locale = getDefaultLocaleCode();
74 }
75
76 for (MessageProvider provider : messageProviders) {
77 message = provider.getMessage(namespace, component, key, locale);
78
79 if (message != null) {
80 // don't check with any additional providers
81 break;
82 }
83 }
84
85 return message;
86 }
87
88 /**
89 * @see MessageService#getMessageText(java.lang.String, java.lang.String, java.lang.String)
90 */
91 public String getMessageText(String namespace, String component, String key) {
92 return getMessageText(namespace, component, key, getDefaultLocaleCode());
93 }
94
95 /**
96 * @see MessageService#getMessageText(java.lang.String, java.lang.String, java.lang.String)
97 */
98 public String getMessageText(String namespace, String component, String key, String locale) {
99 Message message = getMessage(namespace, component, key, locale);
100 if (message != null) {
101 return message.getText();
102 }
103
104 return null;
105 }
106
107 /**
108 * @see MessageService#getMessageText(java.lang.String, java.lang.String, java.lang.String)
109 */
110 public String getMessageText(String key) {
111 return getMessageText(key, getDefaultLocaleCode());
112 }
113
114 /**
115 * @see MessageService#getMessageText(java.lang.String, java.lang.String, java.lang.String)
116 */
117 public String getMessageText(String key, String locale) {
118 Message message = getMessage(null, null, key, locale);
119 if (message != null) {
120 return message.getText();
121 }
122
123 return null;
124 }
125
126 /**
127 * @see MessageService#getAllMessagesForComponent(java.lang.String, java.lang.String)
128 */
129 public Collection<Message> getAllMessagesForComponent(String namespace, String component) {
130 return getAllMessagesForComponent(namespace, component, getDefaultLocaleCode());
131 }
132
133 /**
134 * @see MessageService#getAllMessagesForComponent(java.lang.String, java.lang.String)
135 */
136 public Collection<Message> getAllMessagesForComponent(String namespace, String component, String locale) {
137 Collection<Message> messages = new ArrayList<Message>();
138
139 if (StringUtils.isBlank(locale)) {
140 locale = getDefaultLocaleCode();
141 }
142
143 for (MessageProvider provider : messageProviders) {
144 Collection<Message> providerMessages = provider.getAllMessagesForComponent(namespace, component, locale);
145 mergeMessages(messages, providerMessages);
146 }
147
148 return messages;
149 }
150
151 /**
152 * Merges the second collection into the first collection
153 *
154 * <p>
155 * If a message with the same key (namespace, component, and name) is found in both collections, the message
156 * from first collection will remain. That is, the message in the second collection will NOT override
157 * </p>
158 *
159 * @param messages collection to be merged into
160 * @param messagesToMerge collection that will be merged with first
161 */
162 protected void mergeMessages(Collection<Message> messages, Collection<Message> messagesToMerge) {
163 for (Message message : messagesToMerge) {
164 if (!messages.contains(message)) {
165 messages.add(message);
166 }
167 }
168 }
169
170 /**
171 * Retrieves the default locale code configured through a system parameter
172 *
173 * @return String configured default locale
174 */
175 protected String getDefaultLocaleCode() {
176 String localeCode = CoreFrameworkServiceLocator.getParameterService().getParameterValueAsString(
177 KRADConstants.KNS_NAMESPACE, KRADConstants.DetailTypes.ALL_DETAIL_TYPE,
178 KRADConstants.ParameterNames.DEFAULT_LOCALE_CODE);
179
180 // if not configured fall back to english US
181 if (StringUtils.isBlank(localeCode)) {
182 localeCode = "en-US";
183 }
184
185 return localeCode;
186 }
187
188 /**
189 * Retrieves the collection of message providers configured with the message service
190 *
191 * @return List<MessageProvider> message provider implementations
192 */
193 protected List<MessageProvider> getMessageProviders() {
194 return messageProviders;
195 }
196
197 /**
198 * Setter for the collection of message providers that should be used by the message service
199 * implementation
200 *
201 * @param messageProviders
202 */
203 public void setMessageProviders(List<MessageProvider> messageProviders) {
204 this.messageProviders = messageProviders;
205 }
206 }