/* * Copyright 2006-2007 the original author or authors. * 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; } }