DataSet으로 데이터 변환 시 스키마 데이터셋 설정 및 스키마 변경에 대한 옵션 추가.

This commit is contained in:
ParkSeongMin
2017-05-23 14:54:22 +09:00
parent 2e51f83149
commit bc34e78968
8 changed files with 1301 additions and 892 deletions

View File

@@ -2,7 +2,7 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>com.nexacro.spring</groupId> <groupId>com.nexacro.spring</groupId>
<version>1.0.0</version> <version>1.0.1</version>
<artifactId>nexacro-core</artifactId> <artifactId>nexacro-core</artifactId>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>nexacro-core</name> <name>nexacro-core</name>

View File

@@ -1,5 +1,7 @@
package com.nexacro.spring.data.convert; package com.nexacro.spring.data.convert;
import com.nexacro.xapi.data.DataSet;
/** /**
* <p>데이터 변환에 대한 정보를 저장한다. * <p>데이터 변환에 대한 정보를 저장한다.
@@ -17,6 +19,9 @@ public class ConvertDefinition {
private Class genericType; // for generic private Class genericType; // for generic
private boolean isIgnoreException = false; private boolean isIgnoreException = false;
private DataSet schemaDataSet;
private boolean disallowChangeStructure; // (v1.0.0에서 허용 하게 되어 있음)
public ConvertDefinition(String name) { public ConvertDefinition(String name) {
setName(name); setName(name);
} }
@@ -68,4 +73,36 @@ public class ConvertDefinition {
this.genericType = genericType; this.genericType = genericType;
} }
/**
*
* @return disallow structure change
*/
public boolean isDisallowChangeStructure() {
return disallowChangeStructure;
}
/**
*
* @param disallow structure change
*/
public void setDisallowChangeStructure(boolean disallowChangeStructure) {
this.disallowChangeStructure = disallowChangeStructure;
}
/**
*
* @return the schema dataSet
*/
public DataSet getSchemaDataSet() {
return schemaDataSet;
}
/**
*
* @param schemaDataSet
*/
public void setSchemaDataSet(DataSet schemaDataSet) {
this.schemaDataSet = schemaDataSet;
}
} }

View File

@@ -37,7 +37,7 @@ public class AbstractDataSetConverter extends AbstractListenerHandler {
* @param map * @param map
* @throws NexacroConvertException * @throws NexacroConvertException
*/ */
protected void addRowIntoDataSet(DataSet ds, Map map) throws NexacroConvertException { protected void addRowIntoDataSet(DataSet ds, Map map, boolean disallowChangeStructure) throws NexacroConvertException {
// ignore null data. // ignore null data.
if(map == null) { if(map == null) {
return; return;
@@ -62,11 +62,15 @@ public class AbstractDataSetConverter extends AbstractListenerHandler {
int columnIndex = ds.indexOfColumn(columnName); int columnIndex = ds.indexOfColumn(columnName);
if(columnIndex < 0) { if(columnIndex < 0) {
// flexible map data. 'null' data should be ignored if(disallowChangeStructure) {
ds.setChangeStructureWithData(true); // ignore
continue;
if(!addColumnByMap(ds, columnName, value)) { } else {
continue; // flexible map data. 'null' data should be ignored
ds.setChangeStructureWithData(true);
if(!addColumnByMap(ds, columnName, value)) {
continue;
}
} }
} }
// fire event // fire event
@@ -108,7 +112,13 @@ public class AbstractDataSetConverter extends AbstractListenerHandler {
// Byte[] 변환 // Byte[] 변환
Object object = NexacroConverterHelper.toObject(propertyValue); Object object = NexacroConverterHelper.toObject(propertyValue);
// 컬럼은 무조건 존재한다.
int columnIndex = ds.indexOfColumn(propertyName); int columnIndex = ds.indexOfColumn(propertyName);
if(columnIndex < 0) {
// Map과 달리 이미 구조 변경에 대한 처리가 되었기 때문에 컬럼이 존재하지 않을 경우 무시하도록 한다.
continue;
}
// fire event // fire event
object = fireDataSetConvertedValue(ds, object, newRow, columnIndex, false, false); object = fireDataSetConvertedValue(ds, object, newRow, columnIndex, false, false);
@@ -127,6 +137,9 @@ public class AbstractDataSetConverter extends AbstractListenerHandler {
* @throws NexacroConvertException * @throws NexacroConvertException
*/ */
protected void addColumnIntoDataSet(DataSet ds, Map map) throws NexacroConvertException { protected void addColumnIntoDataSet(DataSet ds, Map map) throws NexacroConvertException {
ds.setChangeStructureWithData(true);
Iterator iterator = map.keySet().iterator(); Iterator iterator = map.keySet().iterator();
while(iterator.hasNext()) { while(iterator.hasNext()) {
Object key = iterator.next(); Object key = iterator.next();
@@ -149,6 +162,8 @@ public class AbstractDataSetConverter extends AbstractListenerHandler {
*/ */
protected void addColumnIntoDataSet(DataSet ds, Object availableFirstData) { protected void addColumnIntoDataSet(DataSet ds, Object availableFirstData) {
ds.setChangeStructureWithData(true);
NexacroBeanWrapper beanWrapper = NexacroBeanWrapper.createBeanWrapper(availableFirstData); NexacroBeanWrapper beanWrapper = NexacroBeanWrapper.createBeanWrapper(availableFirstData);
NexacroBeanProperty[] beanProperties = beanWrapper.getProperties(); NexacroBeanProperty[] beanProperties = beanWrapper.getProperties();

View File

@@ -88,10 +88,15 @@ public class ListToDataSetConverter extends AbstractDataSetConverter implements
private DataSet convertListMapToDataSet(List source, ConvertDefinition definition, Map availableFirstData) throws NexacroConvertException { private DataSet convertListMapToDataSet(List source, ConvertDefinition definition, Map availableFirstData) throws NexacroConvertException {
DataSet ds = new DataSet(definition.getName()); DataSet ds = null;
// dynamic하게 변경 된 데이터는 처리 하지 않는다. if(definition.getSchemaDataSet() != null) {
addColumnIntoDataSet(ds, availableFirstData); // set schema dataSet
ds = definition.getSchemaDataSet();
} else {
ds = new DataSet(definition.getName());
addColumnIntoDataSet(ds, availableFirstData);
}
for(Object obj: source) { for(Object obj: source) {
@@ -99,7 +104,7 @@ public class ListToDataSetConverter extends AbstractDataSetConverter implements
throw new NexacroConvertException("list should use the generic type. target="+ds.getName()); throw new NexacroConvertException("list should use the generic type. target="+ds.getName());
} }
addRowIntoDataSet(ds, (Map) obj); addRowIntoDataSet(ds, (Map) obj, definition.isDisallowChangeStructure());
} }
return ds; return ds;
@@ -112,9 +117,20 @@ public class ListToDataSetConverter extends AbstractDataSetConverter implements
throw new NexacroConvertException("unsupported generic type. type="+availableFirstData.getClass()); throw new NexacroConvertException("unsupported generic type. type="+availableFirstData.getClass());
} }
DataSet ds = new DataSet(definition.getName()); DataSet ds = null;
if(definition.getSchemaDataSet() != null) {
// set schema dataSet
ds = definition.getSchemaDataSet();
addColumnIntoDataSet(ds, availableFirstData); // map과 달리 bean은 이미 정의가 되어 있기 때문에 row를 추가할때 컬럼을 추가하지 않고, 미리 설정한다.
if(!definition.isDisallowChangeStructure()) {
addColumnIntoDataSet(ds, availableFirstData);
}
} else {
ds = new DataSet(definition.getName());
addColumnIntoDataSet(ds, availableFirstData);
}
for(Object obj: source) { for(Object obj: source) {
addRowIntoDataSet(ds, obj); addRowIntoDataSet(ds, obj);

View File

@@ -62,16 +62,36 @@ public class ObjectToDataSetConverter extends AbstractDataSetConverter implement
throw new NexacroConvertException("unsupported source type. type="+source.getClass()); throw new NexacroConvertException("unsupported source type. type="+source.getClass());
} }
DataSet ds = new DataSet(definition.getName()); DataSet ds = null;
addColumnIntoDataSet(ds, source); if(definition.getSchemaDataSet() != null) {
// set schema dataSet
ds = definition.getSchemaDataSet();
// map과 달리 bean은 이미 정의가 되어 있기 때문에 row를 추가할때 컬럼을 추가하지 않고, 미리 설정한다.
if(!definition.isDisallowChangeStructure()) {
addColumnIntoDataSet(ds, source);
}
} else {
ds = new DataSet(definition.getName());
addColumnIntoDataSet(ds, source);
}
addRowIntoDataSet(ds, source); addRowIntoDataSet(ds, source);
return ds; return ds;
} }
private DataSet convertMapToDataSet(Map source, ConvertDefinition definition) throws NexacroConvertException { private DataSet convertMapToDataSet(Map source, ConvertDefinition definition) throws NexacroConvertException {
DataSet ds = new DataSet(definition.getName()); DataSet ds = null;
addColumnIntoDataSet(ds, source); if(definition.getSchemaDataSet() != null) {
addRowIntoDataSet(ds, source); // set schema dataSet
ds = definition.getSchemaDataSet();
} else {
ds = new DataSet(definition.getName());
addColumnIntoDataSet(ds, source);
}
addRowIntoDataSet(ds, source, definition.isDisallowChangeStructure());
return ds; return ds;
} }
@@ -86,8 +106,8 @@ public class ObjectToDataSetConverter extends AbstractDataSetConverter implement
} }
@Override @Override
public void addRowIntoDataSet(DataSet ds, Map source) throws NexacroConvertException { public void addRowIntoDataSet(DataSet ds, Map source, boolean disallowChangeStructure) throws NexacroConvertException {
super.addRowIntoDataSet(ds, source); super.addRowIntoDataSet(ds, source, disallowChangeStructure);
} }
@Override @Override

View File

@@ -20,6 +20,7 @@ import com.nexacro.spring.util.ReflectionUtil;
import com.nexacro.xapi.data.ColumnHeader; import com.nexacro.xapi.data.ColumnHeader;
import com.nexacro.xapi.data.ConstantColumnHeader; import com.nexacro.xapi.data.ConstantColumnHeader;
import com.nexacro.xapi.data.DataSet; import com.nexacro.xapi.data.DataSet;
import com.nexacro.xapi.data.datatype.PlatformDataType;
/** /**
* *
@@ -100,7 +101,7 @@ public class ListToDataSetConverterTest {
Assert.fail("converted object must be implemented DataSet"); Assert.fail("converted object must be implemented DataSet");
} }
NexacroTestUtil.compareDefaultDataSet((DataSet) ds); NexacroTestUtil.compareDefaultDataSet((DataSet) ds, 0);
} }
@@ -123,7 +124,7 @@ public class ListToDataSetConverterTest {
Assert.fail("converted object must be implemented DataSet"); Assert.fail("converted object must be implemented DataSet");
} }
NexacroTestUtil.compareDefaultDataSet((DataSet) ds); NexacroTestUtil.compareDefaultDataSet((DataSet) ds, 0);
} }
@@ -235,6 +236,207 @@ public class ListToDataSetConverterTest {
} }
@Test
public void testAllowChangeStructure() {
// v1.0.0에서 Map의 null 컬럼 추가 되는 것을 확인한다.
List<Map<String, Object>> defaultMap = new ArrayList<Map<String, Object>>();
{
Map<String, Object> map = new HashMap<String, Object>();
map.put("col1", "value");
defaultMap.add(map);
}
{
Map<String, Object> map = new HashMap<String, Object>();
map.put("col2", "value");
defaultMap.add(map);
}
ConvertDefinition definition = new ConvertDefinition("ds");
definition.setDisallowChangeStructure(false); // set allow structure change
Object dsObj = null;
try {
dsObj = converter.convert(defaultMap, definition);
} catch (NexacroConvertException e) {
e.printStackTrace();
Assert.fail(e.getMessage());
}
DataSet ds = (DataSet) dsObj;
Assert.assertTrue(ds.containsColumn("col1"));
Assert.assertTrue(ds.containsColumn("col2"));
}
@Test
public void testDisallowChangeStructure() {
List<Map<String, Object>> defaultMap = new ArrayList<Map<String, Object>>();
{
Map<String, Object> map = new HashMap<String, Object>();
map.put("col1", "value");
defaultMap.add(map);
}
{
Map<String, Object> map = new HashMap<String, Object>();
map.put("col2", "value");
defaultMap.add(map);
}
ConvertDefinition definition = new ConvertDefinition("ds");
definition.setDisallowChangeStructure(true); // set disallow structure change
Object dsObj = null;
try {
dsObj = converter.convert(defaultMap, definition);
} catch (NexacroConvertException e) {
e.printStackTrace();
Assert.fail(e.getMessage());
}
DataSet ds = (DataSet) dsObj;
Assert.assertTrue(ds.containsColumn("col1"));
Assert.assertFalse(ds.containsColumn("col2"));
}
@Test
public void testAllowChangeStructureWithSchemaDataSet() {
DataSet schemaDataSet = new DataSet("schemaDa");
schemaDataSet.addColumn("defaultCol1", PlatformDataType.STRING);
List<Map<String, Object>> defaultMap = new ArrayList<Map<String, Object>>();
{
Map<String, Object> map = new HashMap<String, Object>();
map.put("col1", "value");
defaultMap.add(map);
}
{
Map<String, Object> map = new HashMap<String, Object>();
map.put("col2", "value");
defaultMap.add(map);
}
ConvertDefinition definition = new ConvertDefinition("ds");
definition.setDisallowChangeStructure(false); // set allow structure change
definition.setSchemaDataSet(schemaDataSet); // set schema dataSet
Object dsObj = null;
try {
dsObj = converter.convert(defaultMap, definition);
} catch (NexacroConvertException e) {
e.printStackTrace();
Assert.fail(e.getMessage());
}
DataSet ds = (DataSet) dsObj;
Assert.assertTrue(schemaDataSet.equals(ds));
Assert.assertTrue(ds.containsColumn("defaultCol1"));
Assert.assertTrue(ds.containsColumn("col1"));
Assert.assertTrue(ds.containsColumn("col2"));
}
@Test
public void testAllowChangeStructureWithSchemaDataSetWithBean() {
DataSet schemaDataSet = new DataSet("schemaDa");
schemaDataSet.addColumn("defaultCol1", PlatformDataType.STRING);
List<DefaultBean> defaultBean = NexacroTestUtil.createDefaultBeans();
ConvertDefinition definition = new ConvertDefinition("ds");
definition.setDisallowChangeStructure(false); // set allow structure change
definition.setSchemaDataSet(schemaDataSet); // set schema dataSet
Object dsObj = null;
try {
dsObj = converter.convert(defaultBean, definition);
} catch (NexacroConvertException e) {
e.printStackTrace();
Assert.fail(e.getMessage());
}
DataSet ds = (DataSet) dsObj;
Assert.assertTrue(schemaDataSet.equals(ds));
Assert.assertTrue(ds.containsColumn("defaultCol1"));
NexacroTestUtil.compareDefaultDataSet(ds, 1); // defaultColumn
}
@Test
public void testDisallowChangeStructureWithSchemaDataSet() {
DataSet schemaDataSet = new DataSet("schemaDa");
schemaDataSet.addColumn("defaultCol1", PlatformDataType.STRING);
List<Map<String, Object>> defaultMap = new ArrayList<Map<String, Object>>();
{
Map<String, Object> map = new HashMap<String, Object>();
map.put("col1", "value");
defaultMap.add(map);
}
{
Map<String, Object> map = new HashMap<String, Object>();
map.put("col2", "value");
defaultMap.add(map);
}
ConvertDefinition definition = new ConvertDefinition("ds");
definition.setDisallowChangeStructure(true); // set disallow structure change
definition.setSchemaDataSet(schemaDataSet); // set schema dataSet
Object dsObj = null;
try {
dsObj = converter.convert(defaultMap, definition);
} catch (NexacroConvertException e) {
e.printStackTrace();
Assert.fail(e.getMessage());
}
DataSet ds = (DataSet) dsObj;
Assert.assertTrue(schemaDataSet.equals(ds));
Assert.assertTrue(ds.containsColumn("defaultCol1"));
Assert.assertFalse(ds.containsColumn("col1"));
Assert.assertFalse(ds.containsColumn("col2"));
}
@Test
public void testDisallowChangeStructureWithSchemaDataSetWithBean() {
DataSet schemaDataSet = new DataSet("schemaDa");
schemaDataSet.addColumn("defaultCol1", PlatformDataType.STRING);
List<DefaultBean> defaultBean = NexacroTestUtil.createDefaultBeans();
ConvertDefinition definition = new ConvertDefinition("ds");
definition.setDisallowChangeStructure(true); // set disallow structure change
definition.setSchemaDataSet(schemaDataSet); // set schema dataSet
Object dsObj = null;
try {
dsObj = converter.convert(defaultBean, definition);
} catch (NexacroConvertException e) {
e.printStackTrace();
Assert.fail(e.getMessage());
}
DataSet ds = (DataSet) dsObj;
Assert.assertTrue(schemaDataSet.equals(ds));
Assert.assertTrue(ds.containsColumn("defaultCol1"));
Assert.assertEquals(ds.getColumnCount(), 1);
}
@Test @Test
public void testUpperCase() { public void testUpperCase() {

View File

@@ -206,13 +206,13 @@ public abstract class NexacroTestUtil {
public static void compareDefaultDataSet(DataSet ds) { public static void compareDefaultDataSet(DataSet ds, int addedColumns) {
if (ds == null) { if (ds == null) {
Assert.fail("compare DataSet is null"); Assert.fail("compare DataSet is null");
} }
int expectedSize = dsPropertyNames.length; int expectedSize = dsPropertyNames.length + addedColumns;
int actualSize = ds.getColumnCount(); int actualSize = ds.getColumnCount();
Assert.assertEquals("DataSet column does not matched. please check converted columns. expected=" + expectedSize Assert.assertEquals("DataSet column does not matched. please check converted columns. expected=" + expectedSize
+ ", actual=" + actualSize, expectedSize, actualSize); + ", actual=" + actualSize, expectedSize, actualSize);

View File

@@ -19,6 +19,7 @@ import com.nexacro.spring.data.support.bean.UpperCaseBean;
import com.nexacro.spring.util.ReflectionUtil; import com.nexacro.spring.util.ReflectionUtil;
import com.nexacro.xapi.data.ColumnHeader; import com.nexacro.xapi.data.ColumnHeader;
import com.nexacro.xapi.data.DataSet; import com.nexacro.xapi.data.DataSet;
import com.nexacro.xapi.data.datatype.PlatformDataType;
public class ObjectToDataSetConverterTest { public class ObjectToDataSetConverterTest {
@@ -113,6 +114,124 @@ public class ObjectToDataSetConverterTest {
Assert.assertEquals("ds", dataset.getName()); Assert.assertEquals("ds", dataset.getName());
} }
@Test
public void testAllowChangeStructureWithSchemaDataSet() {
DataSet schemaDataSet = new DataSet("schemaDa");
schemaDataSet.addColumn("defaultCol1", PlatformDataType.STRING);
Map<String, Object> map = new HashMap<String, Object>();
map.put("col1", "value");
ConvertDefinition definition = new ConvertDefinition("ds");
definition.setDisallowChangeStructure(false); // set allow structure change
definition.setSchemaDataSet(schemaDataSet); // set schema dataSet
Object dsObj = null;
try {
dsObj = converter.convert(map, definition);
} catch (NexacroConvertException e) {
e.printStackTrace();
Assert.fail(e.getMessage());
}
DataSet ds = (DataSet) dsObj;
Assert.assertTrue(schemaDataSet.equals(ds));
Assert.assertTrue(ds.containsColumn("defaultCol1"));
Assert.assertTrue(ds.containsColumn("col1"));
}
@Test
public void testAllowChangeStructureWithSchemaDataSetWithBean() {
DataSet schemaDataSet = new DataSet("schemaDa");
schemaDataSet.addColumn("defaultCol1", PlatformDataType.STRING);
DefaultBean defaultBean = new DefaultBean();
defaultBean.setLastName("Kim");
ConvertDefinition definition = new ConvertDefinition("ds");
definition.setDisallowChangeStructure(false); // set allow structure change
definition.setSchemaDataSet(schemaDataSet); // set schema dataSet
Object dsObj = null;
try {
dsObj = converter.convert(defaultBean, definition);
} catch (NexacroConvertException e) {
e.printStackTrace();
Assert.fail(e.getMessage());
}
DataSet ds = (DataSet) dsObj;
Assert.assertTrue(schemaDataSet.equals(ds));
Assert.assertTrue(ds.containsColumn("defaultCol1"));
Assert.assertEquals("Kim", ds.getObject(0, "lastName"));
}
@Test
public void testDisallowChangeStructureWithSchemaDataSet() {
DataSet schemaDataSet = new DataSet("schemaDa");
schemaDataSet.addColumn("defaultCol1", PlatformDataType.STRING);
Map<String, Object> map = new HashMap<String, Object>();
map.put("col1", "value");
ConvertDefinition definition = new ConvertDefinition("ds");
definition.setDisallowChangeStructure(true); // set disallow structure change
definition.setSchemaDataSet(schemaDataSet); // set schema dataSet
Object dsObj = null;
try {
dsObj = converter.convert(map, definition);
} catch (NexacroConvertException e) {
e.printStackTrace();
Assert.fail(e.getMessage());
}
DataSet ds = (DataSet) dsObj;
Assert.assertTrue(schemaDataSet.equals(ds));
Assert.assertTrue(ds.containsColumn("defaultCol1"));
Assert.assertFalse(ds.containsColumn("col1"));
Assert.assertFalse(ds.containsColumn("col2"));
}
@Test
public void testDisallowChangeStructureWithSchemaDataSetWithBean() {
DataSet schemaDataSet = new DataSet("schemaDa");
schemaDataSet.addColumn("defaultCol1", PlatformDataType.STRING);
DefaultBean defaultBean = new DefaultBean();
defaultBean.setLastName("Kim");
ConvertDefinition definition = new ConvertDefinition("ds");
definition.setDisallowChangeStructure(true); // set disallow structure change
definition.setSchemaDataSet(schemaDataSet); // set schema dataSet
Object dsObj = null;
try {
dsObj = converter.convert(defaultBean, definition);
} catch (NexacroConvertException e) {
e.printStackTrace();
Assert.fail(e.getMessage());
}
DataSet ds = (DataSet) dsObj;
Assert.assertTrue(schemaDataSet.equals(ds));
Assert.assertTrue(ds.containsColumn("defaultCol1"));
Assert.assertEquals(ds.getColumnCount(), 1);
}
@Test @Test
public void testUpperCase() { public void testUpperCase() {