001 /** 002 * Copyright 2005-2014 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 package org.kuali.rice.krad.messages; 017 018 import org.apache.commons.lang.StringUtils; 019 import org.kuali.rice.coreservice.framework.CoreFrameworkServiceLocator; 020 import org.kuali.rice.krad.util.KRADConstants; 021 022 import java.util.ArrayList; 023 import java.util.Collection; 024 import java.util.List; 025 026 /** 027 * Implementation of the {@link MessageService} that allows {@link MessageProvider} implementations 028 * to be configured for exposing external message repositories 029 * 030 * <p> 031 * This message service implementation essentially delegates all calls down to one or more message 032 * providers. When more than one message provider is configured, providers higher up in the chain will 033 * receive priority. That is, when finding a message the first provider that has the message will be used 034 * and no others will be consulted. When finding a collection of messages, if the same message (key) exists 035 * from more than one provider, the message from the first encountered provider (in the List) will 036 * be used. 037 * </p> 038 * 039 * <p> 040 * The default namespace and component are constants of the service implementation and may not be changed. 041 * </p> 042 * 043 * @author Kuali Rice Team (rice.collab@kuali.org) 044 */ 045 public class MessageServiceImpl implements MessageService { 046 private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(MessageServiceImpl.class); 047 048 private List<MessageProvider> messageProviders; 049 050 /** 051 * @see MessageService#getMessage(java.lang.String, java.lang.String, java.lang.String) 052 */ 053 public Message getMessage(String namespace, String component, String key) { 054 return getMessage(namespace, component, key, getDefaultLocaleCode()); 055 } 056 057 /** 058 * @see MessageService#getMessage(java.lang.String, java.lang.String, java.lang.String) 059 */ 060 public Message getMessage(String namespace, String component, String key, String locale) { 061 Message message = null; 062 063 // use default namespace and component if not given 064 if (StringUtils.isBlank(namespace)) { 065 namespace = DEFAULT_NAMESPACE_CODE; 066 } 067 068 if (StringUtils.isBlank(component)) { 069 component = DEFAULT_COMPONENT_CODE; 070 } 071 072 if (StringUtils.isBlank(locale)) { 073 locale = getDefaultLocaleCode(); 074 } 075 076 for (MessageProvider provider : messageProviders) { 077 message = provider.getMessage(namespace, component, key, locale); 078 079 if (message != null) { 080 // don't check with any additional providers 081 break; 082 } 083 } 084 085 return message; 086 } 087 088 /** 089 * @see MessageService#getMessageText(java.lang.String, java.lang.String, java.lang.String) 090 */ 091 public String getMessageText(String namespace, String component, String key) { 092 return getMessageText(namespace, component, key, getDefaultLocaleCode()); 093 } 094 095 /** 096 * @see MessageService#getMessageText(java.lang.String, java.lang.String, java.lang.String) 097 */ 098 public String getMessageText(String namespace, String component, String key, String locale) { 099 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 }