org.marketcetera.util.l10n.MessageComparator.java Source code

Java tutorial

Introduction

Here is the source code for org.marketcetera.util.l10n.MessageComparator.java

Source

package org.marketcetera.util.l10n;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import org.apache.commons.lang.SystemUtils;
import org.marketcetera.util.except.I18NException;
import org.marketcetera.util.misc.ClassVersion;

/**
 * A comparator of two message meta-information holders.
 *
 * @author tlerios@marketcetera.com
 * @since 0.6.0
 * @version $Id$
 */

/* $License$ */

@ClassVersion("$Id$")
public class MessageComparator {

    // INSTANCE DATA.

    private MessageInfoPair[] mMismatches;
    private MessageInfo[] mExtraSrcInfo;
    private MessageInfo[] mExtraDstInfo;

    // CONSTRUCTORS.

    /**
     * Creates a new comparator for the given meta-information. For
     * both parameters, the order of list elements is unimportant.
     *
     * @param srcInfo The source meta-information.
     * @param dstInfo The destination meta-information.
     */

    public MessageComparator(List<MessageInfo> srcInfo, List<MessageInfo> dstInfo) {

        // Analyze source and destination.

        HashMap<String, MessageInfo> srcMessages = toHashMap(srcInfo);
        HashMap<String, MessageInfo> dstMessages = toHashMap(dstInfo);

        // Compare.

        LinkedList<MessageInfoPair> mismatches = new LinkedList<MessageInfoPair>();
        LinkedList<MessageInfo> extraSrcInfo = new LinkedList<MessageInfo>();
        for (String name : srcMessages.keySet()) {
            MessageInfo srcMessage = srcMessages.get(name);

            // Message missing from destination.

            if (!dstMessages.containsKey(name)) {
                extraSrcInfo.add(srcMessage);
                continue;
            }

            // Message exists in both source and destination, but
            // parameter count differs.

            MessageInfo dstMessage = dstMessages.get(name);
            if ((srcMessage.getParamCount() != -1) && (dstMessage.getParamCount() != -1)
                    && (srcMessage.getParamCount() != dstMessage.getParamCount())) {
                mismatches.add(new MessageInfoPair(srcMessage, dstMessage));
            }
            dstMessages.remove(name);
        }

        // Retain results.

        mMismatches = mismatches.toArray(MessageInfoPair.EMPTY_ARRAY);
        mExtraSrcInfo = extraSrcInfo.toArray(MessageInfo.EMPTY_ARRAY);
        mExtraDstInfo = dstMessages.values().toArray(MessageInfo.EMPTY_ARRAY);
    }

    /**
     * Creates a new comparator for the given meta-information
     * providers.
     *
     * @param srcProvider The source meta-information provider.
     * @param dstProvider The destination meta-information provider.
     */

    public MessageComparator(MessageInfoProvider srcProvider, MessageInfoProvider dstProvider) {
        this(srcProvider.getMessageInfo(), dstProvider.getMessageInfo());
    }

    /**
     * Creates a new comparator for the given container class
     * meta-information and the properties file deduced from the
     * container's message provider and the given locale.
     *
     * @param classInfo The meta-information of a container class.
     * @param locale The locale. Use {@link Locale#ROOT} for the
     * fallback properties file.
     *
     * @throws I18NException Thrown if there is a problem obtaining
     * the meta-information of the properties file.
     */

    private MessageComparator(ContainerClassInfo classInfo, Locale locale) throws I18NException {
        this(classInfo, new PropertiesFileInfo(classInfo.getProvider(), locale));
    }

    /**
     * Creates a new comparator for the given container class
     * meta-information and the properties file deduced from the
     * container's message provider.
     *
     * @param classInfo The meta-information of a container class.
     *
     * @throws I18NException Thrown if there is a problem obtaining
     * the meta-information of the properties file.
     */

    public MessageComparator(ContainerClassInfo classInfo) throws I18NException {
        this(classInfo, Locale.ROOT);
    }

    /**
     * Creates a new comparator for the given container class and the
     * properties file deduced from the class's message provider and
     * the given locale.
     *
     * @param container The class.
     * @param locale The locale. Use {@link Locale#ROOT} for the
     * fallback properties file.
     *
     * @throws I18NException Thrown if there is a problem obtaining
     * the meta-information of either the container or the properties
     * file.
     */

    public MessageComparator(Class<?> container, Locale locale) throws I18NException {
        this(new ContainerClassInfo(container), locale);
    }

    /**
     * Creates a new comparator for the given container class and the
     * fallback properties file deduced from the class's message
     * provider.
     *
     * @param container The class.
     *
     * @throws I18NException Thrown if there is a problem obtaining
     * the meta-information of either the container or the properties
     * file.
     */

    public MessageComparator(Class<?> container) throws I18NException {
        this(new ContainerClassInfo(container));
    }

    // INSTANCE METHODS.

    /**
     * Converts the given meta-information list into a map, with the
     * map keys being the message keys.
     *
     * @param infoList The meta-information in list form.
     *
     * @return The map.
     */

    private HashMap<String, MessageInfo> toHashMap(List<MessageInfo> infoList) {
        HashMap<String, MessageInfo> result = new HashMap<String, MessageInfo>();
        for (MessageInfo info : infoList) {
            result.put(info.getKey(), info);
        }
        return result;
    }

    /**
     * Returns the receiver's mismatches. A mismatch occurs when two
     * message keys are present in both source and destination, and
     * both have known but different parameter counts.
     *
     * @return The mismatches.
     */

    public MessageInfoPair[] getMismatches() {
        return mMismatches;
    }

    /**
     * Returns the receiver's list of source meta-information that is
     * absent from the destination.
     *
     * @return The list.
     */

    public MessageInfo[] getExtraSrcInfo() {
        return mExtraSrcInfo;
    }

    /**
     * Returns the receiver's list of destination meta-information
     * that is absent from the source.
     *
     * @return The list.
     */

    public MessageInfo[] getExtraDstInfo() {
        return mExtraDstInfo;
    }

    /**
     * Checks whether the receiver found no differences between source
     * and destination.
     *
     * @return True if so.
     */

    public boolean isMatch() {
        return ((getMismatches().length == 0) && (getExtraSrcInfo().length == 0)
                && (getExtraDstInfo().length == 0));
    }

    /**
     * Returns a textual form of the differences between source and
     * destination.
     *
     * @return The differences. This is the empty string if there are
     * no differences.
     */

    public String getDifferences() {
        StringBuilder builder = new StringBuilder();
        for (MessageInfoPair mismatch : getMismatches()) {
            if (builder.length() > 0) {
                builder.append(SystemUtils.LINE_SEPARATOR);
            }
            builder.append(Messages.PARAM_COUNT_MISMATCH.getText(mismatch.getSrcInfo().getKey(),
                    mismatch.getSrcInfo().getParamCount(), mismatch.getDstInfo().getParamCount()));
        }
        for (MessageInfo info : getExtraSrcInfo()) {
            if (builder.length() > 0) {
                builder.append(SystemUtils.LINE_SEPARATOR);
            }
            builder.append(Messages.EXTRA_SRC_MESSAGE.getText(info.getKey()));
        }
        for (MessageInfo info : getExtraDstInfo()) {
            if (builder.length() > 0) {
                builder.append(SystemUtils.LINE_SEPARATOR);
            }
            builder.append(Messages.EXTRA_DST_MESSAGE.getText(info.getKey()));
        }
        return builder.toString();
    }
}