jp.terasoluna.fw.collector.util.ControlBreakChecker.java Source code

Java tutorial

Introduction

Here is the source code for jp.terasoluna.fw.collector.util.ControlBreakChecker.java

Source

/*
 * Copyright (c) 2011 NTT DATA Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package jp.terasoluna.fw.collector.util;

import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.Map;

import jp.terasoluna.fw.collector.Collector;
import jp.terasoluna.fw.collector.LogId;
import jp.terasoluna.fw.collector.util.strategy.ComparatorCompareStrategy;
import jp.terasoluna.fw.collector.util.strategy.CompareStrategy;
import jp.terasoluna.fw.logger.TLogger;

import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang3.builder.EqualsBuilder;

/**
 * ?.<br>
 */
public class ControlBreakChecker {

    /**
     * Log.
     */
    private static final TLogger LOGGER = TLogger.getLogger(ControlBreakChecker.class);

    /**
     * .
     */
    protected ControlBreakChecker() {
    }

    /**
     * ??.<br>
     * @param collector Collector&lt;?&gt;
     * @param keys String...
     * @return true:?/false:???
     */
    public static boolean isPreBreak(Collector<?> collector, String... keys) {
        return isPreBreak(collector, null, keys);
    }

    /**
     * ??.<br>
     * keys??compareStrategies?????CompareStrategy??????.<br>
     * <ul>
     * <li>keys : compareStrategies = N : N (???N)??
     * <ul>
     * <li>keys[i]?CompareStrategy?compareStrategies[i]</li>
     * </ul>
     * </li>
     * <li>keys : compareStrategies = N : 1??
     * <ul>
     * <li>keys[i]?CompareStrategy?compareStrategies[0]</li>
     * </ul>
     * </li>
     * <li>keys : compareStrategies = N : M (N &gt; M)??
     * <ul>
     * <li>keys[i] (i &lt; M)?CompareStrategy?compareStrategies[i]</li>
     * <li>keys[i] (i &gt;= M)?CompareStrategy?null</li>
     * </ul>
     * </li>
     * </ul>
     * ??{@link #equalsObjects(Object, Object, CompareStrategy)} ????.
     * @param collector Collector&lt;?&gt;
     * @param compareStrategies CompareStrategy&lt;?&gt;[]
     * @param keys String[]
     * @return true:?/false:???
     * @see #equalsObjects(Object, Object, CompareStrategy)
     */
    public static boolean isPreBreak(Collector<?> collector, CompareStrategy<?>[] compareStrategies,
            String[] keys) {
        if (collector != null) {
            Object current = collector.getCurrent();
            Object other = collector.getPrevious();

            return isBreakInternal(current, other, compareStrategies, keys);
        }
        return false;
    }

    /**
     * ?.<br>
     * @param collector Collector&lt;?&gt;
     * @param keys String...
     * @return true:?/false:???
     */
    public static boolean isBreak(Collector<?> collector, String... keys) {
        return isBreak(collector, null, keys);
    }

    /**
     * ?.<br>
     * keys??compareStrategies?????CompareStrategy??????.<br>
     * <ul>
     * <li>keys : compareStrategies = N : N (???N)??
     * <ul>
     * <li>keys[i]?CompareStrategy?compareStrategies[i]</li>
     * </ul>
     * </li>
     * <li>keys : compareStrategies = N : 1??
     * <ul>
     * <li>keys[i]?CompareStrategy?compareStrategies[0]</li>
     * </ul>
     * </li>
     * <li>keys : compareStrategies = N : M (N &gt; M)??
     * <ul>
     * <li>keys[i] (i &lt; M)?CompareStrategy?compareStrategies[i]</li>
     * <li>keys[i] (i &gt;= M)?CompareStrategy?null</li>
     * </ul>
     * </li>
     * </ul>
     * ??{@link #equalsObjects(Object, Object, CompareStrategy)} ????.
     * @param collector Collector&lt;?&gt;
     * @param compareStrategies CompareStrategy&lt;?&gt;[]
     * @param keys String[]
     * @return true:?/false:???
     * @see #equalsObjects(Object, Object, CompareStrategy)
     */
    public static boolean isBreak(Collector<?> collector, CompareStrategy<?>[] compareStrategies, String[] keys) {
        if (collector != null) {
            Object current = collector.getCurrent();
            Object other = collector.getNext();

            return isBreakInternal(current, other, compareStrategies, keys);
        }
        return false;
    }

    /**
     * .<br>
     * ????ver.1.1.x????????????.<br>
     * ????????<br>
     * {@link #isBreak(Collector, CompareStrategy[], String[])}?<br>
     * {@link #isPreBreak(Collector, CompareStrategy[], String[])}?<br>
     * {@link #isBreakInternal(Object, Object, CompareStrategy[], String...)}<br>
     * ???.<br>
     * @param current Object 
     * @param other Object 
     * @param comparators Comparator&lt;?&gt;[]
     * @param keys String...
     * @return true:?/false:???
     * @see #isBreak(Collector, CompareStrategy[], String[])
     * @see #isPreBreak(Collector, CompareStrategy[], String[])
     * @see #isBreakInternal(Object, Object, CompareStrategy[], String...)
     */
    protected static boolean isBreakInternal(Object current, Object other, Comparator<?>[] comparators,
            String... keys) {

        // comparator -> compareStrategy?????
        if (comparators != null) {
            CompareStrategy<?>[] compareStrategies = new CompareStrategy[comparators.length];

            for (int i = 0; i < comparators.length; i++) {
                compareStrategies[i] = new ComparatorCompareStrategy(comparators[i]);
            }
            return isBreakInternal(current, other, compareStrategies, keys);
        } else {
            return isBreakInternal(current, other, (CompareStrategy[]) null, keys);
        }

    }

    /**
     * .<br>
     * keys??compareStrategies?????CompareStrategy??????.<br>
     * <ul>
     * <li>keys : compareStrategies = N : N (???N)??
     * <ul>
     * <li>keys[i]?CompareStrategy?compareStrategies[i]</li>
     * </ul>
     * </li>
     * <li>keys : compareStrategies = N : 1??
     * <ul>
     * <li>keys[i]?CompareStrategy?compareStrategies[0]</li>
     * </ul>
     * </li>
     * <li>keys : compareStrategies = N : M (N &gt; M)??
     * <ul>
     * <li>keys[i] (i &lt; M)?CompareStrategy?compareStrategies[i]</li>
     * <li>keys[i] (i &gt;= M)?CompareStrategy?null</li>
     * </ul>
     * </li>
     * </ul>
     * ?? {@link #equalsObjects(Object, Object, CompareStrategy)} ?.
     * @param current Object 
     * @param other Object 
     * @param compareStrategies CompareStrategy&lt;?&gt;[]
     * @param keys String...
     * @return true:?/false:???
     * @see #equalsObjects(Object, Object, CompareStrategy)
     */
    protected static boolean isBreakInternal(Object current, Object other, CompareStrategy<?>[] compareStrategies,
            String... keys) {

        // key?????null???false
        if (keys == null || keys.length == 0) {
            // ??
            return false;
        }

        // ?null????not null???true
        if ((current != null && other == null) || (current == null && other != null)) {
            // 
            return true;
        }

        if (other != null && current != null) {

            for (int keyIndex = 0; keyIndex < keys.length; keyIndex++) {
                String key = keys[keyIndex];
                CompareStrategy<?> compareStrategy = null;

                if (compareStrategies != null) {
                    if (compareStrategies.length == 1) {
                        compareStrategy = compareStrategies[0];
                    } else if (keyIndex < compareStrategies.length) {
                        compareStrategy = compareStrategies[keyIndex];
                    }
                }

                if (key != null && key.length() != 0) {
                    Object currentValue = null;
                    Object otherValue = null;

                    // ??
                    try {
                        currentValue = PropertyUtils.getProperty(current, key);
                    } catch (Exception e) {
                        logOutputPropNotFound(e, current, key);
                        // ????
                        continue;
                    }

                    // ??
                    try {
                        otherValue = PropertyUtils.getProperty(other, key);
                    } catch (Exception e) {
                        logOutputPropNotFound(e, other, key);
                        // ????
                        continue;
                    }

                    // 
                    if (!equalsObjects(currentValue, otherValue, compareStrategy)) {
                        return true;
                    }
                }
            }
        }
        // ??
        return false;
    }

    /**
     * ???.<br>
     * @param collector Collector&lt;?&gt;
     * @param keys String...
     * @return 
     */
    public static Map<String, Object> getPreBreakKey(Collector<?> collector, String... keys) {
        return getPreBreakKey(collector, null, keys);
    }

    /**
     * ???.<br>
     * keys??compareStrategies?????CompareStrategy??????.<br>
     * <ul>
     * <li>keys : compareStrategies = N : N (???N)??
     * <ul>
     * <li>keys[i]?CompareStrategy?compareStrategies[i]</li>
     * </ul>
     * </li>
     * <li>keys : compareStrategies = N : 1??
     * <ul>
     * <li>keys[i]?CompareStrategy?compareStrategies[0]</li>
     * </ul>
     * </li>
     * <li>keys : compareStrategies = N : M (N &gt; M)??
     * <ul>
     * <li>keys[i] (i &lt; M)?CompareStrategy?compareStrategies[i]</li>
     * <li>keys[i] (i &gt;= M)?CompareStrategy?null</li>
     * </ul>
     * </li>
     * </ul>
     * ??{@link #equalsObjects(Object, Object, CompareStrategy)} ????.
     * @param collector Collector&lt;?&gt;
     * @param compareStrategies CompareStrategy&lt;?&gt;[]
     * @param keys String[]
     * @return 
     * @see #equalsObjects(Object, Object, CompareStrategy)
     */
    public static Map<String, Object> getPreBreakKey(Collector<?> collector, CompareStrategy<?>[] compareStrategies,
            String[] keys) {
        if (collector != null) {
            Object current = collector.getCurrent();
            Object other = collector.getPrevious();

            return getBreakKeyInternal(current, other, (CompareStrategy<?>[]) compareStrategies, keys);
        }
        return new LinkedHashMap<String, Object>();
    }

    /**
     * ??.<br>
     * @param collector Collector&lt;?&gt;
     * @param keys String...
     * @return 
     */
    public static Map<String, Object> getBreakKey(Collector<?> collector, String... keys) {
        return getBreakKey(collector, null, keys);
    }

    /**
     * ??.<br>
     * keys??compareStrategies?????CompareStrategy??????.<br>
     * <ul>
     * <li>keys : compareStrategies = N : N (???N)??
     * <ul>
     * <li>keys[i]?CompareStrategy?compareStrategies[i]</li>
     * </ul>
     * </li>
     * <li>keys : compareStrategies = N : 1??
     * <ul>
     * <li>keys[i]?CompareStrategy?compareStrategies[0]</li>
     * </ul>
     * </li>
     * <li>keys : compareStrategies = N : M (N &gt; M)??
     * <ul>
     * <li>keys[i] (i &lt; M)?CompareStrategy?compareStrategies[i]</li>
     * <li>keys[i] (i &gt;= M)?CompareStrategy?null</li>
     * </ul>
     * </li>
     * </ul>
     * ??{@link #equalsObjects(Object, Object, CompareStrategy)} ????.
     * @param collector Collector&lt;?&gt;
     * @param compareStrategies CompareStrategy&lt;?&gt;[]
     * @param keys String[]
     * @return 
     * @see #equalsObjects(Object, Object, CompareStrategy)
     */
    public static Map<String, Object> getBreakKey(Collector<?> collector, CompareStrategy<?>[] compareStrategies,
            String[] keys) {
        if (collector != null) {
            Object current = collector.getCurrent();
            Object other = collector.getNext();

            return getBreakKeyInternal(current, other, (CompareStrategy<?>[]) compareStrategies, keys);
        }
        return new LinkedHashMap<String, Object>();
    }

    /**
     * ?.<br>
     * ????ver.1.1.x????????????.<br>
     * ????????<br>
     * {@link #getBreakKey(Collector, CompareStrategy[], String[])}?<br>
     * {@link #getPreBreakKey(Collector, CompareStrategy[], String[])}?<br>
     * {@link #getBreakKeyInternal(Object, Object, CompareStrategy[], String...)}<br>
     * ???.<br>
     * @param current Object 
     * @param other Object 
     * @param comparators Comparator&lt;?&gt;[]
     * @param keys String...
     * @return 
     * @see #getBreakKey(Collector, CompareStrategy[], String[])
     * @see #getPreBreakKey(Collector, CompareStrategy[], String[])
     * @see #getBreakKeyInternal(Object, Object, CompareStrategy[], String...)
     */
    protected static Map<String, Object> getBreakKeyInternal(Object current, Object other,
            Comparator<?>[] comparators, String... keys) {

        // comparator -> compareStrategy?????
        if (comparators != null) {
            CompareStrategy<?>[] compareStrategies = new CompareStrategy[comparators.length];

            for (int i = 0; i < comparators.length; i++) {
                compareStrategies[i] = new ComparatorCompareStrategy(comparators[i]);
            }
            return getBreakKeyInternal(current, other, compareStrategies, keys);
        } else {
            return getBreakKeyInternal(current, other, (CompareStrategy[]) null, keys);
        }
    }

    /**
     * ?.<br>
     * keys??compareStrategies?????CompareStrategy??????.<br>
     * <ul>
     * <li>keys : compareStrategies = N : N (???N)??
     * <ul>
     * <li>keys[i]?CompareStrategy?compareStrategies[i]</li>
     * </ul>
     * </li>
     * <li>keys : compareStrategies = N : 1??
     * <ul>
     * <li>keys[i]?CompareStrategy?compareStrategies[0]</li>
     * </ul>
     * </li>
     * <li>keys : compareStrategies = N : M (N &gt; M)??
     * <ul>
     * <li>keys[i] (i &lt; M)?CompareStrategy?compareStrategies[i]</li>
     * <li>keys[i] (i &gt;= M)?CompareStrategy?null</li>
     * </ul>
     * </li>
     * </ul>
     * ?? {@link #equalsObjects(Object, Object, CompareStrategy)} ?.
     * @param current Object 
     * @param other Object 
     * @param compareStrategies CompareStrategy&lt;?&gt;[]
     * @param keys String...
     * @return 
     * @see #equalsObjects(Object, Object, CompareStrategy)
     */
    protected static Map<String, Object> getBreakKeyInternal(Object current, Object other,
            CompareStrategy<?>[] compareStrategies, String... keys) {
        boolean inBreak = false;
        Map<String, Object> result = new LinkedHashMap<String, Object>();

        // key?????null???false
        if (keys == null || keys.length == 0) {
            // ??
            return result;
        }

        for (int keyIndex = 0; keyIndex < keys.length; keyIndex++) {
            String key = keys[keyIndex];
            CompareStrategy<?> compareStrategy = null;
            Object currentValue = null;
            Object otherValue = null;

            if (compareStrategies != null) {
                if (compareStrategies.length == 1) {
                    compareStrategy = compareStrategies[0];
                } else if (keyIndex < compareStrategies.length) {
                    compareStrategy = compareStrategies[keyIndex];
                }
            }

            if (key != null && key.length() != 0) {

                // ??
                if (current != null) {
                    try {
                        currentValue = PropertyUtils.getProperty(current, key);
                    } catch (Exception e) {
                        logOutputPropNotFound(e, current, key);
                        // ????
                        continue;
                    }
                }

                // ??
                if (other != null) {
                    try {
                        otherValue = PropertyUtils.getProperty(other, key);
                    } catch (Exception e) {
                        logOutputPropNotFound(e, other, key);
                        // ????
                        continue;
                    }
                }

                if (!inBreak) {
                    // ?null????not null???true
                    if ((current != null && other == null) || (current == null && other != null)) {
                        // 
                        inBreak = true;
                    }

                    // 
                    if (!equalsObjects(currentValue, otherValue, compareStrategy)) {
                        // 
                        inBreak = true;
                    }
                }
            }

            if (inBreak) {
                result.put(key, currentValue);
            }
        }
        return result;
    }

    /**
     * ???????????.<br>
     * <code>equalsObjects(value1, value2, null);</code> ?????.<br>
     * ????ver.1.1.x????????????.<br>
     * 
     * ?<b>??</b>?Comparable?????
     * ver.1.1.x?????????.<br>
     * <ul>
     * <li>ver.1.1.x???equals??????
     * Comparable??equals????.
     * <ul>
     * <li>java.math.BigInteger</li>
     * <li>java.lang.Byte</li>
     * <li>java.lang.Double</li>
     * <li>java.lang.Float</li>
     * <li>java.lang.Integer</li>
     * <li>java.lang.Long</li>
     * <li>java.lang.Short</li>
     * <li>java.lang.Boolean</li>
     * <li>java.lang.Character</li>
     * <li>java.lang.String</li>
     * <li>java.util.Date(java.sql.Date?????)</li>
     * </ul>
     * </li>
     * </ul>
     * 
     * ??????<br>
     * {@link #equalsObjects(Object, Object, CompareStrategy)}<br>
     * ???.<br>
     * @param value1 Object 
     * @param value2 Object 
     * @return ???:true / ???????:false
     * @see #equalsObjects(Object, Object, CompareStrategy)
     * @deprecated ??????{@link #equalsObjects(Object, Object, CompareStrategy)}???.
     */
    @Deprecated
    protected static boolean equalsObjects(Object value1, Object value2) {
        return equalsObjects(value1, value2, null);
    }

    /**
     * ????????.<br>
     * @param e Exception
     * @param obj Object
     * @param key String
     */
    protected static void logOutputPropNotFound(Exception e, Object obj, String key) {
        if (LOGGER.isWarnEnabled()) {
            LOGGER.warn(LogId.WAL041002, key, obj == null ? null : obj.getClass().getSimpleName(),
                    e == null ? null : e.getMessage());
        }
    }

    /**
     * ???????????.<br>
     * <ul>
     * <li>??null?????????.
     * <ul>
     * <li>compareStrategy?null?????compareStrategy?</li>
     * <li>compareStrategy?null????????????
     * <ul>
     * <li>?Comparable????Comparable#compareTo?
     * <li>?Class??????????Object#equals?
     * <li>2????org.apache.commons.lang.builder.EqualsBuilder#reflectionEquals?
     * </ul>
     * </li>
     * </ul>
     * </li>
     * <li>??null?????????.</li>
     * <li>??????null???????????.</li>
     * </ul>
     * @param value1 Object 
     * @param value2 Object 
     * @param compareStrategy CompareStrategy
     * @return ???:true / ???????:false
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    protected static boolean equalsObjects(Object value1, Object value2, CompareStrategy compareStrategy) {

        if (value1 != null && value2 != null) {
            // value1,value2?????????
            if (compareStrategy != null) {
                return compareStrategy.equalsObjects(value1, value2);
            } else {
                Class<? extends Object> clazz = value1.getClass();

                if (value1 instanceof Comparable) {
                    // value1?Comparable?????compareTo??
                    return (((Comparable) value1).compareTo(value2) == 0);
                } else if (clazz.isAssignableFrom(Class.class)) {
                    // value1?Class?????????Object#equals??
                    return value1.equals(value2);
                } else {
                    // ?????reflectionEquals??
                    return EqualsBuilder.reflectionEquals(value1, value2);
                }
            }
        } else if (value1 == null && value2 == null) {
            // value1,value2???????????
            return true;
        }
        // value1,value2??????????
        return false;

    }
}