/* ================================================================== * PrefixedMessageSource.java - Mar 25, 2012 3:27:31 PM * * Copyright 2007-2012 SolarNetwork.net Dev Team * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA * 02111-1307 USA * ================================================================== */ package net.solarnetwork.node.util; import java.util.Locale; import org.springframework.context.HierarchicalMessageSource; import org.springframework.context.MessageSource; import org.springframework.context.MessageSourceResolvable; import org.springframework.context.NoSuchMessageException; /** * Delegating {@link MessageSource} that dynamically removes a pre-configured * prefix from all message codes. * * <p> * The inspiration for this class was to support messages for objects that might * be nested in other objects used in * {@link net.solarnetwork.node.settings.SettingSpecifierProvider} * implementations. When one provider proxies another, or uses nested bean * paths, this class can be used to dynamically re-map message codes. For * example a code <code>delegate.url</code> could be re-mapped to * <code>url</code>. * </p> * * <p> * The configurable properties of this class are: * </p> * * <dl class="class-properties"> * <dt>prefix</dt> * <dd>The message code prefix to dynamically remove from all message * codes.</dd> * * <dt>delegate</dt> * <dd>The {@link MessageSource} to delegate to. If that object implements * {@link HierarchicalMessageSource} then those methods will be supported by * instances of this class as well.</dd> * </dl> * * @author matt * @version 1.1 */ public class PrefixedMessageSource implements MessageSource, HierarchicalMessageSource { private String prefix = ""; private MessageSource delegate; @Override public void setParentMessageSource(MessageSource parent) { if ( delegate instanceof HierarchicalMessageSource ) { ((HierarchicalMessageSource) delegate).setParentMessageSource(parent); } else { throw new UnsupportedOperationException( "Delegate does not implement HierarchicalMessageSource"); } } @Override public MessageSource getParentMessageSource() { if ( delegate instanceof HierarchicalMessageSource ) { return ((HierarchicalMessageSource) delegate).getParentMessageSource(); } throw new UnsupportedOperationException("Delegate does not implement HierarchicalMessageSource"); } @Override public String getMessage(String code, Object[] args, String defaultMessage, Locale locale) { if ( delegate == null ) { return null; } if ( prefix != null && prefix.length() > 0 && code.startsWith(prefix) ) { // remove prefix code = code.substring(prefix.length()); } return delegate.getMessage(code, args, defaultMessage, locale); } @Override public String getMessage(String code, Object[] args, Locale locale) throws NoSuchMessageException { if ( delegate == null ) { return null; } if ( prefix != null && prefix.length() > 0 && code.startsWith(prefix) ) { // remove prefix code = code.substring(prefix.length()); } return delegate.getMessage(code, args, locale); } @Override public String getMessage(final MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException { if ( delegate == null ) { return null; } final String[] codes = resolvable.getCodes(); if ( prefix != null && prefix.length() > 0 ) { for ( int i = 0; i < codes.length; i++ ) { if ( codes[i].startsWith(prefix) ) { codes[i] = codes[i].substring(prefix.length()); } } } return delegate.getMessage(new MessageSourceResolvable() { @Override public String getDefaultMessage() { return resolvable.getDefaultMessage(); } @Override public String[] getCodes() { return codes; } @Override public Object[] getArguments() { return resolvable.getArguments(); } }, locale); } public String getPrefix() { return prefix; } public void setPrefix(String prefix) { this.prefix = prefix; } public MessageSource getDelegate() { return delegate; } public void setDelegate(MessageSource delegate) { this.delegate = delegate; } }