/* * Copyright 2012-2014 MOSPA(Ministry of Security and Public Administration). * * 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 egovframework.rte.bat.core.reflection; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.math.BigDecimal; import java.util.HashMap; import java.util.List; import java.util.Map; import org.springframework.util.ReflectionUtils; /** * Reflection 관련 method * @author 실행환경 개발팀 * @since 2012.07.20 * @version 1.0 * @see * <pre> * 개정이력(Modification Information) * * 수정일 수정자 수정내용 * ------- -------- --------------------------- * 2012.07.20 실행환경개발팀 최초 생성 * </pre> */ public class EgovReflectionSupport<T> { // 실제 VO가 담길 Object private Object object = null; // VO에 들어있는 Method 목록 private Method[] methods; // VO의 Field명과 Method 목록의 Index를 매핑 private HashMap<String, Method> methodMap; // VO의 Field 타입 private Type[] fieldType; /** * VO에 들어있는 Method 목록 get */ public HashMap<String, Method> getMethodMap() { return methodMap; } /** * 주어진 Method 이름(methodName)으로 Method를 검색한다. * @param methods * @param methodName * @return Method */ private Method retrieveMethod(Method[] methods, String methodName) { Method method = null; for (int i = 0; i < methods.length; i++) { if (methods[i].getName().equals(methodName)) { method = methods[i]; break; } } return method; } public EgovReflectionSupport() { super(); } /** * VO 타입의 instance 생성 * @param type VO 타입 */ private void createObject(Class<?> type) { try { object = type.newInstance(); } catch (InstantiationException e) { ReflectionUtils.handleReflectionException(e); } catch (IllegalAccessException e) { ReflectionUtils.handleReflectionException(e); } } /** * VO의 Field명과 Setter Method들을 비교하여 Map에 Put 한다. * Bean 생성시 한 번만 실행 된다. */ public void generateSetterMethodMap(Class<?> type, String[] names) throws Exception { methods = type.newInstance().getClass().getMethods(); methodMap = new HashMap<String, Method>(); for (int i = 0; i < names.length; i++) { try { String strMethod = "set" + (names[i].substring(0, 1)).toUpperCase() + names[i].substring(1); methodMap.put(names[i], retrieveMethod(methods, strMethod)); } catch (Exception e) { throw new Exception("Cannot create a method list of given : " + type.toString()); } } } /** * VO의 Setter method 실행 * @param tokens VO에 set 될 value * @param names VO의 field 명 */ private void invokeSetterMethod(List<String> tokens, String[] names) { Method method; for (int i = 0; i < names.length; i++) { method = methodMap.get(names[i]); try { method.invoke(object, parsingFromString(tokens.get(i).trim(), fieldType[i])); } catch (IllegalAccessException e) { ReflectionUtils.handleReflectionException(e); } catch (InvocationTargetException e) { ReflectionUtils.handleReflectionException(e); } catch (SecurityException e) { ReflectionUtils.handleReflectionException(e); } } } @SuppressWarnings("unchecked") public T generateObject(Class<?> type, List<String> tokens, String[] names) { createObject(type); invokeSetterMethod(tokens, names); return (T) object; } /** * VO의 Field명과 Getter Method들을 비교하여 Map에 Put 한다. * Bean 생성시 한 번만 실행 된다. */ public void generateGetterMethodMap(String[] names, T item) throws Exception { if (methods == null) { methods = item.getClass().getMethods(); methodMap = new HashMap<String, Method>(); try { for (int i = 0; i < names.length; i++) { String strMethod = "get" + (names[i].substring(0, 1)).toUpperCase() + names[i].substring(1); methodMap.put(names[i], retrieveMethod(methods, strMethod)); } } catch (Exception e) { throw new Exception("Cannot create a method list of given : " + item.toString()); } } } /** * item의 field 정보를 가져오기 위해 getter를 invoke * @param item 정보를 담고 있는 VO * @param names VO의 field name * @return getValue field 정보를 get 하여 return */ public Object invokeGettterMethod(T item, String names) { Object value = null; try { value = methodMap.get(names).invoke(item); } catch (IllegalArgumentException e) { ReflectionUtils.handleReflectionException(e); } catch (IllegalAccessException e) { ReflectionUtils.handleReflectionException(e); } catch (InvocationTargetException e) { ReflectionUtils.handleReflectionException(e); } return value; } /** * item의 field 정보를 가져오기 위해 getter를 invoke * @param item item 정보를 담고 있는 VO * @param param * @param mapMethod VO의 getter 메소드를 갖고 있는 Map * @return field 정보를 get 하여 return */ public Object invokeGettterMethod(T item, String param, Map<String, Method> mapMethod) { Object value = null; try { value = mapMethod.get(param).invoke(item); } catch (IllegalArgumentException e) { ReflectionUtils.handleReflectionException(e); } catch (IllegalAccessException e) { ReflectionUtils.handleReflectionException(e); } catch (InvocationTargetException e) { ReflectionUtils.handleReflectionException(e); } return value; } /** * VO의 field의 타입 get * @param type VO의 타입 * @param names VO field names */ public void getFieldType(Class<?> type, String[] names) { fieldType = new Type[names.length]; for (int i = 0; i < names.length; i++) { try { fieldType[i] = type.newInstance().getClass().getDeclaredField(names[i]).getType(); } catch (SecurityException e) { ReflectionUtils.handleReflectionException(e); } catch (NoSuchFieldException e) { ReflectionUtils.handleReflectionException(e); } catch (InstantiationException e) { ReflectionUtils.handleReflectionException(e); } catch (IllegalAccessException e) { ReflectionUtils.handleReflectionException(e); } } } /** * sqlType을 배열 형식으로 받는 메소드 */ public String[] getSqlTypeArray(String[] params, Object item) { String[] sqlTypes = new String[params.length]; for (int i = 0; i < params.length; i++) { try { sqlTypes[i] = item.getClass().getDeclaredField(params[i]).getType().getSimpleName().toString(); } catch (SecurityException e) { ReflectionUtils.handleReflectionException(e); } catch (NoSuchFieldException e) { ReflectionUtils.handleReflectionException(e); } } return sqlTypes; } /** * String to Type parsing * @param tokenValue String 형태의 token value * @param type 실제 VO에서 token value의 type * @return parsingValue 해당 type으로 paring한 value return */ private Object parsingFromString(String tokenValue, Type type) { Object parsingValue = null; if (type == String.class) { parsingValue = tokenValue; } else if (type == int.class) { parsingValue = Integer.parseInt(tokenValue); } else if (type == double.class) { parsingValue = Double.parseDouble(tokenValue); } else if (type == float.class) { parsingValue = Float.parseFloat(tokenValue); } else if (type == long.class) { parsingValue = Long.parseLong(tokenValue); } else if (type == char.class) { parsingValue = tokenValue.charAt(0); } else if (type == byte[].class) { parsingValue = tokenValue.getBytes(); } else if (type == boolean.class) { parsingValue = Boolean.valueOf(tokenValue); } else if (type == BigDecimal.class) { parsingValue = new BigDecimal(tokenValue); } else { parsingValue = tokenValue; } return parsingValue; } }