데이터가 단 건일 경우 변환 기능 추가

This commit is contained in:
win777
2015-11-19 07:02:19 +00:00
parent bf5cdfb642
commit 7a3d0058b8
9 changed files with 589 additions and 55 deletions

View File

@@ -1,5 +1,6 @@
package com.nexacro.spring.data;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
@@ -23,7 +24,7 @@ public class NexacroResult {
private PlatformData platformData;
private Map<String, List> dataSetMaps;
private Map<String, Object> dataSetMaps;
private Map<String, Object> variableMaps;
// result status
@@ -37,7 +38,7 @@ public class NexacroResult {
}
private void initResult() {
dataSetMaps = new HashMap<String, List>();
dataSetMaps = new HashMap<String, Object>();
variableMaps = new HashMap<String, Object>();
platformData = new PlatformData();
}
@@ -54,13 +55,13 @@ public class NexacroResult {
/**
*
* 입력받은 dataSetName(DataSet 이름)으로 List를 <code>DataSet</code>으로 추가한다.
* 입력받은 dataSetName(DataSet 이름)으로 Object를 <code>DataSet</code>으로 추가한다.
* <p><code>List</code>의 값은 <code>java.util.Map<code> 혹은 VO class만 설정가능하다.
*
* @param dataSetName
* @param beans
*/
public void addDataSet(String dataSetName, List beans) {
public void addDataSet(String dataSetName, Object beans) {
checkName(dataSetName);
checkBean(beans);
@@ -90,7 +91,7 @@ public class NexacroResult {
variableMaps.put(variableName, object);
}
public Map<String, List> getDataSets() {
public Map<String, Object> getDataSets() {
return Collections.unmodifiableMap(dataSetMaps);
}
@@ -104,8 +105,11 @@ public class NexacroResult {
}
}
private void checkBean(List bean) {
}
private void checkBean(Object bean) {
if (bean == null) {
throw new IllegalArgumentException("Bean is null");
}
}
public PlatformData getPlatformData() {
return platformData;

View File

@@ -10,7 +10,9 @@ import org.slf4j.LoggerFactory;
import com.nexacro.spring.data.convert.NexacroConverter.ConvertiblePair;
import com.nexacro.spring.data.support.DataSetToListConverter;
import com.nexacro.spring.data.support.DataSetToObjectConverter;
import com.nexacro.spring.data.support.ListToDataSetConverter;
import com.nexacro.spring.data.support.ObjectToDataSetConverter;
import com.nexacro.spring.data.support.ObjectToVariableConverter;
import com.nexacro.spring.data.support.VariableToObjectConverter;
@@ -39,6 +41,8 @@ public class NexacroConverterFactory {
private void addDefaultConverter() {
NexacroConverterFactory.register(new DataSetToListConverter());
NexacroConverterFactory.register(new ListToDataSetConverter());
NexacroConverterFactory.register(new DataSetToObjectConverter());
NexacroConverterFactory.register(new ObjectToDataSetConverter());
NexacroConverterFactory.register(new VariableToObjectConverter());
NexacroConverterFactory.register(new ObjectToVariableConverter());
}

View File

@@ -1,6 +1,7 @@
package com.nexacro.spring.data.support;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.nexacro.spring.data.convert.ConvertDefinition;
@@ -26,7 +27,7 @@ public class DataSetToObjectConverter extends AbstractDataSetConverter implement
}
// support type
if(DataSet.class.equals(source) && NexacroConverterHelper.isSupportedBean(target)) {
if(DataSet.class.equals(source) && !List.class.equals(target) && NexacroConverterHelper.isSupportedBean(target)) {
return true;
}

View File

@@ -1,5 +1,6 @@
package com.nexacro.spring.data.support;
import java.util.List;
import java.util.Map;
import com.nexacro.spring.data.convert.ConvertDefinition;
@@ -20,16 +21,16 @@ public class ObjectToDataSetConverter extends AbstractDataSetConverter implement
@Override
public boolean canConvert(Class source, Class target) {
if(source == null || target == null) {
return false;
}
// support list sub class
if(NexacroConverterHelper.isSupportedBean(source) && DataSet.class.equals(target)) {
return true;
}
return false;
if(source == null || target == null) {
return false;
}
// support type
if(!List.class.isAssignableFrom(source) && NexacroConverterHelper.isSupportedBean(source) && DataSet.class.equals(target)) {
return true;
}
return false;
}
@Override
@@ -38,10 +39,7 @@ public class ObjectToDataSetConverter extends AbstractDataSetConverter implement
if(definition ==null) {
throw new IllegalArgumentException(ConvertDefinition.class.getSimpleName()+" must not be null.");
}
if(source == null) {
return new DataSet(definition.getName());
}
if(source == null) {
return new DataSet(definition.getName());
}
@@ -54,7 +52,7 @@ public class ObjectToDataSetConverter extends AbstractDataSetConverter implement
ds = convertBeanToDataSet(source, definition);
}
return null;
return ds;
}
private DataSet convertBeanToDataSet(Object source, ConvertDefinition definition) throws NexacroConvertException {

View File

@@ -168,15 +168,15 @@ public class NexacroHandlerMethodReturnValueHandler implements HandlerMethodRetu
private void addDataSetsIntoPlatformData(PlatformData platformData, NexacroResult nexacroResult) throws NexacroConvertException {
Map<String, List> dataSets = nexacroResult.getDataSets();
Map<String, Object> dataSets = nexacroResult.getDataSets();
Set<String> dataSetKeySet = dataSets.keySet();
for(String name: dataSetKeySet) {
List list = dataSets.get(name);
if(list == null) {
Object object = dataSets.get(name);
if(object == null) {
platformData.addDataSet(new DataSet(name));
} else {
NexacroConverter dataSetConverter = getDataSetConverter(list.getClass());
NexacroConverter dataSetConverter = getDataSetConverter(object.getClass());
if(dataSetConverter == null) {
logger.debug("not found converter {} to List to DataSet({})" , name);
continue;
@@ -188,7 +188,7 @@ public class NexacroHandlerMethodReturnValueHandler implements HandlerMethodRetu
ConvertDefinition definition = new ConvertDefinition(name);
Object convert = dataSetConverter.convert(list, definition);
Object convert = dataSetConverter.convert(object, definition);
if(convert != null && convert instanceof DataSet) {
platformData.addDataSet((DataSet) convert);

View File

@@ -293,10 +293,10 @@ public class NexacroMethodArgumentResolver implements HandlerMethodArgumentResol
return dataSet;
}
// support only list parameter
if(!List.class.equals(parameterType)) {
throw new IllegalArgumentException(ParamDataSet.class.getSimpleName()+" annotation support List<?> and DataSet parameter.");
}
// // support only list parameter
// if(!List.class.equals(parameterType)) {
// throw new IllegalArgumentException(ParamDataSet.class.getSimpleName()+" annotation support List<?> and DataSet parameter.");
// }
Class convertedGenericType = findGenericType(param);
if(convertedGenericType == null) {
@@ -304,16 +304,15 @@ public class NexacroMethodArgumentResolver implements HandlerMethodArgumentResol
throw new IllegalArgumentException(ParamDataSet.class.getSimpleName()+" annotation must be List<?>.");
}
ConvertDefinition definition = new ConvertDefinition(dsName);
definition.setGenericType(convertedGenericType);
Class<?> fromType = DataSet.class;
Class<?> toType = parameterType;
NexacroConverter<DataSet, List> converter = NexacroConverterFactory.getConverter(fromType, toType);
NexacroConverter<DataSet, Object> converter = NexacroConverterFactory.getConverter(fromType, toType);
if(converter == null) {
throw new IllegalArgumentException("invalid @ParamDataSet. supported type={DataSet, List<?>}");
throw new IllegalArgumentException("invalid @ParamDataSet. supported type={DataSet, Object<?>}");
}
try {
@@ -369,28 +368,55 @@ public class NexacroMethodArgumentResolver implements HandlerMethodArgumentResol
}
// private Class findGenericType(MethodParameter param) {
//
// // current type -> List<?>
// Type genericParameterType = param.getGenericParameterType();
// if (genericParameterType instanceof ParameterizedType) {
//
// // current type -> <?>
// Type[] types = ((ParameterizedType) genericParameterType).getActualTypeArguments();
//
// if(types[0] instanceof ParameterizedType) {
// // List<Map<String, Object>>
// return (Class) ((ParameterizedType) types[0]).getRawType();
// } else {
//
// // List<Bean>
// // List<Map>
// return (Class) types[0];
// }
// }
//
// return null;
// }
private Class findGenericType(MethodParameter param) {
// current type -> List<?>
Type genericParameterType = param.getGenericParameterType();
if (genericParameterType instanceof ParameterizedType) {
// current type -> <?>
Type[] types = ((ParameterizedType) genericParameterType).getActualTypeArguments();
if(types[0] instanceof ParameterizedType) {
// List<Map<String, Object>>
return (Class) ((ParameterizedType) types[0]).getRawType();
} else {
// List<Bean>
// List<Map>
return (Class) types[0];
}
}
return null;
Class<?> parameterType = param.getParameterType();
if (!List.class.equals(parameterType)) {
return parameterType;
} else {
Type genericParameterType = param.getGenericParameterType();
if (genericParameterType instanceof ParameterizedType) {
Type[] types = ((ParameterizedType) genericParameterType).getActualTypeArguments();
return (Class) types[0];
// if(types[0] instanceof ParameterizedType) {
// // List<Map<String, Object>>
// return (Class) ((ParameterizedType) types[0]).getRawType();
// } else {
// // List<Bean>
// // List<Map>
// return (Class) types[0];
// }
}
}
return null;
}
protected void handleMissingValue(String name, MethodParameter parameter) throws NexacroConvertException {
throw new MissingNexacroParameterException(name, parameter.getParameterType().getSimpleName());

View File

@@ -0,0 +1,226 @@
package com.nexacro.spring.data.support;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.crypto.Data;
import junit.framework.Assert;
import org.apache.commons.io.IOUtils;
import org.junit.Before;
import org.junit.Test;
import com.nexacro.spring.data.convert.ConvertDefinition;
import com.nexacro.spring.data.convert.NexacroConvertException;
import com.nexacro.spring.data.support.NexacroTestUtil.StaticPropertyBean;
import com.nexacro.spring.data.support.bean.DefaultBean;
import com.nexacro.spring.util.ReflectionUtil;
import com.nexacro.xapi.data.ColumnHeader;
import com.nexacro.xapi.data.ConstantColumnHeader;
import com.nexacro.xapi.data.DataSet;
import com.nexacro.xapi.data.PlatformData;
import com.nexacro.xapi.tx.DataDeserializer;
import com.nexacro.xapi.tx.DataSerializerFactory;
import com.nexacro.xapi.tx.PlatformException;
import com.nexacro.xapi.tx.PlatformType;
public class DataSetToObjectConverterTest {
private DataSetToObjectConverter converter;
@Before
public void setUp() {
converter = new DataSetToObjectConverter();
}
@Test
public void testSupportedType() {
Class<?> source;
Class<?> target;
boolean canConvert;
source = DataSet.class;
target = Object.class;
canConvert = converter.canConvert(source, target);
Assert.assertTrue(source + " to " + target + " must be converted", canConvert);
}
@Test
public void testConvertDataSetBeanToObject() throws IOException, PlatformException {
String responseFileName = "src/test/java/com/nexacro/spring/resolve/httpRequestForMap.xml";
InputStream responseInputStream = new FileInputStream(new File(responseFileName));
DataDeserializer deserializer = DataSerializerFactory.getDeserializer(PlatformType.CONTENT_TYPE_XML);
PlatformData readData = deserializer.readData(responseInputStream, null, PlatformType.DEFAULT_CHAR_SET);
DataSet dataSet = readData.getDataSet("ds");
ConvertDefinition definition = new ConvertDefinition("ds");
definition.setGenericType(Object.class);
Object obj = null;
try {
obj = converter.convert(dataSet, definition);
} catch (NexacroConvertException e) {
e.printStackTrace();
Assert.fail(e.getMessage());
}
if (!(obj instanceof Object)) {
Assert.fail("It must be Object");
}
}
@Test
public void testNullData() {
DataSet dataSet = null;
ConvertDefinition definition = new ConvertDefinition("ds");
definition.setGenericType(Object.class);
Object ds = null;
try {
ds = converter.convert(dataSet, definition);
} catch (NexacroConvertException e) {
Assert.fail(e.getMessage());
}
if (!(ds instanceof Object)) {
Assert.fail("converted object must be implemented DataSet");
}
}
@Test
public void testMapConvert() {
Map beanMap = new HashMap();
// Result result = new Result();
//// List<?> list = result.getList();
//
//
// DefaultBean bean = new DefaultBean();
// beanList.add(bean);
//
// Object[] array = beanList.toArray();
// array[0].getClass();
//
// Class<? extends List> clazz= beanList.getClass();
//
// ParameterizedType parameterizedType = (ParameterizedType) clazz.getGenericSuperclass();
// System.out.println(parameterizedType.getRawType());
//
// Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
// for(Type type: actualTypeArguments) {
// System.out.println(type);
// }
DefaultBean bean = new DefaultBean();
beanMap.put(bean.getClass().getSimpleName(), bean);
System.out.println("key = " + beanMap);
Class<?> clazz = beanMap.getClass();
System.out.println("clazz = " + clazz);
ParameterizedType superclass = (ParameterizedType) clazz.getGenericSuperclass();
Type[] types = superclass.getActualTypeArguments();
Class<?> actualdataType = null;
if(types != null && types.length >0 && (types[0] instanceof Class<?>) ) {
actualdataType = (Class<?>) (Class<?>) types[0];
}
System.out.println("actualdataType = " + actualdataType);
}
private static final String TYPE_CLASS_NAME_PREFIX = "class ";
private static final String TYPE_INTERFACE_NAME_PREFIX = "interface ";
public static String getClassName(Type type) {
if (type==null) {
return "";
}
String className = type.toString();
if (className.startsWith(TYPE_CLASS_NAME_PREFIX)) {
className = className.substring(TYPE_CLASS_NAME_PREFIX.length());
} else if (className.startsWith(TYPE_INTERFACE_NAME_PREFIX)) {
className = className.substring(TYPE_INTERFACE_NAME_PREFIX.length());
}
return className;
}
/**
* Returns the {@code Class} object associated with the given {@link Type}
* depending on its fully qualified name.
*
* @param type the {@code Type} whose {@code Class} is needed.
* @return the {@code Class} object for the class with the specified name.
*
* @throws ClassNotFoundException if the class cannot be located.
*
* @see {@link ReflectionUtil#getClassName(Type)}
*/
public static Class<?> getClass(Type type) throws ClassNotFoundException {
String className = getClassName(type);
if (className==null || className.isEmpty()) {
return null;
}
return Class.forName(className);
}
public static Type[] getParameterizedTypes(Object object) {
Type superclassType = object.getClass().getGenericSuperclass();
if (!ParameterizedType.class.isAssignableFrom(superclassType.getClass())) {
return null;
}
return ((ParameterizedType)superclassType).getActualTypeArguments();
}
// public static Class<?> getClass(Type type) {
// if (type instanceof Class) {
// return (Class) type;
// }
// else if (type instanceof ParameterizedType) {
// return getClass(((ParameterizedType) type).getRawType());
// }
// else if (type instanceof GenericArrayType) {
// Type componentType = ((GenericArrayType) type).getGenericComponentType();
// Class<?> componentClass = getClass(componentType);
// if (componentClass != null ) {
// return Array.newInstance(componentClass, 0).getClass();
// }
// else {
// return null;
// }
// }
// else {
// return null;
// }
// }
private static class Result {
private List<?> list;
public void setList(List<?> list) {
this.list = list;
}
public List<?> getList() {
return null;
}
}
}

View File

@@ -0,0 +1,236 @@
package com.nexacro.spring.data.support;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import junit.framework.Assert;
import org.junit.Before;
import org.junit.Test;
import com.nexacro.spring.data.convert.ConvertDefinition;
import com.nexacro.spring.data.convert.NexacroConvertException;
import com.nexacro.spring.data.support.NexacroTestUtil.StaticPropertyBean;
import com.nexacro.spring.data.support.bean.DefaultBean;
import com.nexacro.spring.util.ReflectionUtil;
import com.nexacro.xapi.data.ColumnHeader;
import com.nexacro.xapi.data.ConstantColumnHeader;
import com.nexacro.xapi.data.DataSet;
public class ObjectToDataSetConverterTest {
private ObjectToDataSetConverter converter;
@Before
public void setUp() {
converter = new ObjectToDataSetConverter();
}
@Test
public void testSupportedType() {
Class<?> source;
Class<?> target;
boolean canConvert;
source = Object.class;
target = DataSet.class;
canConvert = converter.canConvert(source, target);
Assert.assertTrue(source + " to " + target + " must be converted", canConvert);
}
@Test
public void testConvertObjectBeanToDataSet() {
DefaultBean defaultBean = new DefaultBean();
defaultBean.setLastName("Kim");
ConvertDefinition definition = new ConvertDefinition("ds");
Object ds = null;
try {
ds = converter.convert(defaultBean, definition);
} catch (NexacroConvertException e) {
e.printStackTrace();
Assert.fail(e.getMessage());
}
if (!(ds instanceof DataSet)) {
Assert.fail("converted object must be implemented DataSet");
}
DataSet dataset = (DataSet) ds;
Assert.assertEquals("ds", dataset.getName());
Assert.assertEquals("Kim", dataset.getObject(0, "lastName"));
}
@Test
public void testConvertMapToDataSet() {
Map<String, Object> map = new HashMap<String, Object>();
map.put("firstName", "firstName");
map.put("lastName", "lastName");
ConvertDefinition definition = new ConvertDefinition("ds");
Object ds = null;
try {
ds = converter.convert(map, definition);
} catch (NexacroConvertException e) {
e.printStackTrace();
Assert.fail(e.getMessage());
}
if (!(ds instanceof DataSet)) {
Assert.fail("converted object must be implemented DataSet");
}
DataSet dataset = (DataSet) ds;
Assert.assertEquals("lastName", dataset.getObject(0, "lastName"));
}
@Test
public void testNullData() {
Object object = null;
ConvertDefinition definition = new ConvertDefinition("ds");
Object ds = null;
try {
ds = converter.convert(object, definition);
} catch (NexacroConvertException e) {
Assert.fail(e.getMessage());
}
if (!(ds instanceof DataSet)) {
Assert.fail("converted object must be implemented DataSet");
}
DataSet dataset = (DataSet) ds;
Assert.assertNotNull("dataset should not be null", dataset);
Assert.assertEquals("ds", dataset.getName());
}
@Test
public void testMapConvert() {
Map beanMap = new HashMap();
// Result result = new Result();
//// List<?> list = result.getList();
//
//
// DefaultBean bean = new DefaultBean();
// beanList.add(bean);
//
// Object[] array = beanList.toArray();
// array[0].getClass();
//
// Class<? extends List> clazz= beanList.getClass();
//
// ParameterizedType parameterizedType = (ParameterizedType) clazz.getGenericSuperclass();
// System.out.println(parameterizedType.getRawType());
//
// Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
// for(Type type: actualTypeArguments) {
// System.out.println(type);
// }
DefaultBean bean = new DefaultBean();
beanMap.put(bean.getClass().getSimpleName(), bean);
System.out.println("key = " + beanMap);
Class<?> clazz = beanMap.getClass();
System.out.println("clazz = " + clazz);
ParameterizedType superclass = (ParameterizedType) clazz.getGenericSuperclass();
Type[] types = superclass.getActualTypeArguments();
Class<?> actualdataType = null;
if(types != null && types.length >0 && (types[0] instanceof Class<?>) ) {
actualdataType = (Class<?>) (Class<?>) types[0];
}
System.out.println("actualdataType = " + actualdataType);
}
private static final String TYPE_CLASS_NAME_PREFIX = "class ";
private static final String TYPE_INTERFACE_NAME_PREFIX = "interface ";
public static String getClassName(Type type) {
if (type==null) {
return "";
}
String className = type.toString();
if (className.startsWith(TYPE_CLASS_NAME_PREFIX)) {
className = className.substring(TYPE_CLASS_NAME_PREFIX.length());
} else if (className.startsWith(TYPE_INTERFACE_NAME_PREFIX)) {
className = className.substring(TYPE_INTERFACE_NAME_PREFIX.length());
}
return className;
}
/**
* Returns the {@code Class} object associated with the given {@link Type}
* depending on its fully qualified name.
*
* @param type the {@code Type} whose {@code Class} is needed.
* @return the {@code Class} object for the class with the specified name.
*
* @throws ClassNotFoundException if the class cannot be located.
*
* @see {@link ReflectionUtil#getClassName(Type)}
*/
public static Class<?> getClass(Type type) throws ClassNotFoundException {
String className = getClassName(type);
if (className==null || className.isEmpty()) {
return null;
}
return Class.forName(className);
}
public static Type[] getParameterizedTypes(Object object) {
Type superclassType = object.getClass().getGenericSuperclass();
if (!ParameterizedType.class.isAssignableFrom(superclassType.getClass())) {
return null;
}
return ((ParameterizedType)superclassType).getActualTypeArguments();
}
// public static Class<?> getClass(Type type) {
// if (type instanceof Class) {
// return (Class) type;
// }
// else if (type instanceof ParameterizedType) {
// return getClass(((ParameterizedType) type).getRawType());
// }
// else if (type instanceof GenericArrayType) {
// Type componentType = ((GenericArrayType) type).getGenericComponentType();
// Class<?> componentClass = getClass(componentType);
// if (componentClass != null ) {
// return Array.newInstance(componentClass, 0).getClass();
// }
// else {
// return null;
// }
// }
// else {
// return null;
// }
// }
private static class Result {
private List<?> list;
public void setList(List<?> list) {
this.list = list;
}
public List<?> getList() {
return null;
}
}
}

View File

@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<Root xmlns="http://www.nexacro.com/platform/dataset" ver="5000">
<Parameters>
<Parameter id="varInt" type="int">1</Parameter>
<Parameter id="varString" type="string">varString</Parameter>
</Parameters>
<Dataset id="ds">
<ColumnInfo>
<Column id="access" type="bigdecimal" size="8"/>
<Column id="commissionPercent" type="float" size="8"/>
<Column id="email" type="string" size="32"/>
<Column id="employeeId" type="int" size="4"/>
<Column id="firstName" type="string" size="32"/>
<Column id="height" type="float" size="4"/>
<Column id="hireDate" type="datetime" size="17"/>
<Column id="image" type="blob" size="256" encrypt="base64"/>
<Column id="lastName" type="string" size="32"/>
<Column id="male" type="int" size="2"/>
<Column id="obj" type="undefined" size="0"/>
<Column id="salary" type="bigdecimal" size="16"/>
</ColumnInfo>
<Rows>
<Row>
<Col id="access">11</Col>
<Col id="commissionPercent">11.1</Col>
<Col id="email">tobesoft@tobesoft.com</Col>
<Col id="employeeId">11</Col>
<Col id="firstName">firstName</Col>
<Col id="height">200</Col>
<Col id="hireDate">20090101134516072</Col>
<Col id="image">AQE=</Col>
<Col id="lastName">lastName</Col>
<Col id="male">1</Col>
<Col id="obj">java.lang.Object@1c7e2da</Col>
<Col id="salary">11111</Col>
</Row>
</Rows>
</Dataset>
</Root>