package kr.wisestone.owl.util; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.collect.Lists; import kr.wisestone.owl.constant.MsgConstants; import kr.wisestone.owl.constant.Regular; import kr.wisestone.owl.exception.OwlRuntimeException; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.BeanUtils; import java.beans.PropertyDescriptor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.text.SimpleDateFormat; import java.util.*; import java.util.regex.Pattern; public class ConvertUtil { static final Logger LOGGER = LoggerFactory.getLogger(ConvertUtil.class); /** * 맵 목록을 주어진 오브젝트 목록으로 복사한다. * * @param sources * @param clazz * @param ignores * @return */ public static List convertListToListClass(List> sources, Class clazz, String... ignores) { List targets = new ArrayList(); for (Map source : sources) { targets.add(convertMapToClass(source, clazz, ignores)); } return targets; } public static List convertListToListClass(List> sources, Class clazz) { return convertListToListClass(sources, clazz, new String[] {}); } /** * 맵 오브젝트를 주어진 클래스 오브젝트의 필드로 복사한다. * * @param source * @param clazz * @param ignores * 매핑에서 제외할 필드 * @return */ @SuppressWarnings("unchecked") public static T convertMapToClass(Map source, Class clazz, String... ignores) { Object objClass = null; try { objClass = clazz.newInstance(); } catch (Exception e) { LOGGER.error("", e); } convertMapToObject(source, objClass, ignores); return (T) objClass; } /** * 맵 오브젝트를 주어진 오브젝트의 필드로 복사한다. * * @param map * @param objClass * @param ignores * @return */ public static Object convertMapToObject(Map map, Object objClass, String... ignores) { String keyAttribute = null; Iterator itr = map.keySet().iterator(); while (itr.hasNext()) { keyAttribute = itr.next(); if (ArrayUtils.contains(ignores, keyAttribute)) { continue; } if (map.get(keyAttribute) == null) { continue; } PropertyDescriptor propertyDescriptor = BeanUtils.getPropertyDescriptor(objClass.getClass(), keyAttribute); try { Method method = propertyDescriptor.getWriteMethod(); if (propertyDescriptor.getPropertyType() == String.class) { // xss 방어를 위해 script 문자 공백 치환 method.invoke(objClass, CommonUtil.preventXss(map.get(keyAttribute).toString())); } else if (propertyDescriptor.getPropertyType() == Integer.class) { method.invoke(objClass, new Integer(map.get(keyAttribute).toString())); } else if (propertyDescriptor.getPropertyType() == Long.class) { method.invoke(objClass, Long.valueOf(map.get(keyAttribute).toString())); } else if (propertyDescriptor.getPropertyType() == Double.class) { method.invoke(objClass, Double.valueOf(map.get(keyAttribute).toString())); } else if (propertyDescriptor.getPropertyType() == Boolean.class) { if ("Y".equalsIgnoreCase(map.get(keyAttribute).toString())) { method.invoke(objClass, Boolean.TRUE); } if ("true".equalsIgnoreCase(map.get(keyAttribute).toString())) { method.invoke(objClass, Boolean.TRUE); } else { method.invoke(objClass, Boolean.FALSE); } } } catch (Exception e) { // e.printStackTrace(); } } return objClass; } /** * 주어진 오브젝트 목록(List)을 주어진 클래스 목록으로 복사한다. * * @param sources * @param targetClass * @return */ @SuppressWarnings("unchecked") public static List convertObjectsToClasses( List sources, Class targetClass) { List targets = new ArrayList(); Object target = null; Iterator iterator = sources.iterator(); while (iterator.hasNext()) { S source = iterator.next(); try { target = targetClass.newInstance(); copyProperties(source, target); targets.add((T) target); } catch (Exception e) { throw new OwlRuntimeException(e); } } return targets; } /** * 주어진 오브젝트 목록(Set)을 주어진 클래스 목록으로 복사한다. * * @param sources * @param targetClass * @return */ @SuppressWarnings("unchecked") public static List convertObjectsToClasses( Set sources, Class targetClass) { List targets = new ArrayList(); Object target = null; Iterator iterator = sources.iterator(); while (iterator.hasNext()) { S source = iterator.next(); try { target = targetClass.newInstance(); copyProperties(source, target); targets.add((T) target); } catch (Exception e) { throw new OwlRuntimeException(e); } } return targets; } /** * 오브젝트 속성을 맵에 복사하여 맵을 반환한다. * * @param source * @return */ public static Map convertObjectToMap(Object source) { return convertObjectToMap(source, new String[] {}); } /** * 오브젝트 속성에서 ignores 필드를 제외하고 맵에 복사하여 맵을 반환한다. * * @param source * @param ignores * @return */ public static Map convertObjectToMap(Object source, String...ignores) { Map target = new HashMap(); if (source == null) { throw new OwlRuntimeException(MsgConstants.SOURCE_OBJECT_IS_NULL); } try { copyAttrSourceToTarget(source, target, ignores); } catch (Exception e) { throw new OwlRuntimeException(MsgConstants.ERR_FAILED_CONVERT_OBJECT, e); } return target; } private static void copyAttrSourceToTarget(Object source, Object target, String... ignores) { copyAttrSourceToTarget(source, target, false, ignores); } /** * 소스 오브젝트 속성에서 ignores 필드를 제외하고 타겟 오브젝트로 속성을 복사한다. * * @param source * @param target * @param ignores */ @SuppressWarnings("unchecked") private static void copyAttrSourceToTarget(Object source, Object target, boolean chkEqual, String... ignores) { PropertyDescriptor[] propertyDescriptors = BeanUtils.getPropertyDescriptors(source.getClass()); if (propertyDescriptors == null || propertyDescriptors.length == 0) { LOGGER.debug("속성이 존재하지 않는다. : " + source.getClass().getName()); return; } for (PropertyDescriptor propertyDescriptor : propertyDescriptors) { if (ignores != null && ignores.length > 0) { if (ArrayUtils.contains(ignores, propertyDescriptor.getName())) { LOGGER.debug("무시될 필드 항목이다 : " + propertyDescriptor.getName()); continue; } } if (propertyDescriptor.getPropertyType() == Integer.class || propertyDescriptor.getPropertyType() == Double.class || propertyDescriptor.getPropertyType() == Long.class || propertyDescriptor.getPropertyType() == Boolean.class || propertyDescriptor.getPropertyType() == Date.class || propertyDescriptor.getPropertyType() == String.class) { if (target instanceof Map) { if (copyAttrObjectToMap(source, propertyDescriptor.getName(), (Map) target) == false) { continue; } } else { if (copyAttrObjectToObject(source, propertyDescriptor.getName(), target, chkEqual) == false) { continue; } } } else { // LogUtil.debug(LOGGER, field.getName() + "(" + field.getType().getName() + ")은 지원 타입이 아니다."); } } } /** * 주어진 타입의 모든 속성(필드)을 반환한다. * * @param fields * @param type * @return */ public static List getAllFields(List fields, Class type) { for (Field field: type.getDeclaredFields()) { fields.add(field); } if (type.getSuperclass() != null) { fields = getAllFields(fields, type.getSuperclass()); } return fields; } /** * 주어진 오브젝트에서 주어진 필드를 맵에 복사한다. * * @param source * @param fieldName * @param target * * @return */ private static boolean copyAttrObjectToMap(Object source, String fieldName, Map target) { PropertyDescriptor sourcePropertyDescriptor = BeanUtils.getPropertyDescriptor(source.getClass(), fieldName); Method get = null; try { get = sourcePropertyDescriptor.getReadMethod(); } catch (Exception e) { return false; } Object value = null; try { value = get.invoke(source, new Object[] {}); } catch (Exception e) { throw new OwlRuntimeException(MsgConstants.ERR_FAILED_CONVERT_OBJECT, e); } if (value != null) { if (value instanceof Date) { target.put(fieldName, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format((Date) value)); } else { target.put(fieldName, value); } } return true; } /** * 소스 오브젝트에서 주어진 필드를 타겟 오브젝트에 복사한다. * * @param source * @param fieldName * @param target * * @return */ private static boolean copyAttrObjectToObject(Object source, String fieldName, Object target, boolean chkEqual) { Object sourceValue = null; PropertyDescriptor sourcePropertyDescriptor = BeanUtils.getPropertyDescriptor(source.getClass(), fieldName); PropertyDescriptor targetPropertyDescriptor = BeanUtils.getPropertyDescriptor(target.getClass(), fieldName); if (sourcePropertyDescriptor == null || targetPropertyDescriptor == null) { return false; } Method set = null; Method sourceGetMethod = null; Method targetGetMethod = null; try { sourceGetMethod = sourcePropertyDescriptor.getReadMethod(); targetGetMethod = targetPropertyDescriptor.getReadMethod(); sourceValue = sourceGetMethod.invoke(source, new Object[] {}); if (chkEqual) { Object targetValue = targetGetMethod.invoke(target, new Object[] {}); if (sourceValue == null && targetValue == null) { return true; } else if (sourceValue != null && sourceValue.equals(targetValue)) { return true; } else if (targetValue != null && targetValue.equals(sourceValue)) { return true; } } } catch (Exception e) { if (LOGGER.isWarnEnabled()) { LOGGER.warn("fieldName : " + fieldName, e); } return false; } try { if (sourcePropertyDescriptor.getPropertyType() == Date.class) { set = target.getClass().getMethod(targetPropertyDescriptor.getWriteMethod().getName(), String.class); } else { set = targetPropertyDescriptor.getWriteMethod(); } } catch (Exception e) { LOGGER.error("", e); return false; } try { if (sourceValue != null) { LOGGER.debug("sourceValue : " + sourceValue); LOGGER.debug("Set Method : " + set.toString()); if (sourcePropertyDescriptor.getPropertyType() == Date.class) { set.invoke(target, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format((Date) sourceValue)); } else { set.invoke(target, sourceValue); } } } catch (Exception e) { throw new OwlRuntimeException(MsgConstants.ERR_FAILED_CONVERT_OBJECT, e); } return true; } /** * 소스 오브젝트에서 Primitive Type(ignores 제외)만 타겟 클래스 오브젝트로 복사한다. * * @param source * @param targetClass * @param ignores * @return */ public static T copyProperties(Object source, Class targetClass, String...ignores) { T target = null; try { target = targetClass.newInstance(); } catch (Exception e) { throw new OwlRuntimeException(MsgConstants.ERR_FAILED_CONVERT_OBJECT, e); } copyProperties(source, target, true, ignores); return target; } public static void copyProperties(Object source, Object target, boolean chkEqual, String...ignores) { if (source == null) { throw new OwlRuntimeException(MsgConstants.SOURCE_OBJECT_IS_NULL); } if (target == null) { throw new OwlRuntimeException(MsgConstants.TARGET_OBJECT_IS_NULL); } try { copyAttrSourceToTarget(source, target, chkEqual, ignores); } catch (Exception e) { throw new OwlRuntimeException(MsgConstants.ERR_FAILED_CONVERT_OBJECT, e); } } /** * 소스 오브젝트에서 Primitive Type(ignores 제외)만 타겟 오브젝트로 복사한다. * * @param source * @param target */ public static void copyProperties(Object source, Object target, String...ignores) { copyProperties(source, target, true, ignores); } public static Map convertJsonToMap(String json) { Map content = null; ObjectMapper mapper = new ObjectMapper(); try { content = mapper.readValue(json, new TypeReference>() { }); } catch (Exception e) { throw new OwlRuntimeException(MsgConstants.ERR_FAILED_CONVERT_JSON, e); } return content; } public static String convertObjectToJson(Object target) { String json; ObjectMapper mapper = getObjectMapper(); try { json = mapper.writeValueAsString(target); } catch (Exception e) { throw new OwlRuntimeException(MsgConstants.ERR_FAILED_CONVERT_JSON, e); } return json; } public static T convertJsonToObject(String json, Class targetClass) { T object; ObjectMapper mapper = getObjectMapper(); try { object = mapper.readValue(json, targetClass); } catch (Exception e) { throw new OwlRuntimeException(MsgConstants.ERR_FAILED_CONVERT_JSON, e); } return object; } public static String join(List objects, String fieldName, String seperate) { StringBuffer sb = new StringBuffer(""); try { for (T object : objects) { PropertyDescriptor propertyDescriptor = BeanUtils.getPropertyDescriptor(object.getClass(), fieldName); Method method = propertyDescriptor.getReadMethod(); if (sb.length() == 0) { sb.append(method.invoke(object, fieldName)); } else { sb.append(seperate).append(" ").append(method.invoke(object, fieldName)); } } } catch (Exception e) { LOGGER.error(e.getMessage(), e.getCause()); } return sb.toString(); } public static List getFieldValues(List objects, String fieldName) { return getFieldValues(objects, fieldName, null, null); } public static List getFieldValues(List objects, String fieldName, String beforeAdd) { return getFieldValues(objects, fieldName, beforeAdd, null); } public static List getFieldValues(List objects, String fieldName, String beforeAdd, String prefix) { List fieldValues = new ArrayList(); if (beforeAdd != null) { fieldValues.add(beforeAdd); } try { for (T object : objects) { PropertyDescriptor propertyDescriptor = BeanUtils.getPropertyDescriptor(object.getClass(), fieldName); Method method = propertyDescriptor.getReadMethod(); if (prefix == null) { fieldValues.add(method.invoke(object, fieldName).toString()); } else { fieldValues.add(prefix + method.invoke(object, fieldName).toString()); } } } catch (Exception e) { LOGGER.error(e.getMessage(), e.getCause()); } return fieldValues; } public static String getFieldValue(T object, String fieldName) { Object retVal = null; if (object != null) { PropertyDescriptor propertyDescriptor = BeanUtils.getPropertyDescriptor(object.getClass(), fieldName); Method method = propertyDescriptor.getReadMethod(); try { retVal = method.invoke(object, fieldName); } catch (Exception e) { LOGGER.debug(e.toString()); } } return retVal == null ? "" : retVal.toString(); } private static ObjectMapper getObjectMapper() { ObjectMapper mapper = new ObjectMapper(); mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); return mapper; } public static String[] ToArray(List list) { return list.toArray(new String[list.size()]); } /** * ip주소 long으로 변환 * @param ipAddress String * @return long */ public static long ipToLong(String ipAddress) { long result = 0; if (!StringUtils.isEmpty(ipAddress) && !Pattern.matches(Regular.IP, ipAddress)) { return result; } else { String[] ipAddressArr = ipAddress.split("\\."); for (int i=0; i ipToLongs(String ipAddressList) { if (!StringUtils.isEmpty(ipAddressList)) { String[] split = ipAddressList.split(CommonUtil.COMMA); List longs = Lists.newArrayList(); for (String str : split) { longs.add(ipToLong(str)); } return longs; } return null; } }