net.solarnetwork.node.util.TemplatedMessageSource.java Source code

Java tutorial

Introduction

Here is the source code for net.solarnetwork.node.util.TemplatedMessageSource.java

Source

/* ==================================================================
 * TemplatedMessageSource.java - Jul 22, 2013 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
 * ==================================================================
 * $Id$
 * ==================================================================
 */

package net.solarnetwork.node.util;

import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
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 extracts a pre-configured
 * regular expression match 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>mapProperty['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>regex</dt>
 * <dd>The regular expression to match against message codes. The regular
 * expression must provide at least one capture group; all capture groups are
 * combined into the final message code.</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.0
 */
public class TemplatedMessageSource implements MessageSource, HierarchicalMessageSource {

    private String regex;
    private Pattern pat;
    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 (pat != null) {
            Matcher m = pat.matcher(code);
            final int count = m.groupCount();
            if (m.matches() && count > 0) {
                // remap using regex capture groups
                StringBuilder buf = new StringBuilder();
                for (int i = 1; i <= count; i++) {
                    buf.append(m.group(i));
                }
                code = buf.toString();
            }
        }
        return delegate.getMessage(code, args, defaultMessage, locale);
    }

    @Override
    public String getMessage(String code, Object[] args, Locale locale) throws NoSuchMessageException {
        if (pat != null) {
            Matcher m = pat.matcher(code);
            final int count = m.groupCount();
            if (m.matches() && count > 0) {
                // remap using regex capture groups
                StringBuilder buf = new StringBuilder();
                for (int i = 1; i <= count; i++) {
                    buf.append(m.group(i));
                }
                code = buf.toString();
            }
        }
        return delegate.getMessage(code, args, locale);
    }

    @Override
    public String getMessage(final MessageSourceResolvable resolvable, Locale locale)
            throws NoSuchMessageException {
        final String[] codes = resolvable.getCodes();
        if (pat != null) {
            for (int i = 0; i < codes.length; i++) {
                Matcher m = pat.matcher(codes[i]);
                final int count = m.groupCount();
                if (m.matches() && count > 0) {
                    // remap using regex capture group
                    StringBuilder buf = new StringBuilder();
                    for (int j = 1; j <= count; j++) {
                        buf.append(m.group(j));
                    }
                    codes[i] = buf.toString();
                }
            }
        }
        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 getRegex() {
        return regex;
    }

    public void setRegex(String regex) {
        this.regex = regex;
        if (regex != null && regex.length() > 0) {
            pat = Pattern.compile(regex);
        } else {
            pat = null;
        }
    }

    public MessageSource getDelegate() {
        return delegate;
    }

    public void setDelegate(MessageSource delegate) {
        this.delegate = delegate;
    }

}