jp.co.opentone.bsol.framework.test.util.AssertMapComparer.java Source code

Java tutorial

Introduction

Here is the source code for jp.co.opentone.bsol.framework.test.util.AssertMapComparer.java

Source

/*
 * Copyright 2016 OPEN TONE Inc.
 *
 * 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.co.opentone.bsol.framework.test.util;

import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.sql.SQLException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateUtils;

import junit.framework.Assert;

/**
 * Map??POJO??.
 * <p>
 * Map???????????
 * ??????.
 * <pre>
 * 
 * Map("projectId", "123-456")??????????
 * ?getProjectId?????.
 * </pre>
 * Map???????????
 * ???exceptMap???.
 * @author opentone
 */
public class AssertMapComparer {

    /**
     * ?.
     */
    // CHECKSTYLE:OFF
    public enum AssertCompareType {
        STRING, // ()
        BIGDECIMAL, // BigDecimal
        DATE, // 
        TIMESTAMP, // 
    };
    // CHECKSTYLE:ON

    /**
     * ????.
     */
    public static final String FORMAT_DATE = "yyyy/MM/dd";

    /**
     * ????.
     */
    public static final String FORMAT_TIME = "yyyy/MM/dd HH:mm:ss";

    /**
     * ???????.
     * <p>
     * Map???????????????.
     * Object??????????.
     * <pre>
     * 
     * compMap?"project_id"?????
     * Map??"PROJECT_ID"?Object???projectId?.
     * </pre>
     */
    private Map<String, AssertCompareType> compareKeys;

    /**
     * ?Map.
     */
    private Map<String, Object> compareMap;

    /**
     * .
     */
    private Object compareObj;

    /**
     * ?.
     */
    private List<String> compareResult = new ArrayList<String>();

    /**
     * .
     */
    public AssertMapComparer() {
        compareKeys = new HashMap<String, AssertCompareType>();
    }

    /**
     * .
     * @param compareMap ?Map
     * @param compareObj ?
     */
    public AssertMapComparer(Map<String, Object> compareMap, Object compareObj) {
        this();
        this.compareMap = compareMap;
        this.compareObj = compareObj;
    }

    /**
     * 1???.
     * @param compareKey 
     */
    public void addCompareKey(String compareKey) {
        this.compareKeys.put(compareKey, AssertCompareType.STRING);
    }

    /**
     * ???.
     * @param compareKeyArray ?
     */
    public void addCompareKey(String[] compareKeyArray) {
        if (null != compareKeyArray) {
            for (String compareKey : compareKeyArray) {
                addCompareKey(compareKey);
            }
        }
    }

    /**
     * 1?????.
     * ????????.
     * @param compareKey 
     * @param compareType 
     */
    public void addCompareKey(String compareKey, AssertCompareType compareType) {
        if (StringUtils.isNotEmpty(compareKey)) {
            if (this.compareKeys.containsKey(compareKey)) {
                this.compareKeys.remove(compareKey);
            }
            this.compareKeys.put(compareKey, compareType);
        }
    }

    /**
     * 1?????.
     * ????????.
     * @param compareKey 
     * @param compareType 
     */
    public void updateCompareKey(String compareKey, AssertCompareType compareType) {
        if (StringUtils.isNotEmpty(compareKey)) {
            if (this.compareKeys.containsKey(compareKey)) {
                this.compareKeys.remove(compareKey);
                this.compareKeys.put(compareKey, compareType);
            }
        }
    }

    /**
     * ?.
     */
    public void clearCompareKey() {
        this.compareKeys.clear();
    }

    /**
     * ?Map????.
     * @return ?Map.
     */
    public Map<String, Object> getCompareMap() {
        return compareMap;
    }

    /**
     * ?Map???.
     * @param compareMap ?Map.
     */
    public void setCompareMap(Map<String, Object> compareMap) {
        this.compareMap = compareMap;
    }

    /**
     * ????.
     * @return .
     */
    public Object getCompareObj() {
        return compareObj;
    }

    /**
     * ???.
     * @param compareObj .
     */
    public void setCompareObj(Object compareObj) {
        this.compareObj = compareObj;
    }

    /**
     * ?.????.
     * @return ?.
     */
    public List<String> getCompareResult() {
        return compareResult;
    }

    /**
     * ???.
     */
    public void assertCompare() {
        compareResult.clear();
        if (null == compareMap || null == compareObj) {
            throw new RuntimeException("Field[compareMap] and field[compareDto] must be set.");
        }
        if (null == compareKeys || 0 == compareKeys.size()) {
            throw new RuntimeException("Field[compareKeys] must be set.");
        }
        Set<Entry<String, AssertCompareType>> keySet = compareKeys.entrySet();
        Iterator<Entry<String, AssertCompareType>> iterator = keySet.iterator();
        while (iterator.hasNext()) {
            Entry<String, AssertCompareType> entry = iterator.next();
            String orgKey = entry.getKey();

            String mapKey = orgKey.toUpperCase();
            String objFieldName = toFieldName(orgKey);
            if (null != objFieldName) {
                Object mapValue = compareMap.get(mapKey);
                Object objValue = getObjectValue(objFieldName);
                compare(orgKey, mapValue, objValue);
            }
        }
    }

    /**
     * ?.
     * @param mapKey ??
     * @param mapValue ?1
     * @param objValue ?2
     */
    private void compare(String mapKey, Object mapValue, Object objValue) {
        // ?null?????
        AssertCompareType ruledType = compareKeys.get(mapKey);
        if (null != mapValue && null != objValue) {
            Object convertMapValue = getTypeValue(ruledType, mapValue);
            Object convertObjValue = getTypeValue(ruledType, objValue);
            Assert.assertEquals(convertMapValue, convertObjValue);

            String resultMessage = String.format("compare[type=%s]:[key=%s]:exp=[%s], act=[%s]",
                    ruledType.toString(), mapKey, convertMapValue.toString(), convertObjValue.toString());
            compareResult.add(resultMessage);
        } else if (null != mapValue || null != objValue) {
            Assert.assertEquals(String.format("varName=[%s]", mapKey), mapValue, objValue);
            if (null == mapValue) {
                compareResult.add(String.format("compare[type=%s]:[key=%s]:exp=null, act=[%s]",
                        ruledType.toString(), mapKey, objValue.toString()));
            } else {
                compareResult.add(String.format("compare[type=%s]:[key=%s]:exp=[%s], act=null",
                        ruledType.toString(), mapKey, mapValue.toString()));
            }
        } else {
            compareResult.add(
                    String.format("compare[type=%s]:[key=%s]:exp=null, act=null", ruledType.toString(), mapKey));
        }
    }

    /**
     * ????????.
     * @param type 
     * @param obj ??
     * @return ??
     */
    private Object getTypeValue(AssertCompareType type, Object obj) {
        Object result = null;
        if (AssertCompareType.BIGDECIMAL == type) {
            result = toBigDecimal(obj);
        } else if (AssertCompareType.DATE == type) {
            result = toDate(obj);
        } else if (AssertCompareType.TIMESTAMP == type) {
            result = toTimestamp(obj);
        } else {
            result = obj;
        }
        return result;
    }

    /**
     * Reflection????getter???.
     * @param dtoKey ??
     * @return ?. ??????????n
     */
    private Object getObjectValue(String objFieldName) throws IllegalArgumentException {
        if (StringUtils.isEmpty(objFieldName)) {
            throw new IllegalArgumentException("Arg[dtoFieldName] must not be empty.");
        }
        Object value = null;
        try {
            String methodName = String.format("%s%s%s", "get", objFieldName.substring(0, 1).toUpperCase(),
                    objFieldName.substring(1));
            Method method = compareObj.getClass().getMethod(methodName, (Class[]) null);
            value = method.invoke(compareObj, (Object[]) null);
        } catch (Exception exp) {
            exp.printStackTrace();
            throw new RuntimeException(exp);
        }
        return value;
    }

    /**
     * obj????BigDecimal?.
     * obj?BigDecimal?????????.
     * @param obj ??
     * @return ???BigDecimal
     */
    private BigDecimal toBigDecimal(Object obj) {
        BigDecimal result = null;
        if (obj instanceof BigDecimal) {
            result = (BigDecimal) obj;
        } else {
            result = new BigDecimal(obj.toString());
        }
        return result;
    }

    /**
     * obj?????.
     * obj?Date???????toString()???.
     * @param obj ?
     * @return ???
     */
    private Date toDate(Object obj) {
        return convertDate(obj, FORMAT_DATE);
    }

    /**
     * obj?????.
     * obj?Date???????toString()???.
     * @param obj ?
     * @return ???
     */
    private Date toTimestamp(Object obj) {
        return convertDate(obj, FORMAT_TIME);
    }

    /**
     * Date??.
     * obj?Date???????????.
     * @param obj ?
     * @param format ?
     * @return ???
     */
    private Date convertDate(Object obj, String format) {
        Date result = null;
        try {
            if (null != obj) {
                if (obj instanceof Date) {
                    result = (Date) obj;
                } else if (obj instanceof oracle.sql.Datum) {
                    if (obj instanceof oracle.sql.TIMESTAMP) {
                        java.sql.Timestamp t = (java.sql.Timestamp) ((oracle.sql.TIMESTAMP) obj).toJdbc();
                        result = new Date(t.getTime());
                    } else if (obj instanceof oracle.sql.DATE) {
                        java.sql.Date d = (java.sql.Date) ((oracle.sql.DATE) obj).toJdbc();
                        result = new Date(d.getTime());
                    } else {
                        throw new IllegalArgumentException(
                                "not implemented. type[" + obj.getClass().toString() + "]");
                    }
                } else {
                    result = DateUtils.parseDate(obj.toString(), new String[] { format });
                }
            }
        } catch (ParseException pe) {
            pe.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * ???????.
     * <p>
     * "project_id"????"projectId"???
     * @param keyName ????
     * @return ??
     */
    private String toFieldName(String keyName) {
        String fieldName = null;
        if (null != keyName) {
            StringBuilder builder = new StringBuilder();
            boolean isPrevUnderScore = false;
            for (int i = 0; i < keyName.length(); i++) {
                char ch = keyName.charAt(i);
                if ('_' == ch) {
                    isPrevUnderScore = true;
                } else {
                    if (isPrevUnderScore) {
                        builder.append(Character.toUpperCase(ch));
                        isPrevUnderScore = false;
                    } else {
                        builder.append(ch);
                    }
                }
            }
            fieldName = builder.toString();
        }
        return fieldName;
    }
}