share project nexacro-core
This commit is contained in:
29
.classpath
Normal file
29
.classpath
Normal file
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry including="**/*.java" kind="src" output="target/classes" path="src/main/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry including="**/*.java" kind="src" output="target/classes" path="src/main/resources"/>
|
||||
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry including="**/*.java" kind="src" output="target/test-classes" path="src/test/resources"/>
|
||||
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
<attribute name="org.eclipse.jst.component.nondependency" value=""/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
||||
41
.project
Normal file
41
.project
Normal file
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>nexacro-core</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.wst.common.project.facet.core.builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.springframework.ide.eclipse.core.springbuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.m2e.core.maven2Builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.wst.validation.validationbuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.springframework.ide.eclipse.core.springnature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.m2e.core.maven2Nature</nature>
|
||||
<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
|
||||
<nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
5
.settings/org.eclipse.core.resources.prefs
Normal file
5
.settings/org.eclipse.core.resources.prefs
Normal file
@@ -0,0 +1,5 @@
|
||||
eclipse.preferences.version=1
|
||||
encoding//src/main/java=UTF-8
|
||||
encoding//src/main/resources=UTF-8
|
||||
encoding//src/test/java=UTF-8
|
||||
encoding//src/test/resources=UTF-8
|
||||
12
.settings/org.eclipse.jdt.core.prefs
Normal file
12
.settings/org.eclipse.jdt.core.prefs
Normal file
@@ -0,0 +1,12 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=1.7
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
|
||||
org.eclipse.jdt.core.compiler.source=1.7
|
||||
6
.settings/org.eclipse.wst.common.component
Normal file
6
.settings/org.eclipse.wst.common.component
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
|
||||
<wb-module deploy-name="nexacro-core">
|
||||
<wb-resource deploy-path="/" source-path="/src/main/java"/>
|
||||
<wb-resource deploy-path="/" source-path="/src/main/resources"/>
|
||||
</wb-module>
|
||||
</project-modules>
|
||||
5
.settings/org.eclipse.wst.common.project.facet.core.xml
Normal file
5
.settings/org.eclipse.wst.common.project.facet.core.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<faceted-project>
|
||||
<installed facet="jst.utility" version="1.0"/>
|
||||
<installed facet="java" version="1.7"/>
|
||||
</faceted-project>
|
||||
2
.settings/org.eclipse.wst.validation.prefs
Normal file
2
.settings/org.eclipse.wst.validation.prefs
Normal file
@@ -0,0 +1,2 @@
|
||||
disabled=06target
|
||||
eclipse.preferences.version=1
|
||||
21
install/maven.txt
Normal file
21
install/maven.txt
Normal file
@@ -0,0 +1,21 @@
|
||||
# central에 존재하지 않는 library는 아래 3개이다.
|
||||
mvn install:install-file -Dfile=./lib/nexacro-xapi-1.0.jar -DgroupId=com.nexacro -DartifactId=nexacro-xapi -Dversion=1.0 -Dpackaging=jar
|
||||
mvn install:install-file -Dfile=./lib/nexacro-xeni-1.2.jar -DgroupId=com.nexacro -DartifactId=nexacro-xeni -Dversion=1.2 -Dpackaging=jar
|
||||
mvn install:install-file -Dfile=./lib/xstream-1.4.2.jar -DgroupId=xstream -DartifactId=xstream -Dversion=1.4.2 -Dpackaging=jar
|
||||
|
||||
mvn install:install-file -Dfile=./lib/commons-logging-1.1.jar -DgroupId=commons-logging -DartifactId=commons-logging -Dversion=1.1 -Dpackaging=jar
|
||||
mvn install:install-file -Dfile=./lib/commons-codec-1.5.jar -DgroupId=commons-codec -DartifactId=commons-codec -Dversion=1.5 -Dpackaging=jar
|
||||
mvn install:install-file -Dfile=./lib/commons-fileupload-1.3.1.jar -DgroupId=commons-fileupload -DartifactId=commons-fileupload -Dversion=1.3.1 -Dpackaging=jar
|
||||
mvn install:install-file -Dfile=./lib/commons-io-2.2.jar -DgroupId=commons-io -DartifactId=commons-io -Dversion=2.2 -Dpackaging=jar
|
||||
mvn install:install-file -Dfile=./lib/dom4j-1.6.1.jar -DgroupId=dom4j -DartifactId=dom4j -Dversion=1.6.1 -Dpackaging=jar
|
||||
mvn install:install-file -Dfile=./lib/log4j-1.2.13.jar -DgroupId=log4j -DartifactId=log4j -Dversion=1.2.13 -Dpackaging=jar
|
||||
mvn install:install-file -Dfile=./lib/poi-3.9-20121203.jar -DgroupId=org.apache.poi -DartifactId=poi -Dversion=3.9 -Dpackaging=jar
|
||||
mvn install:install-file -Dfile=./lib/poi-ooxml-3.9-20121203.jar -DgroupId=org.apache.poi -DartifactId=poi-ooxml -Dversion=3.9 -Dpackaging=jar
|
||||
mvn install:install-file -Dfile=./lib/poi-ooxml-schemas-3.9-20121203.jar -DgroupId=org.apache.poi -DartifactId=poi-ooxml-schemas -Dversion=3.9 -Dpackaging=jar
|
||||
mvn install:install-file -Dfile=./lib/poi-scratchpad-3.9-20121203.jar -DgroupId=org.apache.poi -DartifactId=poi-scratchpad -Dversion=3.9 -Dpackaging=jar
|
||||
mvn install:install-file -Dfile=./lib/stax-api-1.0.1.jar -DgroupId=stax -DartifactId=stax-api -Dversion=1.0.1 -Dpackaging=jar
|
||||
mvn install:install-file -Dfile=./lib/xmlbeans-2.3.0.jar -DgroupId=org.apache.xmlbeans -DartifactId=xmlbeans -Dversion=2.3.0 -Dpackaging=jar
|
||||
mvn install:install-file -Dfile=./lib/xmlpull-1.1.3.1.jar -DgroupId=xmlpull -DartifactId=xmlpull -Dversion=1.1.3.1 -Dpackaging=jar
|
||||
mvn install:install-file -Dfile=./lib/xpp3_min-1.1.4c.jar -DgroupId=xpp3 -DartifactId=xpp3_min -Dversion=1.1.4c -Dpackaging=jar
|
||||
|
||||
mvn install:install-file -Dfile=./lib/able-core-1.2.1.jar -DgroupId=able -DartifactId=able-core -Dversion=1.2.1 -Dpackaging=jar
|
||||
BIN
lib/commons-codec-1.5.jar
Normal file
BIN
lib/commons-codec-1.5.jar
Normal file
Binary file not shown.
BIN
lib/commons-fileupload-1.3.1.jar
Normal file
BIN
lib/commons-fileupload-1.3.1.jar
Normal file
Binary file not shown.
BIN
lib/commons-io-2.2.jar
Normal file
BIN
lib/commons-io-2.2.jar
Normal file
Binary file not shown.
BIN
lib/commons-logging-1.1.jar
Normal file
BIN
lib/commons-logging-1.1.jar
Normal file
Binary file not shown.
BIN
lib/dom4j-1.6.1.jar
Normal file
BIN
lib/dom4j-1.6.1.jar
Normal file
Binary file not shown.
BIN
lib/log4j-1.2.13.jar
Normal file
BIN
lib/log4j-1.2.13.jar
Normal file
Binary file not shown.
BIN
lib/mysql-connector-java-5.1.6.jar
Normal file
BIN
lib/mysql-connector-java-5.1.6.jar
Normal file
Binary file not shown.
BIN
lib/nexacro-xapi-1.0.jar
Normal file
BIN
lib/nexacro-xapi-1.0.jar
Normal file
Binary file not shown.
BIN
lib/nexacro-xeni-1.2.jar
Normal file
BIN
lib/nexacro-xeni-1.2.jar
Normal file
Binary file not shown.
BIN
lib/poi-3.9-20121203.jar
Normal file
BIN
lib/poi-3.9-20121203.jar
Normal file
Binary file not shown.
BIN
lib/poi-ooxml-3.9-20121203.jar
Normal file
BIN
lib/poi-ooxml-3.9-20121203.jar
Normal file
Binary file not shown.
BIN
lib/poi-ooxml-schemas-3.9-20121203.jar
Normal file
BIN
lib/poi-ooxml-schemas-3.9-20121203.jar
Normal file
Binary file not shown.
BIN
lib/poi-scratchpad-3.9-20121203.jar
Normal file
BIN
lib/poi-scratchpad-3.9-20121203.jar
Normal file
Binary file not shown.
BIN
lib/stax-api-1.0.1.jar
Normal file
BIN
lib/stax-api-1.0.1.jar
Normal file
Binary file not shown.
BIN
lib/xmlbeans-2.3.0.jar
Normal file
BIN
lib/xmlbeans-2.3.0.jar
Normal file
Binary file not shown.
BIN
lib/xmlpull-1.1.3.1.jar
Normal file
BIN
lib/xmlpull-1.1.3.1.jar
Normal file
Binary file not shown.
BIN
lib/xpp3_min-1.1.4c.jar
Normal file
BIN
lib/xpp3_min-1.1.4c.jar
Normal file
Binary file not shown.
BIN
lib/xstream-1.4.2.jar
Normal file
BIN
lib/xstream-1.4.2.jar
Normal file
Binary file not shown.
182
pom.xml
Normal file
182
pom.xml
Normal file
@@ -0,0 +1,182 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.nexacro.spring</groupId>
|
||||
<version>${project.parent.version}</version>
|
||||
<artifactId>nexacro-core</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>nexacro-core</name>
|
||||
<url>http://maven.apache.org</url>
|
||||
<organization>
|
||||
<name>nexacro-core Dev Group</name>
|
||||
</organization>
|
||||
<description>Description of nexacro-core</description>
|
||||
|
||||
<parent>
|
||||
<groupId>com.nexacro</groupId>
|
||||
<artifactId>nexacro-pom-parent</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</parent>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>2.12</version><!--$NO-MVN-MAN-VER$-->
|
||||
<configuration>
|
||||
<argLine>
|
||||
-Dsun.jnu.encoding=${encoding}
|
||||
-Dfile.encoding=${encoding}
|
||||
</argLine>
|
||||
<systemPropertyVariables>
|
||||
<sun.jnu.encoding>${encoding}</sun.jnu.encoding>
|
||||
<file.encoding>${encoding}</file.encoding>
|
||||
</systemPropertyVariables>
|
||||
<skipTests>false</skipTests>
|
||||
<reportFormat>xml</reportFormat>
|
||||
<forkMode>once</forkMode>
|
||||
<!-- "never" : Maven과 같은 process "once" (default) : 새로운
|
||||
하나의 jvm process에서 모든 Test 실행 "always" : 각 Test 마다 다른 JVM process 실행 "perthread" -->
|
||||
<!-- paralel mode setting -->
|
||||
<parallel>classes</parallel><!-- classes, methods -->
|
||||
<threadCount>10</threadCount>
|
||||
<!-- <excludes> <exclude>**/Abstract*.java</exclude>
|
||||
<exclude>**/*Suite.java</exclude> </excludes> <includes> <include>**/*Test.java</include>
|
||||
</includes> -->
|
||||
</configuration>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven.surefire</groupId>
|
||||
<artifactId>surefire-junit47</artifactId>
|
||||
<version>2.12</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.maven.ide.eclipse</groupId>
|
||||
<artifactId>lifecycle-mapping</artifactId>
|
||||
<version>0.9.9-SNAPSHOT</version>
|
||||
<configuration>
|
||||
<mappingId>generic</mappingId>
|
||||
<configurators></configurators>
|
||||
<mojoExecutions></mojoExecutions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.nexacro</groupId>
|
||||
<artifactId>nexacro-xapi</artifactId>
|
||||
<version>1.0</version>
|
||||
<scope>compile</scope>
|
||||
<systemPath></systemPath>
|
||||
</dependency>
|
||||
|
||||
<!-- spring config -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-beans</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-webmvc</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-aop</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<version>${spring.maven.artifact.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springmodules</groupId>
|
||||
<artifactId>spring-modules-jakarta-commons</artifactId>
|
||||
<version>0.8a</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-configuration</groupId>
|
||||
<artifactId>commons-configuration</artifactId>
|
||||
<version>1.6</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- Logging -->
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>${org.slf4j-version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jcl-over-slf4j</artifactId>
|
||||
<version>${org.slf4j-version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
<version>${org.slf4j-version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<version>1.2.15</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>javax.mail</groupId>
|
||||
<artifactId>mail</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>javax.jms</groupId>
|
||||
<artifactId>jms</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>com.sun.jdmk</groupId>
|
||||
<artifactId>jmxtools</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>com.sun.jmx</groupId>
|
||||
<artifactId>jmxri</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- junit -->
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.8.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<org.slf4j-version>1.7.5</org.slf4j-version>
|
||||
</properties>
|
||||
</project>
|
||||
3
src/main/java/META-INF/MANIFEST.MF
Normal file
3
src/main/java/META-INF/MANIFEST.MF
Normal file
@@ -0,0 +1,3 @@
|
||||
Manifest-Version: 1.0
|
||||
Class-Path:
|
||||
|
||||
51
src/main/java/com/nexacro/spring/NexacroConstants.java
Normal file
51
src/main/java/com/nexacro/spring/NexacroConstants.java
Normal file
@@ -0,0 +1,51 @@
|
||||
package com.nexacro.spring;
|
||||
|
||||
/**
|
||||
*
|
||||
* <pre>
|
||||
* Statements
|
||||
* </pre>
|
||||
*
|
||||
* @ClassName : NexacroConstants.java
|
||||
* @Description : 클래스 설명을 기술합니다.
|
||||
* @author Park SeongMin
|
||||
* @since 2015. 8. 5.
|
||||
* @version 1.0
|
||||
* @see
|
||||
* @Modification Information
|
||||
*
|
||||
* <pre>
|
||||
* since author description
|
||||
* =========== ============= ===========================
|
||||
* 2015. 8. 5. Park SeongMin 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
public final class NexacroConstants {
|
||||
|
||||
// attribute data
|
||||
public final class ATTRIBUTE {
|
||||
public static final String NEXACRO_REQUEST = "NexacroRequest";
|
||||
public static final String NEXACRO_CACHE_DATA = "NexacroCachedData";
|
||||
public static final String NEXACRO_PLATFORM_DATA = "NexacroPlatformData";
|
||||
public static final String NEXACRO_FILE_DATA = "NexacroFileData";
|
||||
}
|
||||
|
||||
// error
|
||||
public final class ERROR {
|
||||
|
||||
public final static int DEFAULT_ERROR_CODE = 0;
|
||||
public final static String ERROR_CODE = "ErrorCode"; // nexacro 결과 코드값 (ex '0' 이상 일경우 성공)
|
||||
public final static String ERROR_MSG = "ErrorMsg"; // nexacro 에러 메시지
|
||||
|
||||
}
|
||||
|
||||
// first row
|
||||
public final class ERROR_FIRST_ROW {
|
||||
public final static String ERROR_DATASET = "FirstRowStatus"; // exception after firstrow
|
||||
public final static String ERROR_CODE = ERROR.ERROR_CODE;
|
||||
public final static String ERROR_MSG = ERROR.ERROR_MSG;
|
||||
}
|
||||
|
||||
public static final String PERFORMANCE_LOGGER = "com.nexacro.performance";
|
||||
|
||||
}
|
||||
76
src/main/java/com/nexacro/spring/NexacroException.java
Normal file
76
src/main/java/com/nexacro/spring/NexacroException.java
Normal file
@@ -0,0 +1,76 @@
|
||||
package com.nexacro.spring;
|
||||
|
||||
/**
|
||||
*
|
||||
* <p>Nexacro 예외를 의미하는 <code>Exception</code>이다.
|
||||
*
|
||||
* @ClassName : NexacroException.java
|
||||
* @Description : 클래스 설명을 기술합니다.
|
||||
* @author Park SeongMin
|
||||
* @since 2015. 7. 30.
|
||||
* @version 1.0
|
||||
* @see
|
||||
* @Modification Information
|
||||
* <pre>
|
||||
* since author description
|
||||
* =========== ============= ===========================
|
||||
* 2015. 7. 30. Park SeongMin 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
public class NexacroException extends Exception {
|
||||
|
||||
/* serialVersionUID */
|
||||
private static final long serialVersionUID = 4095922735986385233L;
|
||||
|
||||
public static final int DEFAULT_ERROR_CODE = -1;
|
||||
public static final String DEFAULT_MESSAGE = "An Error Occured. check the ErrorCode for detail of error infomation.";
|
||||
|
||||
private int errorCode = DEFAULT_ERROR_CODE;
|
||||
private String errorMsg = DEFAULT_MESSAGE;
|
||||
|
||||
/**
|
||||
* 기본 생성자이다.
|
||||
*/
|
||||
public NexacroException() {
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* 메시지를 가지는 생성자이다.
|
||||
*
|
||||
* @param message
|
||||
* 메시지
|
||||
*/
|
||||
public NexacroException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 메시지와 원천(cause) 예외를 가지는 생성자이다.
|
||||
*
|
||||
* @param message
|
||||
* 메시지
|
||||
* @param cause
|
||||
* 원천 예외
|
||||
*/
|
||||
public NexacroException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public int getErrorCode() {
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
public void setErrorCode(int errorCode) {
|
||||
this.errorCode = errorCode;
|
||||
}
|
||||
|
||||
public String getErrorMsg() {
|
||||
return errorMsg;
|
||||
}
|
||||
|
||||
public void setErrorMsg(String errorMsg) {
|
||||
this.errorMsg = errorMsg;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.nexacro.spring.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target({ java.lang.annotation.ElementType.PARAMETER })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface ParamDataSet {
|
||||
public abstract String name();
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.nexacro.spring.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target({ java.lang.annotation.ElementType.PARAMETER })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface ParamVariable {
|
||||
public abstract String name();
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.nexacro.spring.data;
|
||||
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Statements
|
||||
* </pre>
|
||||
*
|
||||
* @ClassName : DataSetRowTypeAccessor.java
|
||||
* @Description : 클래스 설명을 기술합니다.
|
||||
* @author Park SeongMin
|
||||
* @since 2015. 7. 31.
|
||||
* @version 1.0
|
||||
* @see
|
||||
* @Modification Information
|
||||
* <pre>
|
||||
* since author description
|
||||
* =========== ============= ===========================
|
||||
* 2015. 7. 31. Park SeongMin 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public interface DataSetRowTypeAccessor {
|
||||
|
||||
static final String NAME = "DataSetRowType";
|
||||
|
||||
int getRowType();
|
||||
|
||||
void setRowType(int rowType);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.nexacro.spring.data;
|
||||
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Statements
|
||||
* </pre>
|
||||
*
|
||||
* @ClassName : DataSetSavedDataAccessor.java
|
||||
* @Description : 클래스 설명을 기술합니다.
|
||||
* @author Park SeongMin
|
||||
* @since 2015. 7. 31.
|
||||
* @version 1.0
|
||||
* @see
|
||||
* @Modification Information
|
||||
* <pre>
|
||||
* since author description
|
||||
* =========== ============= ===========================
|
||||
* 2015. 7. 31. Park SeongMin 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public interface DataSetSavedDataAccessor<T> {
|
||||
|
||||
static final String NAME = "DataSetSavedData";
|
||||
|
||||
T getData();
|
||||
|
||||
void setData(T t);
|
||||
}
|
||||
102
src/main/java/com/nexacro/spring/data/NexacroFileResult.java
Normal file
102
src/main/java/com/nexacro/spring/data/NexacroFileResult.java
Normal file
@@ -0,0 +1,102 @@
|
||||
package com.nexacro.spring.data;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import com.nexacro.spring.resolve.NexacroHandlerMethodReturnValueHandler;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* nexacro platform으로 File 데이터를 전송하기 위한 정보를 가진다.
|
||||
* </pre>
|
||||
*
|
||||
* @ClassName : NexacroFileResult.java
|
||||
* @Description : 클래스 설명을 기술합니다.
|
||||
* @author Park SeongMin
|
||||
* @since 2015. 8. 18.
|
||||
* @version 1.0
|
||||
* @see NexacroHandlerMethodReturnValueHandler
|
||||
* @Modification Information
|
||||
*
|
||||
* <pre>
|
||||
* since author description
|
||||
* =========== ============= ===========================
|
||||
* 2015. 8. 18. Park SeongMin 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public class NexacroFileResult {
|
||||
|
||||
private File file;
|
||||
|
||||
private String contentType;
|
||||
private String charset;
|
||||
private String originalName;
|
||||
|
||||
public NexacroFileResult(File file) {
|
||||
if(file == null) {
|
||||
throw new IllegalArgumentException("file must not be null.");
|
||||
}
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the file
|
||||
*/
|
||||
public File getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param file
|
||||
* the file to set
|
||||
*/
|
||||
public void setFile(File file) {
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the contentType
|
||||
*/
|
||||
public String getContentType() {
|
||||
return contentType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param contentType
|
||||
* the contentType to set
|
||||
*/
|
||||
public void setContentType(String contentType) {
|
||||
this.contentType = contentType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the charset
|
||||
*/
|
||||
public String getCharset() {
|
||||
return charset;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param charset
|
||||
* the charset to set
|
||||
*/
|
||||
public void setCharset(String charset) {
|
||||
this.charset = charset;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the originalName
|
||||
*/
|
||||
public String getOriginalName() {
|
||||
return originalName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param originalName
|
||||
* the originalName to set
|
||||
*/
|
||||
public void setOriginalName(String originalName) {
|
||||
this.originalName = originalName;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.nexacro.spring.data;
|
||||
|
||||
import com.nexacro.xapi.tx.HttpPartPlatformResponse;
|
||||
import com.nexacro.xapi.tx.PlatformException;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Statements
|
||||
* </pre>
|
||||
*
|
||||
* @ClassName : NexacroFirstRowAccessor.java
|
||||
* @Description : 클래스 설명을 기술합니다.
|
||||
* @author Park SeongMin
|
||||
* @since 2015. 8. 5.
|
||||
* @version 1.0
|
||||
* @see
|
||||
* @Modification Information
|
||||
* <pre>
|
||||
* since author description
|
||||
* =========== ============= ===========================
|
||||
* 2015. 8. 5. Park SeongMin 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public abstract class NexacroFirstRowAccessor {
|
||||
|
||||
public static HttpPartPlatformResponse getHttpPartPlatformResponse(NexacroFirstRowHandler handler) {
|
||||
return handler.getHttpPartPlatformResponse();
|
||||
}
|
||||
|
||||
public static void end(NexacroFirstRowHandler handler) throws PlatformException {
|
||||
handler.end();
|
||||
}
|
||||
|
||||
public static String[] getSendOutVariableNames(NexacroFirstRowHandler handler) {
|
||||
return handler.getSendOutVariableNames();
|
||||
}
|
||||
|
||||
public static int getSendOutVariableCount(NexacroFirstRowHandler handler) {
|
||||
return handler.getSendOutVariableCount();
|
||||
}
|
||||
|
||||
public static String[] getSendOutDataSetNames(NexacroFirstRowHandler handler) {
|
||||
return handler.getSendOutDataSetNames();
|
||||
}
|
||||
|
||||
public static int getSendOutDataSetCount(NexacroFirstRowHandler handler) {
|
||||
return handler.getSendOutDataSetCount();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,238 @@
|
||||
package com.nexacro.spring.data;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import com.nexacro.xapi.data.DataSet;
|
||||
import com.nexacro.xapi.data.DataSetList;
|
||||
import com.nexacro.xapi.data.PlatformData;
|
||||
import com.nexacro.xapi.data.Variable;
|
||||
import com.nexacro.xapi.data.VariableList;
|
||||
import com.nexacro.xapi.tx.HttpPartPlatformResponse;
|
||||
import com.nexacro.xapi.tx.PlatformException;
|
||||
import com.nexacro.xapi.tx.PlatformRequest;
|
||||
import com.nexacro.xapi.tx.PlatformType;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Nexacro Platform에서 지원하는 FirstRow를 처리 한다.
|
||||
* 데이터의 전송은 <Code>Variable</Code> 부터 <Code>DataSet</Code> 순으로 전송 된다.
|
||||
* </pre>
|
||||
*
|
||||
* @ClassName : NexacroFirstRowHandler.java
|
||||
* @author Park SeongMin
|
||||
* @since 2015. 8. 5.
|
||||
* @version 1.0
|
||||
* @see
|
||||
* @Modification Information
|
||||
*
|
||||
* <pre>
|
||||
* since author description
|
||||
* =========== ============= ===========================
|
||||
* 2015. 8. 5. Park SeongMin 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public class NexacroFirstRowHandler {
|
||||
|
||||
private PlatformRequest platformRequest;
|
||||
private HttpServletResponse httpResponse;
|
||||
private HttpPartPlatformResponse partPlatformResponse = null;
|
||||
private PrintWriter writer = null;
|
||||
|
||||
private String contentType;
|
||||
|
||||
private DataSet data = null;
|
||||
private boolean isFirstRowFired = false;
|
||||
private boolean dataSetSended = false;
|
||||
private boolean isInit = false;
|
||||
private boolean isEncrypted = false;
|
||||
private Set sendOutVariableNameSet = new HashSet();
|
||||
private Set sendOutDataSetNameSet = new HashSet();
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*
|
||||
* @param httpServletResponse
|
||||
*/
|
||||
public NexacroFirstRowHandler(HttpServletResponse httpServletResponse) {
|
||||
this(httpServletResponse, null);
|
||||
}
|
||||
|
||||
public NexacroFirstRowHandler(HttpServletResponse httpServletResponse, PlatformRequest platformRequest) {
|
||||
if(httpServletResponse == null) {
|
||||
throw new IllegalArgumentException("HttpServletResponse should not be null.");
|
||||
}
|
||||
this.httpResponse = httpServletResponse;
|
||||
this.platformRequest = platformRequest;
|
||||
}
|
||||
|
||||
public String getContentType() {
|
||||
return contentType;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* set send ContentType
|
||||
* <p>must be set before the transfer.
|
||||
*
|
||||
* @param contentType
|
||||
* @see PlatformType#CONTENT_TYPE_XML
|
||||
* @see PlatformType#CONTENT_TYPE_BINARY
|
||||
* @see PlatformType#CONTENT_TYPE_SSV
|
||||
*/
|
||||
public void setContentType(String contentType) {
|
||||
this.contentType = contentType;
|
||||
}
|
||||
|
||||
public void sendPlatformData(PlatformData platformData) throws PlatformException {
|
||||
isFirstRowFired = true;
|
||||
|
||||
VariableList variableList = platformData.getVariableList();
|
||||
DataSetList dataSetList = platformData.getDataSetList();
|
||||
|
||||
for (int variableListIndex = 0; variableListIndex < variableList.size(); variableListIndex++) {
|
||||
sendVariable(variableList.get(variableListIndex));
|
||||
}
|
||||
|
||||
for (int datasetListIndex = 0; datasetListIndex < dataSetList.size(); datasetListIndex++) {
|
||||
sendDataSet(dataSetList.get(datasetListIndex));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void sendVariable(Variable variable) throws PlatformException {
|
||||
isFirstRowFired = true;
|
||||
intPartPlatformResponse();
|
||||
if (dataSetSended) {
|
||||
throw new PlatformException("DataSet aleady sended. can't send a variable after sending dataSet.");
|
||||
}
|
||||
|
||||
partPlatformResponse.sendVariable(variable);
|
||||
sendOutVariableNameSet.add(variable.getName());
|
||||
|
||||
}
|
||||
|
||||
public void sendDataSet(DataSet dataSet) throws PlatformException {
|
||||
if (dataSet == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
isFirstRowFired = true;
|
||||
dataSetSended = true;
|
||||
intPartPlatformResponse();
|
||||
|
||||
// 기존에 firstRow 로 전송 된 DataSet 잉여 data 전송.
|
||||
// if(data == ds) {
|
||||
if (data != null && !data.getName().equals(dataSet.getName())) {
|
||||
partPlatformResponse.sendDataSet(data);
|
||||
}
|
||||
|
||||
partPlatformResponse.sendDataSet(dataSet);
|
||||
|
||||
data = dataSet;
|
||||
sendOutDataSetNameSet.add(dataSet.getName());
|
||||
}
|
||||
|
||||
public boolean isFirstRowStarted() {
|
||||
return isFirstRowFired;
|
||||
}
|
||||
|
||||
private void intPartPlatformResponse() {
|
||||
if (!isInit) {
|
||||
if(platformRequest == null) {
|
||||
partPlatformResponse = new HttpPartPlatformResponse(httpResponse);
|
||||
} else {
|
||||
partPlatformResponse = new HttpPartPlatformResponse(httpResponse, platformRequest);
|
||||
}
|
||||
if(contentType != null) {
|
||||
partPlatformResponse.setContentType(contentType);
|
||||
}
|
||||
//setWriter();
|
||||
isInit = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* check current first row status
|
||||
* <p><Code>PlatformType.CONTENT_TYPE_SSV</Code> or <Code>CONTENT_TYPE_BIN</Code> may not operate normally.
|
||||
*
|
||||
* @return errorStatus
|
||||
*/
|
||||
public boolean checkError() {
|
||||
setWriter();
|
||||
if (writer != null) {
|
||||
return writer.checkError();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void setWriter() {
|
||||
// writer or outputstream choice
|
||||
if (this.httpResponse != null && this.writer != null) {
|
||||
try {
|
||||
this.writer = this.httpResponse.getWriter();
|
||||
} catch(UnsupportedEncodingException e) {
|
||||
} catch(IllegalStateException e) {
|
||||
} catch (IOException e) {
|
||||
// log.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int getSendOutVariableCount() {
|
||||
return sendOutVariableNameSet.size();
|
||||
}
|
||||
|
||||
String[] getSendOutVariableNames() {
|
||||
|
||||
List sendOutVariableNameList = new ArrayList();
|
||||
Iterator iterator = sendOutVariableNameSet.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
sendOutVariableNameList.add(iterator.next());
|
||||
}
|
||||
|
||||
String[] sendOutVariableNames = new String[sendOutVariableNameList.size()];
|
||||
return (String[]) sendOutVariableNameList.toArray(sendOutVariableNames);
|
||||
}
|
||||
|
||||
int getSendOutDataSetCount() {
|
||||
return sendOutDataSetNameSet.size();
|
||||
}
|
||||
|
||||
String[] getSendOutDataSetNames() {
|
||||
|
||||
List sendOutDataSetNameList = new ArrayList();
|
||||
Iterator iterator = sendOutDataSetNameSet.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
sendOutDataSetNameList.add(iterator.next());
|
||||
}
|
||||
|
||||
String[] sendOutDataSetNames = new String[sendOutDataSetNameList.size()];
|
||||
return (String[]) sendOutDataSetNameList.toArray(sendOutDataSetNames);
|
||||
}
|
||||
|
||||
HttpPartPlatformResponse getHttpPartPlatformResponse() {
|
||||
return partPlatformResponse;
|
||||
}
|
||||
|
||||
void end() throws PlatformException {
|
||||
if (isInit) {
|
||||
isInit = false;
|
||||
partPlatformResponse.end();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
159
src/main/java/com/nexacro/spring/data/NexacroResult.java
Normal file
159
src/main/java/com/nexacro/spring/data/NexacroResult.java
Normal file
@@ -0,0 +1,159 @@
|
||||
package com.nexacro.spring.data;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.nexacro.spring.resolve.NexacroHandlerMethodReturnValueHandler;
|
||||
import com.nexacro.xapi.data.DataSet;
|
||||
import com.nexacro.xapi.data.PlatformData;
|
||||
import com.nexacro.xapi.data.Variable;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* nexacro platform으로 데이터를 송신하기 위한 정보를 가진다.
|
||||
* 데이터 삽입 시 변환은 이루어지지 않으며, NexacroHandlerMethodReturnValueHandler에서 데이터 변환이 이루어진다.
|
||||
* </pre>
|
||||
*
|
||||
* @ClassName : NexacroResult.java
|
||||
* @Description : 클래스 설명을 기술합니다.
|
||||
* @author Park SeongMin
|
||||
* @since 2015. 7. 27.
|
||||
* @version 1.0
|
||||
* @see NexacroHandlerMethodReturnValueHandler
|
||||
* @Modification Information
|
||||
* <pre>
|
||||
* since author description
|
||||
* =========== ============= ===========================
|
||||
* 2015. 7. 27. Park SeongMin 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
public class NexacroResult {
|
||||
|
||||
private PlatformData platformData;
|
||||
|
||||
private Map<String, List> dataSetMaps;
|
||||
private Map<String, Object> variableMaps;
|
||||
|
||||
// result status
|
||||
private int errorCode;
|
||||
private String errorMsg;
|
||||
|
||||
private boolean registedError = false;
|
||||
|
||||
public NexacroResult() {
|
||||
initResult();
|
||||
}
|
||||
|
||||
private void initResult() {
|
||||
dataSetMaps = new HashMap<String, List>();
|
||||
variableMaps = new HashMap<String, Object>();
|
||||
platformData = new PlatformData();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* <code>DataSet<code>을 추가한다.
|
||||
*
|
||||
* @param dataSet
|
||||
*/
|
||||
public void addDataSet(DataSet dataSet) {
|
||||
platformData.addDataSet(dataSet);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* 입력받은 dataSetName(DataSet 이름)으로 List를 <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) {
|
||||
checkName(dataSetName);
|
||||
checkBean(beans);
|
||||
|
||||
dataSetMaps.put(dataSetName, beans);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* <code>Variable</code>을 추가한다.
|
||||
*
|
||||
* @param variable
|
||||
*/
|
||||
public void addVariable(Variable variable) {
|
||||
platformData.addVariable(variable);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* 입력받은 variableName(Variable 이름)으로 Object를 <code>Variable</code>으로 추가한다.
|
||||
*
|
||||
* @param variableName
|
||||
* @param object
|
||||
*/
|
||||
public void addVariable(String variableName, Object object) {
|
||||
checkName(variableName);
|
||||
|
||||
variableMaps.put(variableName, object);
|
||||
}
|
||||
|
||||
public Map<String, List> getDataSets() {
|
||||
return Collections.unmodifiableMap(dataSetMaps);
|
||||
}
|
||||
|
||||
public Map<String, Object> getVariables() {
|
||||
return Collections.unmodifiableMap(variableMaps);
|
||||
}
|
||||
|
||||
private void checkName(String dataName) {
|
||||
if(dataName == null) {
|
||||
throw new IllegalArgumentException("No name specified");
|
||||
}
|
||||
}
|
||||
|
||||
private void checkBean(List bean) {
|
||||
}
|
||||
|
||||
public PlatformData getPlatformData() {
|
||||
return platformData;
|
||||
}
|
||||
|
||||
public void setPlatformData(PlatformData platformData) {
|
||||
this.platformData = platformData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the errorCode
|
||||
*/
|
||||
public int getErrorCode() {
|
||||
return errorCode;
|
||||
}
|
||||
/**
|
||||
* @param errorCode the errorCode to set
|
||||
*/
|
||||
public void setErrorCode(int errorCode) {
|
||||
this.registedError = true;
|
||||
this.errorCode = errorCode;
|
||||
}
|
||||
|
||||
public boolean registedErrorCode() {
|
||||
return this.registedError;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the errorMsg
|
||||
*/
|
||||
public String getErrorMsg() {
|
||||
return errorMsg;
|
||||
}
|
||||
/**
|
||||
* @param errorMsg the errorMsg to set
|
||||
*/
|
||||
public void setErrorMsg(String errorMsg) {
|
||||
this.errorMsg = errorMsg;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package com.nexacro.spring.data.convert;
|
||||
|
||||
import com.nexacro.xapi.data.DataSet;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Statements
|
||||
* </pre>
|
||||
*
|
||||
* @ClassName : ConvertDataSetEvent.java
|
||||
* @Description : 클래스 설명을 기술합니다.
|
||||
* @author Park SeongMin
|
||||
* @since 2015. 8. 9.
|
||||
* @version 1.0
|
||||
* @see
|
||||
* @Modification Information
|
||||
* <pre>
|
||||
* since author description
|
||||
* =========== ============= ===========================
|
||||
* 2015. 8. 9. Park SeongMin 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public class ConvertDataSetEvent extends ConvertEvent {
|
||||
|
||||
/* serialVersionUID */
|
||||
private static final long serialVersionUID = -174881582977983877L;
|
||||
|
||||
private int rowIndex;
|
||||
|
||||
private int columnIndex;
|
||||
|
||||
private boolean isSavedData;
|
||||
private boolean isRemovedData;
|
||||
|
||||
public ConvertDataSetEvent(DataSet source, Object targetValue, int rowIndex, int columnIndex) {
|
||||
this(source, targetValue, rowIndex, columnIndex, false, false);
|
||||
}
|
||||
|
||||
public ConvertDataSetEvent(DataSet source, Object targetValue, int rowIndex, int columnIndex, boolean isSavedData, boolean isRemovedData) {
|
||||
super(source, targetValue);
|
||||
this.rowIndex = rowIndex;
|
||||
this.columnIndex = columnIndex;
|
||||
this.isSavedData = isSavedData;
|
||||
this.isRemovedData = isRemovedData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the rowIndex
|
||||
*/
|
||||
public int getRowIndex() {
|
||||
return rowIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the columnIndex
|
||||
*/
|
||||
public int getColumnIndex() {
|
||||
return columnIndex;
|
||||
}
|
||||
|
||||
public String getColumnName() {
|
||||
DataSet ds = (DataSet) getSource();
|
||||
return ds.getColumn(columnIndex).getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the isSavedData
|
||||
*/
|
||||
public boolean isSavedData() {
|
||||
return isSavedData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the isRemovedData
|
||||
*/
|
||||
public boolean isRemovedData() {
|
||||
return isRemovedData;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package com.nexacro.spring.data.convert;
|
||||
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Statements
|
||||
* </pre>
|
||||
*
|
||||
* @ClassName : NexacroConvertDefinition.java
|
||||
* @Description : 클래스 설명을 기술합니다.
|
||||
* @author Park SeongMin
|
||||
* @since 2015. 7. 28.
|
||||
* @version 1.0
|
||||
* @see
|
||||
* @Modification Information
|
||||
*
|
||||
* <pre>
|
||||
* since author description
|
||||
* =========== ============= ===========================
|
||||
* 2015. 7. 28. Park SeongMin 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public class ConvertDefinition {
|
||||
|
||||
private String name;
|
||||
private Class genericType; // for generic
|
||||
private boolean isIgnoreException = false;
|
||||
|
||||
public ConvertDefinition(String name) {
|
||||
setName(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the name
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name
|
||||
* the name to set
|
||||
*/
|
||||
public void setName(String name) {
|
||||
if(name == null || name.length() == 0) {
|
||||
throw new IllegalArgumentException("converted name must be not null");
|
||||
}
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the isIgnoreException
|
||||
*/
|
||||
public boolean isIgnoreException() {
|
||||
return isIgnoreException;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param isIgnoreException
|
||||
* the isIgnoreException to set
|
||||
*/
|
||||
public void setIgnoreException(boolean isIgnoreException) {
|
||||
this.isIgnoreException = isIgnoreException;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the genericType
|
||||
*/
|
||||
public Class getGenericType() {
|
||||
return genericType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param genericType the genericType to set
|
||||
*/
|
||||
public void setGenericType(Class genericType) {
|
||||
this.genericType = genericType;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package com.nexacro.spring.data.convert;
|
||||
|
||||
import java.util.EventObject;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Statements
|
||||
* </pre>
|
||||
*
|
||||
* @ClassName : ConvertEvent.java
|
||||
* @Description : 클래스 설명을 기술합니다.
|
||||
* @author Park SeongMin
|
||||
* @since 2015. 8. 9.
|
||||
* @version 1.0
|
||||
* @see
|
||||
* @Modification Information
|
||||
* <pre>
|
||||
* since author description
|
||||
* =========== ============= ===========================
|
||||
* 2015. 8. 9. Park SeongMin 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public class ConvertEvent extends EventObject {
|
||||
|
||||
/* serialVersionUID */
|
||||
private static final long serialVersionUID = -8987092428557969722L;
|
||||
|
||||
/* converted value */
|
||||
private Object value;
|
||||
|
||||
/**
|
||||
* Statements
|
||||
*
|
||||
* @param source
|
||||
*/
|
||||
public ConvertEvent(Object source, Object value) {
|
||||
super(source);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the convertedValue
|
||||
*/
|
||||
public Object getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param value the value to set
|
||||
*/
|
||||
public void setValue(Object value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.nexacro.spring.data.convert;
|
||||
|
||||
import com.nexacro.xapi.data.Variable;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Statements
|
||||
* </pre>
|
||||
*
|
||||
* @ClassName : ConvertVariableEvent.java
|
||||
* @Description : 클래스 설명을 기술합니다.
|
||||
* @author Park SeongMin
|
||||
* @since 2015. 8. 9.
|
||||
* @version 1.0
|
||||
* @see
|
||||
* @Modification Information
|
||||
* <pre>
|
||||
* since author description
|
||||
* =========== ============= ===========================
|
||||
* 2015. 8. 9. Park SeongMin 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public class ConvertVariableEvent extends ConvertEvent {
|
||||
|
||||
/* serialVersionUID */
|
||||
private static final long serialVersionUID = 7527494468054562758L;
|
||||
|
||||
/**
|
||||
* Statements
|
||||
*
|
||||
* @param source
|
||||
*/
|
||||
public ConvertVariableEvent(Variable source, Object targetValue) {
|
||||
super(source, targetValue);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.nexacro.spring.data.convert;
|
||||
|
||||
import com.nexacro.spring.NexacroException;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Statements
|
||||
* </pre>
|
||||
*
|
||||
* @ClassName : NexacroConvertException.java
|
||||
* @Description : 클래스 설명을 기술합니다.
|
||||
* @author Park SeongMin
|
||||
* @since 2015. 7. 28.
|
||||
* @version 1.0
|
||||
* @see
|
||||
* @Modification Information
|
||||
* <pre>
|
||||
* since author description
|
||||
* =========== ============= ===========================
|
||||
* 2015. 7. 28. Park SeongMin 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public class NexacroConvertException extends NexacroException {
|
||||
|
||||
/* serialVersionUID */
|
||||
private static final long serialVersionUID = 2572392591528637297L;
|
||||
|
||||
/**
|
||||
* 기본 생성자이다.
|
||||
*/
|
||||
public NexacroConvertException() {
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* 메시지를 가지는 생성자이다.
|
||||
*
|
||||
* @param message
|
||||
* 메시지
|
||||
*/
|
||||
public NexacroConvertException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 메시지와 원천(cause) 예외를 가지는 생성자이다.
|
||||
*
|
||||
* @param message
|
||||
* 메시지
|
||||
* @param cause
|
||||
* 원천 예외
|
||||
*/
|
||||
public NexacroConvertException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.nexacro.spring.data.convert;
|
||||
|
||||
import java.util.EventListener;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Statements
|
||||
* </pre>
|
||||
*
|
||||
* @ClassName : NexacroConverterListener.java
|
||||
* @Description : 클래스 설명을 기술합니다.
|
||||
* @author Park SeongMin
|
||||
* @since 2015. 8. 9.
|
||||
* @version 1.0
|
||||
* @see
|
||||
* @Modification Information
|
||||
* <pre>
|
||||
* since author description
|
||||
* =========== ============= ===========================
|
||||
* 2015. 8. 9. Park SeongMin 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public interface NexacroConvertListener extends EventListener {
|
||||
|
||||
void convertedValue(ConvertEvent event);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
package com.nexacro.spring.data.convert;
|
||||
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Statements
|
||||
* </pre>
|
||||
*
|
||||
* @ClassName : NexacroConverter.java
|
||||
* @Description : 클래스 설명을 기술합니다.
|
||||
* @author Park SeongMin
|
||||
* @since 2015. 7. 28.
|
||||
* @version 1.0
|
||||
* @see
|
||||
* @Modification Information
|
||||
*
|
||||
* <pre>
|
||||
* since author description
|
||||
* =========== ============= ===========================
|
||||
* 2015. 7. 28. Park SeongMin 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public interface NexacroConverter<S, T> {
|
||||
|
||||
/**
|
||||
*
|
||||
* Convert the source of type S to target type T.
|
||||
*
|
||||
* @param Source
|
||||
* @return
|
||||
* @throws NexacroConvertException
|
||||
*/
|
||||
T convert(S source, ConvertDefinition definition) throws NexacroConvertException;
|
||||
|
||||
boolean canConvert(Class source, Class target);
|
||||
|
||||
void addListener(NexacroConvertListener listener);
|
||||
|
||||
void removeListener(NexacroConvertListener listener);
|
||||
|
||||
public static final class ConvertiblePair {
|
||||
|
||||
private final Class<?> sourceType;
|
||||
private final Class<?> targetType;
|
||||
|
||||
public ConvertiblePair(Class<?> sourceType, Class<?> targetType) {
|
||||
this.sourceType = sourceType;
|
||||
this.targetType = targetType;
|
||||
}
|
||||
|
||||
public Class<?> getSourceType() {
|
||||
return this.sourceType;
|
||||
}
|
||||
|
||||
public Class<?> getTargetType() {
|
||||
return this.targetType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null || obj.getClass() != ConvertiblePair.class) {
|
||||
return false;
|
||||
}
|
||||
ConvertiblePair other = (ConvertiblePair) obj;
|
||||
// return this.sourceType.equals(other.sourceType) && this.targetType.equals(other.targetType);
|
||||
// support sub class
|
||||
return this.sourceType.equals(other.sourceType) && this.targetType.equals(other.targetType);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.sourceType.hashCode() * 31 + this.targetType.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.sourceType.getName() + "->" + this.targetType.getName();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
package com.nexacro.spring.data.convert;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
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.ListToDataSetConverter;
|
||||
import com.nexacro.spring.data.support.ObjectToVariableConverter;
|
||||
import com.nexacro.spring.data.support.VariableToObjectConverter;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Statements
|
||||
* </pre>
|
||||
*
|
||||
* @ClassName : NexacroConverterFactory.java
|
||||
* @Description : 클래스 설명을 기술합니다.
|
||||
* @author Park SeongMin
|
||||
* @since 2015. 7. 28.
|
||||
* @version 1.0
|
||||
* @see
|
||||
* @Modification Information
|
||||
*
|
||||
* <pre>
|
||||
* since author description
|
||||
* =========== ============= ===========================
|
||||
* 2015. 7. 28. Park SeongMin 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public class NexacroConverterFactory {
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(NexacroConverterFactory.class);
|
||||
|
||||
private static Set<NexacroConverter> converterSets = new HashSet<NexacroConverter>();
|
||||
|
||||
private static Map<ConvertiblePair, NexacroConverter> convertibleCacheMap = new HashMap<ConvertiblePair, NexacroConverter>();
|
||||
|
||||
private static final NexacroConverterFactory INSTANCE = new NexacroConverterFactory();
|
||||
|
||||
private NexacroConverterFactory() {
|
||||
addDefaultConverter();
|
||||
}
|
||||
|
||||
private void addDefaultConverter() {
|
||||
NexacroConverterFactory.register(new DataSetToListConverter());
|
||||
NexacroConverterFactory.register(new ListToDataSetConverter());
|
||||
NexacroConverterFactory.register(new VariableToObjectConverter());
|
||||
NexacroConverterFactory.register(new ObjectToVariableConverter());
|
||||
}
|
||||
|
||||
public static NexacroConverterFactory getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
public static NexacroConverter getConverter(Class source, Class target) {
|
||||
|
||||
if(source == null || target == null) {
|
||||
throw new IllegalArgumentException("source and target class must not be null.");
|
||||
}
|
||||
|
||||
NexacroConverter converter = findConvertibleCache(source, target);
|
||||
|
||||
if(converter == null) {
|
||||
converter = findSupportedConverter(source, target);
|
||||
}
|
||||
|
||||
if(converter == null) {
|
||||
// new NullConverter(source, target);
|
||||
return null;
|
||||
}
|
||||
|
||||
return converter;
|
||||
}
|
||||
|
||||
private static NexacroConverter findConvertibleCache(Class source, Class target) {
|
||||
ConvertiblePair convertiblePair = new ConvertiblePair(source, target);
|
||||
NexacroConverter converter = convertibleCacheMap.get(convertiblePair);
|
||||
return converter;
|
||||
}
|
||||
|
||||
private static NexacroConverter findSupportedConverter(Class source, Class target) {
|
||||
|
||||
for(NexacroConverter converter: converterSets) {
|
||||
boolean canConvertible = converter.canConvert(source, target);
|
||||
if(canConvertible) {
|
||||
ConvertiblePair pair = new ConvertiblePair(source, target);
|
||||
convertibleCacheMap.put(pair, converter);
|
||||
return converter;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static synchronized void register(Set<NexacroConverter> converters) {
|
||||
if(converters == null) {
|
||||
return;
|
||||
}
|
||||
for(NexacroConverter converter: converters) {
|
||||
register(converter);
|
||||
}
|
||||
}
|
||||
|
||||
public static synchronized void register(NexacroConverter converter) {
|
||||
if(converter == null) {
|
||||
throw new IllegalArgumentException(NexacroConverter.class.getName()+" must not be null.");
|
||||
}
|
||||
|
||||
if(converterSets.contains(converter)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(logger.isDebugEnabled()) {
|
||||
logger.debug(converter.getClass() + " registered.");
|
||||
}
|
||||
converterSets.add(converter);
|
||||
|
||||
// Set<ConvertiblePair> defaultConvertibleTypes = converter.getDefaultConvertibleTypes();
|
||||
// for(ConvertiblePair pair: defaultConvertibleTypes) {
|
||||
// if(convertibleCacheMap.containsKey(pair)) {
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// convertibleCacheMap.put(pair, converter);
|
||||
// if(logger.isDebugEnabled()) {
|
||||
// logger.debug(pair + " registered.");
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
private static String getConvertibleKey(Object source, Object target) {
|
||||
return getConvertibleKey(source.getClass(), target.getClass());
|
||||
}
|
||||
|
||||
private static String getConvertibleKey(Class source, Class target) {
|
||||
return source.getName() + "->" + target.getName();
|
||||
}
|
||||
|
||||
private static class NullConverter implements NexacroConverter {
|
||||
|
||||
private Class source;
|
||||
private Class target;
|
||||
|
||||
private NullConverter(Class source, Class target) {
|
||||
this.source = source;
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
public boolean canConvert(Class source, Class target) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public Object convert(Object source, ConvertDefinition definition) throws NexacroConvertException {
|
||||
throw new UnsupportedOperationException("Unsupported convert type. source="+source+", target="+target);
|
||||
}
|
||||
|
||||
public void addListener(NexacroConvertListener listener) {
|
||||
}
|
||||
|
||||
public void removeListener(NexacroConvertListener listener) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.nexacro.spring.data.convert;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Statements
|
||||
* </pre>
|
||||
*
|
||||
* @ClassName : NexacroConverterFactoryBean.java
|
||||
* @Description : 클래스 설명을 기술합니다.
|
||||
* @author Park SeongMin
|
||||
* @since 2015. 8. 9.
|
||||
* @version 1.0
|
||||
* @see
|
||||
* @Modification Information
|
||||
* <pre>
|
||||
* since author description
|
||||
* =========== ============= ===========================
|
||||
* 2015. 8. 9. Park SeongMin 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public class NexacroConverterFactoryBean implements FactoryBean<NexacroConverterFactory>, InitializingBean {
|
||||
|
||||
private Set<NexacroConverter> converters;
|
||||
|
||||
private NexacroConverterFactory converterFactory;
|
||||
|
||||
/**
|
||||
* @param converters the converters to set
|
||||
*/
|
||||
public void setConverters(Set<NexacroConverter> converters) {
|
||||
this.converters = converters;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
this.converterFactory = NexacroConverterFactory.getInstance();
|
||||
converterFactory.register(converters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NexacroConverterFactory getObject() throws Exception {
|
||||
return converterFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<NexacroConverterFactory> getObjectType() {
|
||||
return NexacroConverterFactory.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleton() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.nexacro.spring.data.metadata;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Statements
|
||||
* </pre>
|
||||
*
|
||||
* @ClassName : NexacroList.java
|
||||
* @Description : 클래스 설명을 기술합니다.
|
||||
* @author Park SeongMin
|
||||
* @since 2015. 8. 6.
|
||||
* @version 1.0
|
||||
* @see
|
||||
* @Modification Information
|
||||
* <pre>
|
||||
* since author description
|
||||
* =========== ============= ===========================
|
||||
* 2015. 8. 6. Park SeongMin 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public abstract class NexacroMetaData extends ArrayList {
|
||||
|
||||
public abstract void setMetaData(Object obj);
|
||||
|
||||
public abstract Object getMetaData();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.nexacro.spring.data.metadata.support;
|
||||
|
||||
import com.nexacro.spring.data.metadata.NexacroMetaData;
|
||||
import com.nexacro.spring.data.support.NexacroBeanWrapper;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Statements
|
||||
* </pre>
|
||||
*
|
||||
* @ClassName : NexacroBeanMetaData.java
|
||||
* @Description : 클래스 설명을 기술합니다.
|
||||
* @author Park SeongMin
|
||||
* @since 2015. 8. 6.
|
||||
* @version 1.0
|
||||
* @see
|
||||
* @Modification Information
|
||||
* <pre>
|
||||
* since author description
|
||||
* =========== ============= ===========================
|
||||
* 2015. 8. 6. Park SeongMin 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public class BeanMetaData extends NexacroMetaData {
|
||||
|
||||
private Object metaDataObject;
|
||||
|
||||
public BeanMetaData(Object obj) {
|
||||
setMetaData(obj);
|
||||
}
|
||||
|
||||
public BeanMetaData(Class<?> genericType) {
|
||||
NexacroBeanWrapper beanWrapper = NexacroBeanWrapper.createBeanWrapper(genericType);
|
||||
Object insatance = beanWrapper.getInsatance();
|
||||
setMetaData(insatance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMetaData(Object obj) {
|
||||
if(!(obj instanceof NexacroBeanWrapper)) {
|
||||
NexacroBeanWrapper beanWrapper = NexacroBeanWrapper.createBeanWrapper(obj);
|
||||
this.metaDataObject = beanWrapper.getInsatance();
|
||||
} else {
|
||||
this.metaDataObject = obj;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getMetaData() {
|
||||
return this.metaDataObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BeanMetaData [class=" + this.metaDataObject.getClass() + "]";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package com.nexacro.spring.data.metadata.support;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.nexacro.spring.data.metadata.NexacroMetaData;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Statements
|
||||
* </pre>
|
||||
*
|
||||
* @ClassName : MapMetaData.java
|
||||
* @Description : 클래스 설명을 기술합니다.
|
||||
* @author Park SeongMin
|
||||
* @since 2015. 8. 6.
|
||||
* @version 1.0
|
||||
* @see
|
||||
* @Modification Information
|
||||
*
|
||||
* <pre>
|
||||
* since author description
|
||||
* =========== ============= ===========================
|
||||
* 2015. 8. 6. Park SeongMin 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public class MapMetaData extends NexacroMetaData {
|
||||
|
||||
private Map<String, Object> metaDataMap;
|
||||
|
||||
/**
|
||||
* Statements
|
||||
*
|
||||
* @param mapData
|
||||
*/
|
||||
public MapMetaData(Map<String, Object> mapData) {
|
||||
setMetaData(mapData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMetaData(Object metaDataMap) {
|
||||
this.metaDataMap = (Map) metaDataMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getMetaData() {
|
||||
return this.metaDataMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "MapMetaData [metaDataMap=" + metaDataMap + "]";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.nexacro.spring.data.metadata.support;
|
||||
|
||||
import com.nexacro.spring.data.metadata.NexacroMetaData;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Statements
|
||||
* </pre>
|
||||
*
|
||||
* @ClassName : UnsupportedMetaData.java
|
||||
* @Description : 클래스 설명을 기술합니다.
|
||||
* @author Park SeongMin
|
||||
* @since 2015. 8. 6.
|
||||
* @version 1.0
|
||||
* @see
|
||||
* @Modification Information
|
||||
* <pre>
|
||||
* since author description
|
||||
* =========== ============= ===========================
|
||||
* 2015. 8. 6. Park SeongMin 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public class UnsupportedMetaData extends NexacroMetaData {
|
||||
|
||||
private String message;
|
||||
|
||||
public UnsupportedMetaData(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMetaData(Object obj) {
|
||||
// throw new UnsupportedOperationException(this.message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getMetaData() {
|
||||
// throw new UnsupportedOperationException(this.message);
|
||||
return message;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,293 @@
|
||||
package com.nexacro.spring.data.support;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.InvalidPropertyException;
|
||||
import org.springframework.beans.PropertyAccessException;
|
||||
|
||||
import com.nexacro.spring.data.DataSetRowTypeAccessor;
|
||||
import com.nexacro.spring.data.DataSetSavedDataAccessor;
|
||||
import com.nexacro.spring.data.convert.NexacroConvertException;
|
||||
import com.nexacro.spring.util.ReflectionUtil;
|
||||
import com.nexacro.xapi.data.DataSet;
|
||||
import com.nexacro.xapi.data.datatype.DataType;
|
||||
import com.nexacro.xapi.data.datatype.PlatformDataType;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Statements
|
||||
* </pre>
|
||||
*
|
||||
* @ClassName : AbstractDataSetConverterHandler.java
|
||||
* @Description : 클래스 설명을 기술합니다.
|
||||
* @author Park SeongMin
|
||||
* @since 2015. 8. 11.
|
||||
* @version 1.0
|
||||
* @see
|
||||
* @Modification Information
|
||||
* <pre>
|
||||
* since author description
|
||||
* =========== ============= ===========================
|
||||
* 2015. 8. 11. Park SeongMin 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public class AbstractDataSetConverter extends AbstractListenerHandler {
|
||||
|
||||
|
||||
/***************************************************************************************************/
|
||||
/************************************** Object -> DataSet ****************************************/
|
||||
/***************************************************************************************************/
|
||||
|
||||
/**
|
||||
* Statements
|
||||
*
|
||||
* @param ds
|
||||
* @param obj
|
||||
* @throws NexacroConvertException
|
||||
*/
|
||||
protected void addRowIntoDataSet(DataSet ds, Map map) throws NexacroConvertException {
|
||||
// ignore null data.
|
||||
if(map == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
int newRow = ds.newRow();
|
||||
Iterator iterator = map.keySet().iterator();
|
||||
while(iterator.hasNext()) {
|
||||
Object key = iterator.next();
|
||||
Object value = map.get(key);
|
||||
|
||||
if(!(key instanceof String)) {
|
||||
throw new NexacroConvertException("must be Map<String, Object> if you use List<Map>. target="+ds.getName());
|
||||
}
|
||||
String columnName = (String) key;
|
||||
|
||||
// Byte[] 변환
|
||||
Object object = NexacroConverterHelper.toObject(value);
|
||||
|
||||
int columnIndex = ds.indexOfColumn(columnName);
|
||||
// fire event
|
||||
object = fireDataSetConvertedValue(ds, object, newRow, columnIndex, false, false);
|
||||
|
||||
// add data
|
||||
ds.set(newRow, columnName, object);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void addRowIntoDataSet(DataSet ds, Object obj) {
|
||||
|
||||
if(obj == null) { // ignore null data
|
||||
return;
|
||||
}
|
||||
|
||||
int newRow = ds.newRow();
|
||||
|
||||
NexacroBeanWrapper beanWrapper = NexacroBeanWrapper.createBeanWrapper(obj);
|
||||
|
||||
NexacroBeanProperty[] beanProperties = beanWrapper.getProperties();
|
||||
for(NexacroBeanProperty property: beanProperties) {
|
||||
|
||||
// ignore static. constColumn..
|
||||
if(property.isStatic()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String propertyName = property.getPropertyName();
|
||||
|
||||
Object propertyValue = beanWrapper.getPropertyValue(property);
|
||||
// Byte[] 변환
|
||||
Object object = NexacroConverterHelper.toObject(propertyValue);
|
||||
|
||||
int columnIndex = ds.indexOfColumn(propertyName);
|
||||
// fire event
|
||||
object = fireDataSetConvertedValue(ds, object, newRow, columnIndex, false, false);
|
||||
|
||||
// add data
|
||||
ds.set(newRow, columnIndex, object);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void addColumnIntoDataSet(DataSet ds, Map map) throws NexacroConvertException {
|
||||
Iterator iterator = map.keySet().iterator();
|
||||
while(iterator.hasNext()) {
|
||||
Object key = iterator.next();
|
||||
Object value = map.get(key);
|
||||
|
||||
if(!(key instanceof String)) {
|
||||
throw new NexacroConvertException("must be Map<String, Object> if you use List<Map>. target="+ds.getName());
|
||||
}
|
||||
String columnName = (String) key;
|
||||
if(value == null) {
|
||||
ds.addColumn(columnName, PlatformDataType.UNDEFINED);
|
||||
continue;
|
||||
}
|
||||
|
||||
// add column
|
||||
if(!NexacroConverterHelper.isConvertibleType(value.getClass())) {
|
||||
continue;
|
||||
}
|
||||
DataType dataTypeOfValue = NexacroConverterHelper.getDataTypeOfValue(value);
|
||||
ds.addColumn(columnName, dataTypeOfValue);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
protected void addColumnIntoDataSet(DataSet ds, Object availableFirstData) {
|
||||
|
||||
NexacroBeanWrapper beanWrapper = NexacroBeanWrapper.createBeanWrapper(availableFirstData);
|
||||
|
||||
NexacroBeanProperty[] beanProperties = beanWrapper.getProperties();
|
||||
for(NexacroBeanProperty property: beanProperties) {
|
||||
|
||||
String propertyName = property.getPropertyName();
|
||||
Class<?> propertyType = property.getPropertyType();
|
||||
|
||||
if(!NexacroConverterHelper.isConvertibleType(propertyType)) {
|
||||
continue;
|
||||
}
|
||||
DataType dataTypeOfValue = NexacroConverterHelper.getDataType(propertyType);
|
||||
|
||||
if(property.isStatic()) {
|
||||
Object staticValue = beanWrapper.getPropertyValue(property);
|
||||
// Byte[] 변환
|
||||
staticValue = NexacroConverterHelper.toObject(staticValue);
|
||||
int columnIndex = ds.indexOfColumn(propertyName);
|
||||
// fire event
|
||||
staticValue = fireDataSetConvertedValue(ds, staticValue, -1, columnIndex, false, false);
|
||||
ds.addConstantColumn(propertyName, dataTypeOfValue, staticValue);
|
||||
} else {
|
||||
ds.addColumn(propertyName, dataTypeOfValue);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected String[] getDataSetColumnNames(DataSet ds) {
|
||||
int columnCount = ds.getColumnCount();
|
||||
String[] columnNames = new String[columnCount];
|
||||
for(int i=0; i<columnNames.length; i++) {
|
||||
columnNames[i] = ds.getColumn(i).getName();
|
||||
}
|
||||
return columnNames;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************************************/
|
||||
/************************************** DataSet -> Object ****************************************/
|
||||
/***************************************************************************************************/
|
||||
|
||||
protected void addRowIntoMap(Map<String, Object> dataMap, DataSet ds, int rowIndex, String[] columnNames) {
|
||||
|
||||
int rowType = ds.getRowType(rowIndex);
|
||||
for(int columnIndex=0; columnIndex<columnNames.length; columnIndex++) {
|
||||
Object object = ds.getObject(rowIndex, columnIndex);
|
||||
|
||||
// fire event
|
||||
object = fireDataSetConvertedValue(ds, object, rowIndex, columnIndex, false, false);
|
||||
|
||||
dataMap.put(columnNames[columnIndex], object);
|
||||
}
|
||||
|
||||
// saved data
|
||||
if(ds.hasSavedRow(rowIndex)) {
|
||||
Map<String, Object> savedDataRow = new HashMap<String, Object>();
|
||||
for(int columnIndex=0; columnIndex<columnNames.length; columnIndex++) {
|
||||
Object object = ds.getSavedData(rowIndex, columnIndex);
|
||||
|
||||
// fire event
|
||||
object = fireDataSetConvertedValue(ds, object, rowIndex, columnIndex, true, false);
|
||||
|
||||
savedDataRow.put(columnNames[columnIndex], object);
|
||||
}
|
||||
|
||||
// set saved data
|
||||
dataMap.put(DataSetSavedDataAccessor.NAME, savedDataRow);
|
||||
}
|
||||
|
||||
// row type
|
||||
dataMap.put(DataSetRowTypeAccessor.NAME, rowType);
|
||||
|
||||
}
|
||||
|
||||
protected void addRowAndOrgRowIntoBean(NexacroBeanWrapper beanWrapper, DataSet ds, int rowIndex) throws NexacroConvertException {
|
||||
|
||||
boolean isSavedData = false;
|
||||
boolean isRemovedData = false;
|
||||
addRowIntoBean(beanWrapper, ds, rowIndex, isSavedData, isRemovedData);
|
||||
|
||||
// set saved data
|
||||
if(ds.hasSavedRow(rowIndex)) {
|
||||
Object bean = beanWrapper.getInsatance();
|
||||
Class<?> beanType = bean.getClass();
|
||||
if(ReflectionUtil.isImplemented(beanType, DataSetSavedDataAccessor.class)) {
|
||||
isSavedData = true;
|
||||
NexacroBeanWrapper savedBeanWrapper = NexacroBeanWrapper.createBeanWrapper(beanType);
|
||||
addRowIntoBean(savedBeanWrapper, ds, rowIndex, isSavedData, isRemovedData);
|
||||
|
||||
DataSetSavedDataAccessor accessor = (DataSetSavedDataAccessor) bean;
|
||||
accessor.setData(savedBeanWrapper.getInsatance());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void addRowIntoBean(NexacroBeanWrapper beanWrapper,
|
||||
DataSet ds, int rowIndex, boolean isSavedData, boolean isRemovedData) throws NexacroConvertException {
|
||||
|
||||
NexacroBeanProperty[] beanProperties = beanWrapper.getProperties();
|
||||
for(NexacroBeanProperty property: beanProperties) {
|
||||
|
||||
String propertyName = property.getPropertyName();
|
||||
int columnIndex = ds.indexOfColumn(propertyName);
|
||||
if(columnIndex == -1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Class<?> propertyType = property.getPropertyType();
|
||||
|
||||
Object convertDataSetValue =
|
||||
NexacroConverterHelper.toObjectFromDataSetValue(ds, rowIndex, columnIndex, propertyType, isSavedData, isRemovedData);
|
||||
|
||||
// fire event
|
||||
convertDataSetValue = fireDataSetConvertedValue(ds, convertDataSetValue, rowIndex, columnIndex, isSavedData, isRemovedData);
|
||||
|
||||
try {
|
||||
beanWrapper.setPropertyValue(property, convertDataSetValue);
|
||||
} catch (InvalidPropertyException e) {
|
||||
throw new NexacroConvertException(e.getMessage(), e);
|
||||
} catch (PropertyAccessException e) {
|
||||
throw new NexacroConvertException(e.getMessage(), e);
|
||||
} catch (BeansException e) {
|
||||
throw new NexacroConvertException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
Object bean = beanWrapper.getInsatance();
|
||||
Class beanType = bean.getClass();
|
||||
|
||||
// row type
|
||||
if(ReflectionUtil.isImplemented(beanType, DataSetRowTypeAccessor.class)) {
|
||||
|
||||
int rowType;
|
||||
if(isRemovedData) {
|
||||
rowType = DataSet.ROW_TYPE_DELETED;
|
||||
} else if(isSavedData){
|
||||
rowType = DataSet.ROW_TYPE_NORMAL;
|
||||
} else {
|
||||
rowType = ds.getRowType(rowIndex);
|
||||
}
|
||||
|
||||
DataSetRowTypeAccessor accessor = (DataSetRowTypeAccessor) bean;
|
||||
accessor.setRowType(rowType);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
package com.nexacro.spring.data.support;
|
||||
|
||||
import javax.swing.event.EventListenerList;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.nexacro.spring.data.convert.ConvertDataSetEvent;
|
||||
import com.nexacro.spring.data.convert.ConvertVariableEvent;
|
||||
import com.nexacro.spring.data.convert.NexacroConvertListener;
|
||||
import com.nexacro.xapi.data.DataSet;
|
||||
import com.nexacro.xapi.data.Variable;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Statements
|
||||
* </pre>
|
||||
*
|
||||
* @ClassName : AbstractNexacroConverter.java
|
||||
* @Description : 클래스 설명을 기술합니다.
|
||||
* @author Park SeongMin
|
||||
* @since 2015. 8. 9.
|
||||
* @version 1.0
|
||||
* @see
|
||||
* @Modification Information
|
||||
* <pre>
|
||||
* since author description
|
||||
* =========== ============= ===========================
|
||||
* 2015. 8. 9. Park SeongMin 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public abstract class AbstractListenerHandler {
|
||||
|
||||
protected Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
/* EventListenerList */
|
||||
private EventListenerList listenerList;
|
||||
|
||||
/**
|
||||
* <code>NexacroConverterListener</code>를 등록한다.
|
||||
*
|
||||
* @param listener NexacroConverterListener
|
||||
* @see #removeListener(NexacroConvertListener)
|
||||
*/
|
||||
public void addListener(NexacroConvertListener listener) {
|
||||
if (listenerList == null) {
|
||||
listenerList = new EventListenerList();
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("addListener=" + listener);
|
||||
}
|
||||
|
||||
listenerList.add(NexacroConvertListener.class, listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* <code>NexacroConverterListener</code>를 제거한다.
|
||||
*
|
||||
* @param listener NexacroConverterListener
|
||||
* @see #addListener(NexacroConvertListener)
|
||||
*/
|
||||
public void removeListener(NexacroConvertListener listener) {
|
||||
if (listenerList == null || listenerList.getListenerCount() == 0) {
|
||||
int listenerCount = (listenerList == null) ? -1 : listenerList.getListenerCount();
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("removeListener:"
|
||||
+ " listenerCount=" + listenerCount
|
||||
+ ", listener=" + listener);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("removeListener=" + listener);
|
||||
}
|
||||
|
||||
listenerList.remove(NexacroConvertListener.class, listener);
|
||||
}
|
||||
|
||||
public Object fireDataSetConvertedValue(DataSet ds, Object targetValue, int rowIndex, int columnIndex, boolean isSavedData, boolean isRemovedData) {
|
||||
if (listenerList == null || listenerList.getListenerCount() == 0) {
|
||||
return targetValue;
|
||||
}
|
||||
|
||||
ConvertDataSetEvent event = new ConvertDataSetEvent(ds, targetValue, rowIndex, columnIndex, isSavedData, isRemovedData);
|
||||
Object[] listeners = listenerList.getListenerList();
|
||||
|
||||
for (int i=0; i<listeners.length; i += 2) {
|
||||
if (listeners[i] == NexacroConvertListener.class) {
|
||||
((NexacroConvertListener) listeners[i+1]).convertedValue(event);
|
||||
}
|
||||
}
|
||||
|
||||
return event.getValue();
|
||||
|
||||
}
|
||||
|
||||
public Object fireVariableConvertedValue(Variable var, Object targetValue) {
|
||||
if (listenerList == null || listenerList.getListenerCount() == 0) {
|
||||
return targetValue;
|
||||
}
|
||||
|
||||
ConvertVariableEvent event = new ConvertVariableEvent(var, targetValue);
|
||||
Object[] listeners = listenerList.getListenerList();
|
||||
|
||||
for (int i=0; i<listeners.length; i += 2) {
|
||||
if (listeners[i] == NexacroConvertListener.class) {
|
||||
((NexacroConvertListener) listeners[i+1]).convertedValue(event);
|
||||
}
|
||||
}
|
||||
|
||||
return event.getValue();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,221 @@
|
||||
package com.nexacro.spring.data.support;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.nexacro.spring.data.DataSetRowTypeAccessor;
|
||||
import com.nexacro.spring.data.convert.ConvertDefinition;
|
||||
import com.nexacro.spring.data.convert.NexacroConvertException;
|
||||
import com.nexacro.spring.data.convert.NexacroConverter;
|
||||
import com.nexacro.xapi.data.DataSet;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Statements
|
||||
* </pre>
|
||||
*
|
||||
* @ClassName : DataSetToListConverter.java
|
||||
* @Description : 클래스 설명을 기술합니다.
|
||||
* @author Park SeongMin
|
||||
* @since 2015. 7. 28.
|
||||
* @version 1.0
|
||||
* @see
|
||||
* @Modification Information
|
||||
* <pre>
|
||||
* since author description
|
||||
* =========== ============= ===========================
|
||||
* 2015. 7. 28. Park SeongMin 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public class DataSetToListConverter extends AbstractDataSetConverter implements NexacroConverter<DataSet, List> {
|
||||
|
||||
@Override
|
||||
public boolean canConvert(Class source, Class target) {
|
||||
if(source == null || target == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// support type
|
||||
if(DataSet.class.equals(source) && List.class.equals(target)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* @see com.nexacro.spring.data.NexacroConverter#convert(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public List convert(DataSet ds, ConvertDefinition definition) throws NexacroConvertException {
|
||||
|
||||
if(definition ==null) {
|
||||
throw new NexacroConvertException(ConvertDefinition.class.getSimpleName()+" must not be null.");
|
||||
}
|
||||
|
||||
// bean 혹은 Map만을 대상으로 한다.
|
||||
Class genericType = definition.getGenericType();
|
||||
|
||||
if(ds == null) {
|
||||
// return ReflectionUtil.instantiateClass(genericType);
|
||||
return new ArrayList();
|
||||
}
|
||||
|
||||
if(genericType == null) {
|
||||
throw new NexacroConvertException("List<> generic type must be declared.");
|
||||
}
|
||||
|
||||
List dataList = null;
|
||||
if(Map.class.equals(genericType)) {
|
||||
dataList = convertDataSetToListMap(ds, definition);
|
||||
} else {
|
||||
dataList = convertDataSetToListBean(ds, definition);
|
||||
}
|
||||
|
||||
return dataList;
|
||||
|
||||
}
|
||||
|
||||
private List<Map<String, Object>> convertDataSetToListMap(DataSet ds, ConvertDefinition definition) {
|
||||
|
||||
String[] columnNames = getDataSetColumnNames(ds);
|
||||
|
||||
// default row
|
||||
List<Map<String, Object>> dataListMap = new ArrayList<Map<String, Object>>();
|
||||
int rowCount = ds.getRowCount();
|
||||
for(int rowIndex=0; rowIndex<rowCount; rowIndex++) {
|
||||
addRowIntoListMap(dataListMap, ds, rowIndex, columnNames);
|
||||
}
|
||||
|
||||
// removed row
|
||||
int removedRowCount = ds.getRemovedRowCount();
|
||||
for(int removedIndex=0; removedIndex<removedRowCount; removedIndex++) {
|
||||
addRemovedRowIntoListMap(dataListMap, ds, removedIndex, columnNames);
|
||||
}
|
||||
|
||||
return dataListMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Statements
|
||||
*
|
||||
* @param ds
|
||||
* @param columnCount
|
||||
* @param columnNames
|
||||
* @param hasSavedData
|
||||
* @param dataListMap
|
||||
* @param rowIndex
|
||||
*/
|
||||
private void addRowIntoListMap(List<Map<String, Object>> dataListMap, DataSet ds, int rowIndex, String[] columnNames) {
|
||||
|
||||
// default row
|
||||
Map<String, Object> dataRow = new HashMap<String, Object>();
|
||||
addRowIntoMap(dataRow, ds, rowIndex, columnNames);
|
||||
|
||||
// set data
|
||||
dataListMap.add(dataRow);
|
||||
}
|
||||
|
||||
/**
|
||||
* Statements
|
||||
*
|
||||
* @param ds
|
||||
* @param columnCount
|
||||
* @param columnNames
|
||||
* @param dataList
|
||||
* @param removedIndex
|
||||
*/
|
||||
private void addRemovedRowIntoListMap(List<Map<String, Object>> dataList, DataSet ds, int removedIndex, String[] columnNames) {
|
||||
|
||||
// removed data
|
||||
Map<String, Object> dataRow = new HashMap<String, Object>();
|
||||
for(int columnIndex=0; columnIndex<columnNames.length; columnIndex++) {
|
||||
Object object = ds.getRemovedData(removedIndex, columnIndex);
|
||||
|
||||
// fire event
|
||||
object = fireDataSetConvertedValue(ds, object, removedIndex, columnIndex, false, true);
|
||||
|
||||
dataRow.put(columnNames[columnIndex], object);
|
||||
}
|
||||
|
||||
// row type
|
||||
dataRow.put(DataSetRowTypeAccessor.NAME, DataSet.ROW_TYPE_DELETED);
|
||||
|
||||
// set removed data
|
||||
dataList.add(dataRow);
|
||||
}
|
||||
|
||||
|
||||
private List<?> convertDataSetToListBean(DataSet ds, ConvertDefinition definition) throws NexacroConvertException {
|
||||
|
||||
Class genericType = definition.getGenericType();
|
||||
|
||||
// 지원하는 형식인지 확인 한다.
|
||||
if(!NexacroConverterHelper.isSupportedBean(genericType)) {
|
||||
throw new NexacroConvertException("unsupported source type. type="+genericType);
|
||||
}
|
||||
|
||||
// 데이터 변환이 가능한 field 목록을 획득한다.
|
||||
// Map<String, Field> adjustConvertibleFields = NexacroConverterHelper.getAdjustConvertibleFields(genericType, ds);
|
||||
|
||||
List dataList = new ArrayList();
|
||||
|
||||
boolean isOrgData = false;
|
||||
boolean isRemovedData = false;
|
||||
|
||||
// default row
|
||||
int rowCount = ds.getRowCount();
|
||||
for(int rowIndex=0; rowIndex<rowCount; rowIndex++) {
|
||||
addRowIntoListBean(dataList, genericType, ds, rowIndex);
|
||||
}
|
||||
|
||||
// removed row
|
||||
int removedRowCount = ds.getRemovedRowCount();
|
||||
for(int removedIndex=0; removedIndex<removedRowCount; removedIndex++) {
|
||||
addRemovedRowIntoListBean(dataList, genericType, ds, removedIndex);
|
||||
}
|
||||
|
||||
return dataList;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Statements
|
||||
*
|
||||
* @param ds
|
||||
* @param beanType
|
||||
* @param adjustConvertibleFields
|
||||
* @param keySet
|
||||
* @param dataList
|
||||
* @param rowIndex
|
||||
* @throws NexacroConvertException
|
||||
*/
|
||||
private void addRowIntoListBean(List dataList, Class beanType, DataSet ds, int rowIndex) throws NexacroConvertException {
|
||||
|
||||
// Object bean = ReflectionUtil.instantiateClass(beanType);
|
||||
|
||||
NexacroBeanWrapper beanWrapper = NexacroBeanWrapper.createBeanWrapper(beanType);
|
||||
addRowAndOrgRowIntoBean(beanWrapper, ds, rowIndex);
|
||||
|
||||
Object bean = beanWrapper.getInsatance();
|
||||
dataList.add(bean);
|
||||
}
|
||||
|
||||
private void addRemovedRowIntoListBean(List dataList, Class beanType, DataSet ds, int removedIndex)
|
||||
throws NexacroConvertException {
|
||||
|
||||
// Object bean = ReflectionUtil.instantiateClass(beanType);
|
||||
NexacroBeanWrapper beanWrapper = NexacroBeanWrapper.createBeanWrapper(beanType);
|
||||
Object bean = beanWrapper.getInsatance();
|
||||
boolean isSavedData = false;
|
||||
boolean isRemovedData = true;
|
||||
addRowIntoBean(beanWrapper, ds, removedIndex, isSavedData, isRemovedData);
|
||||
|
||||
dataList.add(bean);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
package com.nexacro.spring.data.support;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.nexacro.spring.data.convert.ConvertDefinition;
|
||||
import com.nexacro.spring.data.convert.NexacroConvertException;
|
||||
import com.nexacro.spring.data.convert.NexacroConverter;
|
||||
import com.nexacro.spring.util.ReflectionUtil;
|
||||
import com.nexacro.xapi.data.DataSet;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Statements
|
||||
* </pre>
|
||||
*
|
||||
* @ClassName : DataSetToObjectConverter.java
|
||||
* @Description : 클래스 설명을 기술합니다.
|
||||
* @author Park SeongMin
|
||||
* @since 2015. 8. 17.
|
||||
* @version 1.0
|
||||
* @see
|
||||
* @Modification Information
|
||||
* <pre>
|
||||
* since author description
|
||||
* =========== ============= ===========================
|
||||
* 2015. 8. 17. Park SeongMin 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public class DataSetToObjectConverter extends AbstractDataSetConverter implements NexacroConverter<DataSet, Object> {
|
||||
|
||||
@Override
|
||||
public boolean canConvert(Class source, Class target) {
|
||||
if(source == null || target == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// support type
|
||||
if(DataSet.class.equals(source) && NexacroConverterHelper.isSupportedBean(target)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(DataSet source, ConvertDefinition definition) throws NexacroConvertException {
|
||||
|
||||
if(definition ==null) {
|
||||
throw new NexacroConvertException(ConvertDefinition.class.getSimpleName()+" must not be null.");
|
||||
}
|
||||
|
||||
// bean 혹은 Map만을 대상으로 한다.
|
||||
Class genericType = definition.getGenericType();
|
||||
|
||||
if(source == null) {
|
||||
return ReflectionUtil.instantiateClass(genericType);
|
||||
}
|
||||
|
||||
if(genericType == null) {
|
||||
throw new NexacroConvertException("generic type must be declared.");
|
||||
}
|
||||
|
||||
Object obj = null;
|
||||
if(Map.class.equals(genericType)) {
|
||||
obj = convertDataSetToMap(source, definition);
|
||||
} else {
|
||||
obj = convertDataSetToBean(source, definition);
|
||||
}
|
||||
|
||||
return obj;
|
||||
|
||||
}
|
||||
|
||||
private Object convertDataSetToBean(DataSet ds, ConvertDefinition definition) throws NexacroConvertException {
|
||||
Class genericType = definition.getGenericType();
|
||||
|
||||
// 지원하는 형식인지 확인 한다.
|
||||
if(!NexacroConverterHelper.isSupportedBean(genericType)) {
|
||||
throw new NexacroConvertException("unsupported generic type. type="+genericType);
|
||||
}
|
||||
|
||||
NexacroBeanWrapper beanWrapper = NexacroBeanWrapper.createBeanWrapper(genericType);
|
||||
addRowAndOrgRowIntoBean(beanWrapper, ds, 0);
|
||||
|
||||
Object bean = beanWrapper.getInsatance();
|
||||
|
||||
return bean;
|
||||
}
|
||||
|
||||
private Object convertDataSetToMap(DataSet ds, ConvertDefinition definition) {
|
||||
|
||||
String[] columnNames = getDataSetColumnNames(ds);
|
||||
|
||||
// default row
|
||||
Map<String, Object> dataRow = new HashMap<String, Object>();
|
||||
addRowIntoMap(dataRow, ds, 0, columnNames);
|
||||
|
||||
return dataRow;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
package com.nexacro.spring.data.support;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.nexacro.spring.data.convert.ConvertDefinition;
|
||||
import com.nexacro.spring.data.convert.NexacroConvertException;
|
||||
import com.nexacro.spring.data.convert.NexacroConverter;
|
||||
import com.nexacro.spring.data.metadata.NexacroMetaData;
|
||||
import com.nexacro.xapi.data.DataSet;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Statements
|
||||
* </pre>
|
||||
*
|
||||
* @ClassName : ListToDataSetConverter.java
|
||||
* @Description : 클래스 설명을 기술합니다.
|
||||
* @author Park SeongMin
|
||||
* @since 2015. 7. 28.
|
||||
* @version 1.0
|
||||
* @see
|
||||
* @Modification Information
|
||||
* <pre>
|
||||
* since author description
|
||||
* =========== ============= ===========================
|
||||
* 2015. 7. 28. Park SeongMin 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public class ListToDataSetConverter extends AbstractDataSetConverter implements NexacroConverter<List, DataSet> {
|
||||
|
||||
private static final int CHECK_INDEX = 0;
|
||||
|
||||
@Override
|
||||
public boolean canConvert(Class source, Class target) {
|
||||
|
||||
if(source == null || target == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// support list sub class
|
||||
if(List.class.isAssignableFrom(source) && DataSet.class.equals(target)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* @see com.nexacro.spring.data.NexacroConverter#convert(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public DataSet convert(List source, ConvertDefinition definition) throws NexacroConvertException {
|
||||
|
||||
if(definition ==null) {
|
||||
throw new IllegalArgumentException(ConvertDefinition.class.getSimpleName()+" must not be null.");
|
||||
}
|
||||
if(source == null) {
|
||||
return new DataSet(definition.getName());
|
||||
}
|
||||
|
||||
// check first value
|
||||
Object availableFirstData = checkAvailable(source);
|
||||
if(availableFirstData == null) {
|
||||
return new DataSet(definition.getName());
|
||||
}
|
||||
|
||||
// DataSet SavedType은 처리 하지 않는다. (UI 처리 불필요)
|
||||
DataSet ds = null;
|
||||
if(availableFirstData instanceof Map) {
|
||||
ds = convertListMapToDataSet(source, definition, (Map) availableFirstData);
|
||||
} else {
|
||||
ds = convertListBeanToDataSet(source, definition, availableFirstData);
|
||||
}
|
||||
|
||||
return ds;
|
||||
}
|
||||
|
||||
private Object checkAvailable(List source) {
|
||||
|
||||
// for ibatis empty data
|
||||
if(source instanceof NexacroMetaData) {
|
||||
NexacroMetaData metaData = (NexacroMetaData) source;
|
||||
return metaData.getMetaData();
|
||||
}
|
||||
|
||||
if(source.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
for(Object obj: source) {
|
||||
if(obj != null) {
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private DataSet convertListMapToDataSet(List source, ConvertDefinition definition, Map availableFirstData) throws NexacroConvertException {
|
||||
|
||||
DataSet ds = new DataSet(definition.getName());
|
||||
|
||||
// dynamic하게 변경 된 데이터는 처리 하지 않는다.
|
||||
addColumnIntoDataSet(ds, availableFirstData);
|
||||
|
||||
for(Object obj: source) {
|
||||
|
||||
if(!(obj instanceof Map)) {
|
||||
throw new NexacroConvertException("list should use the generic type. target="+ds.getName());
|
||||
}
|
||||
|
||||
addRowIntoDataSet(ds, (Map) obj);
|
||||
}
|
||||
|
||||
return ds;
|
||||
}
|
||||
|
||||
private DataSet convertListBeanToDataSet(List source, ConvertDefinition definition, Object availableFirstData) throws NexacroConvertException {
|
||||
|
||||
// 지원하는 형식인지 확인 한다.
|
||||
if(!NexacroConverterHelper.isSupportedBean(availableFirstData.getClass())) {
|
||||
throw new NexacroConvertException("unsupported generic type. type="+availableFirstData.getClass());
|
||||
}
|
||||
|
||||
DataSet ds = new DataSet(definition.getName());
|
||||
|
||||
addColumnIntoDataSet(ds, availableFirstData);
|
||||
|
||||
for(Object obj: source) {
|
||||
addRowIntoDataSet(ds, obj);
|
||||
}
|
||||
|
||||
return ds;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package com.nexacro.spring.data.support;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Statements
|
||||
* </pre>
|
||||
*
|
||||
* @ClassName : NexacroBeanProperty.java
|
||||
* @Description : 클래스 설명을 기술합니다.
|
||||
* @author Park SeongMin
|
||||
* @since 2015. 8. 10.
|
||||
* @version 1.0
|
||||
* @see
|
||||
* @Modification Information
|
||||
* <pre>
|
||||
* since author description
|
||||
* =========== ============= ===========================
|
||||
* 2015. 8. 10. Park SeongMin 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public class NexacroBeanProperty {
|
||||
|
||||
private final String propertyName;
|
||||
private final Class<?> propertyType;
|
||||
|
||||
private boolean isStatic;
|
||||
private String originalPropertyName;
|
||||
|
||||
// for performance..
|
||||
// private PropertyDescriptor descriptor;
|
||||
// descriptor의 getWriteMethod 시 synchoronized
|
||||
private Method writeMethod;
|
||||
|
||||
public NexacroBeanProperty(String propertyName, Class<?> propertyType) {
|
||||
this.propertyName = propertyName;
|
||||
this.propertyType = propertyType;
|
||||
}
|
||||
|
||||
public String getPropertyName() {
|
||||
return propertyName;
|
||||
}
|
||||
|
||||
public Class<?> getPropertyType() {
|
||||
return propertyType;
|
||||
}
|
||||
|
||||
void setStatic(boolean isStatic) {
|
||||
this.isStatic = isStatic;
|
||||
}
|
||||
|
||||
public boolean isStatic() {
|
||||
return isStatic;
|
||||
}
|
||||
|
||||
String getOriginalPropertyName() {
|
||||
return originalPropertyName;
|
||||
}
|
||||
|
||||
void setOriginalPropertyName(String originalPropertyName) {
|
||||
this.originalPropertyName = originalPropertyName;
|
||||
}
|
||||
|
||||
Method getWriteMethod() {
|
||||
return writeMethod;
|
||||
}
|
||||
|
||||
void setWriteMethod(Method writeMethod) {
|
||||
this.writeMethod = writeMethod;
|
||||
}
|
||||
|
||||
// PropertyDescriptor getPropertyDescriptor() {
|
||||
// return this.descriptor;
|
||||
// }
|
||||
//
|
||||
// void setPropertyDescriptor(PropertyDescriptor descriptor) {
|
||||
// this.descriptor = descriptor;
|
||||
// }
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,353 @@
|
||||
package com.nexacro.spring.data.support;
|
||||
|
||||
import java.beans.IntrospectionException;
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.BeanWrapper;
|
||||
import org.springframework.beans.BeanWrapperImpl;
|
||||
import org.springframework.beans.NotWritablePropertyException;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import com.nexacro.spring.util.ReflectionFailException;
|
||||
import com.nexacro.spring.util.ReflectionUtil;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Statements
|
||||
* </pre>
|
||||
*
|
||||
* @ClassName : NexacroBeanWrapper.java
|
||||
* @Description : 클래스 설명을 기술합니다.
|
||||
* @author Park SeongMin
|
||||
* @since 2015. 8. 4.
|
||||
* @version 1.0
|
||||
* @see
|
||||
* @Modification Information
|
||||
* <pre>
|
||||
* since author description
|
||||
* =========== ============= ===========================
|
||||
* 2015. 8. 4. Park SeongMin 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public class NexacroBeanWrapper {
|
||||
|
||||
/*
|
||||
BeanWrapper의 경우 Method 명칭에 해당하는 property 명칭으로 값을 설정한다.
|
||||
하지만 field가 boolean일 경우 eclipseis에서 generation 되는 메서드의 명칭은 is가 생략되기 때문에
|
||||
해당부분만을 처리하며, 나머지는 spring으로 위임한다.
|
||||
*/
|
||||
|
||||
private BeanWrapper beanWrapper;
|
||||
private CachedBeanMappings cachedMapping;
|
||||
|
||||
|
||||
private NexacroBeanWrapper(Object obj) {
|
||||
beanWrapper = new BeanWrapperImpl(obj);
|
||||
}
|
||||
|
||||
private NexacroBeanWrapper(Class<?> clazz) {
|
||||
beanWrapper = new BeanWrapperImpl(clazz);
|
||||
}
|
||||
|
||||
public NexacroBeanProperty[] getProperties() {
|
||||
return getCachedBeanMappings().getProperties();
|
||||
}
|
||||
|
||||
public NexacroBeanProperty getProperty(String propertyName) {
|
||||
return getCachedBeanMappings().getProperty(propertyName);
|
||||
}
|
||||
|
||||
public void setPropertyValue(NexacroBeanProperty property, Object value) {
|
||||
if(property == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 데이터 설정 시 beanwrapper를 사용하지 않고 직접 처리 한다.
|
||||
// 데이터 변경에 대한 Event 처리, Data Type 처리 등에 따른 속도 저하..
|
||||
// 10만건 처리 시 5초 vs 1초 정도 차이.
|
||||
// PropertyDescriptor propertyDescriptor = property.getPropertyDescriptor();
|
||||
// Method writeMethod = propertyDescriptor.getWriteMethod();
|
||||
Method writeMethod = property.getWriteMethod();
|
||||
try {
|
||||
ReflectionUtil.makeAccessible(writeMethod);
|
||||
writeMethod.invoke(getInsatance(), value);
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new NotWritablePropertyException(getInsatance().getClass(), property.getPropertyName(), "Could not set object property", e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new NotWritablePropertyException(getInsatance().getClass(), property.getPropertyName(), "Could not set object property", e);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new NotWritablePropertyException(getInsatance().getClass(), property.getPropertyName(), "Could not set object property", e.getTargetException());
|
||||
}
|
||||
|
||||
// if(property.getOriginalPropertyName() != null) {
|
||||
// beanWrapper.setPropertyValue(property.getOriginalPropertyName(), value);
|
||||
// } else {
|
||||
// beanWrapper.setPropertyValue(property.getPropertyName(), value);
|
||||
// }
|
||||
}
|
||||
|
||||
public void setPropertyValue(String propertyName, Object value) {
|
||||
NexacroBeanProperty property = getCachedBeanMappings().getProperty(propertyName);
|
||||
if(property == null ) {
|
||||
throw new NotWritablePropertyException(getInsatance().getClass(), propertyName);
|
||||
}
|
||||
setPropertyValue(property, value);
|
||||
}
|
||||
|
||||
public Object getPropertyValue(NexacroBeanProperty property) {
|
||||
if(property == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String propertyName = property.getPropertyName();
|
||||
if(property.getOriginalPropertyName() != null) {
|
||||
propertyName = property.getOriginalPropertyName();
|
||||
}
|
||||
|
||||
// if(beanWrapper.isReadableProperty(propertyName)) {
|
||||
return beanWrapper.getPropertyValue(propertyName);
|
||||
|
||||
}
|
||||
|
||||
public Object getPropertyValue(String propertyName) {
|
||||
NexacroBeanProperty property = getCachedBeanMappings().getProperty(propertyName);
|
||||
if(property == null) {
|
||||
throw new NotWritablePropertyException(getInsatance().getClass(), propertyName);
|
||||
}
|
||||
return getPropertyValue(property);
|
||||
}
|
||||
|
||||
public Object getInsatance() {
|
||||
return beanWrapper.getWrappedInstance();
|
||||
}
|
||||
|
||||
private CachedBeanMappings getCachedBeanMappings() {
|
||||
if(cachedMapping != null) {
|
||||
return cachedMapping;
|
||||
}
|
||||
|
||||
cachedMapping = CachedBeanMappings.beanMappings(beanWrapper);
|
||||
return cachedMapping;
|
||||
}
|
||||
|
||||
public static NexacroBeanWrapper createBeanWrapper(Object obj) {
|
||||
return new NexacroBeanWrapper(obj);
|
||||
}
|
||||
|
||||
public static NexacroBeanWrapper createBeanWrapper(Class<?> clazz) {
|
||||
return new NexacroBeanWrapper(clazz);
|
||||
}
|
||||
|
||||
private static class CachedBeanMappings {
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(NexacroBeanWrapper.class);
|
||||
private static final String IS = "is";
|
||||
private static Map<Class, CachedBeanMappings> classCache = Collections.synchronizedMap(new HashMap<Class, CachedBeanMappings>());
|
||||
|
||||
private Map<String, NexacroBeanProperty> propertyCache;
|
||||
|
||||
/* supported all properties */
|
||||
private NexacroBeanProperty[] beanProperties;
|
||||
|
||||
private CachedBeanMappings(BeanWrapper beanWrapper) {
|
||||
initBeanPropertyNames(beanWrapper);
|
||||
}
|
||||
|
||||
static CachedBeanMappings beanMappings(BeanWrapper beanWrapper) {
|
||||
|
||||
Class wrappedClass = beanWrapper.getWrappedClass();
|
||||
CachedBeanMappings mapping = classCache.get(wrappedClass);
|
||||
if(mapping != null) {
|
||||
return mapping;
|
||||
}
|
||||
mapping = new CachedBeanMappings(beanWrapper);
|
||||
classCache.put(wrappedClass, mapping);
|
||||
return mapping;
|
||||
}
|
||||
|
||||
private void initBeanPropertyNames(BeanWrapper beanWrapper) {
|
||||
|
||||
propertyCache = new HashMap<String, NexacroBeanProperty>();
|
||||
List<NexacroBeanProperty> tmpList = new ArrayList<NexacroBeanProperty>();
|
||||
|
||||
Class wrappedClass = beanWrapper.getWrappedClass();
|
||||
|
||||
// not ordered..
|
||||
PropertyDescriptor[] propertyDescriptors = beanWrapper.getPropertyDescriptors();
|
||||
|
||||
for(PropertyDescriptor descriptor: propertyDescriptors) {
|
||||
|
||||
if(!validateReadAndWriteMethod(wrappedClass, descriptor)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// ignore row type
|
||||
if("rowType".equalsIgnoreCase(descriptor.getName())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String name = descriptor.getName();
|
||||
Class<?> propertyType = descriptor.getPropertyType();
|
||||
boolean isConverted = false;
|
||||
String adjustName = name;
|
||||
if(propertyType == boolean.class) {
|
||||
if(!name.startsWith(IS)) {
|
||||
try {
|
||||
// check exist field
|
||||
if(wrappedClass.getField(IS + getBaseName(name)) != null) {
|
||||
adjustName = IS + getBaseName(name);
|
||||
isConverted = true;
|
||||
}
|
||||
} catch (SecurityException e) {
|
||||
} catch (NoSuchFieldException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NexacroBeanProperty beanProperty = new NexacroBeanProperty(adjustName, propertyType);
|
||||
if(isConverted) {
|
||||
beanProperty.setOriginalPropertyName(name);
|
||||
}
|
||||
|
||||
if(isStaticProperty(descriptor)) {
|
||||
beanProperty.setStatic(true);
|
||||
}
|
||||
|
||||
// beanProperty.setPropertyDescriptor(descriptor);
|
||||
beanProperty.setWriteMethod(descriptor.getWriteMethod());
|
||||
|
||||
tmpList.add(beanProperty);
|
||||
propertyCache.put(adjustName, beanProperty);
|
||||
}
|
||||
beanProperties = new NexacroBeanProperty[tmpList.size()];
|
||||
beanProperties = tmpList.toArray(beanProperties);
|
||||
}
|
||||
|
||||
public NexacroBeanProperty[] getProperties() {
|
||||
return beanProperties;
|
||||
}
|
||||
|
||||
public NexacroBeanProperty getProperty(String name) {
|
||||
return propertyCache.get(name);
|
||||
}
|
||||
|
||||
private boolean validateReadAndWriteMethod(Class<?> clazz, PropertyDescriptor descriptor) {
|
||||
|
||||
String name = descriptor.getName();
|
||||
Method readMethod = descriptor.getReadMethod();
|
||||
Method writeMethod = descriptor.getWriteMethod();
|
||||
|
||||
if(name == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!NexacroConverterHelper.isConvertibleType(descriptor.getPropertyType())) {
|
||||
// unsupported type
|
||||
return false;
|
||||
}
|
||||
|
||||
if(readMethod == null && writeMethod != null) {
|
||||
// find static method.. introspection is unsupported static getter.
|
||||
String findPropertyName = "get"+getBaseName(name);
|
||||
Method findedMethod = ReflectionUtils.findMethod(clazz, findPropertyName);
|
||||
if(findedMethod != null) {
|
||||
if(ReflectionUtil.isStaticMethod(findedMethod)) {
|
||||
setStaticReadMethodIntoDescriptor(descriptor, findedMethod);
|
||||
}
|
||||
}
|
||||
|
||||
readMethod = descriptor.getReadMethod();
|
||||
if(readMethod != null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if(logger.isDebugEnabled()) {
|
||||
logger.debug("skipped property {} of bean class[{}]:" +
|
||||
" Bean Property {} is not readable or has an invalid getter or setter." +
|
||||
" Does the return type of the getter match the parameter type of the setter"
|
||||
, name, clazz, name);
|
||||
|
||||
}
|
||||
|
||||
} else if(readMethod == null || writeMethod == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
private void setStaticReadMethodIntoDescriptor(PropertyDescriptor descriptor, Method staticMethod) {
|
||||
|
||||
// for spring GenericTypeAwarePropertyDescriptor
|
||||
Field field = null;
|
||||
try {
|
||||
field = ReflectionUtil.getField(descriptor.getClass(), "readMethod");
|
||||
} catch(ReflectionFailException e) {
|
||||
// nothing..
|
||||
}
|
||||
|
||||
if(field != null) {
|
||||
ReflectionUtil.makeAccessible(field);
|
||||
try {
|
||||
field.set(descriptor, staticMethod);
|
||||
} catch (IllegalArgumentException e) {
|
||||
logger.error("{} finded static gerrer '{}' method setting failed.", descriptor.getName(), staticMethod);
|
||||
return;
|
||||
} catch (IllegalAccessException e) {
|
||||
logger.error("{} finded static gerrer '{}' method setting failed.", descriptor.getName(), staticMethod);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
descriptor.setReadMethod(staticMethod);
|
||||
} catch (IntrospectionException e) {
|
||||
logger.error("{} finded static gerrer '{}' method setting failed.", descriptor.getName(), staticMethod);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private boolean isStaticProperty(PropertyDescriptor descriptor) {
|
||||
|
||||
Method readMethod = descriptor.getReadMethod();
|
||||
Method writeMethod = descriptor.getWriteMethod();
|
||||
|
||||
if(ReflectionUtil.isStaticMethod(readMethod) && ReflectionUtil.isStaticMethod(writeMethod)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private String getBaseName(String name) {
|
||||
if (name == null || name.length() == 0) {
|
||||
return name;
|
||||
}
|
||||
return name.substring(0, 1).toUpperCase(Locale.ENGLISH) + name.substring(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// private static class GenericTypeAwarePropertyDescriptorWrapper extends GenericTypeAwarePropertyDescriptor {
|
||||
//
|
||||
// private Method staticReadMethod;
|
||||
//
|
||||
//
|
||||
// }
|
||||
|
||||
}
|
||||
@@ -0,0 +1,470 @@
|
||||
package com.nexacro.spring.data.support;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.nexacro.spring.data.convert.NexacroConverter.ConvertiblePair;
|
||||
import com.nexacro.spring.util.ReflectionUtil;
|
||||
import com.nexacro.xapi.data.ColumnHeader;
|
||||
import com.nexacro.xapi.data.DataSet;
|
||||
import com.nexacro.xapi.data.DataTypes;
|
||||
import com.nexacro.xapi.data.Variable;
|
||||
import com.nexacro.xapi.data.datatype.DataType;
|
||||
import com.nexacro.xapi.data.datatype.DataTypeFactory;
|
||||
import com.nexacro.xapi.data.datatype.PlatformDataType;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Statements
|
||||
* </pre>
|
||||
*
|
||||
* @ClassName : VariableConverterHelper.java
|
||||
* @Description : 클래스 설명을 기술합니다.
|
||||
* @author Park SeongMin
|
||||
* @since 2015. 7. 28.
|
||||
* @version 1.0
|
||||
* @see
|
||||
* @Modification Information
|
||||
* <pre>
|
||||
* since author description
|
||||
* =========== ============= ===========================
|
||||
* 2015. 7. 28. Park SeongMin 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public abstract class NexacroConverterHelper {
|
||||
|
||||
private static final Set<ConvertiblePair> listToDataSetConvertibleSets = Collections.singleton(new ConvertiblePair(List.class, DataSet.class));
|
||||
private static final Set<ConvertiblePair> dataSetToListConvertibleSets = Collections.singleton(new ConvertiblePair(DataSet.class, List.class));
|
||||
|
||||
private static final Set<ConvertiblePair> objectToVariableConvertibleSets = new HashSet<ConvertiblePair>();
|
||||
private static final Set<ConvertiblePair> variableToObjectConvertibleSets = new HashSet<ConvertiblePair>();
|
||||
|
||||
private static final Map<Class<?>, Class<?>> primitiveTypeWrapperMap = new HashMap<Class<?>, Class<?>>(8);
|
||||
private static final Map<Class<?>, Class<?>> nonPrimitiveTypeMap = new HashMap<Class<?>, Class<?>>(4);
|
||||
|
||||
|
||||
static {
|
||||
// byte[], int, long, float, double, boolean, Object, String, BigDecimal, Date
|
||||
// byte, char, short는 지원하지 않는다.
|
||||
primitiveTypeWrapperMap.put(byte[].class, Byte[].class);
|
||||
// 아래 항목 지원 시 데이터 유실이 발생할 수 있다.
|
||||
// primitiveWrapperTypeMap.put(byte.class, Byte.class);
|
||||
// primitiveWrapperTypeMap.put(char.class, Character.class);
|
||||
// primitiveWrapperTypeMap.put(short.class, Short.class);
|
||||
primitiveTypeWrapperMap.put(int.class, Integer.class);
|
||||
primitiveTypeWrapperMap.put(long.class, Long.class);
|
||||
primitiveTypeWrapperMap.put(float.class, Float.class);
|
||||
primitiveTypeWrapperMap.put(double.class, Double.class);
|
||||
primitiveTypeWrapperMap.put(boolean.class, Boolean.class);
|
||||
|
||||
nonPrimitiveTypeMap.put(Object.class, Object.class);
|
||||
nonPrimitiveTypeMap.put(String.class, String.class);
|
||||
nonPrimitiveTypeMap.put(BigDecimal.class, BigDecimal.class);
|
||||
nonPrimitiveTypeMap.put(Date.class, Date.class);
|
||||
|
||||
Set<Class<?>> keySet = primitiveTypeWrapperMap.keySet();
|
||||
for(Class<?> clazz: keySet) {
|
||||
objectToVariableConvertibleSets.add(new ConvertiblePair(clazz, Variable.class));
|
||||
objectToVariableConvertibleSets.add(new ConvertiblePair(primitiveTypeWrapperMap.get(clazz), Variable.class));
|
||||
}
|
||||
for(Class<?> clazz: keySet) {
|
||||
variableToObjectConvertibleSets.add(new ConvertiblePair(Variable.class, clazz));
|
||||
variableToObjectConvertibleSets.add(new ConvertiblePair(Variable.class, primitiveTypeWrapperMap.get(clazz)));
|
||||
}
|
||||
|
||||
Set<Class<?>> nonKeySet = nonPrimitiveTypeMap.keySet();
|
||||
for(Class<?> clazz: nonKeySet) {
|
||||
objectToVariableConvertibleSets.add(new ConvertiblePair(clazz, Variable.class));
|
||||
}
|
||||
for(Class<?> clazz: nonKeySet) {
|
||||
variableToObjectConvertibleSets.add(new ConvertiblePair(Variable.class, clazz));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static Set<ConvertiblePair> getObjectToVariableConvertibleTypes() {
|
||||
return objectToVariableConvertibleSets;
|
||||
}
|
||||
|
||||
static Set<ConvertiblePair> getVariableToObjectConvertibleTypes() {
|
||||
return variableToObjectConvertibleSets;
|
||||
}
|
||||
|
||||
static Set<ConvertiblePair> getListToDataSetConvertibleTypes() {
|
||||
return listToDataSetConvertibleSets;
|
||||
}
|
||||
|
||||
static Set<ConvertiblePair> getDataSetToListConvertibleTypes() {
|
||||
return dataSetToListConvertibleSets;
|
||||
}
|
||||
|
||||
public static Object getDefaultValue(DataType dataType) {
|
||||
|
||||
int type = dataType.getType();
|
||||
|
||||
if(type == DataTypes.STRING) {
|
||||
return DataTypes.DEFAULT_VALUE_STRING;
|
||||
} else if(type == DataTypes.INT) {
|
||||
return DataTypes.DEFAULT_VALUE_INT;
|
||||
} else if(type == DataTypes.LONG) {
|
||||
return DataTypes.DEFAULT_VALUE_LONG;
|
||||
} else if(type == DataTypes.FLOAT) {
|
||||
return DataTypes.DEFAULT_VALUE_FLOAT;
|
||||
} else if(type == DataTypes.DOUBLE) {
|
||||
return DataTypes.DEFAULT_VALUE_DOUBLE;
|
||||
} else if(type == DataTypes.BOOLEAN) {
|
||||
return DataTypes.DEFAULT_VALUE_BOOLEAN;
|
||||
} else if(type == DataTypes.DATE) {
|
||||
return DataTypes.DEFAULT_VALUE_DATE;
|
||||
} else if(type == DataTypes.DATE_TIME) {
|
||||
return DataTypes.DEFAULT_VALUE_DATE_TIME;
|
||||
} else if(type == DataTypes.TIME) {
|
||||
return DataTypes.DEFAULT_VALUE_TIME;
|
||||
} else if(type == DataTypes.BIG_DECIMAL) {
|
||||
return DataTypes.DEFAULT_VALUE_BIG_DECIMAL;
|
||||
} else if(type == DataTypes.BLOB) {
|
||||
return DataTypes.DEFAULT_VALUE_BLOB;
|
||||
}
|
||||
return DataTypes.DEFAULT_VALUE_OBJECT;
|
||||
}
|
||||
|
||||
public static Object getDefaultMetaDataValue(DataType dataType) {
|
||||
|
||||
int type = dataType.getType();
|
||||
|
||||
if(type == DataTypes.STRING) {
|
||||
return "";
|
||||
} else if(type == DataTypes.INT) {
|
||||
return DataTypes.DEFAULT_VALUE_INT;
|
||||
} else if(type == DataTypes.LONG) {
|
||||
return DataTypes.DEFAULT_VALUE_LONG;
|
||||
} else if(type == DataTypes.FLOAT) {
|
||||
return DataTypes.DEFAULT_VALUE_FLOAT;
|
||||
} else if(type == DataTypes.DOUBLE) {
|
||||
return DataTypes.DEFAULT_VALUE_DOUBLE;
|
||||
} else if(type == DataTypes.BOOLEAN) {
|
||||
return DataTypes.DEFAULT_VALUE_BOOLEAN;
|
||||
} else if(type == DataTypes.DATE) {
|
||||
return new Date();
|
||||
} else if(type == DataTypes.DATE_TIME) {
|
||||
return new Date();
|
||||
} else if(type == DataTypes.TIME) {
|
||||
return new Date();
|
||||
} else if(type == DataTypes.BIG_DECIMAL) {
|
||||
return new BigDecimal(0);
|
||||
} else if(type == DataTypes.BLOB) {
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
return DataTypes.DEFAULT_VALUE_OBJECT;
|
||||
}
|
||||
|
||||
public static DataType getDataType(Class targetClass) {
|
||||
|
||||
// DataTypeFactory의 byte[] 문제.
|
||||
if(String.class.equals(targetClass)) {
|
||||
return PlatformDataType.STRING;
|
||||
} else if(int.class.equals(targetClass) || Integer.class.equals(targetClass)) {
|
||||
return PlatformDataType.INT;
|
||||
} else if(long.class.equals(targetClass) || Long.class.equals(targetClass)) {
|
||||
return PlatformDataType.LONG;
|
||||
} else if(float.class.equals(targetClass) || Float.class.equals(targetClass)) {
|
||||
return PlatformDataType.FLOAT;
|
||||
} else if(double.class.equals(targetClass) || Double.class.equals(targetClass)) {
|
||||
return PlatformDataType.DOUBLE;
|
||||
} else if(boolean.class.equals(targetClass) || Boolean.class.equals(targetClass)) {
|
||||
return PlatformDataType.BOOLEAN;
|
||||
} else if(Date.class.equals(targetClass)) {
|
||||
return PlatformDataType.DATE_TIME;
|
||||
} else if(BigDecimal.class.equals(targetClass)) {
|
||||
return PlatformDataType.BIG_DECIMAL;
|
||||
} else if(Object.class.equals(targetClass)) {
|
||||
return PlatformDataType.UNDEFINED;
|
||||
} else if(targetClass.isArray() && (byte[].class.equals(targetClass) || Byte[].class.equals(targetClass))) {
|
||||
return PlatformDataType.BLOB;
|
||||
}
|
||||
|
||||
return PlatformDataType.UNDEFINED;
|
||||
}
|
||||
|
||||
static DataType getDataTypeOfValue(Object value) {
|
||||
if(value == null) {
|
||||
return PlatformDataType.UNDEFINED;
|
||||
}
|
||||
DataType dataTypeOfValue = DataTypeFactory.getDataTypeOfValue(value);
|
||||
if(dataTypeOfValue.getType() == PlatformDataType.UNDEFINED.getType()) {
|
||||
if(value instanceof Byte[]) {
|
||||
dataTypeOfValue = PlatformDataType.BLOB;
|
||||
}
|
||||
} else if(dataTypeOfValue.getType() == PlatformDataType.DATE.getType()) {
|
||||
// data는 DATE_TIME으로 변경.
|
||||
dataTypeOfValue = PlatformDataType.DATE_TIME;
|
||||
}
|
||||
return dataTypeOfValue;
|
||||
}
|
||||
|
||||
|
||||
static Variable toVariable(String name, Object value) {
|
||||
Variable var = new Variable(name);
|
||||
if(value == null) {
|
||||
return var;
|
||||
}
|
||||
// 최초 type 설정이 안되어 있을 경우 설정된 값에 따라 Type이 설정 된다.
|
||||
if(value instanceof Byte[]) {
|
||||
var.set(toPrimitive((Byte[]) value));
|
||||
} else {
|
||||
var.set(value);
|
||||
}
|
||||
return var;
|
||||
}
|
||||
|
||||
static Object toObject(Variable variable, Class<?> targetClass) {
|
||||
|
||||
// 직접 변환할까..
|
||||
if(String.class.equals(targetClass)) {
|
||||
return variable.getString();
|
||||
} else if(int.class.equals(targetClass) || Integer.class.equals(targetClass)) {
|
||||
return variable.getInt();
|
||||
} else if(long.class.equals(targetClass) || Long.class.equals(targetClass)) {
|
||||
return variable.getLong();
|
||||
} else if(float.class.equals(targetClass) || Float.class.equals(targetClass)) {
|
||||
return variable.getFloat();
|
||||
} else if(double.class.equals(targetClass) || Double.class.equals(targetClass)) {
|
||||
return variable.getDouble();
|
||||
} else if(boolean.class.equals(targetClass) || Boolean.class.equals(targetClass)) {
|
||||
return variable.getBoolean();
|
||||
} else if(Date.class.equals(targetClass)) {
|
||||
return variable.getDateTime();
|
||||
} else if(BigDecimal.class.equals(targetClass)) {
|
||||
return variable.getBigDecimal();
|
||||
} else if(Object.class.equals(targetClass)) {
|
||||
return variable.getObject();
|
||||
} else if(targetClass.isArray()) {
|
||||
if(byte[].class.equals(targetClass)) {
|
||||
return variable.getBlob();
|
||||
} else if(Byte[].class.equals(targetClass)) {
|
||||
byte[] blob = variable.getBlob();
|
||||
return toObject(blob);
|
||||
}
|
||||
}
|
||||
|
||||
return variable.getObject();
|
||||
}
|
||||
|
||||
static Object toObject(Object obj) {
|
||||
if(obj == null) {
|
||||
return null;
|
||||
}
|
||||
if(obj instanceof Byte[]) {
|
||||
return toPrimitive((Byte[])obj);
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
static Object toObjectFromDataSetValue(DataSet ds, int rowIndex, int colIndex, Class<?> targetClass, boolean isSavedData, boolean isRemovedData) {
|
||||
|
||||
if(Object.class.equals(targetClass)) {
|
||||
if(isSavedData) {
|
||||
return ds.getSavedData(rowIndex, colIndex);
|
||||
} else if(isRemovedData) {
|
||||
return ds.getRemovedData(rowIndex, colIndex);
|
||||
} else {
|
||||
return ds.getObject(rowIndex, colIndex);
|
||||
}
|
||||
} else if(String.class.equals(targetClass)) {
|
||||
if(isSavedData) {
|
||||
return ds.getSavedStringData(rowIndex, colIndex);
|
||||
} else if(isRemovedData) {
|
||||
return ds.getRemovedStringData(rowIndex, colIndex);
|
||||
} else {
|
||||
return ds.getString(rowIndex, colIndex);
|
||||
}
|
||||
} else if(int.class.equals(targetClass) || Integer.class.equals(targetClass)) {
|
||||
if(isSavedData) {
|
||||
return ds.getSavedIntData(rowIndex, colIndex);
|
||||
} else if(isRemovedData) {
|
||||
return ds.getRemovedIntData(rowIndex, colIndex);
|
||||
} else {
|
||||
return ds.getInt(rowIndex, colIndex);
|
||||
}
|
||||
} else if(long.class.equals(targetClass) || Long.class.equals(targetClass)) {
|
||||
if(isSavedData) {
|
||||
return ds.getSavedLongData(rowIndex, colIndex);
|
||||
} else if(isRemovedData) {
|
||||
return ds.getRemovedLongData(rowIndex, colIndex);
|
||||
} else {
|
||||
return ds.getLong(rowIndex, colIndex);
|
||||
}
|
||||
} else if(float.class.equals(targetClass) || Float.class.equals(targetClass)) {
|
||||
if(isSavedData) {
|
||||
return ds.getSavedFloatData(rowIndex, colIndex);
|
||||
} else if(isRemovedData) {
|
||||
return ds.getRemovedFloatData(rowIndex, colIndex);
|
||||
} else {
|
||||
return ds.getFloat(rowIndex, colIndex);
|
||||
}
|
||||
} else if(double.class.equals(targetClass) || Double.class.equals(targetClass)) {
|
||||
if(isSavedData) {
|
||||
return ds.getSavedDoubleData(rowIndex, colIndex);
|
||||
} else if(isRemovedData) {
|
||||
return ds.getRemovedDoubleData(rowIndex, colIndex);
|
||||
} else {
|
||||
return ds.getDouble(rowIndex, colIndex);
|
||||
}
|
||||
} else if(boolean.class.equals(targetClass) || Boolean.class.equals(targetClass)) {
|
||||
if(isSavedData) {
|
||||
return ds.getSavedBooleanData(rowIndex, colIndex);
|
||||
} else if(isRemovedData) {
|
||||
return ds.getRemovedBooleanData(rowIndex, colIndex);
|
||||
} else {
|
||||
return ds.getBoolean(rowIndex, colIndex);
|
||||
}
|
||||
} else if(Date.class.equals(targetClass)) {
|
||||
if(isSavedData) {
|
||||
return ds.getSavedDateTimeData(rowIndex, colIndex);
|
||||
} else if(isRemovedData) {
|
||||
return ds.getRemovedDateTimeData(rowIndex, colIndex);
|
||||
} else {
|
||||
return ds.getDateTime(rowIndex, colIndex);
|
||||
}
|
||||
} else if(BigDecimal.class.equals(targetClass)) {
|
||||
if(isSavedData) {
|
||||
return ds.getSavedBigDecimalData(rowIndex, colIndex);
|
||||
} else if(isRemovedData) {
|
||||
return ds.getRemovedBigDecimalData(rowIndex, colIndex);
|
||||
} else {
|
||||
return ds.getBigDecimal(rowIndex, colIndex);
|
||||
}
|
||||
} else if(targetClass.isArray()) {
|
||||
if(byte[].class.equals(targetClass)) {
|
||||
if(isSavedData) {
|
||||
return ds.getSavedBlobData(rowIndex, colIndex);
|
||||
} else if(isRemovedData) {
|
||||
return ds.getRemovedBlobData(rowIndex, colIndex);
|
||||
} else {
|
||||
return ds.getBlob(rowIndex, colIndex);
|
||||
}
|
||||
} else if(Byte[].class.equals(targetClass)) {
|
||||
byte[] blob;
|
||||
if(isSavedData) {
|
||||
blob = ds.getSavedBlobData(rowIndex, colIndex);
|
||||
return toObject(blob);
|
||||
} else if(isRemovedData) {
|
||||
blob = ds.getRemovedBlobData(rowIndex, colIndex);
|
||||
return toObject(blob);
|
||||
} else {
|
||||
blob = ds.getBlob(rowIndex, colIndex);
|
||||
return toObject(blob);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// return object
|
||||
if(isSavedData) {
|
||||
return ds.getSavedData(rowIndex, colIndex);
|
||||
} else if(isRemovedData) {
|
||||
return ds.getRemovedData(rowIndex, colIndex);
|
||||
} else {
|
||||
return ds.getObject(rowIndex, colIndex);
|
||||
}
|
||||
}
|
||||
|
||||
static boolean isSupportedBean(Class clazz) {
|
||||
if(!clazz.isInterface() && !clazz.isPrimitive() && !clazz.isEnum() && !clazz.isArray()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static Map<String, Field> getAdjustConvertibleFields(Class clazz, DataSet ds) {
|
||||
|
||||
Map<String, Field> accessibleFields = getAccessibleFields(clazz);
|
||||
|
||||
Map<String, Field> adjustConvertibleFields = new HashMap<String, Field>();
|
||||
// 획득한 field와 dataset field를 검사하여 실제로 사용될 field 들을 추려둔다.
|
||||
int columnCount = ds.getColumnCount();
|
||||
for(int i=0; i<columnCount; i++) {
|
||||
ColumnHeader column = ds.getColumn(i);
|
||||
String columnName = column.getName();
|
||||
|
||||
// 대소문자를 구별한다!
|
||||
Field field = accessibleFields.get(columnName);
|
||||
if(field != null) {
|
||||
adjustConvertibleFields.put(columnName, field);
|
||||
}
|
||||
}
|
||||
|
||||
return adjustConvertibleFields;
|
||||
|
||||
}
|
||||
|
||||
static Map<String, Field> getAccessibleFields(Class clazz) {
|
||||
|
||||
Map<String, Field> accessibleFields = new HashMap<String, Field>();
|
||||
|
||||
Class<?> searchType = clazz;
|
||||
while (!Object.class.equals(searchType) && searchType != null) {
|
||||
Field[] fields = searchType.getDeclaredFields();
|
||||
for (Field field : fields) {
|
||||
Class<?> type = field.getType();
|
||||
if(isConvertibleType(type)) {
|
||||
ReflectionUtil.makeAccessible(field);
|
||||
accessibleFields.put(field.getName(), field);
|
||||
}
|
||||
}
|
||||
searchType = searchType.getSuperclass();
|
||||
}
|
||||
|
||||
return accessibleFields;
|
||||
}
|
||||
|
||||
static boolean isConvertibleType(Class<?> type) {
|
||||
if(primitiveTypeWrapperMap.get(type) != null) {
|
||||
return true;
|
||||
} else if(nonPrimitiveTypeMap.get(type) != null) {
|
||||
return true;
|
||||
} else if(primitiveTypeWrapperMap.containsValue(type)) {
|
||||
return true;
|
||||
} else if(nonPrimitiveTypeMap.containsValue(type)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* commons.lang.ArrayUtils source*/
|
||||
private static Byte[] toObject(byte[] array) {
|
||||
if (array == null) {
|
||||
return null;
|
||||
} else if (array.length == 0) {
|
||||
return new Byte[0];
|
||||
}
|
||||
final Byte[] result = new Byte[array.length];
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
result[i] = new Byte(array[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static byte[] toPrimitive(Byte[] array) {
|
||||
if (array == null) {
|
||||
return null;
|
||||
} else if (array.length == 0) {
|
||||
return new byte[0];
|
||||
}
|
||||
final byte[] result = new byte[array.length];
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
result[i] = array[i].byteValue();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
package com.nexacro.spring.data.support;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.nexacro.spring.data.convert.ConvertDefinition;
|
||||
import com.nexacro.spring.data.convert.NexacroConvertException;
|
||||
import com.nexacro.spring.data.convert.NexacroConverter;
|
||||
import com.nexacro.xapi.data.DataSet;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Statements
|
||||
* </pre>
|
||||
*
|
||||
* @ClassName : ObjectToDataSetConverter.java
|
||||
* @Description : 클래스 설명을 기술합니다.
|
||||
* @author Park SeongMin
|
||||
* @since 2015. 8. 17.
|
||||
* @version 1.0
|
||||
* @see
|
||||
* @Modification Information
|
||||
* <pre>
|
||||
* since author description
|
||||
* =========== ============= ===========================
|
||||
* 2015. 8. 17. Park SeongMin 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public class ObjectToDataSetConverter extends AbstractDataSetConverter implements NexacroConverter<Object, DataSet> {
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSet convert(Object source, ConvertDefinition definition) throws NexacroConvertException {
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
// DataSet SavedType은 처리 하지 않는다. (UI 처리 불필요)
|
||||
DataSet ds = null;
|
||||
if(source instanceof Map) {
|
||||
ds = convertMapToDataSet((Map)source, definition);
|
||||
} else {
|
||||
ds = convertBeanToDataSet(source, definition);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private DataSet convertBeanToDataSet(Object source, ConvertDefinition definition) throws NexacroConvertException {
|
||||
|
||||
// 지원하는 형식인지 확인 한다.
|
||||
if(!NexacroConverterHelper.isSupportedBean(source.getClass())) {
|
||||
throw new NexacroConvertException("unsupported source type. type="+source.getClass());
|
||||
}
|
||||
|
||||
DataSet ds = new DataSet(definition.getName());
|
||||
addColumnIntoDataSet(ds, source);
|
||||
addRowIntoDataSet(ds, source);
|
||||
return ds;
|
||||
}
|
||||
|
||||
private DataSet convertMapToDataSet(Map source, ConvertDefinition definition) throws NexacroConvertException {
|
||||
DataSet ds = new DataSet(definition.getName());
|
||||
addColumnIntoDataSet(ds, source);
|
||||
addRowIntoDataSet(ds, source);
|
||||
return ds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addColumnIntoDataSet(DataSet ds, Map source) throws NexacroConvertException {
|
||||
super.addColumnIntoDataSet(ds, source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addColumnIntoDataSet(DataSet ds, Object source) {
|
||||
super.addColumnIntoDataSet(ds, source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addRowIntoDataSet(DataSet ds, Map source) throws NexacroConvertException {
|
||||
super.addRowIntoDataSet(ds, source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addRowIntoDataSet(DataSet ds, Object source) {
|
||||
super.addRowIntoDataSet(ds, source);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.nexacro.spring.data.support;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import com.nexacro.spring.data.convert.ConvertDefinition;
|
||||
import com.nexacro.spring.data.convert.NexacroConvertException;
|
||||
import com.nexacro.spring.data.convert.NexacroConverter;
|
||||
import com.nexacro.xapi.data.Variable;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Statements
|
||||
* </pre>
|
||||
*
|
||||
* @ClassName : ObjectToVariableConverter.java
|
||||
* @Description : 클래스 설명을 기술합니다.
|
||||
* @author Park SeongMin
|
||||
* @since 2015. 7. 28.
|
||||
* @version 1.0
|
||||
* @see
|
||||
* @Modification Information
|
||||
* <pre>
|
||||
* since author description
|
||||
* =========== ============= ===========================
|
||||
* 2015. 7. 28. Park SeongMin 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public class ObjectToVariableConverter extends AbstractListenerHandler implements NexacroConverter<Object, Variable> {
|
||||
|
||||
@Override
|
||||
public boolean canConvert(Class source, Class target) {
|
||||
if(source == null || target == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ConvertiblePair comparePair = new ConvertiblePair(source, target);
|
||||
Set<ConvertiblePair> objectToVariableConvertibleTypes = NexacroConverterHelper.getObjectToVariableConvertibleTypes();
|
||||
|
||||
for(ConvertiblePair pair: objectToVariableConvertibleTypes) {
|
||||
if(pair.equals(comparePair)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Variable convert(Object source, ConvertDefinition definition) throws NexacroConvertException {
|
||||
|
||||
Variable variable = NexacroConverterHelper.toVariable(definition.getName(), source);
|
||||
|
||||
// fire event
|
||||
Object obj = fireVariableConvertedValue(variable, variable.getObject());
|
||||
variable.set(obj);
|
||||
|
||||
return variable;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package com.nexacro.spring.data.support;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import com.nexacro.spring.data.convert.ConvertDefinition;
|
||||
import com.nexacro.spring.data.convert.NexacroConvertException;
|
||||
import com.nexacro.spring.data.convert.NexacroConverter;
|
||||
import com.nexacro.xapi.data.Variable;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Statements
|
||||
* </pre>
|
||||
*
|
||||
* @ClassName : VariableToObjectConverter.java
|
||||
* @Description : 클래스 설명을 기술합니다.
|
||||
* @author Park SeongMin
|
||||
* @since 2015. 7. 28.
|
||||
* @version 1.0
|
||||
* @see
|
||||
* @Modification Information
|
||||
* <pre>
|
||||
* since author description
|
||||
* =========== ============= ===========================
|
||||
* 2015. 7. 28. Park SeongMin 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public class VariableToObjectConverter extends AbstractListenerHandler implements NexacroConverter<Variable, Object> {
|
||||
|
||||
@Override
|
||||
public boolean canConvert(Class source, Class target) {
|
||||
if(source == null || target == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ConvertiblePair comparePair = new ConvertiblePair(source, target);
|
||||
Set<ConvertiblePair> variableToObjectConvertibleTypes = NexacroConverterHelper.getVariableToObjectConvertibleTypes();
|
||||
|
||||
for(ConvertiblePair pair: variableToObjectConvertibleTypes) {
|
||||
if(pair.equals(comparePair)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* @see com.nexacro.spring.data.NexacroConverter#convert(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public Object convert(Variable source, ConvertDefinition definition) throws NexacroConvertException {
|
||||
|
||||
Object object = NexacroConverterHelper.toObject(source, definition.getGenericType());
|
||||
|
||||
// fire event
|
||||
object = fireVariableConvertedValue(source, object);
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.nexacro.spring.interceptor;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class ExceptionTracer {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(ExceptionTracer.class);
|
||||
|
||||
public void trace(Exception exception) throws Exception {
|
||||
LOGGER.error(exception.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
8
src/main/java/com/nexacro/spring/package-info.java
Normal file
8
src/main/java/com/nexacro/spring/package-info.java
Normal file
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* @author Park SeongMin
|
||||
*
|
||||
*/
|
||||
package com.nexacro.spring;
|
||||
@@ -0,0 +1,231 @@
|
||||
package com.nexacro.spring.resolve;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.util.StopWatch;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
|
||||
import org.springframework.web.method.support.ModelAndViewContainer;
|
||||
import org.springframework.web.servlet.View;
|
||||
|
||||
import com.nexacro.spring.NexacroConstants;
|
||||
import com.nexacro.spring.data.NexacroFileResult;
|
||||
import com.nexacro.spring.data.NexacroResult;
|
||||
import com.nexacro.spring.data.convert.ConvertDefinition;
|
||||
import com.nexacro.spring.data.convert.NexacroConvertException;
|
||||
import com.nexacro.spring.data.convert.NexacroConverter;
|
||||
import com.nexacro.spring.data.convert.NexacroConverterFactory;
|
||||
import com.nexacro.spring.view.NexacroFileView;
|
||||
import com.nexacro.spring.view.NexacroView;
|
||||
import com.nexacro.xapi.data.DataSet;
|
||||
import com.nexacro.xapi.data.PlatformData;
|
||||
import com.nexacro.xapi.data.Variable;
|
||||
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Controller에서 반환되는 데이터를 nexacro platform 데이터 형식으로 데이터 변환을 수행한다.
|
||||
*
|
||||
* 지원하는 형식은 다음과 같다.
|
||||
*
|
||||
* <li>NexacroResult</li>
|
||||
* <li>NexacroFileResult</li>
|
||||
* <li>PlatformData</li>
|
||||
* </pre>
|
||||
*
|
||||
* @ClassName : NexacroHandlerMethodReturnValueHandler.java
|
||||
* @Description : 클래스 설명을 기술합니다.
|
||||
* @author Park SeongMin
|
||||
* @since 2015. 7. 27.
|
||||
* @version 1.0
|
||||
* @see
|
||||
* @Modification Information
|
||||
* <pre>
|
||||
* since author description
|
||||
* =========== ============= ===========================
|
||||
* 2015. 7. 27. Park SeongMin 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public class NexacroHandlerMethodReturnValueHandler implements HandlerMethodReturnValueHandler {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(NexacroHandlerMethodReturnValueHandler.class);
|
||||
private Logger performanceLogger = LoggerFactory.getLogger(NexacroConstants.PERFORMANCE_LOGGER);
|
||||
|
||||
private View view;
|
||||
private View fileView;
|
||||
|
||||
public View getView() {
|
||||
if(view == null) {
|
||||
return new NexacroView();
|
||||
} else {
|
||||
return view;
|
||||
}
|
||||
}
|
||||
|
||||
public void setView(View view) {
|
||||
this.view = view;
|
||||
}
|
||||
|
||||
public View getFileView() {
|
||||
if(fileView == null) {
|
||||
return new NexacroFileView();
|
||||
} else {
|
||||
return fileView;
|
||||
}
|
||||
}
|
||||
|
||||
public void setFileView(View fileView) {
|
||||
this.fileView = fileView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsReturnType(MethodParameter returnType) {
|
||||
|
||||
Class<?> parameterType = returnType.getParameterType();
|
||||
if(NexacroResult.class.isAssignableFrom(parameterType)) {
|
||||
return true;
|
||||
} else if(PlatformData.class.isAssignableFrom(parameterType)) {
|
||||
return true;
|
||||
} else if(NexacroFileResult.class.isAssignableFrom(parameterType)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleReturnValue(Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer,
|
||||
NativeWebRequest webRequest) throws Exception {
|
||||
|
||||
Class<?> parameterType = returnType.getParameterType();
|
||||
|
||||
if(returnValue == null) {
|
||||
mavContainer.setView(getView());
|
||||
return;
|
||||
}
|
||||
|
||||
View responseView = null;
|
||||
|
||||
StopWatch sw = new StopWatch(getClass().getSimpleName());
|
||||
sw.start("resolve return value");
|
||||
try {
|
||||
if(NexacroResult.class.isAssignableFrom(parameterType)) {
|
||||
// first use platform data
|
||||
NexacroResult nexacroResult = (NexacroResult) returnValue;
|
||||
PlatformData platformData = nexacroResult.getPlatformData();
|
||||
|
||||
// add datasets
|
||||
addDataSetsIntoPlatformData(platformData, nexacroResult);
|
||||
|
||||
// add variables
|
||||
addVariablesIntoPlatformData(platformData, nexacroResult);
|
||||
|
||||
addErrorInformationIntoPlatformData(platformData, nexacroResult);
|
||||
|
||||
// 변환 된 PlatformData 전달.
|
||||
mavContainer.addAttribute(NexacroConstants.ATTRIBUTE.NEXACRO_PLATFORM_DATA, platformData);
|
||||
responseView = getView();
|
||||
|
||||
} else if(PlatformData.class.isAssignableFrom(parameterType)) {
|
||||
PlatformData platformData = (PlatformData) returnValue;
|
||||
mavContainer.addAttribute(NexacroConstants.ATTRIBUTE.NEXACRO_PLATFORM_DATA, platformData);
|
||||
responseView = getView();
|
||||
} else if(NexacroFileResult.class.isAssignableFrom(parameterType)) {
|
||||
NexacroFileResult fileResult = (NexacroFileResult) returnValue;
|
||||
mavContainer.addAttribute(NexacroConstants.ATTRIBUTE.NEXACRO_FILE_DATA, fileResult);
|
||||
responseView = getFileView();
|
||||
} else {
|
||||
// default..
|
||||
responseView = getView();
|
||||
}
|
||||
} catch(Exception e) {
|
||||
logger.error("Error handling return value. value"+returnValue+", e="+e +", message="+e.getMessage());
|
||||
throw e;
|
||||
} finally {
|
||||
sw.stop();
|
||||
if(performanceLogger.isTraceEnabled()) {
|
||||
performanceLogger.trace(sw.prettyPrint());
|
||||
}
|
||||
}
|
||||
|
||||
mavContainer.setView(responseView);
|
||||
|
||||
}
|
||||
|
||||
private void addDataSetsIntoPlatformData(PlatformData platformData, NexacroResult nexacroResult) throws NexacroConvertException {
|
||||
|
||||
Map<String, List> dataSets = nexacroResult.getDataSets();
|
||||
Set<String> dataSetKeySet = dataSets.keySet();
|
||||
for(String name: dataSetKeySet) {
|
||||
List list = dataSets.get(name);
|
||||
NexacroConverter dataSetConverter = getDataSetConverter(list.getClass());
|
||||
|
||||
ConvertDefinition definition = new ConvertDefinition(name);
|
||||
Object convert = dataSetConverter.convert(list, definition);
|
||||
|
||||
if(convert != null && convert instanceof DataSet) {
|
||||
platformData.addDataSet((DataSet) convert);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addVariablesIntoPlatformData(PlatformData platformData, NexacroResult nexacroResult) throws NexacroConvertException {
|
||||
|
||||
Map<String, Object> variables = nexacroResult.getVariables();
|
||||
Set<String> variableKeySets = variables.keySet();
|
||||
for(String name: variableKeySets) {
|
||||
Object object = variables.get(name);
|
||||
NexacroConverter variableConverter = getVariableConverter(object.getClass());
|
||||
|
||||
ConvertDefinition definition = new ConvertDefinition(name);
|
||||
Object convert = variableConverter.convert(object, definition);
|
||||
|
||||
if(convert != null && convert instanceof Variable) {
|
||||
platformData.addVariable((Variable) convert);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Statements
|
||||
*
|
||||
* @param platformData
|
||||
* @param nexacroResult
|
||||
*/
|
||||
private void addErrorInformationIntoPlatformData(PlatformData platformData, NexacroResult nexacroResult) {
|
||||
|
||||
// result status
|
||||
if(nexacroResult.registedErrorCode()) {
|
||||
int errorCode = nexacroResult.getErrorCode();
|
||||
String errorMsg = nexacroResult.getErrorMsg();
|
||||
|
||||
platformData.addVariable(Variable.createVariable(NexacroConstants.ERROR.ERROR_CODE, errorCode));
|
||||
platformData.addVariable(Variable.createVariable(NexacroConstants.ERROR.ERROR_MSG, errorMsg));
|
||||
} else {
|
||||
if(platformData.getVariable(NexacroConstants.ERROR.ERROR_CODE) == null) {
|
||||
// binary 통신 시 반드시 필요.
|
||||
platformData.addVariable(Variable.createVariable(NexacroConstants.ERROR.ERROR_CODE, NexacroConstants.ERROR.DEFAULT_ERROR_CODE));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private NexacroConverter getDataSetConverter(Class source) {
|
||||
return getConverter(source, DataSet.class);
|
||||
}
|
||||
|
||||
private NexacroConverter getVariableConverter(Class source) {
|
||||
return getConverter(source, Variable.class);
|
||||
}
|
||||
|
||||
private NexacroConverter getConverter(Class source, Class target) {
|
||||
return NexacroConverterFactory.getConverter(source, target);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,383 @@
|
||||
package com.nexacro.spring.resolve;
|
||||
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.util.StopWatch;
|
||||
import org.springframework.web.bind.support.WebDataBinderFactory;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
import org.springframework.web.context.request.RequestAttributes;
|
||||
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||
import org.springframework.web.method.support.ModelAndViewContainer;
|
||||
|
||||
import com.nexacro.spring.NexacroConstants;
|
||||
import com.nexacro.spring.annotation.ParamDataSet;
|
||||
import com.nexacro.spring.annotation.ParamVariable;
|
||||
import com.nexacro.spring.data.NexacroFirstRowHandler;
|
||||
import com.nexacro.spring.data.convert.ConvertDefinition;
|
||||
import com.nexacro.spring.data.convert.NexacroConvertException;
|
||||
import com.nexacro.spring.data.convert.NexacroConvertListener;
|
||||
import com.nexacro.spring.data.convert.NexacroConverter;
|
||||
import com.nexacro.spring.data.convert.NexacroConverterFactory;
|
||||
import com.nexacro.spring.servlet.NexacroContext;
|
||||
import com.nexacro.spring.servlet.NexacroContextHolder;
|
||||
import com.nexacro.xapi.data.DataSet;
|
||||
import com.nexacro.xapi.data.DataSetList;
|
||||
import com.nexacro.xapi.data.PlatformData;
|
||||
import com.nexacro.xapi.data.Variable;
|
||||
import com.nexacro.xapi.data.VariableList;
|
||||
import com.nexacro.xapi.tx.HttpPlatformRequest;
|
||||
import com.nexacro.xapi.tx.HttpPlatformResponse;
|
||||
import com.nexacro.xapi.tx.PlatformException;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* <pre>
|
||||
* Nexacro platform을 위한 <code>HandlerMethodArgumentResolver</code>이다.
|
||||
*
|
||||
* 지원하는 형식은 다음과 같다.
|
||||
*
|
||||
* ...
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @ClassName : NexacroMethodArgumnetResolver.java
|
||||
* @author Park SeongMin
|
||||
* @since 2015. 7. 27.
|
||||
* @version 1.0
|
||||
* @see NexacroHandlerMethodReturnValueHandler
|
||||
* @Modification Information
|
||||
*
|
||||
* <pre>
|
||||
* since author description
|
||||
* =========== ============= ===========================
|
||||
* 2015. 7. 27. Park SeongMin 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
public class NexacroMethodArgumentResolver implements HandlerMethodArgumentResolver {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(NexacroMethodArgumentResolver.class);
|
||||
private Logger performanceLogger = LoggerFactory.getLogger(NexacroConstants.PERFORMANCE_LOGGER);
|
||||
|
||||
// convert에서 사용가능한 event listener를 등록할 수 있어야 한다.
|
||||
private static final Map<Class<?>, Object> primitiveTypeDefaultValueMap = new HashMap<Class<?>, Object>(8);
|
||||
|
||||
private List<NexacroConvertListener> convertListeners;
|
||||
|
||||
static {
|
||||
primitiveTypeDefaultValueMap.put(byte.class, 0);
|
||||
primitiveTypeDefaultValueMap.put(short.class, 0);
|
||||
primitiveTypeDefaultValueMap.put(int.class, 0);
|
||||
primitiveTypeDefaultValueMap.put(long.class, 0l);
|
||||
primitiveTypeDefaultValueMap.put(float.class, 0.0f);
|
||||
primitiveTypeDefaultValueMap.put(double.class, 0.0d);
|
||||
primitiveTypeDefaultValueMap.put(char.class, '\u0000');
|
||||
primitiveTypeDefaultValueMap.put(boolean.class, false);
|
||||
}
|
||||
|
||||
public NexacroMethodArgumentResolver() {
|
||||
if(logger.isDebugEnabled()) {
|
||||
logger.debug("NexacroMethodArgumnetResolver() " + this);
|
||||
}
|
||||
}
|
||||
|
||||
public void setConvertListeners(List<NexacroConvertListener> convertListeners) {
|
||||
this.convertListeners = convertListeners;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsParameter(MethodParameter param) {
|
||||
if(isDefaultParameter(param)) {
|
||||
return true;
|
||||
} else if(isExtendedParameter(param)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isDefaultParameter(MethodParameter param) {
|
||||
Class paramClass = param.getParameterType();
|
||||
if(PlatformData.class.equals(paramClass)) {
|
||||
return true;
|
||||
} else if(DataSetList.class.equals(paramClass)) {
|
||||
return true;
|
||||
} else if(VariableList.class.equals(paramClass)) {
|
||||
return true;
|
||||
} else if(HttpPlatformRequest.class.equals(paramClass)) {
|
||||
return true;
|
||||
} else if(HttpPlatformResponse.class.equals(paramClass)) {
|
||||
return true;
|
||||
} else if(NexacroFirstRowHandler.class.equals(paramClass)) {
|
||||
return true;
|
||||
} else {
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isExtendedParameter(MethodParameter param) {
|
||||
if(param.getParameterAnnotation(ParamDataSet.class) != null) {
|
||||
return true;
|
||||
} else if(param.getParameterAnnotation(ParamVariable.class) != null) {
|
||||
return true;
|
||||
} else {
|
||||
// nothing.
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object resolveArgument(MethodParameter param, ModelAndViewContainer arg1, NativeWebRequest nativeWebRequest,
|
||||
WebDataBinderFactory arg3) throws Exception {
|
||||
|
||||
NexacroContext nexacroCachedData = prepareResolveArguments(nativeWebRequest);
|
||||
|
||||
StopWatch sw = new StopWatch(getClass().getSimpleName());
|
||||
sw.start("resolve argument (" +param.getParameterName()+ ")");
|
||||
|
||||
Object obj = null;
|
||||
try {
|
||||
|
||||
if(isDefaultParameter(param)) {
|
||||
obj = extractDefaultParameter(param, nexacroCachedData);
|
||||
} else {
|
||||
obj = extractExtendedParameter(param, nexacroCachedData);
|
||||
}
|
||||
} finally {
|
||||
sw.stop();
|
||||
if(performanceLogger.isTraceEnabled()) {
|
||||
performanceLogger.trace(sw.prettyPrint());
|
||||
}
|
||||
}
|
||||
|
||||
obj = postResolveArguments(param, obj);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 데이터 변환을 수행하기 전 Request로 부터 Platform 데이터로의 변환을 수행한다.
|
||||
* </pre>
|
||||
*
|
||||
* @param nativeWebRequest
|
||||
* @return NexacroCachedData
|
||||
* @throws PlatformException
|
||||
*/
|
||||
private NexacroContext prepareResolveArguments(NativeWebRequest nativeWebRequest) throws PlatformException {
|
||||
NexacroContext cache = (NexacroContext) parsePlatformRequestOrGetAttribute(nativeWebRequest);
|
||||
return cache;
|
||||
}
|
||||
|
||||
private Object postResolveArguments(MethodParameter param, Object resolvedObject) {
|
||||
|
||||
if(resolvedObject != null) {
|
||||
return resolvedObject;
|
||||
}
|
||||
|
||||
// primitive type의 경우 해당 데이터 타입으로 전달해야 한다.
|
||||
// null로 전달할 경우 IllegalArgumentException이 발생한다.
|
||||
Class<?> parameterType = param.getParameterType();
|
||||
if(primitiveTypeDefaultValueMap.containsKey(parameterType)) {
|
||||
return primitiveTypeDefaultValueMap.get(parameterType);
|
||||
}
|
||||
|
||||
return resolvedObject;
|
||||
}
|
||||
|
||||
private Object extractDefaultParameter(MethodParameter param, NexacroContext nexacroCachedData) {
|
||||
|
||||
Class<?> parameterType = param.getParameterType();
|
||||
|
||||
if(PlatformData.class.equals(parameterType)) {
|
||||
return nexacroCachedData.getPlatformData();
|
||||
} else if(DataSetList.class.equals(parameterType)) {
|
||||
return nexacroCachedData.getPlatformData().getDataSetList();
|
||||
} else if(VariableList.class.equals(parameterType)) {
|
||||
return nexacroCachedData.getPlatformData().getVariableList();
|
||||
} else if(HttpPlatformRequest.class.equals(parameterType)) {
|
||||
return nexacroCachedData.getPlatformRequest();
|
||||
} else if(HttpPlatformResponse.class.equals(parameterType)) {
|
||||
return nexacroCachedData.getPlatformResponse();
|
||||
} else if(NexacroFirstRowHandler.class.equals(parameterType)) {
|
||||
return nexacroCachedData.getFirstRowHandler();
|
||||
} else {
|
||||
// nothing.
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private Object extractExtendedParameter(MethodParameter param, NexacroContext nexacroCachedData) throws NexacroConvertException {
|
||||
|
||||
if(param.getParameterAnnotation(ParamDataSet.class) != null) {
|
||||
return extractDataSetParameter(param, nexacroCachedData);
|
||||
} else if(param.getParameterAnnotation(ParamVariable.class) != null) {
|
||||
return extractVariableParameter(param, nexacroCachedData);
|
||||
} else {
|
||||
// nothing.
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Object extractDataSetParameter(MethodParameter param, NexacroContext nexacroCachedData) throws NexacroConvertException {
|
||||
|
||||
Class<?> parameterType = param.getParameterType();
|
||||
ParamDataSet paramDataSet = param.getParameterAnnotation(ParamDataSet.class);
|
||||
|
||||
String dsName = paramDataSet.name();
|
||||
DataSet dataSet = nexacroCachedData.getPlatformData().getDataSet(dsName);
|
||||
if(dataSet == null) {
|
||||
if(logger.isDebugEnabled()) {
|
||||
logger.debug(dsName + " is null.");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// return dataset
|
||||
if(DataSet.class.equals(parameterType)) {
|
||||
return dataSet;
|
||||
}
|
||||
|
||||
// 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) {
|
||||
// Generic이 null 일 경우에 Map으로 할지? 혹은 바로 오류를 내보낼지 처리 하도록 하자.
|
||||
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);
|
||||
if(converter == null) {
|
||||
throw new IllegalArgumentException("invalid @ParamDataSet. supported type={DataSet, List<?>}");
|
||||
}
|
||||
|
||||
try {
|
||||
addConvertListeners(converter);
|
||||
return converter.convert(dataSet, definition);
|
||||
} finally {
|
||||
removeConvertListeners(converter);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Object extractVariableParameter(MethodParameter param, NexacroContext nexacroCachedData) throws NexacroConvertException {
|
||||
|
||||
Class<?> parameterType = param.getParameterType();
|
||||
// support only list parameter
|
||||
|
||||
ParamVariable paramVariable = param.getParameterAnnotation(ParamVariable.class);
|
||||
String varName = paramVariable.name();
|
||||
Variable variable = nexacroCachedData.getPlatformData().getVariable(varName);
|
||||
if(variable == null) {
|
||||
if(logger.isDebugEnabled()) {
|
||||
logger.debug(varName + " is null.");
|
||||
}
|
||||
return null;
|
||||
//throw new IllegalArgumentException("invalid @ParamVariable. ex)@ParamVariable(name=\"variableName\") Object var");
|
||||
}
|
||||
|
||||
// reutrn variable
|
||||
if(Variable.class.equals(parameterType)) {
|
||||
return variable;
|
||||
}
|
||||
|
||||
Class<?> fromType = Variable.class;
|
||||
Class<?> toType = parameterType;
|
||||
NexacroConverter<Variable, Object> converter = NexacroConverterFactory.getConverter(fromType, toType);
|
||||
if(converter == null) {
|
||||
throw new IllegalArgumentException("invalid @ParamVariable. supported type={Variable, Object, String, int, boolean, long, float, double, BigDecimal, Date, byte[]} ");
|
||||
}
|
||||
|
||||
ConvertDefinition definition = new ConvertDefinition(varName);
|
||||
definition.setGenericType(parameterType);
|
||||
|
||||
try {
|
||||
addConvertListeners(converter);
|
||||
return converter.convert(variable, definition);
|
||||
} finally {
|
||||
removeConvertListeners(converter);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private Class findGenericType(MethodParameter param) {
|
||||
|
||||
Type genericParameterType = param.getGenericParameterType();
|
||||
if (genericParameterType instanceof ParameterizedType) {
|
||||
Type[] types = ((ParameterizedType) genericParameterType).getActualTypeArguments();
|
||||
return (Class) types[0];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private Object getAttribute(NativeWebRequest nativeWebRequest, String attrName) {
|
||||
return nativeWebRequest.getAttribute(attrName, RequestAttributes.SCOPE_REQUEST);
|
||||
}
|
||||
|
||||
private void setAttribute(NativeWebRequest nativeWebRequest, String attrName, Object obj) {
|
||||
nativeWebRequest.setAttribute(attrName, obj, RequestAttributes.SCOPE_REQUEST);
|
||||
}
|
||||
|
||||
/**
|
||||
* NexacroPlatform 형식의 Cache 데이터를 반환 한다.
|
||||
*
|
||||
* @return
|
||||
* @throws PlatformException
|
||||
*/
|
||||
private NexacroContext parsePlatformRequestOrGetAttribute(NativeWebRequest nativeWebRequest) throws PlatformException {
|
||||
|
||||
// when already parsed. ex - methodArgumentResolver or interceptor
|
||||
NexacroContext cache = NexacroContextHolder.getNexacroContext();
|
||||
if(cache != null) {
|
||||
return cache;
|
||||
}
|
||||
|
||||
HttpServletRequest servletRequest = (HttpServletRequest) nativeWebRequest.getNativeRequest();
|
||||
HttpServletResponse servletResponse = (HttpServletResponse) nativeWebRequest.getNativeResponse();
|
||||
|
||||
cache = NexacroContextHolder.getNexacroContext(servletRequest, servletResponse);
|
||||
return cache;
|
||||
}
|
||||
|
||||
private void addConvertListeners(NexacroConverter converter) {
|
||||
if(this.convertListeners == null) {
|
||||
return;
|
||||
}
|
||||
for(NexacroConvertListener listener: this.convertListeners) {
|
||||
converter.addListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
private void removeConvertListeners(NexacroConverter converter) {
|
||||
if(this.convertListeners == null) {
|
||||
return;
|
||||
}
|
||||
for(NexacroConvertListener listener: this.convertListeners) {
|
||||
converter.removeListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package com.nexacro.spring.resolve;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import org.springframework.web.servlet.View;
|
||||
import org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver;
|
||||
|
||||
import com.nexacro.spring.NexacroException;
|
||||
import com.nexacro.spring.util.NexacroUtil;
|
||||
import com.nexacro.spring.view.NexacroModelAndView;
|
||||
import com.nexacro.spring.view.NexacroView;
|
||||
|
||||
public class NexcroMappingExceptionResolver extends AbstractHandlerExceptionResolver {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(NexcroMappingExceptionResolver.class);
|
||||
|
||||
private View view;
|
||||
|
||||
public View getView() {
|
||||
if(view == null) {
|
||||
return new NexacroView();
|
||||
} else {
|
||||
return view;
|
||||
}
|
||||
}
|
||||
|
||||
public void setView(View view) {
|
||||
this.view = view;
|
||||
}
|
||||
|
||||
public NexcroMappingExceptionResolver() {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
|
||||
|
||||
// nexacro 요청이 아닌 경우 별도 ExceptionResolver 가 처리 할 수 있도록 null을 반환 한다.
|
||||
if(NexacroUtil.isNexacroRequest(request)) {
|
||||
|
||||
// for able framework
|
||||
prepareResolveException(request, response, handler, ex);
|
||||
|
||||
// Nexacro Exception 만을 handling 하도록 한다.
|
||||
// for nexacro request
|
||||
NexacroModelAndView mav = new NexacroModelAndView(getView());
|
||||
|
||||
if(ex instanceof NexacroException){ // NexacroConvertException
|
||||
NexacroException nexaExp = (NexacroException) ex;
|
||||
mav.setErrorCode(nexaExp.getErrorCode());
|
||||
mav.setErrorMsg(nexaExp.getErrorMsg());
|
||||
} else {
|
||||
// PlatformException..
|
||||
mav.setErrorCode(NexacroException.DEFAULT_ERROR_CODE); //Undefined error Code
|
||||
// mav.setErrorMsg(NexacroException.DEFAULT_MESSAGE);
|
||||
mav.setErrorMsg(ex.toString());
|
||||
}
|
||||
|
||||
return mav;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void prepareResolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
|
||||
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("Resolving exception from handler [" + handler + "]: " + ex);
|
||||
}
|
||||
|
||||
logException(ex, request);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package com.nexacro.spring.security;
|
||||
|
||||
import com.nexacro.spring.data.convert.ConvertEvent;
|
||||
import com.nexacro.spring.data.convert.NexacroConvertListener;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Statements
|
||||
* </pre>
|
||||
*
|
||||
* @ClassName : WebSecurityListener.java
|
||||
* @Description : 클래스 설명을 기술합니다.
|
||||
* @author Park SeongMin
|
||||
* @since 2015. 8. 9.
|
||||
* @version 1.0
|
||||
* @see
|
||||
* @Modification Information
|
||||
* <pre>
|
||||
* since author description
|
||||
* =========== ============= ===========================
|
||||
* 2015. 8. 9. Park SeongMin 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public class NexacroWebSecurityListener implements NexacroConvertListener {
|
||||
|
||||
@Override
|
||||
public void convertedValue(ConvertEvent event) {
|
||||
|
||||
if(event == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// security
|
||||
checkSecurity(event);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Statements
|
||||
*
|
||||
* @param event
|
||||
* @throws Exception
|
||||
*/
|
||||
private void checkSecurity(ConvertEvent event) {
|
||||
|
||||
Object value = event.getValue();
|
||||
|
||||
if(value == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
String strValue = value.toString();
|
||||
try {
|
||||
SecurityUtil.checkPathTraversal(strValue);
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
|
||||
String convertXSS = SecurityUtil.convertXSS(strValue);
|
||||
|
||||
if(!strValue.equals(convertXSS)) {
|
||||
event.setValue(value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
186
src/main/java/com/nexacro/spring/security/SecurityUtil.java
Normal file
186
src/main/java/com/nexacro/spring/security/SecurityUtil.java
Normal file
@@ -0,0 +1,186 @@
|
||||
package com.nexacro.spring.security;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.nexacro.xapi.data.DataSet;
|
||||
import com.nexacro.xapi.data.DataSetList;
|
||||
import com.nexacro.xapi.data.PlatformData;
|
||||
import com.nexacro.xapi.data.Variable;
|
||||
import com.nexacro.xapi.data.VariableList;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Statements
|
||||
* </pre>
|
||||
*
|
||||
* @ClassName : SecurityUtil.java
|
||||
* @Description : 클래스 설명을 기술합니다.
|
||||
* @author Park SeongMin
|
||||
* @since 2015. 8. 11.
|
||||
* @version 1.0
|
||||
* @see
|
||||
* @Modification Information
|
||||
*
|
||||
* <pre>
|
||||
* since author description
|
||||
* =========== ============= ===========================
|
||||
* 2015. 8. 11. Park SeongMin 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public abstract class SecurityUtil {
|
||||
|
||||
public static void checkSecurity(PlatformData platformData) throws SecurityException {
|
||||
|
||||
VariableList variableList = platformData.getVariableList();
|
||||
int size = variableList.size();
|
||||
for(int i=0; i<size; i++) {
|
||||
Variable variable = variableList.get(i);
|
||||
checkSecurity(variable);
|
||||
}
|
||||
|
||||
|
||||
DataSetList dataSetList = platformData.getDataSetList();
|
||||
size = dataSetList.size();
|
||||
for(int i=0; i<size; i++) {
|
||||
DataSet ds = dataSetList.get(i);
|
||||
checkSecurity(ds);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void checkSecurity(Variable variable) throws SecurityException {
|
||||
|
||||
String value = null;
|
||||
try {
|
||||
value = variable.getString();
|
||||
} catch(Exception e) {
|
||||
// ignore
|
||||
return;
|
||||
}
|
||||
|
||||
checkPathTraversal(value);
|
||||
// convert xss
|
||||
String convertedValue = convertXSS(value);
|
||||
if(value != null && !value.equals(convertedValue)) {
|
||||
variable.set(convertedValue);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void checkSecurity(DataSet ds) throws SecurityException {
|
||||
|
||||
int rowCount = ds.getRowCount();
|
||||
int colCount = ds.getColumnCount();
|
||||
for(int rowIndex=0; rowIndex<rowCount; rowIndex++) {
|
||||
|
||||
boolean hasSavedRow = ds.hasSavedRow(rowIndex);
|
||||
for(int colIndex=0; colIndex<colCount; colIndex++) {
|
||||
|
||||
String value = ds.getString(rowIndex, colIndex);
|
||||
|
||||
checkPathTraversal(value);
|
||||
// convert xss
|
||||
String convertedValue = convertXSS(value);
|
||||
|
||||
if(value != null && !value.equals(convertedValue)) {
|
||||
ds.set(rowIndex, colIndex, value);
|
||||
}
|
||||
|
||||
// saved data..
|
||||
if(hasSavedRow) {
|
||||
value = ds.getSavedStringData(rowIndex, colIndex);
|
||||
|
||||
checkPathTraversal(value);
|
||||
// convert xss
|
||||
convertedValue = convertXSS(value);
|
||||
|
||||
if(value != null && !value.equals(convertedValue)) {
|
||||
ds.setSavedData(rowIndex, colIndex, convertedValue);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // end data
|
||||
|
||||
int removedCount = ds.getRemovedRowCount();
|
||||
for(int removedIndex=0; removedIndex<removedCount; removedIndex++) {
|
||||
|
||||
for(int colIndex=0; colIndex<colCount; colIndex++) {
|
||||
String value = null;
|
||||
try {
|
||||
value = ds.getRemovedStringData(removedIndex, colIndex);
|
||||
} catch(Exception e) {
|
||||
// ignore
|
||||
continue;
|
||||
}
|
||||
|
||||
checkPathTraversal(value);
|
||||
// convert xss
|
||||
String convertedValue = convertXSS(value);
|
||||
|
||||
if(value != null && !value.equals(convertedValue)) {
|
||||
ds.setRemovedData(removedIndex, colIndex, convertedValue);
|
||||
}
|
||||
|
||||
}
|
||||
} // end removed data
|
||||
|
||||
}
|
||||
|
||||
public static void checkUploadFileExt(String fileName) throws SecurityException {
|
||||
|
||||
if(fileName == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Map<String, String> securityResult = new HashMap<String, String>();
|
||||
// // check file extention
|
||||
// securityResult = WebSecurityUtil.uploadFileExtCheck(fileName, "uploadExt");
|
||||
// if ("true".equals(securityResult.get("result"))) {
|
||||
// throw new SecurityException("Web Security Violation " + ((String)securityResult.get("securitySort")) + ", Violation Char:: ' " + ((String)securityResult.get("violationChar")) + "'");
|
||||
// }
|
||||
//
|
||||
// // check file upload detour
|
||||
// securityResult = WebSecurityUtil.uploadFileExtCheck(fileName, "uploadDetour");
|
||||
// if ("true".equals(securityResult.get("result"))) {
|
||||
// throw new SecurityException("Web Security Violation : " + ((String)securityResult.get("securitySort")) + ", Violation Char:: ' " + ((String)securityResult.get("violationChar")) + "'");
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
public static void checkPathTraversal(String value) throws SecurityException {
|
||||
|
||||
if(value == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// check path traversal attack..
|
||||
Map<String, String> securityResult = new HashMap<String, String>();
|
||||
// try {
|
||||
// securityResult = WebSecurityUtil.checkDownloadParams(value);
|
||||
// } catch (UnsupportedEncodingException e) {
|
||||
// // logging..
|
||||
// throw new SecurityException("encoding format does not support. value="+value, e);
|
||||
// }
|
||||
|
||||
if ("true".equals(securityResult.get("result"))) {
|
||||
// logging..
|
||||
|
||||
throw new SecurityException("Web Security Violation : " + ((String) securityResult.get("securitySort"))
|
||||
+ ", Violation Char:: ' " + ((String) securityResult.get("violationChar")) + "'");
|
||||
}
|
||||
}
|
||||
|
||||
public static String convertXSS(String value) {
|
||||
if(value == null) {
|
||||
return null;
|
||||
}
|
||||
String convertedValue = value;
|
||||
// String convertedValue = WebSecurityUtil.convertXSSParam(value);
|
||||
return convertedValue;
|
||||
}
|
||||
|
||||
}
|
||||
165
src/main/java/com/nexacro/spring/servlet/NexacroContext.java
Normal file
165
src/main/java/com/nexacro/spring/servlet/NexacroContext.java
Normal file
@@ -0,0 +1,165 @@
|
||||
package com.nexacro.spring.servlet;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import com.nexacro.spring.data.NexacroFirstRowHandler;
|
||||
import com.nexacro.spring.util.CharsetUtil;
|
||||
import com.nexacro.xapi.data.PlatformData;
|
||||
import com.nexacro.xapi.tx.HttpPlatformRequest;
|
||||
import com.nexacro.xapi.tx.HttpPlatformResponse;
|
||||
import com.nexacro.xapi.tx.PlatformException;
|
||||
import com.nexacro.xapi.tx.PlatformType;
|
||||
import com.nexacro.xapi.util.StringUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* <pre>
|
||||
* cache 데이터
|
||||
* </pre>
|
||||
*
|
||||
* @ClassName : NexacroCachedData.java
|
||||
* @Description : cache 데이터
|
||||
* @author Park SeongMin
|
||||
* @since 2015. 7. 28.
|
||||
* @version 1.0
|
||||
* @see
|
||||
* @Modification Information
|
||||
* <pre>
|
||||
* since author description
|
||||
* =========== ============= ===========================
|
||||
* 2015. 7. 28. Park SeongMin 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
public class NexacroContext {
|
||||
|
||||
/* 데이터 수신시 HTTP GET 데이터 등록 여부의 키 */
|
||||
private static final String REGISTER_GET_PARAMETER = "http.getparameter.register";
|
||||
/* HTTP GET 데이터 등록시 Variable 형식으로 변환 여부의 키 */
|
||||
private static final String GET_PARAMETER_AS_VARIABLE = "http.getparameter.asvariable";
|
||||
|
||||
private HttpServletRequest request;
|
||||
private HttpServletResponse response;
|
||||
|
||||
private HttpPlatformRequest platformRequest;
|
||||
private HttpPlatformResponse platformResponse;
|
||||
|
||||
private NexacroFirstRowHandler firstRowHandler;
|
||||
|
||||
public NexacroContext(HttpServletRequest request, HttpServletResponse response) throws PlatformException {
|
||||
parseRequest(request, response);
|
||||
}
|
||||
|
||||
private void parseRequest(HttpServletRequest request, HttpServletResponse response) throws PlatformException {
|
||||
|
||||
this.request = request;
|
||||
this.response = response;
|
||||
|
||||
InputStream inputStream = null;
|
||||
try {
|
||||
inputStream = request.getInputStream();
|
||||
} catch (IOException e) {
|
||||
throw new PlatformException("Could not get HTTP InputStream", e);
|
||||
}
|
||||
|
||||
String charsetOfRequest = CharsetUtil.getCharsetOfRequest(request, PlatformType.DEFAULT_CHAR_SET);
|
||||
|
||||
String httpContentType = request.getContentType();
|
||||
String userAgent = request.getHeader("User-Agent");
|
||||
String contentType = findContentType(httpContentType, userAgent);
|
||||
|
||||
// SSV 자동처리를 위해 inputStream을 사용하도록 한다.
|
||||
HttpPlatformRequest httpPlatformRequest = new HttpPlatformRequest(inputStream);
|
||||
if(PlatformType.HTTP_CONTENT_TYPE_BINARY.equals(httpContentType)) {
|
||||
httpPlatformRequest.setContentType(contentType);
|
||||
}
|
||||
httpPlatformRequest.receiveData();
|
||||
// SSV 일 경우에만 contentType 존재. 그 외 처리를 위해 설정.
|
||||
if(httpPlatformRequest.getContentType() == null) {
|
||||
httpPlatformRequest.setContentType(contentType);
|
||||
}
|
||||
|
||||
HttpPlatformResponse httpPlatformResponse = new HttpPlatformResponse(response, httpPlatformRequest);
|
||||
|
||||
this.platformRequest = httpPlatformRequest;
|
||||
this.platformResponse = httpPlatformResponse;
|
||||
|
||||
}
|
||||
|
||||
public HttpPlatformRequest getPlatformRequest() {
|
||||
return platformRequest;
|
||||
}
|
||||
|
||||
public HttpPlatformResponse getPlatformResponse() {
|
||||
if(platformResponse != null) {
|
||||
return platformResponse;
|
||||
}
|
||||
platformResponse = new HttpPlatformResponse(response, platformRequest);
|
||||
return platformResponse;
|
||||
}
|
||||
|
||||
public NexacroFirstRowHandler getFirstRowHandler() {
|
||||
if(firstRowHandler != null) {
|
||||
return firstRowHandler;
|
||||
}
|
||||
|
||||
firstRowHandler = new NexacroFirstRowHandler(response, platformRequest);
|
||||
|
||||
return firstRowHandler;
|
||||
}
|
||||
|
||||
public boolean isFirstRowFired() {
|
||||
if(firstRowHandler != null) {
|
||||
return firstRowHandler.isFirstRowStarted();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public PlatformData getPlatformData() {
|
||||
return this.platformRequest != null ? this.platformRequest.getData(): null;
|
||||
}
|
||||
|
||||
/* HTTP의 ContentType으로부터 송수신 형식을 검색한다. */
|
||||
String findContentType(String httpContentType, String userAgent) {
|
||||
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
|
||||
|
||||
if (StringUtils.isEmpty(httpContentType)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int index = httpContentType.indexOf(';');
|
||||
String contentType = (index == -1) ? httpContentType : httpContentType.substring(0, index);
|
||||
|
||||
if (PlatformType.HTTP_CONTENT_TYPE_XML.equals(contentType)) {
|
||||
if (isMiPlatform(userAgent)) {
|
||||
return PlatformType.CONTENT_TYPE_MI_XML;
|
||||
} else {
|
||||
return PlatformType.CONTENT_TYPE_XML;
|
||||
}
|
||||
} else if (PlatformType.HTTP_CONTENT_TYPE_BINARY.equals(contentType)) {
|
||||
if (isMiPlatform(userAgent)) {
|
||||
return PlatformType.CONTENT_TYPE_MI_BINARY;
|
||||
} else {
|
||||
return PlatformType.CONTENT_TYPE_BINARY;
|
||||
}
|
||||
} else if (PlatformType.HTTP_CONTENT_TYPE_HTML.equals(contentType)) {
|
||||
return PlatformType.CONTENT_TYPE_HTML;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/* MiPlatform 여부 */
|
||||
private boolean isMiPlatform(String userAgent) {
|
||||
// MiPlatform 3.1;win32;1400x1050
|
||||
if (userAgent == null) {
|
||||
return false;
|
||||
} else {
|
||||
return (userAgent.startsWith("MiPlatform"));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.nexacro.spring.servlet;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.web.context.request.RequestAttributes;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
|
||||
import com.nexacro.spring.NexacroConstants;
|
||||
import com.nexacro.xapi.tx.PlatformException;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 현재 Thread 단위의 Web 요청에 대한 Nexacro Platform 데이터를 가진다.
|
||||
* </pre>
|
||||
*
|
||||
* @ClassName : NexacroContextHolder.java
|
||||
* @author Park SeongMin
|
||||
* @since 2015. 8. 11.
|
||||
* @version 1.0
|
||||
* @see
|
||||
* @Modification Information
|
||||
* <pre>
|
||||
* since author description
|
||||
* =========== ============= ===========================
|
||||
* 2015. 8. 11. Park SeongMin 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public abstract class NexacroContextHolder {
|
||||
|
||||
public static NexacroContext getNexacroContext(HttpServletRequest request, HttpServletResponse response) throws PlatformException {
|
||||
NexacroContext nexacroContext = new NexacroContext(request, response);
|
||||
RequestContextHolder.getRequestAttributes().setAttribute(NexacroConstants.ATTRIBUTE.NEXACRO_REQUEST, NexacroConstants.ATTRIBUTE.NEXACRO_REQUEST, RequestAttributes.SCOPE_REQUEST);
|
||||
setNexacroContext(nexacroContext);
|
||||
return nexacroContext;
|
||||
}
|
||||
|
||||
public static void setNexacroContext(NexacroContext context) {
|
||||
RequestContextHolder.getRequestAttributes().setAttribute(NexacroConstants.ATTRIBUTE.NEXACRO_CACHE_DATA, context, RequestAttributes.SCOPE_REQUEST);
|
||||
}
|
||||
|
||||
public static NexacroContext getNexacroContext() {
|
||||
Object context = RequestContextHolder.getRequestAttributes().getAttribute(NexacroConstants.ATTRIBUTE.NEXACRO_CACHE_DATA, RequestAttributes.SCOPE_REQUEST);
|
||||
if(context == null) {
|
||||
return null;
|
||||
}
|
||||
if(context instanceof NexacroContext) {
|
||||
return (NexacroContext) context;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
package com.nexacro.spring.servlet;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.util.StopWatch;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
|
||||
|
||||
import com.nexacro.spring.NexacroConstants;
|
||||
import com.nexacro.xapi.data.Debugger;
|
||||
import com.nexacro.xapi.data.PlatformData;
|
||||
import com.nexacro.xapi.tx.HttpPlatformRequest;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Statements
|
||||
* </pre>
|
||||
*
|
||||
* @ClassName : NexacroWebSecurityInterceptor.java
|
||||
* @Description : 클래스 설명을 기술합니다.
|
||||
* @author Park SeongMin
|
||||
* @since 2015. 8. 11.
|
||||
* @version 1.0
|
||||
* @see
|
||||
* @Modification Information
|
||||
*
|
||||
* <pre>
|
||||
* since author description
|
||||
* =========== ============= ===========================
|
||||
* 2015. 8. 11. Park SeongMin 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public class NexacroInterceptor extends HandlerInterceptorAdapter {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(NexacroInterceptor.class);
|
||||
private Logger performanceLogger = LoggerFactory.getLogger(NexacroConstants.PERFORMANCE_LOGGER);
|
||||
|
||||
/**
|
||||
* This implementation always returns <code>true</code>.
|
||||
*/
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||
parseNexacroRequest(request, response, handler);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
|
||||
ModelAndView modelAndView) throws Exception {
|
||||
super.postHandle(request, response, handler, modelAndView);
|
||||
}
|
||||
|
||||
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
|
||||
throws Exception {
|
||||
super.afterCompletion(request, response, handler, ex);
|
||||
}
|
||||
|
||||
private void parseNexacroRequest(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||
// check in able framework
|
||||
// checkSecurityWithServletRequest(request);
|
||||
// checkSecurityMultipart(request);
|
||||
|
||||
StopWatch sw = new StopWatch(getClass().getSimpleName());
|
||||
try {
|
||||
sw.start("parse request");
|
||||
NexacroContext context = NexacroContextHolder.getNexacroContext(request, response);
|
||||
HttpPlatformRequest platformRequest = context.getPlatformRequest();
|
||||
// sw.start("check security");
|
||||
// checkSecurityWithPlatformRequest(platformRequest);
|
||||
} finally {
|
||||
sw.stop();
|
||||
if(performanceLogger.isTraceEnabled()) {
|
||||
performanceLogger.trace(sw.prettyPrint());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void checkSecurityWithPlatformRequest(HttpPlatformRequest request) throws SecurityException {
|
||||
PlatformData platformData = request.getData();
|
||||
|
||||
// SecurityUtil.checkSecurity(platformData);
|
||||
|
||||
if(logger.isDebugEnabled()) {
|
||||
logger.debug("got request=[{}]", new Debugger().detail(platformData));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
245
src/main/java/com/nexacro/spring/util/CharsetUtil.java
Normal file
245
src/main/java/com/nexacro/spring/util/CharsetUtil.java
Normal file
@@ -0,0 +1,245 @@
|
||||
package com.nexacro.spring.util;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.IllegalCharsetNameException;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class CharsetUtil {
|
||||
|
||||
private static Properties languageMappingProperties = new Properties();
|
||||
private static String languageMappingResourceName = "language_mapping.properties";
|
||||
private static final Logger logger = LoggerFactory.getLogger(CharsetUtil.class);
|
||||
|
||||
static {
|
||||
|
||||
InputStream inputStream = null;
|
||||
try {
|
||||
inputStream = CharsetUtil.class.getResourceAsStream(languageMappingResourceName);
|
||||
languageMappingProperties.load(inputStream);
|
||||
} catch (IOException e) {
|
||||
if(logger.isWarnEnabled()) {
|
||||
logger.warn("fail to reading language to charset mapping file. properties file='"+languageMappingResourceName+"'");
|
||||
}
|
||||
} finally {
|
||||
if (inputStream != null) {
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (IOException ignore) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static String getCharsetOfRequest(HttpServletRequest request, String defaultChasrset) {
|
||||
|
||||
String charset = null;
|
||||
|
||||
String contentsType = HttpUtil.getHeaderValue(request, HttpUtil.HEADER_CONTENT_TYPE);
|
||||
|
||||
charset = getCharsetOfContentType(contentsType);
|
||||
|
||||
if (charset == null) {
|
||||
String charsetValue = HttpUtil.getHeaderValue(request, HttpUtil.HEADER_ACCEPT_CHARSET);
|
||||
charset = getCharsetOfAcceptCharset(charsetValue);
|
||||
}
|
||||
|
||||
// "ko-kr,ko;q=0.8,en-us;q=0.5,en;q=0.3"와 같이 여러개가 오는 경우가 있다.
|
||||
if (charset == null) {
|
||||
String languageValue = HttpUtil.getHeaderValue(request, HttpUtil.HEADER_ACCEPT_LANGUAGE);
|
||||
charset = getCharsetOfAcceptLanguage(languageValue);
|
||||
}
|
||||
|
||||
if (charset == null) {
|
||||
charset = defaultChasrset;
|
||||
}
|
||||
|
||||
if (charset == null) {
|
||||
// do nothing
|
||||
}
|
||||
// 이래도 null이면 그대로 반환해야 한다.
|
||||
// null도 의미를 갖는다.
|
||||
// 만약 null이 발생할 수 없다면 모델에 설정된 charset이 사용될 수 없다.
|
||||
|
||||
return getTrimValue(charset);
|
||||
|
||||
}
|
||||
|
||||
private static String getCharsetOfContentType(String contentsType) {
|
||||
|
||||
if (contentsType == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String charset = null;
|
||||
|
||||
String[] contentsTypes = contentsType.split(";");
|
||||
|
||||
boolean isUTF8Enabled = false;
|
||||
boolean isUTF16Enabled = false;
|
||||
for (int i = 0; i < contentsTypes.length; i++) {
|
||||
String[] keyAndValue = contentsTypes[i].split("=");
|
||||
|
||||
if (keyAndValue.length == 2) {
|
||||
String trimedValue = keyAndValue[0].trim();
|
||||
|
||||
if (trimedValue.equalsIgnoreCase("charset")) {
|
||||
charset = keyAndValue[1];
|
||||
|
||||
if (!isUTF8Enabled) {
|
||||
isUTF8Enabled = isUTF8Enabled(charset);
|
||||
}
|
||||
|
||||
if (!isUTF16Enabled) {
|
||||
isUTF16Enabled = isUTF16Enabled(charset);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return getOutputCharset(getTrimValue(charset), isUTF8Enabled, isUTF16Enabled);
|
||||
}
|
||||
|
||||
private static String getCharsetOfAcceptCharset(String acceptCharsets) {
|
||||
|
||||
if (acceptCharsets == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String charset = null;
|
||||
boolean isUTF8Enabled = false;
|
||||
boolean isUTF16Enabled = false;
|
||||
// "EUC-KR,utf-8;q=0.7,*;q=0.7"와 같이 여러개가 오는 경우가 있다.
|
||||
String[] charsetValues = acceptCharsets.split(",");
|
||||
|
||||
double maxQuality = 0.0d;
|
||||
for (int i = 0; i < charsetValues.length; i++) {
|
||||
int index = charsetValues[i].indexOf(";q=");
|
||||
String charsetName = charsetValues[i];
|
||||
try {
|
||||
if (!Charset.isSupported(charsetName)) {
|
||||
continue;
|
||||
}
|
||||
} catch (IllegalCharsetNameException e) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
if (!isUTF8Enabled) {
|
||||
isUTF8Enabled = isUTF8Enabled(charsetName);
|
||||
}
|
||||
|
||||
if (!isUTF16Enabled) {
|
||||
isUTF16Enabled = isUTF16Enabled(charsetName);
|
||||
}
|
||||
|
||||
double quality = 1.0d;
|
||||
if (index >= 0) {
|
||||
charsetName = charsetValues[i].substring(0, index - 1);
|
||||
quality = Double.valueOf(charsetValues[i].substring(index + ";q=".length()));
|
||||
}
|
||||
|
||||
if (quality >= maxQuality && maxQuality <= 1.0d) {
|
||||
|
||||
charset = charsetName;
|
||||
maxQuality = quality;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return getOutputCharset(getTrimValue(charset), isUTF8Enabled, isUTF16Enabled);
|
||||
}
|
||||
|
||||
private static String getCharsetOfAcceptLanguage(String languagevalue) {
|
||||
|
||||
if (languagevalue == null) {
|
||||
return null;
|
||||
}
|
||||
String charset = null;
|
||||
boolean isUTF8Enabled = false;
|
||||
boolean isUTF16Enabled = false;
|
||||
String[] languageValues = languagevalue.split(",");
|
||||
String charsetName = null;
|
||||
double maxQuality = 0.0d;
|
||||
for (int i = 0; i < languageValues.length; i++) {
|
||||
int index = languageValues[i].indexOf(";q=");
|
||||
String languageName = languageValues[i];
|
||||
double quality = 1.0d;
|
||||
if (index >= 0) {
|
||||
languageName = languageValues[i].substring(0, index - 1);
|
||||
quality = Double.valueOf(languageValues[i].substring(index + ";q=".length()));
|
||||
}
|
||||
|
||||
charsetName = languageMappingProperties.getProperty(languageName);
|
||||
|
||||
if (!isUTF8Enabled) {
|
||||
isUTF8Enabled = isUTF8Enabled(charsetName);
|
||||
}
|
||||
|
||||
if (!isUTF16Enabled) {
|
||||
isUTF16Enabled = isUTF16Enabled(charsetName);
|
||||
}
|
||||
|
||||
// 여기서는 위에서와 같이 isSupporting을 확인하지 않는다. properties파일에 설정되어 있는 값은
|
||||
// 유효하다는 전제 하에.
|
||||
if (charsetName != null) {
|
||||
if (quality >= maxQuality && maxQuality <= 1.0d) {
|
||||
charset = charsetName;
|
||||
maxQuality = quality;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
if (languageValues != null && charset == null) {
|
||||
// Accept-Language 체크를 한다는 것은 Accept-Charset이 없고 Accept-Charset만 있는
|
||||
// 경우이다.
|
||||
// 그럼에도 불구하고 charset이 null이라면 X-UP에서 해당 언어가 뭔지를 모르는 것이다.
|
||||
// 이경우에는 기본값을 사용하자.
|
||||
charset = "UTF-8";
|
||||
}
|
||||
|
||||
return getOutputCharset(getTrimValue(charset), isUTF8Enabled, isUTF16Enabled);
|
||||
}
|
||||
|
||||
private static String getTrimValue(String charset) {
|
||||
if (charset != null) {
|
||||
return charset.trim();
|
||||
} else {
|
||||
return charset;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isUTF8Enabled(String charset) {
|
||||
if (charset != null && charset.trim().equalsIgnoreCase("utf-8")) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isUTF16Enabled(String charset) {
|
||||
if (charset != null && charset.trim().equalsIgnoreCase("utf-16")) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static String getOutputCharset(String charset, boolean isUTF8Enabled, boolean isUTF16Enabled) {
|
||||
if (isUTF8Enabled) {
|
||||
return "utf-8";
|
||||
} else if (isUTF16Enabled) {
|
||||
return "utf-16";
|
||||
} else {
|
||||
return charset;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
54
src/main/java/com/nexacro/spring/util/FileUtils.java
Normal file
54
src/main/java/com/nexacro/spring/util/FileUtils.java
Normal file
@@ -0,0 +1,54 @@
|
||||
package com.nexacro.spring.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.channels.FileChannel;
|
||||
|
||||
public class FileUtils {
|
||||
|
||||
public static void copyFile(File sourceFile, File destFile) throws IOException {
|
||||
long writedSize = 0;
|
||||
long sourceSize = sourceFile.length();
|
||||
if (!destFile.exists()) {
|
||||
destFile.createNewFile();
|
||||
}
|
||||
|
||||
FileChannel source = null;
|
||||
FileChannel destination = null;
|
||||
try {
|
||||
source = new FileInputStream(sourceFile).getChannel();
|
||||
destination = new FileOutputStream(destFile).getChannel();
|
||||
while (writedSize < sourceSize) {
|
||||
writedSize += destination.transferFrom(source, writedSize, sourceSize - writedSize);
|
||||
}
|
||||
} finally {
|
||||
if (source != null) {
|
||||
source.close();
|
||||
}
|
||||
if (destination != null) {
|
||||
destination.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isFileUsed(File file) {
|
||||
|
||||
if(file == null) { return false; }
|
||||
|
||||
if(file.isHidden()) {
|
||||
return false;
|
||||
}
|
||||
else if(!file.exists()) {
|
||||
return false;
|
||||
}
|
||||
else if(!file.canRead()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
113
src/main/java/com/nexacro/spring/util/HttpUtil.java
Normal file
113
src/main/java/com/nexacro/spring/util/HttpUtil.java
Normal file
@@ -0,0 +1,113 @@
|
||||
package com.nexacro.spring.util;
|
||||
|
||||
import java.util.Enumeration;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
*
|
||||
* <pre>
|
||||
* HTTP Util class
|
||||
* </pre>
|
||||
*
|
||||
* @ClassName : HttpUtil.java
|
||||
* @Description : HTTP Util class
|
||||
* @author Park SeongMin
|
||||
* @since 2015. 7. 27.
|
||||
* @version 1.0
|
||||
* @see
|
||||
* @Modification Information
|
||||
*
|
||||
* <pre>
|
||||
* since author description
|
||||
* =========== ============= ===========================
|
||||
* 2015. 7. 27. Park SeongMin 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
public abstract class HttpUtil {
|
||||
|
||||
public static final String HEADER_USER_AGENT = "User-Agent";
|
||||
public static final String HEADER_CONTENT_ENCODING = "Content-Encoding";
|
||||
public static final String HEADER_CONTENT_TYPE = "Content-Type";
|
||||
public static final String HEADER_ACCEPT_CHARSET = "Accept-Charset";
|
||||
public static final String HEADER_ACCEPT_LANGUAGE = "Accept-Language";
|
||||
|
||||
public static String getHeaderValue(HttpServletRequest request, String targetHeaderName) {
|
||||
|
||||
if (targetHeaderName == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Enumeration enumeration = request.getHeaderNames();
|
||||
while (enumeration.hasMoreElements()) {
|
||||
String headerName = (String) enumeration.nextElement();
|
||||
if (targetHeaderName.equalsIgnoreCase(headerName)) {
|
||||
return request.getHeader(headerName);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String getRemoteAddr(HttpServletRequest request) {
|
||||
|
||||
/*
|
||||
* http://lesstif.com/pages/viewpage.action?pageId=20775886
|
||||
*
|
||||
* WAS 는 보통 2차 방화벽 안에 있고 Web Server 를 통해 client 에서 호출되거나 cluster로 구성되어
|
||||
* load balancer 에서 호출되는데 이럴 경우에서 getRemoteAddr() 을 호출하면 웹서버나 load
|
||||
* balancer의 IP 가 나옴
|
||||
* WebLogic 의 web server 연계 모듈인 weblogic connector 는
|
||||
* 위 헤더를 사용하지 않고 Proxy-Client-IP 나 WL-Proxy-Client-IP 를 사용하므로
|
||||
* weblogic 에서 도는 application 작성시 수정이 필요함
|
||||
*/
|
||||
|
||||
String clientIp = request.getHeader("X-Forwarded-For");
|
||||
if (!isEmpty(clientIp)) {
|
||||
return getFirstIp(clientIp);
|
||||
}
|
||||
|
||||
clientIp = request.getHeader("Proxy-Client-IP");
|
||||
if (!isEmpty(clientIp)) {
|
||||
return getFirstIp(clientIp);
|
||||
}
|
||||
|
||||
clientIp = request.getHeader("WL-Proxy-Client-IP");
|
||||
if (!isEmpty(clientIp)) {
|
||||
return getFirstIp(clientIp);
|
||||
}
|
||||
|
||||
clientIp = request.getHeader("HTTP_CLIENT_IP");
|
||||
if (!isEmpty(clientIp)) {
|
||||
return getFirstIp(clientIp);
|
||||
}
|
||||
|
||||
clientIp = request.getHeader("HTTP_X_FORWARDED_FOR");
|
||||
if (!isEmpty(clientIp)) {
|
||||
return getFirstIp(clientIp);
|
||||
}
|
||||
|
||||
return request.getRemoteAddr();
|
||||
|
||||
}
|
||||
|
||||
private static boolean isEmpty(String str) {
|
||||
if (str == null || str.length() == 0 || "unknown".equalsIgnoreCase(str)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static String getFirstIp(String ip) {
|
||||
|
||||
if (ip == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String[] split = ip.split(",");
|
||||
return split[0];
|
||||
}
|
||||
|
||||
}
|
||||
87
src/main/java/com/nexacro/spring/util/NexacroUtil.java
Normal file
87
src/main/java/com/nexacro/spring/util/NexacroUtil.java
Normal file
@@ -0,0 +1,87 @@
|
||||
package com.nexacro.spring.util;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.springframework.web.context.request.RequestAttributes;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
|
||||
import com.nexacro.spring.NexacroConstants;
|
||||
import com.nexacro.xapi.data.DataSet;
|
||||
import com.nexacro.xapi.data.datatype.PlatformDataType;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Statements
|
||||
* </pre>
|
||||
*
|
||||
* @ClassName : NexacroUtil.java
|
||||
* @Description : 클래스 설명을 기술합니다.
|
||||
* @author Park SeongMin
|
||||
* @since 2015. 7. 28.
|
||||
* @version 1.0
|
||||
* @see
|
||||
* @Modification Information
|
||||
* <pre>
|
||||
* since author description
|
||||
* =========== ============= ===========================
|
||||
* 2015. 7. 28. Park SeongMin 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public abstract class NexacroUtil {
|
||||
|
||||
public static final String ATTR_PLATFORM_REQUEST = "PlatformRequest";
|
||||
|
||||
public static DataSet createFirstRowStatusDataSet(int errorCode, String errorMsg) {
|
||||
|
||||
DataSet ds = new DataSet(NexacroConstants.ERROR_FIRST_ROW.ERROR_DATASET);
|
||||
ds.addColumn(NexacroConstants.ERROR_FIRST_ROW.ERROR_CODE, PlatformDataType.INT);
|
||||
ds.addColumn(NexacroConstants.ERROR_FIRST_ROW.ERROR_MSG, PlatformDataType.STRING);
|
||||
|
||||
int newRow = ds.newRow();
|
||||
ds.set(newRow, NexacroConstants.ERROR_FIRST_ROW.ERROR_CODE, errorCode);
|
||||
ds.set(newRow, NexacroConstants.ERROR_FIRST_ROW.ERROR_MSG, errorMsg);
|
||||
|
||||
return ds;
|
||||
}
|
||||
|
||||
public static boolean isNexacroRequest(HttpServletRequest request) {
|
||||
|
||||
// runtime 버전의 경우에만 userAgent 값이 설정 된다.
|
||||
Object nexacroRequest = RequestContextHolder.getRequestAttributes().getAttribute(NexacroConstants.ATTRIBUTE.NEXACRO_REQUEST, RequestAttributes.SCOPE_REQUEST);
|
||||
if(NexacroConstants.ATTRIBUTE.NEXACRO_REQUEST.equals(nexacroRequest)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
String userAgent = request.getHeader(HttpUtil.HEADER_USER_AGENT);
|
||||
|
||||
if(userAgent != null) {
|
||||
userAgent = userAgent.trim().toLowerCase();
|
||||
|
||||
if(userAgent.startsWith(HEADER_NEXACRO.USER_AGENT_KEY.toLowerCase())) {
|
||||
return true;
|
||||
} else if (userAgent.startsWith(HEADER_XPLATFORM.USER_AGENT_KEY.toLowerCase())) {
|
||||
return true;
|
||||
} else if (userAgent.startsWith(HEADER_MIPLATFORM.USER_AGENT_KEY.toLowerCase())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static class HEADER_NEXACRO {
|
||||
public final static String USER_AGENT_KEY = "nexacro";
|
||||
public final static String USER_AGENT_SAMPLE = "nexacroplatform14-Win32/2014 (compatible; Mozilla/4.0; MSIE 7.0)";
|
||||
}
|
||||
|
||||
public static class HEADER_XPLATFORM {
|
||||
public final static String USER_AGENT_KEY = "XPLATFORM";
|
||||
public final static String USER_AGENT_SAMPLE = "XPLATFORM-Win32/2009 (compatible; Mozilla/4.0; MSIE 7.0)";
|
||||
}
|
||||
|
||||
public static class HEADER_MIPLATFORM {
|
||||
public final static String USER_AGENT_KEY = "MiPlatform";
|
||||
public final static String USER_AGENT_SAMPLE = "MiPlatform 3.1;win32;1280x800";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.nexacro.spring.util;
|
||||
|
||||
public class ReflectionFailException extends RuntimeException {
|
||||
|
||||
public ReflectionFailException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public ReflectionFailException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
403
src/main/java/com/nexacro/spring/util/ReflectionUtil.java
Normal file
403
src/main/java/com/nexacro/spring/util/ReflectionUtil.java
Normal file
@@ -0,0 +1,403 @@
|
||||
package com.nexacro.spring.util;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class ReflectionUtil {
|
||||
|
||||
public static Field[] getFields(String className) throws ReflectionFailException {
|
||||
Field[] fields = null;
|
||||
|
||||
try {
|
||||
Class<?> cls = Class.forName(className);
|
||||
|
||||
fields = cls.getFields();
|
||||
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new ReflectionFailException("class not found.", e);
|
||||
}
|
||||
|
||||
return fields;
|
||||
}
|
||||
|
||||
public static String[] getPublicFieldNames(String className) throws ReflectionFailException {
|
||||
Field[] fields = getFields(className);
|
||||
|
||||
List<String> fieldNameList = new ArrayList<String>();
|
||||
|
||||
for (int fieldsIndex = 0; fieldsIndex < fields.length; fieldsIndex++) {
|
||||
if (Modifier.isPublic(fields[fieldsIndex].getModifiers())) {
|
||||
fieldNameList.add(fields[fieldsIndex].getName());
|
||||
}
|
||||
}
|
||||
|
||||
String[] fieldsNames = new String[fieldNameList.size()];
|
||||
|
||||
fieldsNames = fieldNameList.toArray(fieldsNames);
|
||||
|
||||
return fieldsNames;
|
||||
|
||||
}
|
||||
|
||||
public static Method[] getMethods(Class<?> clazz) throws ReflectionFailException {
|
||||
|
||||
Method[] methods = null;
|
||||
methods = clazz.getDeclaredMethods();
|
||||
|
||||
return methods;
|
||||
}
|
||||
|
||||
public static Method[] getMethods(Class<?> clazz, String methodName) throws ReflectionFailException {
|
||||
|
||||
Method[] methods = getMethods(clazz);
|
||||
int foundCount = 0;
|
||||
for (int i = 0; i < methods.length; i++) {
|
||||
if (methods[i].getName().equals(methodName)) {
|
||||
foundCount++;
|
||||
}
|
||||
}
|
||||
|
||||
Method[] foundMethods = new Method[foundCount];
|
||||
int foundMethodIndex = 0;
|
||||
for (int i = 0; i < methods.length; i++) {
|
||||
if (methods[i].getName().equals(methodName)) {
|
||||
foundMethods[foundMethodIndex] = methods[i];
|
||||
foundMethodIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
return foundMethods;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to find a {@link Method} on the supplied class with the supplied
|
||||
* name
|
||||
* and parameter types. Searches all superclasses up to {@code Object}.
|
||||
* <p>
|
||||
* Returns {@code null} if no {@link Method} can be found.
|
||||
*
|
||||
* @param clazz
|
||||
* the class to introspect
|
||||
* @param name
|
||||
* the name of the method
|
||||
* @param paramTypes
|
||||
* the parameter types of the method
|
||||
* (may be {@code null} to indicate any signature)
|
||||
* @return the Method object, or {@code null} if none found
|
||||
* @throws ReflectionFailException
|
||||
*/
|
||||
public static Method getMethod(Class<?> clazz, String name, Class<?>... paramTypes) {
|
||||
if (clazz == null) {
|
||||
throw new IllegalArgumentException("Class should not be null");
|
||||
}
|
||||
if (name == null) {
|
||||
throw new IllegalArgumentException("Method name should not be null");
|
||||
}
|
||||
Class<?> searchType = clazz;
|
||||
while (searchType != null) {
|
||||
Method[] methods = (searchType.isInterface() ? searchType.getMethods() : searchType.getDeclaredMethods());
|
||||
for (Method method : methods) {
|
||||
if (name.equals(method.getName())
|
||||
&& (paramTypes == null || Arrays.equals(paramTypes, method.getParameterTypes()))) {
|
||||
return method;
|
||||
}
|
||||
}
|
||||
searchType = searchType.getSuperclass();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Method[] getMethods(String className) throws ReflectionFailException {
|
||||
|
||||
Class<?> cls = null;
|
||||
Method[] methods = null;
|
||||
try {
|
||||
cls = Class.forName(className);
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new ReflectionFailException("class not found.", e);
|
||||
}
|
||||
|
||||
return getMethods(cls);
|
||||
|
||||
}
|
||||
|
||||
public static Method[] getMethods(Object object) throws ReflectionFailException {
|
||||
if (object == null) {
|
||||
return null;
|
||||
}
|
||||
return getMethods(object.getClass());
|
||||
}
|
||||
|
||||
public static String[] getPublicMethodNames(String className) throws ReflectionFailException {
|
||||
|
||||
Method[] methods = getMethods(className);
|
||||
|
||||
List<String> methodNameList = new ArrayList<String>();
|
||||
|
||||
for (int i = 0; i < methods.length; i++) {
|
||||
if (Modifier.isPublic(methods[i].getModifiers())) {
|
||||
methodNameList.add(methods[i].getName());
|
||||
}
|
||||
}
|
||||
|
||||
String[] methodNames = new String[methodNameList.size()];
|
||||
methodNames = methodNameList.toArray(methodNames);
|
||||
|
||||
return methodNames;
|
||||
|
||||
}
|
||||
|
||||
public static Object executeMethod(Method method, Object instanceObject, Object[] parameterValueObject)
|
||||
throws ReflectionFailException {
|
||||
Object retobj = null;
|
||||
try {
|
||||
retobj = method.invoke(instanceObject, parameterValueObject);
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new ReflectionFailException("execution method failed.", e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new ReflectionFailException("execution method failed.", e);
|
||||
} catch (InvocationTargetException e) {
|
||||
Throwable cause = e.getCause();
|
||||
StackTraceElement[] stackTraceElements = cause.getStackTrace();
|
||||
StringBuffer stackTraceBuffer = new StringBuffer();
|
||||
for (int i = 0; i < stackTraceElements.length; i++) {
|
||||
stackTraceBuffer.append(" at ");
|
||||
stackTraceBuffer.append(stackTraceElements[i].getClassName()).append(".");
|
||||
stackTraceBuffer.append(stackTraceElements[i].getMethodName());
|
||||
stackTraceBuffer.append("(").append(stackTraceElements[i].getFileName());
|
||||
stackTraceBuffer.append(":").append(stackTraceElements[i].getLineNumber()).append(")");
|
||||
stackTraceBuffer.append("\n");
|
||||
}
|
||||
throw new ReflectionFailException(stackTraceBuffer.toString(), e);
|
||||
}
|
||||
|
||||
return retobj;
|
||||
}
|
||||
|
||||
public static boolean isImplemented(Class targetClass, Class interfaceClass) {
|
||||
Class[] interfaceClasses = targetClass.getInterfaces();
|
||||
for (int i = 0; i < interfaceClasses.length; i++) {
|
||||
if (interfaceClasses[i] == interfaceClass) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Class superClass = targetClass.getSuperclass();
|
||||
if (superClass != null) {
|
||||
return isImplemented(superClass, interfaceClass);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isStaticField(Field field) {
|
||||
if(field == null) {
|
||||
return false;
|
||||
}
|
||||
return isStatic(field.getModifiers());
|
||||
}
|
||||
|
||||
public static boolean isStaticMethod(Method method) {
|
||||
if(method == null) {
|
||||
return false;
|
||||
}
|
||||
return isStatic(method.getModifiers());
|
||||
}
|
||||
|
||||
public static boolean isStatic(int modifiers) {
|
||||
return Modifier.isStatic(modifiers);
|
||||
}
|
||||
|
||||
public static Object getFieldInstance(Object object, String fieldName) throws ReflectionFailException {
|
||||
|
||||
if (object == null) {
|
||||
return null;
|
||||
}
|
||||
if (fieldName == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String[] fieldNames = fieldName.split("\\.");
|
||||
return getFieldInstance(object, fieldNames);
|
||||
|
||||
}
|
||||
|
||||
public static Field getField(Object object, String fieldName) throws ReflectionFailException {
|
||||
|
||||
if (object == null) {
|
||||
return null;
|
||||
}
|
||||
if (fieldName == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Field field = null;
|
||||
Class clazz = null;
|
||||
|
||||
clazz = object.getClass();
|
||||
|
||||
return getField(clazz, fieldName);
|
||||
|
||||
}
|
||||
|
||||
public static Field getField(Class clazz, String fieldName) throws ReflectionFailException {
|
||||
|
||||
if (clazz == null) {
|
||||
return null;
|
||||
}
|
||||
if (fieldName == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Field field = null;
|
||||
|
||||
Exception rootException = null;
|
||||
try {
|
||||
field = clazz.getDeclaredField(fieldName);
|
||||
return field;
|
||||
} catch (SecurityException e) {
|
||||
rootException = e;
|
||||
} catch (NoSuchFieldException e) {
|
||||
rootException = e;
|
||||
}
|
||||
|
||||
Class superClass = clazz.getSuperclass();
|
||||
while (superClass != null) {
|
||||
try {
|
||||
field = superClass.getDeclaredField(fieldName);
|
||||
return field;
|
||||
} catch (SecurityException e) {
|
||||
} catch (NoSuchFieldException e) {
|
||||
}
|
||||
superClass = superClass.getSuperclass();
|
||||
}
|
||||
|
||||
throw new ReflectionFailException("getting field " + fieldName + " failed.", rootException);
|
||||
}
|
||||
|
||||
public static Object getFieldInstance(Object object, String[] fieldNames) throws ReflectionFailException {
|
||||
|
||||
if (object == null) {
|
||||
return null;
|
||||
}
|
||||
if (fieldNames == null) {
|
||||
return null;
|
||||
}
|
||||
if (fieldNames.length == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
Field field = getField(object, fieldNames[0]);
|
||||
field.setAccessible(true);
|
||||
|
||||
if (fieldNames.length == 1) {
|
||||
Object value = field.get(object);
|
||||
return value;
|
||||
} else {
|
||||
Object subObject = field.get(object);
|
||||
if (subObject == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String[] subFieldNames = new String[fieldNames.length - 1];
|
||||
String subFieldName = "";
|
||||
for (int i = 1; i < fieldNames.length; i++) {
|
||||
subFieldNames[i - 1] = fieldNames[i];
|
||||
}
|
||||
return getFieldInstance(subObject, subFieldNames);
|
||||
}
|
||||
|
||||
} catch (SecurityException e) {
|
||||
throw new ReflectionFailException("getting field value failed.", e);
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new ReflectionFailException("getting field value failed.", e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new ReflectionFailException("getting field value failed.", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static Method[] getAllDeclaredMethods(Class<?> leafClass) {
|
||||
final List<Method> methods = new ArrayList<Method>(32);
|
||||
|
||||
doWithMethods(leafClass, methods);
|
||||
|
||||
return methods.toArray(new Method[methods.size()]);
|
||||
}
|
||||
|
||||
private static void doWithMethods(Class clazz, List<Method> methodList) {
|
||||
Method[] methods = clazz.getDeclaredMethods();
|
||||
for (int i = 0; i < methods.length; i++) {
|
||||
methodList.add(methods[i]);
|
||||
}
|
||||
|
||||
if (clazz.getSuperclass() != null) {
|
||||
doWithMethods(clazz.getSuperclass(), methodList);
|
||||
} else if (clazz.isInterface()) {
|
||||
for (Class<?> superIfc : clazz.getInterfaces()) {
|
||||
doWithMethods(superIfc, methodList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void makeAccessible(Field field) {
|
||||
if ((!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers()) || Modifier
|
||||
.isFinal(field.getModifiers())) && !field.isAccessible()) {
|
||||
field.setAccessible(true);
|
||||
}
|
||||
}
|
||||
|
||||
public static void makeAccessible(Method method) {
|
||||
if ((!Modifier.isPublic(method.getModifiers()) || !Modifier.isPublic(method.getDeclaringClass().getModifiers()))
|
||||
&& !method.isAccessible()) {
|
||||
method.setAccessible(true);
|
||||
}
|
||||
}
|
||||
|
||||
public static void makeAccessible(Constructor<?> ctor) {
|
||||
if ((!Modifier.isPublic(ctor.getModifiers()) || !Modifier.isPublic(ctor.getDeclaringClass().getModifiers()))
|
||||
&& !ctor.isAccessible()) {
|
||||
ctor.setAccessible(true);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> T instantiateClass(Class<T> clazz) throws ReflectionFailException {
|
||||
if(clazz == null) {
|
||||
throw new ReflectionFailException("Class must not be null");
|
||||
}
|
||||
if (clazz.isInterface()) {
|
||||
throw new ReflectionFailException(clazz+ " specified class is an interface");
|
||||
}
|
||||
try {
|
||||
return instantiateClass(clazz.getDeclaredConstructor());
|
||||
} catch (NoSuchMethodException ex) {
|
||||
throw new ReflectionFailException(clazz+ " no default constructor found", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws ReflectionFailException {
|
||||
if(ctor == null) {
|
||||
throw new ReflectionFailException("Constructor must not be null");
|
||||
}
|
||||
try {
|
||||
makeAccessible(ctor);
|
||||
return ctor.newInstance(args);
|
||||
} catch (InstantiationException ex) {
|
||||
throw new ReflectionFailException(ctor.getDeclaringClass()+ " is it an abstract class?", ex);
|
||||
} catch (IllegalAccessException ex) {
|
||||
throw new ReflectionFailException(ctor.getDeclaringClass() + " is the constructor accessible?", ex);
|
||||
} catch (IllegalArgumentException ex) {
|
||||
throw new ReflectionFailException(ctor.getDeclaringClass() + " illegal arguments for constructor", ex);
|
||||
} catch (InvocationTargetException ex) {
|
||||
throw new ReflectionFailException(ctor.getDeclaringClass() + " constructor threw exception", ex.getTargetException());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#ko-kr=euc-kr
|
||||
ko-kr=utf-8
|
||||
|
||||
#ko=euc-kr
|
||||
ko=utf-8
|
||||
ko.coderange=/uac00-/ud7af
|
||||
#en=ios8859-1
|
||||
en=utf-8
|
||||
#en-us=ios8859-1
|
||||
en-us=utf-8
|
||||
en.coderange=
|
||||
#jp=Shift-JIS
|
||||
jp=utf-8
|
||||
jp.coderange=/u3040-/u30ff/u3400-/u4db5/u4e00-/u9fcb/uf900-/ufa6a
|
||||
ja=utf-8
|
||||
ja.coderange=/u3040-/u30ff/u3400-/u4db5/u4e00-/u9fcb/uf900-/ufa6a
|
||||
|
||||
zh=utf-8
|
||||
zh.coderange=/u4e00-/u9fff/u20000-/u2a6df/uf900-/ufaff/u2f800-/u2fa1f
|
||||
94
src/main/java/com/nexacro/spring/view/NexacroFileView.java
Normal file
94
src/main/java/com/nexacro/spring/view/NexacroFileView.java
Normal file
@@ -0,0 +1,94 @@
|
||||
package com.nexacro.spring.view;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.activation.MimetypesFileTypeMap;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
|
||||
import com.nexacro.spring.NexacroConstants;
|
||||
import com.nexacro.spring.NexacroException;
|
||||
import com.nexacro.spring.data.NexacroFileResult;
|
||||
import com.nexacro.spring.util.CharsetUtil;
|
||||
import com.nexacro.spring.util.FileUtils;
|
||||
import com.nexacro.xapi.data.PlatformData;
|
||||
import com.nexacro.xapi.data.Variable;
|
||||
import com.nexacro.xapi.tx.PlatformException;
|
||||
|
||||
public class NexacroFileView extends NexacroView {
|
||||
|
||||
public NexacroFileView() {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderMergedOutputModel(Map<String, Object> model,
|
||||
HttpServletRequest request, HttpServletResponse response)
|
||||
throws Exception {
|
||||
|
||||
Object object = model.get(NexacroConstants.ATTRIBUTE.NEXACRO_FILE_DATA);
|
||||
if(object == null || !(object instanceof NexacroFileResult)) {
|
||||
sendResponse(request, response);
|
||||
return;
|
||||
}
|
||||
|
||||
NexacroFileResult fileResult = (NexacroFileResult) object;
|
||||
|
||||
String charset = fileResult.getCharset();
|
||||
String contentType = fileResult.getContentType();
|
||||
String originalName = fileResult.getOriginalName();
|
||||
File file = fileResult.getFile();
|
||||
if(file == null) {
|
||||
sendFailResponse(request, response, "send response failed. file is null.");
|
||||
return;
|
||||
}
|
||||
if(!FileUtils.isFileUsed(file)) {
|
||||
sendFailResponse(request, response, "send response failed. '" + file.getName() + "' can not be used.");
|
||||
return;
|
||||
}
|
||||
|
||||
if(contentType == null) {
|
||||
contentType = MimetypesFileTypeMap.getDefaultFileTypeMap().getContentType(file);
|
||||
}
|
||||
|
||||
charset = charset != null? charset: CharsetUtil.getCharsetOfRequest(request, "utf-8");
|
||||
contentType = contentType != null? contentType: "application/octet-stream";
|
||||
originalName = originalName != null? originalName: file.getName();
|
||||
|
||||
String enName = URLEncoder.encode(originalName, "utf-8");
|
||||
|
||||
response.setContentType(contentType + "; charset=" + charset);
|
||||
response.setHeader("Content-Transfer-Encoding", "binary");
|
||||
response.setHeader("Content-Disposition", "attachment; filename=" + enName + "; size=" + file.length());
|
||||
response.setHeader("Content-Description", "...");
|
||||
response.setHeader("Pragma", "no-cache");
|
||||
response.setHeader("Expires", "-1");
|
||||
|
||||
OutputStream out = response.getOutputStream();
|
||||
FileInputStream fis = null;
|
||||
try {
|
||||
fis = new FileInputStream(file);
|
||||
FileCopyUtils.copy(fis, out);
|
||||
} catch (Exception e) {
|
||||
sendFailResponse(request, response, e.getMessage());
|
||||
} finally {
|
||||
if (fis != null) { try { fis.close(); } catch (Exception e) {}}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void sendFailResponse(HttpServletRequest request, HttpServletResponse response, String errorMsg) throws PlatformException {
|
||||
|
||||
PlatformData platformData = new PlatformData();
|
||||
platformData.addVariable(Variable.createVariable(NexacroConstants.ERROR.ERROR_CODE, NexacroException.DEFAULT_ERROR_CODE));
|
||||
platformData.addVariable(Variable.createVariable(NexacroConstants.ERROR.ERROR_MSG, errorMsg));
|
||||
|
||||
sendResponse(request, response, platformData);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.nexacro.spring.view;
|
||||
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import org.springframework.web.servlet.View;
|
||||
|
||||
import com.nexacro.spring.NexacroConstants;
|
||||
import com.nexacro.xapi.data.DataSet;
|
||||
import com.nexacro.xapi.data.PlatformData;
|
||||
import com.nexacro.xapi.data.Variable;
|
||||
|
||||
public class NexacroModelAndView extends ModelAndView {
|
||||
|
||||
private PlatformData platformData = new PlatformData();
|
||||
|
||||
public NexacroModelAndView(){
|
||||
setNexacroObject();
|
||||
}
|
||||
|
||||
public NexacroModelAndView(String viewName){
|
||||
super(viewName);
|
||||
setNexacroObject();
|
||||
}
|
||||
|
||||
public NexacroModelAndView(View view){
|
||||
super(view);
|
||||
setNexacroObject();
|
||||
}
|
||||
|
||||
public PlatformData getPlatformData() {
|
||||
return platformData;
|
||||
}
|
||||
|
||||
public void setPlatformData(PlatformData platformData) {
|
||||
this.platformData = platformData;
|
||||
setNexacroObject();
|
||||
}
|
||||
|
||||
public void addVariable(Variable var) {
|
||||
this.platformData.addVariable(var);
|
||||
}
|
||||
|
||||
public void addDataSet(DataSet ds) {
|
||||
this.platformData.addDataSet(ds);
|
||||
}
|
||||
|
||||
public void setErrorCode(int code){
|
||||
platformData.addVariable(Variable.createVariable(NexacroConstants.ERROR.ERROR_CODE, code));
|
||||
setNexacroObject();
|
||||
}
|
||||
|
||||
public void setErrorMsg(String msg){
|
||||
platformData.addVariable(Variable.createVariable(NexacroConstants.ERROR.ERROR_MSG, msg));
|
||||
setNexacroObject();
|
||||
}
|
||||
|
||||
private void setNexacroObject() {
|
||||
super.addObject(NexacroConstants.ATTRIBUTE.NEXACRO_PLATFORM_DATA, platformData);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
235
src/main/java/com/nexacro/spring/view/NexacroView.java
Normal file
235
src/main/java/com/nexacro/spring/view/NexacroView.java
Normal file
@@ -0,0 +1,235 @@
|
||||
package com.nexacro.spring.view;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.util.StopWatch;
|
||||
import org.springframework.web.servlet.view.AbstractView;
|
||||
|
||||
import com.nexacro.spring.NexacroConstants;
|
||||
import com.nexacro.spring.data.NexacroFirstRowAccessor;
|
||||
import com.nexacro.spring.data.NexacroFirstRowHandler;
|
||||
import com.nexacro.spring.servlet.NexacroContext;
|
||||
import com.nexacro.spring.servlet.NexacroContextHolder;
|
||||
import com.nexacro.spring.util.NexacroUtil;
|
||||
import com.nexacro.xapi.data.DataSet;
|
||||
import com.nexacro.xapi.data.DataSetList;
|
||||
import com.nexacro.xapi.data.Debugger;
|
||||
import com.nexacro.xapi.data.PlatformData;
|
||||
import com.nexacro.xapi.data.Variable;
|
||||
import com.nexacro.xapi.data.VariableList;
|
||||
import com.nexacro.xapi.tx.HttpPlatformResponse;
|
||||
import com.nexacro.xapi.tx.PlatformException;
|
||||
import com.nexacro.xapi.tx.PlatformType;
|
||||
|
||||
public class NexacroView extends AbstractView {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(NexacroView.class);
|
||||
private Logger performanceLogger = LoggerFactory.getLogger(NexacroConstants.PERFORMANCE_LOGGER);
|
||||
|
||||
private String defaultContentType;
|
||||
private String defaultCharset;
|
||||
|
||||
public NexacroView(){
|
||||
}
|
||||
|
||||
public String getDefaultContentType() {
|
||||
if(defaultContentType == null) {
|
||||
return PlatformType.CONTENT_TYPE_XML;
|
||||
} else {
|
||||
return defaultContentType;
|
||||
}
|
||||
}
|
||||
|
||||
public void setDefaultContentType(String defaultContentType) {
|
||||
this.defaultContentType = defaultContentType;
|
||||
}
|
||||
|
||||
public String getDefaultCharset() {
|
||||
if(defaultContentType == null) {
|
||||
return PlatformType.DEFAULT_CHAR_SET;
|
||||
} else {
|
||||
return defaultCharset;
|
||||
}
|
||||
}
|
||||
|
||||
public void setDefaultCharset(String defaultCharset) {
|
||||
this.defaultCharset = defaultCharset;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderMergedOutputModel(Map<String, Object> model,
|
||||
HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||
|
||||
Object object = model.get(NexacroConstants.ATTRIBUTE.NEXACRO_PLATFORM_DATA);
|
||||
if(object == null || !(object instanceof PlatformData)) {
|
||||
sendResponse(request, response);
|
||||
return;
|
||||
}
|
||||
|
||||
sendResponse(request, response, (PlatformData) object);
|
||||
|
||||
}
|
||||
|
||||
protected void sendResponse(HttpServletRequest request, HttpServletResponse response) throws PlatformException{
|
||||
sendResponse(request, response, generatePlatformData());
|
||||
}
|
||||
|
||||
protected void sendResponse(HttpServletRequest request, HttpServletResponse response, PlatformData platformData) throws PlatformException{
|
||||
|
||||
NexacroContext cachedData = getCachedData(request, response);
|
||||
|
||||
HttpPlatformResponse platformResponse = null;
|
||||
|
||||
StopWatch sw = new StopWatch(getClass().getSimpleName());
|
||||
sw.start("rendering platformdata");
|
||||
|
||||
try {
|
||||
|
||||
if(cachedData != null) {
|
||||
if(cachedData.isFirstRowFired()) {
|
||||
NexacroFirstRowHandler firstRowHandler = cachedData.getFirstRowHandler();
|
||||
sendFirstRowData(platformData, firstRowHandler, true);
|
||||
|
||||
return;
|
||||
} else {
|
||||
platformResponse = cachedData.getPlatformResponse();
|
||||
platformResponse.setData(platformData);
|
||||
platformResponse.sendData();
|
||||
}
|
||||
} else {
|
||||
// TODO default 혹은 request parsing..
|
||||
platformResponse = new HttpPlatformResponse(response);
|
||||
platformResponse.setContentType(getDefaultContentType());
|
||||
platformResponse.setCharset(getDefaultCharset());
|
||||
platformResponse.setData(platformData);
|
||||
platformResponse.sendData();
|
||||
}
|
||||
} finally {
|
||||
sw.stop();
|
||||
if(performanceLogger.isTraceEnabled()) {
|
||||
performanceLogger.trace(sw.prettyPrint());
|
||||
}
|
||||
}
|
||||
|
||||
if(logger.isDebugEnabled()) {
|
||||
logger.debug("response platformdata=[{}]", new Debugger().detail(platformData));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void sendFirstRowData(PlatformData platformData, NexacroFirstRowHandler firstRowHandler, boolean isCallEndMethod)
|
||||
throws PlatformException {
|
||||
|
||||
removeTransferData(firstRowHandler, platformData);
|
||||
|
||||
// add first row status DataSet
|
||||
platformData.addDataSet(NexacroUtil.createFirstRowStatusDataSet(NexacroConstants.ERROR.DEFAULT_ERROR_CODE, null));
|
||||
|
||||
if(logger.isDebugEnabled()) {
|
||||
logger.debug("response platformdata=[{}]", new Debugger().detail(platformData));
|
||||
}
|
||||
firstRowHandler.sendPlatformData(platformData);
|
||||
if(isCallEndMethod) {
|
||||
NexacroFirstRowAccessor.end(firstRowHandler);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Statements
|
||||
*
|
||||
* @param firstRowHandler
|
||||
* @param variableList
|
||||
*/
|
||||
private void removeTransferData(NexacroFirstRowHandler firstRowHandler, PlatformData platformData) {
|
||||
|
||||
VariableList variableList = platformData.getVariableList();
|
||||
|
||||
if(NexacroFirstRowAccessor.getSendOutDataSetCount(firstRowHandler) > 0) {
|
||||
// dataset already sended..
|
||||
int size = variableList.size();
|
||||
for(int i=0; i<size; i++) {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("DataSet aleady sended. ignore variable="+variableList.get(i).getName());
|
||||
}
|
||||
}
|
||||
platformData.setVariableList(new VariableList());
|
||||
|
||||
} else {
|
||||
removeTransferVariables(firstRowHandler, variableList);
|
||||
}
|
||||
|
||||
DataSetList dataSetList = platformData.getDataSetList();
|
||||
removeTransferDataSets(firstRowHandler, dataSetList);
|
||||
|
||||
}
|
||||
|
||||
private void removeTransferVariables(NexacroFirstRowHandler firstRowHandler, VariableList variableList) {
|
||||
|
||||
String[] sendOutVariableNames = NexacroFirstRowAccessor.getSendOutVariableNames(firstRowHandler);
|
||||
Variable var = null;
|
||||
int variableListSize = variableList.size();
|
||||
for(int variableListIndex = variableListSize-1 ; variableListIndex>=0 ; variableListIndex--) {
|
||||
var = variableList.get(variableListIndex);
|
||||
if(var == null) {
|
||||
continue;
|
||||
}
|
||||
boolean isSended = false;
|
||||
for(int sendedVariableIndex = 0; sendedVariableIndex<sendOutVariableNames.length; sendedVariableIndex++) {
|
||||
if(var.getName().equals(sendOutVariableNames[sendedVariableIndex])) {
|
||||
isSended = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(isSended) {
|
||||
variableList.remove(variableListIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void removeTransferDataSets(NexacroFirstRowHandler firstRowHandler, DataSetList dataSetList) {
|
||||
|
||||
String[] sendOutDataSetNames = NexacroFirstRowAccessor.getSendOutDataSetNames(firstRowHandler);
|
||||
DataSet dataSet = null;
|
||||
int dataSetListSize = dataSetList.size();
|
||||
for(int datasetListIndex = dataSetListSize - 1 ; datasetListIndex >= 0; datasetListIndex--) {
|
||||
dataSet = dataSetList.get(datasetListIndex);
|
||||
if(dataSet == null) {
|
||||
continue;
|
||||
}
|
||||
boolean isSended = false;
|
||||
for(int sendedDataSetIndex = 0; sendedDataSetIndex<sendOutDataSetNames.length; sendedDataSetIndex++) {
|
||||
if(dataSet.getName().equals(sendOutDataSetNames[sendedDataSetIndex])) {
|
||||
isSended = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(isSended) {
|
||||
dataSetList.remove(datasetListIndex);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private PlatformData generatePlatformData() {
|
||||
PlatformData platformData = new PlatformData();
|
||||
platformData.addVariable(Variable.createVariable(NexacroConstants.ERROR.ERROR_CODE, NexacroConstants.ERROR.DEFAULT_ERROR_CODE));
|
||||
return platformData;
|
||||
}
|
||||
|
||||
private NexacroContext getCachedData(HttpServletRequest request, HttpServletResponse response) {
|
||||
|
||||
// get already parsed request
|
||||
NexacroContext nexacroContext = NexacroContextHolder.getNexacroContext();
|
||||
if(nexacroContext != null) {
|
||||
return nexacroContext;
|
||||
}
|
||||
|
||||
return nexacroContext;
|
||||
}
|
||||
|
||||
}
|
||||
39
src/site/site.xml
Normal file
39
src/site/site.xml
Normal file
@@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project name="nexacro able sample">
|
||||
<bannerLeft>
|
||||
<name>Maven</name>
|
||||
<src>http://maven.apache.org/images/apache-maven-project.png
|
||||
</src>
|
||||
<href>http://maven.apache.org/</href>
|
||||
</bannerLeft>
|
||||
<bannerRight>
|
||||
<src>http://maven.apache.org/images/maven-small.gif</src>
|
||||
</bannerRight>
|
||||
|
||||
<skin>
|
||||
<groupId>org.apache.maven.skins</groupId>
|
||||
<artifactId>maven-fluido-skin</artifactId>
|
||||
<version>1.4</version>
|
||||
</skin>
|
||||
|
||||
<body>
|
||||
<links>
|
||||
<item name="Apache" href="http://www.apache.org/" />
|
||||
<item name="Maven 1.x" href="http://maven.apache.org/maven-1.x/" />
|
||||
<item name="Maven 2" href="http://maven.apache.org/" />
|
||||
</links>
|
||||
|
||||
<!--
|
||||
<menu name="Maven 2.0">
|
||||
<item name="Introduction" href="index.html" />
|
||||
<item name="Download" href="download.html" />
|
||||
<item name="Release Notes" href="release-notes.html" />
|
||||
<item name="General Information" href="about.html" />
|
||||
<item name="For Maven 1.x Users" href="maven1.html" />
|
||||
<item name="Road Map" href="roadmap.html" />
|
||||
</menu>
|
||||
-->
|
||||
<menu ref="reports" />
|
||||
|
||||
</body>
|
||||
</project>
|
||||
154
src/test/java/com/nexacro/spring/data/FirstRowHttpResponse.java
Normal file
154
src/test/java/com/nexacro/spring/data/FirstRowHttpResponse.java
Normal file
@@ -0,0 +1,154 @@
|
||||
package com.nexacro.spring.data;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Collection;
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.servlet.ServletOutputStream;
|
||||
import javax.servlet.http.Cookie;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
public class FirstRowHttpResponse implements HttpServletResponse {
|
||||
|
||||
ServletOutputStream outputStream = null;
|
||||
String charsetEncoding = null;
|
||||
String contentType = null;
|
||||
|
||||
public void setContentType(String arg0) {
|
||||
this.contentType = arg0;
|
||||
}
|
||||
|
||||
public String getContentType() {
|
||||
return this.contentType;
|
||||
}
|
||||
|
||||
public String getCharacterEncoding() {
|
||||
return this.charsetEncoding;
|
||||
}
|
||||
|
||||
public void setCharacterEncoding(String charsetEncoding) {
|
||||
this.charsetEncoding = charsetEncoding;
|
||||
}
|
||||
|
||||
public ServletOutputStream getOutputStream() throws IOException {
|
||||
return this.outputStream;
|
||||
}
|
||||
|
||||
public void setOutputStream(ServletOutputStream outputStream) {
|
||||
this.outputStream = outputStream;
|
||||
}
|
||||
|
||||
public void addCookie(Cookie arg0) {
|
||||
}
|
||||
|
||||
public void addDateHeader(String arg0, long arg1) {
|
||||
}
|
||||
|
||||
public void addHeader(String arg0, String arg1) {
|
||||
}
|
||||
|
||||
public void addIntHeader(String arg0, int arg1) {
|
||||
}
|
||||
|
||||
public boolean containsHeader(String arg0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public String encodeRedirectURL(String arg0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String encodeRedirectUrl(String arg0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String encodeURL(String arg0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String encodeUrl(String arg0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void sendError(int arg0) throws IOException {
|
||||
}
|
||||
|
||||
public void sendError(int arg0, String arg1) throws IOException {
|
||||
}
|
||||
|
||||
public void sendRedirect(String arg0) throws IOException {
|
||||
}
|
||||
|
||||
public void setDateHeader(String arg0, long arg1) {
|
||||
}
|
||||
|
||||
public void setHeader(String arg0, String arg1) {
|
||||
}
|
||||
|
||||
public void setIntHeader(String arg0, int arg1) {
|
||||
}
|
||||
|
||||
public void setStatus(int arg0) {
|
||||
}
|
||||
|
||||
public void setStatus(int arg0, String arg1) {
|
||||
}
|
||||
|
||||
public void flushBuffer() throws IOException {
|
||||
|
||||
}
|
||||
|
||||
public int getBufferSize() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public Locale getLocale() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public PrintWriter getWriter() throws IOException {
|
||||
return new PrintWriter(new OutputStreamWriter(outputStream, "UTF-8"));
|
||||
}
|
||||
|
||||
public boolean isCommitted() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
}
|
||||
|
||||
public void resetBuffer() {
|
||||
}
|
||||
|
||||
public void setBufferSize(int arg0) {
|
||||
}
|
||||
|
||||
public void setContentLength(int arg0) {
|
||||
}
|
||||
|
||||
public void setLocale(Locale arg0) {
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public String getHeader(String name) {
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public Collection<String> getHeaderNames() {
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public Collection<String> getHeaders(String headerName) {
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public int getStatus() {
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
package com.nexacro.spring.data;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.ServletOutputStream;
|
||||
|
||||
public class FirstRowTrackableServletOutputStream extends ServletOutputStream {
|
||||
|
||||
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
||||
List<byte[]> flushedByteArrayList = new ArrayList<byte[]>();
|
||||
|
||||
Object syncronizeObject = new Object();
|
||||
byte[] resultData = null;
|
||||
boolean isClose = false;
|
||||
|
||||
@Override
|
||||
public void write(int b) throws IOException {
|
||||
write(new byte[] { (byte) b });
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
|
||||
// ByteArrayOutputStream 은 close 시 아무런 영향이 없다.
|
||||
// 메모리 대상이기 때문에 Garbage Collector 에 의해 소멸된다.
|
||||
output.close();
|
||||
isClose = true;
|
||||
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
return output.equals(obj);
|
||||
}
|
||||
|
||||
public void flush() throws IOException {
|
||||
synchronized (syncronizeObject) {
|
||||
|
||||
resultData = output.toByteArray();
|
||||
output.reset();
|
||||
|
||||
flushedByteArrayList.add(resultData);
|
||||
|
||||
if (isClose) {
|
||||
throw new IOException("connection reset by peer");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<byte[]> getFlushedByteList() {
|
||||
return flushedByteArrayList;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return output.hashCode();
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
output.reset();
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return output.size();
|
||||
}
|
||||
|
||||
public byte[] toByteArray() {
|
||||
return output.toByteArray();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return output.toString();
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public String toString(int hibyte) {
|
||||
return output.toString(hibyte);
|
||||
}
|
||||
|
||||
public String toString(String enc) throws UnsupportedEncodingException {
|
||||
return output.toString(enc);
|
||||
}
|
||||
|
||||
public void write(byte[] b, int off, int len) {
|
||||
output.write(b, off, len);
|
||||
}
|
||||
|
||||
public void write(byte[] b) throws IOException {
|
||||
output.write(b);
|
||||
}
|
||||
|
||||
public void writeTo(OutputStream out) throws IOException {
|
||||
output.writeTo(out);
|
||||
}
|
||||
|
||||
public OutputStream getOutputStream() {
|
||||
return this.output;
|
||||
}
|
||||
|
||||
public byte[] getResultData() {
|
||||
return resultData;
|
||||
}
|
||||
|
||||
public void setResultData(byte[] resultData) {
|
||||
this.resultData = resultData;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
package com.nexacro.spring.data;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.ServletOutputStream;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import com.nexacro.xapi.data.DataSet;
|
||||
import com.nexacro.xapi.data.PlatformData;
|
||||
import com.nexacro.xapi.data.Variable;
|
||||
import com.nexacro.xapi.tx.DataDeserializer;
|
||||
import com.nexacro.xapi.tx.DataSerializerFactory;
|
||||
import com.nexacro.xapi.tx.PlatformException;
|
||||
import com.nexacro.xapi.tx.PlatformType;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Statements
|
||||
* </pre>
|
||||
*
|
||||
* @ClassName : NexacroFirstRowHandlerTest.java
|
||||
* @Description : 클래스 설명을 기술합니다.
|
||||
* @author Park SeongMin
|
||||
* @since 2015. 8. 18.
|
||||
* @version 1.0
|
||||
* @see
|
||||
* @Modification Information
|
||||
*
|
||||
* <pre>
|
||||
* since author description
|
||||
* =========== ============= ===========================
|
||||
* 2015. 8. 18. Park SeongMin 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(locations = { "classpath*:spring/context-*.xml" } )
|
||||
public class NexacroFirstRowHandlerTest {
|
||||
|
||||
// @Autowired
|
||||
// private LargeDataService largeService;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendVariableAfterSendDataSet() {
|
||||
|
||||
FirstRowTrackableServletOutputStream outputStream = new FirstRowTrackableServletOutputStream();
|
||||
NexacroFirstRowHandler firstRowHandler = createFirstRowHandler(outputStream);
|
||||
|
||||
DataSet ds = new DataSet("ds1");
|
||||
try {
|
||||
firstRowHandler.sendDataSet(ds);
|
||||
} catch (PlatformException e) {
|
||||
Assert.fail("send dataset failed. e=" + e);
|
||||
}
|
||||
|
||||
Variable var = Variable.createVariable("var1", "test");
|
||||
try {
|
||||
firstRowHandler.sendVariable(var);
|
||||
Assert.fail("DataSet aleady sended. can't send a variable after sending dataSet.");
|
||||
} catch (PlatformException e) {
|
||||
}
|
||||
}
|
||||
|
||||
// @Test
|
||||
public void testFirstRowIbatis() {
|
||||
boolean useJdbcTemplate = false;
|
||||
doCallService(useJdbcTemplate);
|
||||
}
|
||||
|
||||
// @Test
|
||||
public void testFirstRowJdbcTemplate() {
|
||||
boolean useJdbcTemplate = true;
|
||||
doCallService(useJdbcTemplate);
|
||||
}
|
||||
|
||||
private void doCallService(boolean useJdbcTemplate) {
|
||||
|
||||
FirstRowTrackableServletOutputStream outputStream = new FirstRowTrackableServletOutputStream();
|
||||
NexacroFirstRowHandler firstRowHandler = createFirstRowHandler(outputStream);
|
||||
|
||||
String sendDataSetName = "firstRowData";
|
||||
int initDataCount = 1000;
|
||||
|
||||
int firstRowCount = 100;
|
||||
// call service
|
||||
// if(useJdbcTemplate) {
|
||||
// largeService.selectJdbcLargeData(firstRowHandler, sendDataSetName, firstRowCount, initDataCount);
|
||||
// } else {
|
||||
// largeService.selectLargeData(firstRowHandler, sendDataSetName, firstRowCount, initDataCount);
|
||||
// }
|
||||
|
||||
// end tag
|
||||
try {
|
||||
NexacroFirstRowAccessor.end(firstRowHandler);
|
||||
} catch (PlatformException e) {
|
||||
Assert.fail("fail. call end method. e=" + e);
|
||||
}
|
||||
|
||||
PlatformData platformData = readPlatformData(outputStream);
|
||||
|
||||
Assert.assertNotNull("first row function is not work. check it.", platformData);
|
||||
|
||||
DataSet sendedDataSet = platformData.getDataSet(sendDataSetName);
|
||||
Assert.assertNotNull("first row function is not work. check it.", sendedDataSet);
|
||||
|
||||
int actualRowCount = sendedDataSet.getRowCount();
|
||||
int expectedRowCount = initDataCount;
|
||||
Assert.assertEquals("sended row count not same.", expectedRowCount, actualRowCount);
|
||||
|
||||
}
|
||||
|
||||
private NexacroFirstRowHandler createFirstRowHandler(ServletOutputStream outputStream) {
|
||||
|
||||
// response를 생성한다.
|
||||
FirstRowHttpResponse httpServletResponse = new FirstRowHttpResponse();
|
||||
|
||||
// output stream을 입력합니다.
|
||||
httpServletResponse.setOutputStream(outputStream);
|
||||
|
||||
httpServletResponse.setCharacterEncoding("UTF-8");
|
||||
httpServletResponse.setContentType("text/xml;charset=UTF-8");
|
||||
|
||||
NexacroFirstRowHandler firstRowHandler = new NexacroFirstRowHandler(httpServletResponse);
|
||||
|
||||
return firstRowHandler;
|
||||
|
||||
}
|
||||
|
||||
private PlatformData readPlatformData(FirstRowTrackableServletOutputStream outputStream) {
|
||||
|
||||
// check outputstream..
|
||||
List<byte[]> flushedOutputList = outputStream.getFlushedByteList();
|
||||
String platformXml = "";
|
||||
int flushedSize = flushedOutputList.size();
|
||||
for (int listIndex = 0; listIndex < flushedSize; listIndex++) {
|
||||
byte[] outputBytes = (byte[]) flushedOutputList.get(listIndex);
|
||||
String xmlflagment = new String(outputBytes);
|
||||
platformXml = platformXml + xmlflagment;
|
||||
// the data of last flush by xapi, aways come a blank data. so check
|
||||
// without last data for blank data.
|
||||
if (listIndex != (flushedSize - 1) && xmlflagment.trim().equals("")) {
|
||||
Assert.fail("xml flagment must not be blank");
|
||||
}
|
||||
}
|
||||
|
||||
DataDeserializer deserializer = DataSerializerFactory.getDeserializer(PlatformType.CONTENT_TYPE_XML);
|
||||
InputStream inputStream = new ByteArrayInputStream(platformXml.getBytes());
|
||||
|
||||
PlatformData platformData = null;
|
||||
try {
|
||||
platformData = deserializer.readData(inputStream, null, "utf8");
|
||||
} catch (PlatformException e) {
|
||||
Assert.fail("get platformData failed. e=" + e);
|
||||
}
|
||||
|
||||
return platformData;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.nexacro.spring.data.convert;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Statements
|
||||
* </pre>
|
||||
*
|
||||
* @ClassName : NexacroConvertListenerTest.java
|
||||
* @Description : 클래스 설명을 기술합니다.
|
||||
* @author Park SeongMin
|
||||
* @since 2015. 8. 9.
|
||||
* @version 1.0
|
||||
* @see
|
||||
* @Modification Information
|
||||
* <pre>
|
||||
* since author description
|
||||
* =========== ============= ===========================
|
||||
* 2015. 8. 9. Park SeongMin 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public class NexacroConvertListenerTest {
|
||||
|
||||
@Test
|
||||
public void testNothing() {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
package com.nexacro.spring.data.convert;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.nexacro.xapi.data.DataSet;
|
||||
import com.nexacro.xapi.data.Variable;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Statements
|
||||
* </pre>
|
||||
*
|
||||
* @ClassName : NexacroConverterFactoryTest.java
|
||||
* @Description : 클래스 설명을 기술합니다.
|
||||
* @author Park SeongMin
|
||||
* @since 2015. 8. 4.
|
||||
* @version 1.0
|
||||
* @see
|
||||
* @Modification Information
|
||||
*
|
||||
* <pre>
|
||||
* since author description
|
||||
* =========== ============= ===========================
|
||||
* 2015. 8. 4. Park SeongMin 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public class NexacroConverterFactoryTest {
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaultConverter() {
|
||||
|
||||
Class<?> source, target;
|
||||
NexacroConverter converter = null;
|
||||
|
||||
source = Object.class;
|
||||
target = Variable.class;
|
||||
converter = NexacroConverterFactory.getConverter(source, target);
|
||||
Assert.assertNotNull(source + " -> " + target + " converter not registed.", converter);
|
||||
|
||||
source = Variable.class;
|
||||
target = Object.class;
|
||||
converter = NexacroConverterFactory.getConverter(source, target);
|
||||
Assert.assertNotNull(source + " -> " + target + " converter not registed.", converter);
|
||||
|
||||
source = List.class;
|
||||
target = DataSet.class;
|
||||
converter = NexacroConverterFactory.getConverter(source, target);
|
||||
Assert.assertNotNull(source + " -> " + target + " converter not registed.", converter);
|
||||
|
||||
source = DataSet.class;
|
||||
target = List.class;
|
||||
converter = NexacroConverterFactory.getConverter(source, target);
|
||||
Assert.assertNotNull(source + " -> " + target + " converter not registed.", converter);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRegistConverter() {
|
||||
|
||||
Class<?> source, target;
|
||||
source = Collection.class;
|
||||
target = DataSet.class;
|
||||
|
||||
UndefinedConverter undefinedConverter = new UndefinedConverter(source, target);
|
||||
NexacroConverterFactory.register(undefinedConverter);
|
||||
NexacroConverter converter = NexacroConverterFactory.getConverter(source, target);
|
||||
Assert.assertNotNull(source + " -> " + target + " converter not registed.", converter);
|
||||
|
||||
}
|
||||
|
||||
private static class UndefinedConverter implements NexacroConverter {
|
||||
|
||||
private Class<?> sourceType;
|
||||
private Class<?> targetType;
|
||||
|
||||
UndefinedConverter(Class<?> sourceType, Class<?> targetType) {
|
||||
this.sourceType = sourceType;
|
||||
this.targetType = targetType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(Object source, ConvertDefinition definition) throws NexacroConvertException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canConvert(Class source, Class target) {
|
||||
if (sourceType.equals(source) && targetType.equals(target)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(NexacroConvertListener listener) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener(NexacroConvertListener listener) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,702 @@
|
||||
package com.nexacro.spring.data.support;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.BeanWrapper;
|
||||
import org.springframework.beans.BeanWrapperImpl;
|
||||
import org.springframework.util.StopWatch;
|
||||
|
||||
import com.nexacro.spring.data.DataSetRowTypeAccessor;
|
||||
import com.nexacro.spring.data.DataSetSavedDataAccessor;
|
||||
import com.nexacro.spring.data.convert.ConvertDefinition;
|
||||
import com.nexacro.spring.data.convert.NexacroConvertException;
|
||||
import com.nexacro.spring.data.support.NexacroTestUtil.DataSetRowTypeBean;
|
||||
import com.nexacro.spring.data.support.NexacroTestUtil.DataSetSavedDataBean;
|
||||
import com.nexacro.spring.data.support.NexacroTestUtil.StaticPropertyBean;
|
||||
import com.nexacro.spring.data.support.bean.DefaultBean;
|
||||
import com.nexacro.xapi.data.DataSet;
|
||||
import com.nexacro.xapi.data.datatype.PlatformDataType;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Statements
|
||||
* </pre>
|
||||
*
|
||||
* @ClassName : DataSetToListConverterTest.java
|
||||
* @Description : 클래스 설명을 기술합니다.
|
||||
* @author Park SeongMin
|
||||
* @since 2015. 8. 4.
|
||||
* @version 1.0
|
||||
* @see
|
||||
* @Modification Information
|
||||
* <pre>
|
||||
* since author description
|
||||
* =========== ============= ===========================
|
||||
* 2015. 8. 4. Park SeongMin 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public class DataSetToListConverterTest {
|
||||
|
||||
private DataSetToListConverter converter;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
converter = new DataSetToListConverter();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSupportedType() {
|
||||
Class<?> source;
|
||||
Class<?> target;
|
||||
|
||||
source = DataSet.class;
|
||||
target = List.class;
|
||||
boolean canConvert = converter.canConvert(source, target);
|
||||
|
||||
Assert.assertTrue(source + " to " + target + " must be converted", canConvert);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnSupportedType() {
|
||||
Class<?> source;
|
||||
Class<?> target;
|
||||
boolean canConvert;
|
||||
|
||||
source = DataSet.class;
|
||||
target = ArrayList.class;
|
||||
canConvert = converter.canConvert(source, target);
|
||||
Assert.assertFalse(source + " to " + target + " can not convertible", canConvert);
|
||||
|
||||
source = List.class;
|
||||
target = DataSet.class;
|
||||
canConvert = converter.canConvert(source, target);
|
||||
Assert.assertFalse(source + " to " + target + " can not convertible", canConvert);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConvertDataSetToListBean() {
|
||||
|
||||
DataSet defaultDataSet = NexacroTestUtil.createDefaultDataSet();
|
||||
|
||||
ConvertDefinition definition = new ConvertDefinition(defaultDataSet.getName());
|
||||
definition.setGenericType(DefaultBean.class); // for bean
|
||||
|
||||
Object convertedList = null;
|
||||
try {
|
||||
convertedList = converter.convert(defaultDataSet, definition);
|
||||
} catch (NexacroConvertException e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail(e.getMessage());
|
||||
}
|
||||
|
||||
if(!(convertedList instanceof List)) {
|
||||
Assert.fail("converted object must be implemented List");
|
||||
}
|
||||
|
||||
NexacroTestUtil.compareDefaultBeans((List<DefaultBean>) convertedList);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConvertDataSetToListMap() {
|
||||
|
||||
DataSet defaultDataSet = NexacroTestUtil.createDefaultDataSet();
|
||||
|
||||
ConvertDefinition definition = new ConvertDefinition(defaultDataSet.getName());
|
||||
definition.setGenericType(Map.class); // for map
|
||||
|
||||
Object convertedList = null;
|
||||
try {
|
||||
convertedList = converter.convert(defaultDataSet, definition);
|
||||
} catch (NexacroConvertException e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail(e.getMessage());
|
||||
}
|
||||
|
||||
if(!(convertedList instanceof List)) {
|
||||
Assert.fail("converted object must be implemented List");
|
||||
}
|
||||
|
||||
NexacroTestUtil.compareDefaultMaps((List<Map<String, Object>>) convertedList);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUndefinedGenericType() {
|
||||
DataSet defaultDataSet = NexacroTestUtil.createDefaultDataSet();
|
||||
|
||||
ConvertDefinition definition = new ConvertDefinition(defaultDataSet.getName());
|
||||
// definition.setGenericType(DefaultBean.class);
|
||||
|
||||
Object convertedList = null;
|
||||
try {
|
||||
convertedList = converter.convert(defaultDataSet, definition);
|
||||
Assert.fail("generic type not declared. exception must be occured.");
|
||||
} catch (NexacroConvertException e) {
|
||||
// nothing..
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullData() {
|
||||
|
||||
DataSet ds = null;
|
||||
ConvertDefinition definition = new ConvertDefinition("ds");
|
||||
definition.setGenericType(DefaultBean.class);
|
||||
|
||||
List list = null;
|
||||
try {
|
||||
list = converter.convert(ds, definition);
|
||||
} catch (NexacroConvertException e) {
|
||||
Assert.fail(e.getMessage());
|
||||
}
|
||||
|
||||
Assert.assertNotNull("converted list should not be null", list);
|
||||
Assert.assertEquals(ArrayList.class, list.getClass());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStaticColumns() {
|
||||
|
||||
double commissionPercent = 10.0d;
|
||||
|
||||
DataSet ds = new DataSet("static");
|
||||
ds.addConstantColumn("commissionPercent", PlatformDataType.DOUBLE, commissionPercent);
|
||||
ds.addColumn("name", PlatformDataType.STRING);
|
||||
int newRow;
|
||||
newRow = ds.newRow();
|
||||
ds.set(newRow, "name", "tom");
|
||||
newRow = ds.newRow();
|
||||
ds.set(newRow, "name", "david");
|
||||
|
||||
ConvertDefinition definition = new ConvertDefinition(ds.getName());
|
||||
definition.setGenericType(StaticPropertyBean.class);
|
||||
List convertedList = null;
|
||||
try {
|
||||
convertedList = converter.convert(ds, definition);
|
||||
} catch (NexacroConvertException e) {
|
||||
Assert.fail(e.getMessage());
|
||||
}
|
||||
|
||||
Assert.assertNotNull("converted list should not be null.", convertedList);
|
||||
|
||||
StaticPropertyBean staticBean = (StaticPropertyBean) convertedList.get(0);
|
||||
Assert.assertEquals("tom", staticBean.getName());
|
||||
Assert.assertEquals(commissionPercent, staticBean.getCommissionPercent());
|
||||
|
||||
staticBean = (StaticPropertyBean) convertedList.get(1);
|
||||
Assert.assertEquals("david", staticBean.getName());
|
||||
Assert.assertEquals(commissionPercent, staticBean.getCommissionPercent());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpperCase() {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLowerCase() {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDataSetRowTypeWithBean() {
|
||||
|
||||
Class convertedType = DataSetRowTypeBean.class;// for bean
|
||||
|
||||
DataSet ds = new DataSet("dsRowType");
|
||||
ds.addColumn("name", PlatformDataType.STRING);
|
||||
int newRow = ds.newRow();
|
||||
ds.set(newRow, "name", "tom");
|
||||
|
||||
// update..
|
||||
ds.startStoreDataChanges();
|
||||
ds.set(newRow, "name", "david");
|
||||
|
||||
ConvertDefinition definition = new ConvertDefinition(ds.getName());
|
||||
definition.setGenericType(convertedType);
|
||||
|
||||
List convertedList = null;
|
||||
try {
|
||||
convertedList = converter.convert(ds, definition);
|
||||
} catch (NexacroConvertException e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail(e.getMessage());
|
||||
}
|
||||
|
||||
if(!(convertedList instanceof List)) {
|
||||
Assert.fail("converted object must be implemented List");
|
||||
}
|
||||
|
||||
Assert.assertNotNull("converted list should not be null.", convertedList);
|
||||
|
||||
int expectedCnt = ds.getRowCount();
|
||||
int actualCnt = convertedList.size();
|
||||
Assert.assertEquals(expectedCnt, actualCnt);
|
||||
|
||||
DataSetRowTypeBean rowTypeBean = (DataSetRowTypeBean) convertedList.get(0);
|
||||
Assert.assertEquals("david", rowTypeBean.getName());
|
||||
// expected DataSet.ROW_TYPE_NAME_UPDATED
|
||||
Assert.assertEquals("rowType data should be maintained.", DataSet.ROW_TYPE_UPDATED, rowTypeBean.getRowType());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDataSetRowTypeWithMap() {
|
||||
|
||||
Class convertedType = Map.class;
|
||||
|
||||
DataSet ds = new DataSet("dsRowType");
|
||||
ds.addColumn("name", PlatformDataType.STRING);
|
||||
int newRow = ds.newRow();
|
||||
ds.set(newRow, "name", "tom");
|
||||
|
||||
// update..
|
||||
ds.startStoreDataChanges();
|
||||
ds.set(newRow, "name", "david");
|
||||
|
||||
ConvertDefinition definition = new ConvertDefinition(ds.getName());
|
||||
definition.setGenericType(convertedType);
|
||||
|
||||
List convertedList = null;
|
||||
try {
|
||||
convertedList = converter.convert(ds, definition);
|
||||
} catch (NexacroConvertException e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail(e.getMessage());
|
||||
}
|
||||
|
||||
if(!(convertedList instanceof List)) {
|
||||
Assert.fail("converted object must be implemented List");
|
||||
}
|
||||
|
||||
Assert.assertNotNull("converted list should not be null.", convertedList);
|
||||
|
||||
int expectedCnt = ds.getRowCount();
|
||||
int actualCnt = convertedList.size();
|
||||
Assert.assertEquals(expectedCnt, actualCnt);
|
||||
|
||||
Map rowTypeMap = (Map) convertedList.get(0);
|
||||
Assert.assertEquals("david", rowTypeMap.get("name"));
|
||||
Assert.assertEquals("rowType data should be maintained.", DataSet.ROW_TYPE_UPDATED, rowTypeMap.get(DataSetRowTypeAccessor.NAME));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDataSetSavedDataWithBean() {
|
||||
|
||||
Class convertedType = DataSetSavedDataBean.class;// for bean
|
||||
|
||||
DataSet ds = new DataSet("dsRowType");
|
||||
ds.addColumn("name", PlatformDataType.STRING);
|
||||
int newRow = ds.newRow();
|
||||
ds.set(newRow, "name", "tom");
|
||||
|
||||
// update..
|
||||
ds.startStoreDataChanges();
|
||||
ds.set(newRow, "name", "david");
|
||||
|
||||
// inserted..
|
||||
newRow = ds.newRow();
|
||||
ds.set(newRow, "name", "tom");
|
||||
|
||||
ConvertDefinition definition = new ConvertDefinition(ds.getName());
|
||||
definition.setGenericType(convertedType);
|
||||
|
||||
List convertedList = null;
|
||||
try {
|
||||
convertedList = converter.convert(ds, definition);
|
||||
} catch (NexacroConvertException e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail(e.getMessage());
|
||||
}
|
||||
|
||||
if(!(convertedList instanceof List)) {
|
||||
Assert.fail("converted object must be implemented List");
|
||||
}
|
||||
|
||||
Assert.assertNotNull("converted list should not be null.", convertedList);
|
||||
|
||||
int expectedCnt = ds.getRowCount();
|
||||
int actualCnt = convertedList.size();
|
||||
Assert.assertEquals(expectedCnt, actualCnt);
|
||||
|
||||
DataSetSavedDataBean bean, savedData = null;
|
||||
String expectedSavedData, actualSavedData;
|
||||
|
||||
// first row is updated data..
|
||||
bean = (DataSetSavedDataBean) convertedList.get(0);
|
||||
Assert.assertEquals("david", bean.getName());
|
||||
Assert.assertEquals("rowType data should be maintained.", DataSet.ROW_TYPE_UPDATED, bean.getRowType());
|
||||
savedData = bean.getData();
|
||||
expectedSavedData = "tom";
|
||||
actualSavedData = savedData.getName();
|
||||
Assert.assertEquals("saved data should be maintained.", expectedSavedData, actualSavedData);
|
||||
|
||||
|
||||
// second row is inserted data..
|
||||
bean = (DataSetSavedDataBean) convertedList.get(1);
|
||||
Assert.assertEquals("tom", bean.getName());
|
||||
Assert.assertEquals("rowType data should be maintained.", DataSet.ROW_TYPE_INSERTED, bean.getRowType());
|
||||
savedData = bean.getData();
|
||||
Assert.assertNull("additional data should be null data.", savedData);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDataSetSavedDataWithMap() {
|
||||
|
||||
Class convertedType = Map.class; // for map
|
||||
|
||||
DataSet ds = new DataSet("dsRowType");
|
||||
ds.addColumn("name", PlatformDataType.STRING);
|
||||
int newRow = ds.newRow();
|
||||
ds.set(newRow, "name", "tom");
|
||||
|
||||
// update..
|
||||
ds.startStoreDataChanges();
|
||||
ds.set(newRow, "name", "david");
|
||||
|
||||
// inserted..
|
||||
newRow = ds.newRow();
|
||||
ds.set(newRow, "name", "tom");
|
||||
|
||||
ConvertDefinition definition = new ConvertDefinition(ds.getName());
|
||||
definition.setGenericType(convertedType);
|
||||
|
||||
List convertedList = null;
|
||||
try {
|
||||
convertedList = converter.convert(ds, definition);
|
||||
} catch (NexacroConvertException e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail(e.getMessage());
|
||||
}
|
||||
|
||||
if(!(convertedList instanceof List)) {
|
||||
Assert.fail("converted object must be implemented List");
|
||||
}
|
||||
|
||||
Assert.assertNotNull("converted list should not be null.", convertedList);
|
||||
|
||||
int expectedCnt = ds.getRowCount();
|
||||
int actualCnt = convertedList.size();
|
||||
Assert.assertEquals(expectedCnt, actualCnt);
|
||||
|
||||
Map<String, Object> dataMap, savedData = null;
|
||||
String expectedSavedData, actualSavedData;
|
||||
|
||||
// first row is updated data..
|
||||
dataMap = (Map<String, Object>) convertedList.get(0);
|
||||
Assert.assertEquals("david", dataMap.get("name"));
|
||||
Assert.assertEquals("rowType data should be maintained.", DataSet.ROW_TYPE_UPDATED, dataMap.get(DataSetRowTypeAccessor.NAME));
|
||||
|
||||
savedData = (Map<String, Object>) dataMap.get(DataSetSavedDataAccessor.NAME);
|
||||
expectedSavedData = "tom";
|
||||
actualSavedData = (String) savedData.get("name");
|
||||
Assert.assertEquals("saved data should be maintained.", expectedSavedData, actualSavedData);
|
||||
|
||||
// second row is inserted data..
|
||||
dataMap = (Map<String, Object>) convertedList.get(1);
|
||||
Assert.assertEquals("tom", dataMap.get("name"));
|
||||
Assert.assertEquals("rowType data should be maintained.", DataSet.ROW_TYPE_INSERTED, dataMap.get(DataSetRowTypeAccessor.NAME));
|
||||
savedData = (Map<String, Object>) dataMap.get(DataSetSavedDataAccessor.NAME);
|
||||
Assert.assertNull("additional data should be null data.", savedData);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemovedDataWithBean() {
|
||||
|
||||
Class convertedType = DataSetSavedDataBean.class;
|
||||
|
||||
DataSet ds = new DataSet("dsRowType");
|
||||
ds.addColumn("name", PlatformDataType.STRING);
|
||||
int newRow = ds.newRow();
|
||||
ds.set(newRow, "name", "tom");
|
||||
|
||||
// delete..
|
||||
ds.startStoreDataChanges();
|
||||
ds.set(newRow, "name", "david");
|
||||
ds.removeRow(0);
|
||||
|
||||
// inserted..
|
||||
newRow = ds.newRow();
|
||||
ds.set(newRow, "name", "tom");
|
||||
|
||||
ConvertDefinition definition = new ConvertDefinition(ds.getName());
|
||||
definition.setGenericType(convertedType); // for bean
|
||||
|
||||
List convertedList = null;
|
||||
try {
|
||||
convertedList = converter.convert(ds, definition);
|
||||
} catch (NexacroConvertException e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail(e.getMessage());
|
||||
}
|
||||
|
||||
if(!(convertedList instanceof List)) {
|
||||
Assert.fail("converted object must be implemented List");
|
||||
}
|
||||
|
||||
Assert.assertNotNull("converted list should not be null.", convertedList);
|
||||
|
||||
int expectedCnt = ds.getRowCount() + 1; // +1 is removed data..
|
||||
int actualCnt = convertedList.size();
|
||||
Assert.assertEquals(expectedCnt, actualCnt);
|
||||
|
||||
DataSetSavedDataBean bean, savedData = null;
|
||||
|
||||
// first row is inserted data.
|
||||
bean = (DataSetSavedDataBean) convertedList.get(0);
|
||||
Assert.assertEquals("tom", bean.getName());
|
||||
Assert.assertEquals("rowType data should be maintained.", DataSet.ROW_TYPE_INSERTED, bean.getRowType());
|
||||
savedData = bean.getData();
|
||||
Assert.assertNull("additional data should be null data.", savedData);
|
||||
|
||||
// second row is deleted data..
|
||||
bean = (DataSetSavedDataBean) convertedList.get(1);
|
||||
Assert.assertEquals("deleted data must be saved data", "tom", bean.getName()); // original data..
|
||||
Assert.assertEquals("rowType data should be maintained.", DataSet.ROW_TYPE_DELETED, bean.getRowType());
|
||||
savedData = bean.getData();
|
||||
Assert.assertNull("saved data must be null.", savedData);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemovedDataWithMap() {
|
||||
|
||||
Class convertedType = Map.class;
|
||||
|
||||
DataSet ds = new DataSet("dsRowType");
|
||||
ds.addColumn("name", PlatformDataType.STRING);
|
||||
int newRow = ds.newRow();
|
||||
ds.set(newRow, "name", "tom");
|
||||
|
||||
// delete..
|
||||
ds.startStoreDataChanges();
|
||||
ds.set(newRow, "name", "david");
|
||||
ds.removeRow(0);
|
||||
|
||||
// inserted..
|
||||
newRow = ds.newRow();
|
||||
ds.set(newRow, "name", "tom");
|
||||
|
||||
ConvertDefinition definition = new ConvertDefinition(ds.getName());
|
||||
definition.setGenericType(convertedType); // for bean
|
||||
|
||||
List convertedList = null;
|
||||
try {
|
||||
convertedList = converter.convert(ds, definition);
|
||||
} catch (NexacroConvertException e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail(e.getMessage());
|
||||
}
|
||||
|
||||
if(!(convertedList instanceof List)) {
|
||||
Assert.fail("converted object must be implemented List");
|
||||
}
|
||||
|
||||
Assert.assertNotNull("converted list should not be null.", convertedList);
|
||||
|
||||
int expectedCnt = ds.getRowCount() + 1; // +1 is removed data..
|
||||
int actualCnt = convertedList.size();
|
||||
Assert.assertEquals(expectedCnt, actualCnt);
|
||||
|
||||
Map<String, Object> dataMap, savedData = null;
|
||||
String expectedSavedData, actualSavedData;
|
||||
|
||||
// first row is inserted data.
|
||||
dataMap = (Map<String, Object>) convertedList.get(0);
|
||||
Assert.assertEquals("tom", dataMap.get("name"));
|
||||
Assert.assertEquals("rowType data should be maintained.", DataSet.ROW_TYPE_INSERTED, dataMap.get(DataSetRowTypeAccessor.NAME));
|
||||
savedData = (Map<String, Object>) dataMap.get(DataSetSavedDataAccessor.NAME);
|
||||
Assert.assertNull("additional data should be null data.", savedData);
|
||||
|
||||
// second row is deleted data..
|
||||
dataMap = (Map<String, Object>) convertedList.get(1);
|
||||
Assert.assertEquals("deleted data must be saved data", "tom", dataMap.get("name")); // original data..
|
||||
Assert.assertEquals("rowType data should be maintained.", DataSet.ROW_TYPE_DELETED, dataMap.get(DataSetRowTypeAccessor.NAME));
|
||||
savedData = (Map<String, Object>) dataMap.get(DataSetSavedDataAccessor.NAME);
|
||||
Assert.assertNull("saved data must be null.", savedData);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStaticSpringBeanWrapper() {
|
||||
|
||||
BeanWrapper wrapper = new BeanWrapperImpl(StaticPropertyBean.class);
|
||||
wrapper.setPropertyValue("commissionPercent", 10.0d);
|
||||
// System.out.println(wrapper.getPropertyValue("comissionPercent"));
|
||||
StaticPropertyBean bean = (StaticPropertyBean) wrapper.getWrappedInstance();
|
||||
// System.out.println(bean.getComissionPercent());
|
||||
|
||||
}
|
||||
|
||||
// @Test
|
||||
public void testStaticIbatis() {
|
||||
|
||||
// StaticPropertyBean bean = new StaticPropertyBean();
|
||||
// bean.setCommissionPercent(10.0d);
|
||||
//
|
||||
// ClassInfo ref = ClassInfo.getInstance(StaticPropertyBean.class);
|
||||
//
|
||||
// Invoker setInvoker = ref.getSetInvoker("commissionPercent");
|
||||
// try {
|
||||
// setInvoker.invoke(bean, new Object[]{11.0d});
|
||||
// } catch (IllegalAccessException e1) {
|
||||
// e1.printStackTrace();
|
||||
// } catch (InvocationTargetException e1) {
|
||||
// e1.printStackTrace();
|
||||
// }
|
||||
//
|
||||
// Invoker getInvoker = ref.getGetInvoker("commissionPercent");
|
||||
// try {
|
||||
// Object invoke = getInvoker.invoke(bean, new Object[]{});
|
||||
//// System.out.println(invoke);
|
||||
// } catch (IllegalAccessException e) {
|
||||
// e.printStackTrace();
|
||||
// } catch (InvocationTargetException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConvertPerformance() {
|
||||
|
||||
StopWatch sw = new StopWatch(getClass().getSimpleName());
|
||||
|
||||
int columnCount = 10;
|
||||
DataSet ds = new DataSet("ds");
|
||||
for(int i=0; i<columnCount; i++) {
|
||||
ds.addColumn("column"+i, PlatformDataType.STRING);
|
||||
}
|
||||
|
||||
sw.start("set data");
|
||||
int rowCount = 10000;
|
||||
for(int rowIndex=0; rowIndex<rowCount; rowIndex++) {
|
||||
int newRow = ds.newRow();
|
||||
for(int colIndex=0; colIndex<columnCount; colIndex++) {
|
||||
ds.set(newRow, colIndex, "value"+rowIndex+colIndex);
|
||||
}
|
||||
}
|
||||
sw.stop();
|
||||
|
||||
sw.start("get data");
|
||||
for(int rowIndex=0; rowIndex<rowCount; rowIndex++) {
|
||||
for(int colIndex=0; colIndex<columnCount; colIndex++) {
|
||||
ds.getString(rowIndex, colIndex);
|
||||
}
|
||||
}
|
||||
sw.stop();
|
||||
|
||||
|
||||
|
||||
DataSetToListConverter converter = new DataSetToListConverter();
|
||||
ConvertDefinition definition = new ConvertDefinition("ds");
|
||||
definition.setGenericType(Map.class);
|
||||
try {
|
||||
sw.start("convert List<Map>");
|
||||
java.util.List convert = converter.convert(ds, definition);
|
||||
} catch (NexacroConvertException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
sw.stop();
|
||||
}
|
||||
|
||||
definition.setGenericType(DataSetObj.class);
|
||||
try {
|
||||
sw.start("convert List<DataSetObj>");
|
||||
java.util.List convert = converter.convert(ds, definition);
|
||||
} catch (NexacroConvertException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
sw.stop();
|
||||
}
|
||||
|
||||
System.out.println(sw.prettyPrint());
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static class DataSetObj {
|
||||
private String column0;
|
||||
private String column1;
|
||||
private String column2;
|
||||
private String column3;
|
||||
private String column4;
|
||||
private String column5;
|
||||
private String column6;
|
||||
private String column7;
|
||||
private String column8;
|
||||
private String column9;
|
||||
public String getColumn0() {
|
||||
return column0;
|
||||
}
|
||||
public void setColumn0(String column0) {
|
||||
this.column0 = column0;
|
||||
}
|
||||
public String getColumn1() {
|
||||
return column1;
|
||||
}
|
||||
public void setColumn1(String column1) {
|
||||
this.column1 = column1;
|
||||
}
|
||||
public String getColumn2() {
|
||||
return column2;
|
||||
}
|
||||
public void setColumn2(String column2) {
|
||||
this.column2 = column2;
|
||||
}
|
||||
public String getColumn3() {
|
||||
return column3;
|
||||
}
|
||||
public void setColumn3(String column3) {
|
||||
this.column3 = column3;
|
||||
}
|
||||
public String getColumn4() {
|
||||
return column4;
|
||||
}
|
||||
public void setColumn4(String column4) {
|
||||
this.column4 = column4;
|
||||
}
|
||||
public String getColumn5() {
|
||||
return column5;
|
||||
}
|
||||
public void setColumn5(String column5) {
|
||||
this.column5 = column5;
|
||||
}
|
||||
public String getColumn6() {
|
||||
return column6;
|
||||
}
|
||||
public void setColumn6(String column6) {
|
||||
this.column6 = column6;
|
||||
}
|
||||
public String getColumn7() {
|
||||
return column7;
|
||||
}
|
||||
public void setColumn7(String column7) {
|
||||
this.column7 = column7;
|
||||
}
|
||||
public String getColumn8() {
|
||||
return column8;
|
||||
}
|
||||
public void setColumn8(String column8) {
|
||||
this.column8 = column8;
|
||||
}
|
||||
public String getColumn9() {
|
||||
return column9;
|
||||
}
|
||||
public void setColumn9(String column9) {
|
||||
this.column9 = column9;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,372 @@
|
||||
package com.nexacro.spring.data.support;
|
||||
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
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.xapi.data.ColumnHeader;
|
||||
import com.nexacro.xapi.data.ConstantColumnHeader;
|
||||
import com.nexacro.xapi.data.DataSet;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Statements
|
||||
* </pre>
|
||||
*
|
||||
* @ClassName : ListToDataSetConverterTest.java
|
||||
* @Description : 클래스 설명을 기술합니다.
|
||||
* @author Park SeongMin
|
||||
* @since 2015. 8. 4.
|
||||
* @version 1.0
|
||||
* @see
|
||||
* @Modification Information
|
||||
* <pre>
|
||||
* since author description
|
||||
* =========== ============= ===========================
|
||||
* 2015. 8. 4. Park SeongMin 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public class ListToDataSetConverterTest {
|
||||
|
||||
private ListToDataSetConverter converter;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
converter = new ListToDataSetConverter();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSupportedType() {
|
||||
Class<?> source;
|
||||
Class<?> target;
|
||||
boolean canConvert;
|
||||
|
||||
source = List.class;
|
||||
target = DataSet.class;
|
||||
canConvert = converter.canConvert(source, target);
|
||||
Assert.assertTrue(source + " to " + target + " must be converted", canConvert);
|
||||
|
||||
// List sub class support.
|
||||
source = ArrayList.class;
|
||||
target = DataSet.class;
|
||||
canConvert = converter.canConvert(source, target);
|
||||
Assert.assertTrue(source + " to " + target + " must be converted", canConvert);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnSupportedType() {
|
||||
|
||||
Class<?> source;
|
||||
Class<?> target;
|
||||
boolean canConvert;
|
||||
|
||||
source = Object.class;
|
||||
target = DataSet.class;
|
||||
canConvert = converter.canConvert(source, target);
|
||||
Assert.assertFalse(source + " to " + target + " can not convertible", canConvert);
|
||||
|
||||
|
||||
List list = new ArrayList();
|
||||
list.add(new Object[]{1, 2});
|
||||
list.add(new Object[]{3, 4});
|
||||
|
||||
ConvertDefinition definition = new ConvertDefinition("ds");
|
||||
try {
|
||||
converter.convert(list, definition);
|
||||
Assert.fail("Object[] is unsupported type.");
|
||||
} catch (NexacroConvertException e) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConvertListBeanToDataSet() {
|
||||
|
||||
List<DefaultBean> defaultBean = NexacroTestUtil.createDefaultBeans();
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
NexacroTestUtil.compareDefaultDataSet((DataSet) ds);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConvertListMapToDataSet() {
|
||||
|
||||
List<Map<String, Object>> defaultMap = NexacroTestUtil.createDefaultMaps();
|
||||
|
||||
ConvertDefinition definition = new ConvertDefinition("ds");
|
||||
|
||||
Object ds = null;
|
||||
try {
|
||||
ds = converter.convert(defaultMap, definition);
|
||||
} catch (NexacroConvertException e) {
|
||||
e.printStackTrace();
|
||||
Assert.fail(e.getMessage());
|
||||
}
|
||||
|
||||
if(!(ds instanceof DataSet)) {
|
||||
Assert.fail("converted object must be implemented DataSet");
|
||||
}
|
||||
|
||||
NexacroTestUtil.compareDefaultDataSet((DataSet) ds);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullData() {
|
||||
|
||||
List list = null;
|
||||
ConvertDefinition definition = new ConvertDefinition("ds");
|
||||
|
||||
DataSet ds = null;
|
||||
try {
|
||||
ds = converter.convert(list, definition);
|
||||
} catch (NexacroConvertException e) {
|
||||
Assert.fail(e.getMessage());
|
||||
}
|
||||
|
||||
Assert.assertNotNull("dataset should not be null", ds);
|
||||
Assert.assertEquals("ds", ds.getName());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStaticColumns() {
|
||||
|
||||
StaticPropertyBean staticBean;
|
||||
double commissionPercent = 10.0d;
|
||||
|
||||
List<StaticPropertyBean> staticBeanList = new ArrayList<StaticPropertyBean>();
|
||||
staticBean = new StaticPropertyBean();
|
||||
staticBean.setName("tom");
|
||||
staticBean.setCommissionPercent(commissionPercent);
|
||||
staticBeanList.add(staticBean);
|
||||
|
||||
staticBean = new StaticPropertyBean();
|
||||
staticBean.setName("david");
|
||||
staticBeanList.add(staticBean);
|
||||
|
||||
ConvertDefinition definition = new ConvertDefinition("ds");
|
||||
DataSet ds = null;
|
||||
try {
|
||||
ds = converter.convert(staticBeanList, definition);
|
||||
} catch (NexacroConvertException e) {
|
||||
Assert.fail(e.getMessage());
|
||||
}
|
||||
|
||||
Assert.assertNotNull("converted list should not be null.", ds);
|
||||
|
||||
int columnCount = ds.getColumnCount();
|
||||
Assert.assertEquals("two columns must be exist.", 2, ds.getColumnCount());
|
||||
|
||||
ColumnHeader column = ds.getColumn("name");
|
||||
Assert.assertFalse(column.isConstant());
|
||||
|
||||
column = ds.getColumn("commissionPercent");
|
||||
Assert.assertTrue(column.isConstant());
|
||||
ConstantColumnHeader constColumn = (ConstantColumnHeader) column;
|
||||
|
||||
// check const column value
|
||||
Assert.assertEquals(commissionPercent, constColumn.getValue());
|
||||
|
||||
Assert.assertEquals("tom", ds.getString(0, "name"));
|
||||
Assert.assertEquals("david", ds.getString(1, "name"));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpperCase() {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLowerCase() {
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
@Test
|
||||
public void testNotSupportedRowType() {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotSupportedSavedData() {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotSupportedRemovedData() {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void testListConvert() {
|
||||
|
||||
List<DefaultBean> beanList = new ArrayList<DefaultBean>();
|
||||
|
||||
// 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();
|
||||
beanList.add(bean);
|
||||
|
||||
System.out.println("key = " + beanList);
|
||||
Class<?> clazz = beanList.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);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListType() {
|
||||
|
||||
List<DefaultBean> beanList = new ArrayList<DefaultBean>();
|
||||
Type[] parameterizedTypes = getParameterizedTypes(beanList);
|
||||
|
||||
Class<?> class1;
|
||||
try {
|
||||
class1 = getClass(parameterizedTypes[0]);
|
||||
System.out.println(class1);
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
// List<DefaultBean> beanList = new ArrayList<DefaultBean>();
|
||||
//
|
||||
// Class<?> class1 = getClass(beanList.getClass());
|
||||
// System.out.println(class1);
|
||||
// System.out.println(getClass(class1));
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package com.nexacro.spring.data.support;
|
||||
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.springframework.beans.NotWritablePropertyException;
|
||||
|
||||
import com.nexacro.spring.data.support.bean.DefaultBean;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Statements
|
||||
* </pre>
|
||||
*
|
||||
* @ClassName : NexacroBeanWrapperTest.java
|
||||
* @Description : 클래스 설명을 기술합니다.
|
||||
* @author Park SeongMin
|
||||
* @since 2015. 8. 4.
|
||||
* @version 1.0
|
||||
* @see
|
||||
* @Modification Information
|
||||
* <pre>
|
||||
* since author description
|
||||
* =========== ============= ===========================
|
||||
* 2015. 8. 4. Park SeongMin 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public class NexacroBeanWrapperTest {
|
||||
|
||||
@Test
|
||||
public void testInstantiateClass() {
|
||||
|
||||
NexacroBeanWrapper accessor = createAccessor(DefaultBean.class);
|
||||
Object insatance = accessor.getInsatance();
|
||||
assertNotNull(insatance);
|
||||
|
||||
if(!(insatance instanceof DefaultBean)) {
|
||||
fail("instantiate class must be instance of " + DefaultBean.class);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetPropertyValue() {
|
||||
|
||||
NexacroBeanWrapper accessor = createAccessor(DefaultBean.class);
|
||||
accessor.setPropertyValue("firstName", "tom");
|
||||
DefaultBean target = (DefaultBean) accessor.getInsatance();
|
||||
assertTrue("Set name to tom", target.getFirstName().equals("tom"));
|
||||
}
|
||||
|
||||
@Rule
|
||||
public ExpectedException thrown= ExpectedException.none();
|
||||
|
||||
@Test
|
||||
// @Test (expected=NotWritablePropertyException.class)
|
||||
public void testSetInvalidPropertyValue() {
|
||||
thrown.expect(NotWritablePropertyException.class);
|
||||
thrown.expectMessage("Invalid property 'invalid'");
|
||||
|
||||
NexacroBeanWrapper accessor = createAccessor(DefaultBean.class);
|
||||
accessor.setPropertyValue("invalid", "tom");
|
||||
DefaultBean target = (DefaultBean) accessor.getInsatance();
|
||||
Assert.assertEquals("Set name to tom", "tom", target.getFirstName());
|
||||
}
|
||||
|
||||
private NexacroBeanWrapper createAccessor(Class clazz) {
|
||||
NexacroBeanWrapper beanWrapper = NexacroBeanWrapper.createBeanWrapper(clazz);
|
||||
return beanWrapper;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,409 @@
|
||||
package com.nexacro.spring.data.support;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.Assert;
|
||||
|
||||
import com.nexacro.spring.data.DataSetRowTypeAccessor;
|
||||
import com.nexacro.spring.data.DataSetSavedDataAccessor;
|
||||
import com.nexacro.spring.data.support.bean.DefaultBean;
|
||||
import com.nexacro.xapi.data.ColumnHeader;
|
||||
import com.nexacro.xapi.data.DataSet;
|
||||
import com.nexacro.xapi.data.datatype.DataType;
|
||||
import com.nexacro.xapi.data.datatype.PlatformDataType;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Statements
|
||||
* </pre>
|
||||
*
|
||||
* @ClassName : TestDataUtil.java
|
||||
* @Description : 클래스 설명을 기술합니다.
|
||||
* @author Park SeongMin
|
||||
* @since 2015. 8. 10.
|
||||
* @version 1.0
|
||||
* @see
|
||||
* @Modification Information
|
||||
*
|
||||
* <pre>
|
||||
* since author description
|
||||
* =========== ============= ===========================
|
||||
* 2015. 8. 10. Park SeongMin 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public abstract class NexacroTestUtil {
|
||||
|
||||
private static String[] dsPropertyNames;
|
||||
private static List<Object[]> dsValuesList;
|
||||
private static DataType[] dsDataTypes;
|
||||
|
||||
// private static List<Map<String, Object>> dataMapList;
|
||||
// private static Map<String, DataType> dataTypeMap;
|
||||
|
||||
private static Map<Class, Object> supportedClassesValue;
|
||||
|
||||
static {
|
||||
initSupportedClassesValue();
|
||||
initDsPropertyNames();
|
||||
initDsValueList();
|
||||
initDsDataTypes();
|
||||
}
|
||||
|
||||
static Map<Class, Object> getSupportedClassesValue() {
|
||||
return Collections.unmodifiableMap(supportedClassesValue);
|
||||
}
|
||||
|
||||
private static void initSupportedClassesValue() {
|
||||
|
||||
supportedClassesValue = new HashMap<Class, Object>();
|
||||
|
||||
Calendar instance = null;
|
||||
Date hireDate = null;
|
||||
instance = Calendar.getInstance();
|
||||
instance.set(2009, Calendar.JANUARY, 1);
|
||||
hireDate = new Date(instance.getTimeInMillis());
|
||||
|
||||
supportedClassesValue.put(int.class, 11);
|
||||
supportedClassesValue.put(Integer.class, new Integer(11));
|
||||
supportedClassesValue.put(long.class, 11l);
|
||||
supportedClassesValue.put(Long.class, new Long(11l));
|
||||
supportedClassesValue.put(float.class, 180.1f);
|
||||
supportedClassesValue.put(Float.class, new Float(180.1f));
|
||||
supportedClassesValue.put(double.class, 11.1d);
|
||||
supportedClassesValue.put(Double.class, new Double(11.1d));
|
||||
supportedClassesValue.put(boolean.class, true);
|
||||
supportedClassesValue.put(Boolean.class, Boolean.TRUE);
|
||||
supportedClassesValue.put(byte[].class, new byte[] { 1, 1 });
|
||||
supportedClassesValue.put(Byte[].class, new Byte[] { 1, 1 });
|
||||
supportedClassesValue.put(String.class, "seongmin");
|
||||
supportedClassesValue.put(Date.class, hireDate);
|
||||
supportedClassesValue.put(BigDecimal.class, new BigDecimal("10001"));
|
||||
supportedClassesValue.put(Object.class, new Object());
|
||||
|
||||
}
|
||||
|
||||
private static void initDsPropertyNames() {
|
||||
|
||||
dsPropertyNames = new String[] { "employeeId", "access", "height", "commissionPercent", "male", "image",
|
||||
"firstName", "lastName", "email", "hireDate", "salary", "obj" };
|
||||
|
||||
}
|
||||
|
||||
private static void initDsValueList() {
|
||||
|
||||
dsValuesList = new ArrayList<Object[]>();
|
||||
|
||||
Calendar instance = null;
|
||||
Date hireDate = null;
|
||||
instance = Calendar.getInstance();
|
||||
instance.set(2009, Calendar.JANUARY, 1);
|
||||
hireDate = new Date(instance.getTimeInMillis());
|
||||
|
||||
Object[] firstValues = new Object[] { 11, 11l, 180.1f, 11.1d, true, new byte[] { 1, 1 }, "seongmin", "park",
|
||||
"seongmin@tobesoft.com", hireDate, new BigDecimal("10001"), new Object() };
|
||||
dsValuesList.add(firstValues);
|
||||
|
||||
instance = Calendar.getInstance();
|
||||
instance.set(2009, Calendar.JANUARY, 2);
|
||||
hireDate = new Date(instance.getTimeInMillis());
|
||||
Object[] secondValues = new Object[] { 12, 12l, 180.2f, 11.2d, false, new byte[] { 1, 2 }, "hyena", "lee",
|
||||
"hyena@tobesoft.com", hireDate, new BigDecimal("10002"), new Object() };
|
||||
dsValuesList.add(secondValues);
|
||||
|
||||
}
|
||||
|
||||
private static void initDsDataTypes() {
|
||||
dsDataTypes = new DataType[] { PlatformDataType.INT, PlatformDataType.LONG, PlatformDataType.FLOAT,
|
||||
PlatformDataType.DOUBLE, PlatformDataType.BOOLEAN, PlatformDataType.BLOB, PlatformDataType.STRING,
|
||||
PlatformDataType.STRING, PlatformDataType.STRING, PlatformDataType.DATE_TIME,
|
||||
PlatformDataType.BIG_DECIMAL, PlatformDataType.UNDEFINED };
|
||||
}
|
||||
|
||||
public static List<DefaultBean> createDefaultBeans() {
|
||||
|
||||
List<DefaultBean> beanList = new ArrayList<DefaultBean>();
|
||||
|
||||
for (Object[] value : dsValuesList) {
|
||||
|
||||
NexacroBeanWrapper wrapper = NexacroBeanWrapper.createBeanWrapper(DefaultBean.class);
|
||||
for (int i=0; i<dsPropertyNames.length; i++) {
|
||||
wrapper.setPropertyValue(dsPropertyNames[i], value[i]);
|
||||
}
|
||||
Object bean = wrapper.getInsatance();
|
||||
beanList.add((DefaultBean) bean);
|
||||
}
|
||||
|
||||
return beanList;
|
||||
|
||||
}
|
||||
|
||||
public static DataSet createDefaultDataSet() {
|
||||
|
||||
DataSet ds = new DataSet("employee");
|
||||
for (int i = 0; i < dsPropertyNames.length; i++) {
|
||||
ds.addColumn(dsPropertyNames[i], dsDataTypes[i]);
|
||||
}
|
||||
|
||||
for (Object[] value : dsValuesList) {
|
||||
int newRow = ds.newRow();
|
||||
for (int i = 0; i < dsPropertyNames.length; i++) {
|
||||
ds.set(newRow, dsPropertyNames[i], value[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return ds;
|
||||
}
|
||||
|
||||
public static List<Map<String, Object>> createDefaultMaps() {
|
||||
|
||||
List<Map<String, Object>> mapList = new ArrayList<Map<String, Object>>();
|
||||
|
||||
for (Object[] value : dsValuesList) {
|
||||
|
||||
Map<String, Object> dataMap = new HashMap<String, Object>();
|
||||
|
||||
for (int i=0; i<dsPropertyNames.length; i++) {
|
||||
dataMap.put(dsPropertyNames[i], value[i]);
|
||||
}
|
||||
mapList.add(dataMap);
|
||||
}
|
||||
|
||||
return mapList;
|
||||
}
|
||||
|
||||
public static void compareDefaultBeans(List<DefaultBean> beanList) {
|
||||
|
||||
if (beanList == null) {
|
||||
Assert.fail("bean list is null");
|
||||
}
|
||||
|
||||
int expectedSize = dsValuesList.size();
|
||||
int actualSize = beanList.size();
|
||||
Assert.assertEquals("bean list size does not matched. please check converted columns. expected=" + expectedSize
|
||||
+ ", actual=" + actualSize, expectedSize, actualSize);
|
||||
|
||||
for (int rowIndex = 0; rowIndex < actualSize; rowIndex++) {
|
||||
DefaultBean defaultBean = beanList.get(rowIndex);
|
||||
NexacroBeanWrapper beanWrapper = NexacroBeanWrapper.createBeanWrapper(defaultBean);
|
||||
|
||||
NexacroBeanProperty[] properties = beanWrapper.getProperties();
|
||||
if (dsPropertyNames.length != properties.length) {
|
||||
Assert.fail("bean properties does not matched. please check converted columns. expected="
|
||||
+ dsPropertyNames.length + ", actual=" + properties.length);
|
||||
}
|
||||
|
||||
Object[] values = dsValuesList.get(rowIndex);
|
||||
for (int propertyIndex = 0; propertyIndex < dsPropertyNames.length; propertyIndex++) {
|
||||
NexacroBeanProperty property = beanWrapper.getProperty(dsPropertyNames[propertyIndex]);
|
||||
|
||||
Object expectedValue = values[propertyIndex];
|
||||
Object actualValue = beanWrapper.getPropertyValue(dsPropertyNames[propertyIndex]);
|
||||
|
||||
Assert.assertEquals("row(" + rowIndex + ") property(" + dsPropertyNames[propertyIndex]
|
||||
+ ") value does not matched. expected=" + expectedValue + ", actual=" + actualValue,
|
||||
expectedValue, actualValue);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void compareDefaultDataSet(DataSet ds) {
|
||||
|
||||
if (ds == null) {
|
||||
Assert.fail("compare DataSet is null");
|
||||
}
|
||||
|
||||
int expectedSize = dsPropertyNames.length;
|
||||
int actualSize = ds.getColumnCount();
|
||||
Assert.assertEquals("DataSet column does not matched. please check converted columns. expected=" + expectedSize
|
||||
+ ", actual=" + actualSize, expectedSize, actualSize);
|
||||
|
||||
// check column
|
||||
for (int propertyIndex = 0; propertyIndex < dsPropertyNames.length; propertyIndex++) {
|
||||
|
||||
String propertyName = dsPropertyNames[propertyIndex];
|
||||
ColumnHeader column = ds.getColumn(propertyName);
|
||||
|
||||
if (!propertyName.equals(column.getName())) {
|
||||
Assert.fail("column name does not matched. expected=" + dsPropertyNames[propertyIndex] + ", autual="
|
||||
+ column.getName());
|
||||
}
|
||||
if (!dsDataTypes[propertyIndex].equals(column.getPlatformDataType())) {
|
||||
Assert.fail(column.getName() + " data type does not matched. expected=" + dsDataTypes[propertyIndex] + ", autual="
|
||||
+ column.getPlatformDataType());
|
||||
}
|
||||
}
|
||||
|
||||
// check values
|
||||
int rowCount = ds.getRowCount();
|
||||
if (dsValuesList.size() != rowCount) {
|
||||
Assert.fail("DataSet rows does not matched. expected=" + dsValuesList.size() + ", actual=" + rowCount);
|
||||
}
|
||||
|
||||
for (int rowIndex = 0; rowIndex < rowCount; rowIndex++) {
|
||||
|
||||
Object[] values = dsValuesList.get(rowIndex);
|
||||
for (int propertyIndex = 0; propertyIndex < dsPropertyNames.length; propertyIndex++) {
|
||||
String propertyName = dsPropertyNames[propertyIndex];
|
||||
|
||||
Object expectedValue = values[propertyIndex];
|
||||
Object actualValue = ds.getObject(rowIndex, propertyName);
|
||||
|
||||
Assert.assertEquals("row(" + rowIndex + ") property(" + dsPropertyNames[propertyIndex]
|
||||
+ ") value does not matched. expected=" + expectedValue + ", actual=" + actualValue,
|
||||
expectedValue, actualValue);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void compareDefaultMaps(List<Map<String, Object>> mapList) {
|
||||
|
||||
if (mapList == null) {
|
||||
Assert.fail("map list is null");
|
||||
}
|
||||
|
||||
int size = mapList.size();
|
||||
if (dsValuesList.size() != size) {
|
||||
Assert.fail("map list size does not matched. expected=" + dsValuesList.size() + ", actual=" + size);
|
||||
}
|
||||
|
||||
for (int rowIndex = 0; rowIndex < size; rowIndex++) {
|
||||
Map<String, Object> dataMap = mapList.get(rowIndex);
|
||||
|
||||
Set<String> keySet = dataMap.keySet();
|
||||
|
||||
// row type이 추가되어 있다.
|
||||
int expectedSize = dsPropertyNames.length + 1;
|
||||
int actualSize = keySet.size();
|
||||
Assert.assertEquals("map properties does not matched. please check converted columns. expected="
|
||||
+ expectedSize + ", actual=" + actualSize, expectedSize, actualSize);
|
||||
|
||||
Object[] values = dsValuesList.get(rowIndex);
|
||||
for (int propertyIndex = 0; propertyIndex < dsPropertyNames.length; propertyIndex++) {
|
||||
|
||||
String propertyName = dsPropertyNames[propertyIndex];
|
||||
|
||||
Object expectedValue = values[propertyIndex];
|
||||
Object actualValue = dataMap.get(propertyName);
|
||||
|
||||
Assert.assertEquals("row(" + rowIndex + ") property(" + dsPropertyNames[propertyIndex]
|
||||
+ ") value does not matched. expected=" + expectedValue + ", actual=" + actualValue,
|
||||
expectedValue, actualValue);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class StaticPropertyBean {
|
||||
|
||||
private String name;
|
||||
private static double commissionPercent;
|
||||
|
||||
/**
|
||||
* @return the name
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name
|
||||
* the name to set
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the commissionPercent
|
||||
*/
|
||||
public static double getCommissionPercent() {
|
||||
return commissionPercent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param commissionPercent the commissionPercent to set
|
||||
*/
|
||||
public static void setCommissionPercent(double commissionPercent) {
|
||||
StaticPropertyBean.commissionPercent = commissionPercent;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class DataSetRowTypeBean implements DataSetRowTypeAccessor {
|
||||
|
||||
private String name;
|
||||
private int rowType;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRowType() {
|
||||
return this.rowType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRowType(int rowType) {
|
||||
this.rowType = rowType;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class DataSetSavedDataBean implements DataSetSavedDataAccessor<DataSetSavedDataBean>, DataSetRowTypeAccessor {
|
||||
|
||||
private String name;
|
||||
private int rowType;
|
||||
|
||||
private DataSetSavedDataBean savedData;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSetSavedDataBean getData() {
|
||||
return this.savedData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setData(DataSetSavedDataBean savedData) {
|
||||
this.savedData = savedData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRowType() {
|
||||
return this.rowType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRowType(int rowType) {
|
||||
this.rowType = rowType;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
package com.nexacro.spring.data.support;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
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.xapi.data.Variable;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Statements
|
||||
* </pre>
|
||||
*
|
||||
* @ClassName : ObjectToVariableTest.java
|
||||
* @Description : 클래스 설명을 기술합니다.
|
||||
* @author Park SeongMin
|
||||
* @since 2015. 8. 19.
|
||||
* @version 1.0
|
||||
* @see
|
||||
* @Modification Information
|
||||
* <pre>
|
||||
* since author description
|
||||
* =========== ============= ===========================
|
||||
* 2015. 8. 19. Park SeongMin 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public class ObjectToVariableConverterTest {
|
||||
|
||||
private ObjectToVariableConverter converter;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
converter = new ObjectToVariableConverter();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSupportedType() {
|
||||
Class target = Variable.class;
|
||||
boolean canConvert;
|
||||
|
||||
Map<Class, Object> supportedClassValues = NexacroTestUtil.getSupportedClassesValue();
|
||||
Set<Class> classSet = supportedClassValues.keySet();
|
||||
for(Class clazz: classSet) {
|
||||
Class source = clazz;
|
||||
canConvert = converter.canConvert(source, target);
|
||||
Assert.assertTrue(source + " to " + target + " must be converted", canConvert);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnSupportedType() {
|
||||
Class<?> source;
|
||||
Class<?> target;
|
||||
boolean canConvert;
|
||||
|
||||
target = Variable.class;
|
||||
|
||||
source = byte.class;
|
||||
canConvert= converter.canConvert(source, target);
|
||||
Assert.assertFalse(source + " to " + target + " can not convertible", canConvert);
|
||||
|
||||
source = char.class;
|
||||
canConvert= converter.canConvert(source, target);
|
||||
Assert.assertFalse(source + " to " + target + " can not convertible", canConvert);
|
||||
|
||||
source = short.class;
|
||||
canConvert= converter.canConvert(source, target);
|
||||
Assert.assertFalse(source + " to " + target + " can not convertible", canConvert);
|
||||
|
||||
source = java.sql.Date.class;
|
||||
canConvert= converter.canConvert(source, target);
|
||||
Assert.assertFalse(source + " to " + target + " can not convertible", canConvert);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConvertAll() {
|
||||
|
||||
Map<Class, Object> supportedClassValues = NexacroTestUtil.getSupportedClassesValue();
|
||||
|
||||
Set<Class> classSet = supportedClassValues.keySet();
|
||||
for(Class clazz: classSet) {
|
||||
|
||||
String variableName = "var";
|
||||
Object value = supportedClassValues.get(clazz);
|
||||
ConvertDefinition definition = new ConvertDefinition(variableName);
|
||||
|
||||
Variable convertedVar = null;
|
||||
try {
|
||||
convertedVar = converter.convert(value, definition);
|
||||
} catch (NexacroConvertException e) {
|
||||
Assert.fail(clazz + " -> variable convert failed. e="+e.getMessage());
|
||||
}
|
||||
|
||||
Assert.assertNotNull("'"+clazz + " -> variable' converted value should not be null.", convertedVar);
|
||||
|
||||
String actualVariableName = convertedVar.getName();
|
||||
Assert.assertEquals(variableName, actualVariableName);
|
||||
|
||||
// compare data.
|
||||
Object actualValue = convertedVar.getObject();
|
||||
if(Byte[].class.equals(clazz)) {
|
||||
// Byte[]의 경우 Variable은 byte[]로 존재하기 때문에 실제데이터를 비교한다.
|
||||
Byte[] expected = (Byte[]) value;
|
||||
byte[] actual = (byte[]) convertedVar.getBlob();
|
||||
Assert.assertEquals("Byte[] data was not properly converted.", expected.length, actual.length);
|
||||
for(int i=0; i<expected.length; i++) {
|
||||
Assert.assertEquals("Byte[] data was not properly converted.", expected[i].byteValue(), actual[i]);
|
||||
}
|
||||
|
||||
} else {
|
||||
Assert.assertEquals("'"+clazz + " -> variable' data was not properly converted.", value, actualValue);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSupportAutomaticConversionByteArr() {
|
||||
|
||||
Byte[] byteArr = new Byte[]{1, 2};
|
||||
|
||||
ConvertDefinition definition = new ConvertDefinition("var");
|
||||
Variable convertedVar = null;
|
||||
try {
|
||||
convertedVar = converter.convert(byteArr, definition);
|
||||
} catch (NexacroConvertException e) {
|
||||
Assert.fail("variable -> Byte[] convert failed. e="+e.getMessage());
|
||||
}
|
||||
|
||||
Assert.assertNotNull("'Byte[] -> variable' converted value should not be null.", convertedVar);
|
||||
|
||||
byte[] actualByteArr = convertedVar.getBlob();
|
||||
Assert.assertNotNull("'Byte[] -> variable' converted value should not be null.", actualByteArr);
|
||||
Assert.assertEquals("Byte[] data was not properly converted.", byteArr.length, actualByteArr.length);
|
||||
|
||||
for(int i=0; i<byteArr.length; i++) {
|
||||
Assert.assertEquals("Byte[] data was not properly converted.", byteArr[i].byteValue(), actualByteArr[i]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,261 @@
|
||||
package com.nexacro.spring.data.support;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
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.xapi.data.Variable;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Statements
|
||||
* </pre>
|
||||
*
|
||||
* @ClassName : VariableToObjectConverterTest.java
|
||||
* @Description : 클래스 설명을 기술합니다.
|
||||
* @author Park SeongMin
|
||||
* @since 2015. 8. 19.
|
||||
* @version 1.0
|
||||
* @see
|
||||
* @Modification Information
|
||||
* <pre>
|
||||
* since author description
|
||||
* =========== ============= ===========================
|
||||
* 2015. 8. 19. Park SeongMin 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public class VariableToObjectConverterTest {
|
||||
|
||||
private VariableToObjectConverter converter;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
converter = new VariableToObjectConverter();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSupportedType() {
|
||||
Class source = Variable.class;
|
||||
Class target;
|
||||
boolean canConvert;
|
||||
|
||||
Map<Class, Object> supportedClassValues = NexacroTestUtil.getSupportedClassesValue();
|
||||
Set<Class> classSet = supportedClassValues.keySet();
|
||||
for(Class clazz: classSet) {
|
||||
target = clazz;
|
||||
canConvert = converter.canConvert(source, target);
|
||||
Assert.assertTrue(source + " to " + target + " must be converted", canConvert);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnSupportedType() {
|
||||
Class<?> source;
|
||||
Class<?> target;
|
||||
boolean canConvert;
|
||||
|
||||
source = Variable.class;
|
||||
|
||||
target = byte.class;
|
||||
canConvert= converter.canConvert(source, target);
|
||||
Assert.assertFalse(source + " to " + target + " can not convertible", canConvert);
|
||||
|
||||
target = char.class;
|
||||
canConvert= converter.canConvert(source, target);
|
||||
Assert.assertFalse(source + " to " + target + " can not convertible", canConvert);
|
||||
|
||||
target = short.class;
|
||||
canConvert= converter.canConvert(source, target);
|
||||
Assert.assertFalse(source + " to " + target + " can not convertible", canConvert);
|
||||
|
||||
target = java.sql.Date.class;
|
||||
canConvert= converter.canConvert(source, target);
|
||||
Assert.assertFalse(source + " to " + target + " can not convertible", canConvert);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConvertAll() {
|
||||
|
||||
Map<Class, Object> supportedClassValues = NexacroTestUtil.getSupportedClassesValue();
|
||||
|
||||
Set<Class> classSet = supportedClassValues.keySet();
|
||||
for(Class clazz: classSet) {
|
||||
|
||||
Object value = supportedClassValues.get(clazz);
|
||||
Variable var = new Variable("var");
|
||||
|
||||
// variable에 Byte[]는 삽입되어서는 안된다. Byte[]는 byte[]로 변환되어 삽입되어져야 한다.
|
||||
if(Byte[].class.equals(clazz)) {
|
||||
Object object = NexacroConverterHelper.toObject(value);
|
||||
var.set(object);
|
||||
} else {
|
||||
var.set(value);
|
||||
}
|
||||
|
||||
ConvertDefinition definition = new ConvertDefinition(var.getName());
|
||||
definition.setGenericType(clazz);
|
||||
|
||||
Object convertedObj = null;
|
||||
try {
|
||||
convertedObj = converter.convert(var, definition);
|
||||
} catch (NexacroConvertException e) {
|
||||
Assert.fail("variable -> " + clazz + " convert failed. e="+e.getMessage());
|
||||
}
|
||||
|
||||
Assert.assertNotNull("'variable -> " + clazz + "' converted value should not be null.", convertedObj);
|
||||
if(Byte[].class.equals(clazz)) {
|
||||
// Byte[]의 경우 실제데이터를 비교한다.
|
||||
Byte[] expected = (Byte[]) value;
|
||||
Byte[] actual = (Byte[]) convertedObj;
|
||||
Assert.assertEquals("Byte[] data was not properly converted.", expected.length, actual.length);
|
||||
for(int i=0; i<expected.length; i++) {
|
||||
Assert.assertEquals("Byte[] data was not properly converted.", expected[i], actual[i]);
|
||||
}
|
||||
|
||||
} else {
|
||||
Assert.assertEquals("'variable -> " + clazz + "' data was not properly converted", value, convertedObj);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnSupportedByteArrInsertedVariable() {
|
||||
|
||||
Byte[] byteArr = new Byte[]{1, 2};
|
||||
|
||||
Variable var = new Variable("var");
|
||||
var.set(byteArr);
|
||||
|
||||
|
||||
ConvertDefinition definition = new ConvertDefinition(var.getName());
|
||||
definition.setGenericType(byteArr.getClass());
|
||||
Object convertedObj = null;
|
||||
try {
|
||||
convertedObj = converter.convert(var, definition);
|
||||
} catch (NexacroConvertException e) {
|
||||
Assert.fail("variable -> Byte[] convert failed. e="+e.getMessage());
|
||||
}
|
||||
|
||||
Assert.assertNull("Byte[] is inserted in the variable is not supported.", convertedObj);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInteger() {
|
||||
int value = 1;
|
||||
Variable var = Variable.createVariable("var", value);
|
||||
ConvertDefinition definition = new ConvertDefinition(var.getName());
|
||||
definition.setGenericType(int.class);
|
||||
|
||||
Object obj = null;
|
||||
try {
|
||||
obj = converter.convert(var, definition);
|
||||
} catch (NexacroConvertException e) {
|
||||
Assert.fail(e.getMessage());
|
||||
}
|
||||
|
||||
Assert.assertNotNull("object should not be null.", obj);
|
||||
Assert.assertEquals(value, obj);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntegerWrapper() {
|
||||
Integer value = new Integer(1);
|
||||
Variable var = Variable.createVariable("var", value);
|
||||
ConvertDefinition definition = new ConvertDefinition(var.getName());
|
||||
definition.setGenericType(Integer.class);
|
||||
|
||||
Object obj = null;
|
||||
try {
|
||||
obj = converter.convert(var, definition);
|
||||
} catch (NexacroConvertException e) {
|
||||
Assert.fail(e.getMessage());
|
||||
}
|
||||
|
||||
Assert.assertNotNull("object should not be null.", obj);
|
||||
Assert.assertEquals(value, obj);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLong() {
|
||||
long value = 1l;
|
||||
Variable var = Variable.createVariable("var", value);
|
||||
ConvertDefinition definition = new ConvertDefinition(var.getName());
|
||||
definition.setGenericType(long.class);
|
||||
|
||||
Object obj = null;
|
||||
try {
|
||||
obj = converter.convert(var, definition);
|
||||
} catch (NexacroConvertException e) {
|
||||
Assert.fail(e.getMessage());
|
||||
}
|
||||
|
||||
Assert.assertNotNull("object should not be null.", obj);
|
||||
Assert.assertEquals(value, obj);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLongWrapper() {
|
||||
Long value = new Long(1l);
|
||||
Variable var = Variable.createVariable("var", value);
|
||||
ConvertDefinition definition = new ConvertDefinition(var.getName());
|
||||
definition.setGenericType(Long.class);
|
||||
|
||||
Object obj = null;
|
||||
try {
|
||||
obj = converter.convert(var, definition);
|
||||
} catch (NexacroConvertException e) {
|
||||
Assert.fail(e.getMessage());
|
||||
}
|
||||
|
||||
Assert.assertNotNull("object should not be null.", obj);
|
||||
Assert.assertEquals(value, obj);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFloat() {
|
||||
float value = 1.1f;
|
||||
Variable var = Variable.createVariable("var", value);
|
||||
ConvertDefinition definition = new ConvertDefinition(var.getName());
|
||||
definition.setGenericType(float.class);
|
||||
|
||||
Object obj = null;
|
||||
try {
|
||||
obj = converter.convert(var, definition);
|
||||
} catch (NexacroConvertException e) {
|
||||
Assert.fail(e.getMessage());
|
||||
}
|
||||
|
||||
Assert.assertNotNull("object should not be null.", obj);
|
||||
Assert.assertEquals(value, obj);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFloatWrapper() {
|
||||
Float value = 1.1f;
|
||||
Variable var = Variable.createVariable("var", value);
|
||||
ConvertDefinition definition = new ConvertDefinition(var.getName());
|
||||
definition.setGenericType(Float.class);
|
||||
|
||||
Object obj = null;
|
||||
try {
|
||||
obj = converter.convert(var, definition);
|
||||
} catch (NexacroConvertException e) {
|
||||
Assert.fail(e.getMessage());
|
||||
}
|
||||
|
||||
Assert.assertNotNull("object should not be null.", obj);
|
||||
Assert.assertEquals(value, obj);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,215 @@
|
||||
package com.nexacro.spring.data.support.bean;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Statements
|
||||
* </pre>
|
||||
*
|
||||
* @ClassName : DefaultBean.java
|
||||
* @Description : 클래스 설명을 기술합니다.
|
||||
* @author Park SeongMin
|
||||
* @since 2015. 8. 4.
|
||||
* @version 1.0
|
||||
* @see
|
||||
* @Modification Information
|
||||
*
|
||||
* <pre>
|
||||
* since author description
|
||||
* =========== ============= ===========================
|
||||
* 2015. 8. 4. Park SeongMin 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public class DefaultBean {
|
||||
|
||||
private int employeeId;
|
||||
private long access;
|
||||
private float height;
|
||||
private double commissionPercent;
|
||||
private boolean male;
|
||||
private byte[] image;
|
||||
|
||||
private String firstName;
|
||||
private String lastName;
|
||||
private String email;
|
||||
|
||||
private Date hireDate;
|
||||
private BigDecimal salary;
|
||||
|
||||
private Object obj;
|
||||
|
||||
private DefaultBean savedData;
|
||||
private int rowType;
|
||||
|
||||
/**
|
||||
* @return the employeeId
|
||||
*/
|
||||
public int getEmployeeId() {
|
||||
return employeeId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param employeeId the employeeId to set
|
||||
*/
|
||||
public void setEmployeeId(int employeeId) {
|
||||
this.employeeId = employeeId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the access
|
||||
*/
|
||||
public long getAccess() {
|
||||
return access;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param access the access to set
|
||||
*/
|
||||
public void setAccess(long access) {
|
||||
this.access = access;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the height
|
||||
*/
|
||||
public float getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param height the height to set
|
||||
*/
|
||||
public void setHeight(float height) {
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the commissionPercent
|
||||
*/
|
||||
public double getCommissionPercent() {
|
||||
return commissionPercent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param commissionPercent the commissionPercent to set
|
||||
*/
|
||||
public void setCommissionPercent(double commissionPercent) {
|
||||
this.commissionPercent = commissionPercent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the male
|
||||
*/
|
||||
public boolean isMale() {
|
||||
return male;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param male the male to set
|
||||
*/
|
||||
public void setMale(boolean male) {
|
||||
this.male = male;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the image
|
||||
*/
|
||||
public byte[] getImage() {
|
||||
return image;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param image the image to set
|
||||
*/
|
||||
public void setImage(byte[] image) {
|
||||
this.image = image;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the firstName
|
||||
*/
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param firstName the firstName to set
|
||||
*/
|
||||
public void setFirstName(String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the lastName
|
||||
*/
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param lastName the lastName to set
|
||||
*/
|
||||
public void setLastName(String lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the email
|
||||
*/
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param email the email to set
|
||||
*/
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the hireDate
|
||||
*/
|
||||
public Date getHireDate() {
|
||||
return hireDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param hireDate the hireDate to set
|
||||
*/
|
||||
public void setHireDate(Date hireDate) {
|
||||
this.hireDate = hireDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the salary
|
||||
*/
|
||||
public BigDecimal getSalary() {
|
||||
return salary;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param salary the salary to set
|
||||
*/
|
||||
public void setSalary(BigDecimal salary) {
|
||||
this.salary = salary;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the obj
|
||||
*/
|
||||
public Object getObj() {
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param obj the obj to set
|
||||
*/
|
||||
public void setObj(Object obj) {
|
||||
this.obj = obj;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.nexacro.spring.data.support.bean;
|
||||
|
||||
import com.nexacro.spring.data.DataSetRowTypeAccessor;
|
||||
import com.nexacro.spring.data.DataSetSavedDataAccessor;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Statements
|
||||
* </pre>
|
||||
*
|
||||
* @ClassName : NexacroBean.java
|
||||
* @Description : 클래스 설명을 기술합니다.
|
||||
* @author Park SeongMin
|
||||
* @since 2015. 8. 4.
|
||||
* @version 1.0
|
||||
* @see
|
||||
* @Modification Information
|
||||
* <pre>
|
||||
* since author description
|
||||
* =========== ============= ===========================
|
||||
* 2015. 8. 4. Park SeongMin 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public class NexacroSupportedBean extends DefaultBean implements DataSetRowTypeAccessor, DataSetSavedDataAccessor<NexacroSupportedBean>{
|
||||
|
||||
private int rowType;
|
||||
private NexacroSupportedBean savedData;
|
||||
|
||||
@Override
|
||||
public NexacroSupportedBean getData() {
|
||||
return savedData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setData(NexacroSupportedBean t) {
|
||||
this.savedData = t;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRowType() {
|
||||
return this.rowType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRowType(int rowType) {
|
||||
this.rowType = rowType;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.nexacro.spring.data.support.bean;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Statements
|
||||
* </pre>
|
||||
*
|
||||
* @ClassName : ExtendedBean.java
|
||||
* @Description : 클래스 설명을 기술합니다.
|
||||
* @author Park SeongMin
|
||||
* @since 2015. 8. 10.
|
||||
* @version 1.0
|
||||
* @see
|
||||
* @Modification Information
|
||||
*
|
||||
* <pre>
|
||||
* since author description
|
||||
* =========== ============= ===========================
|
||||
* 2015. 8. 10. Park SeongMin 최초 생성
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public class UnsupportedBean extends DefaultBean {
|
||||
|
||||
private List<String> stringList;
|
||||
|
||||
private DefaultBean unsupportedBean;
|
||||
|
||||
/**
|
||||
* @return the unsupportedBean
|
||||
*/
|
||||
public DefaultBean getUnsupportedBean() {
|
||||
return unsupportedBean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param unsupportedBean
|
||||
* the unsupportedBean to set
|
||||
*/
|
||||
public void setUnsupportedBean(DefaultBean unsupportedBean) {
|
||||
this.unsupportedBean = unsupportedBean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the stringList
|
||||
*/
|
||||
public List<String> getStringList() {
|
||||
return stringList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param stringList
|
||||
* the stringList to set
|
||||
*/
|
||||
public void setStringList(List<String> stringList) {
|
||||
this.stringList = stringList;
|
||||
}
|
||||
|
||||
}
|
||||
140
src/test/resources/log4j.xml
Normal file
140
src/test/resources/log4j.xml
Normal file
@@ -0,0 +1,140 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
|
||||
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false">
|
||||
|
||||
<!-- ConsoleAppender -->
|
||||
<appender name="console" class="org.apache.log4j.ConsoleAppender">
|
||||
<param name="Encoding" value="UTF-8" />
|
||||
<!-- ref.) attr : Encoding, ImmediateFlush, Target, Threshold -->
|
||||
<layout class="org.apache.log4j.PatternLayout">
|
||||
<param name="ConversionPattern" value="%d %5p [%c] %m%n" />
|
||||
</layout>
|
||||
<!-- String 매칭 되는 Log 삭제
|
||||
<filter class="org.apache.log4j.varia.StringMatchFilter">
|
||||
<param name="StringToMatch" value="Result" />
|
||||
<param name="AcceptOnMatch" value="false" />
|
||||
</filter>
|
||||
-->
|
||||
</appender>
|
||||
|
||||
<!-- FileAppender -->
|
||||
<appender name="appLog" class="org.apache.log4j.FileAppender">
|
||||
<param name="Encoding" value="UTF-8" />
|
||||
<param name="File" value="/DES/logs/was/pilot/applog/app.log" />
|
||||
<param name="ImmediateFlush" value="true" />
|
||||
<param name="Append" value="true" />
|
||||
<layout class="org.apache.log4j.PatternLayout">
|
||||
<param name="ConversionPattern" value="%d %5p [%c] %m%n" />
|
||||
</layout>
|
||||
</appender>
|
||||
|
||||
<!-- FileAppender : XML
|
||||
<appender name="appLog" class="org.apache.log4j.FileAppender">
|
||||
<param name="Encoding" value="UTF-8" />
|
||||
<param name="File" value="/DES/logs/was/pilot/appxmllog/appxml.log" />
|
||||
<param name="ImmediateFlush" value="true" />
|
||||
<param name="Append" value="true" />
|
||||
<layout class="org.apache.log4j.xml.XMLLayout"></layout>
|
||||
</appender>
|
||||
-->
|
||||
|
||||
<!-- RollingFileAppender -->
|
||||
<appender name="sqlLog" class="org.apache.log4j.RollingFileAppender">
|
||||
<param name="File" value="/DES/logs/was/pilot/sqllog/sql.log" />
|
||||
<param name="Append" value="true" />
|
||||
<param name="MaxFileSize" value="1000KB" />
|
||||
<layout class="org.apache.log4j.PatternLayout">
|
||||
<param name="ConversionPattern" value="%d %5p [%c] %m%n" />
|
||||
</layout>
|
||||
</appender>
|
||||
|
||||
<!-- JDBCAppender
|
||||
<appender name="jdbcAppender" class="org.apache.log4j.jdbc.JDBCAppender">
|
||||
<param name="Driver" value="oracle.jdbc.driver.OracleDriver"/>
|
||||
<param name="URL" value="jdbc:oracle:thin:@127.0.0.1:1521:orcl"/>
|
||||
<param name="User" value="scott"/>
|
||||
<param name="Password" value="tiger"/-->
|
||||
<!--param name="bufferSize" value="1"/--><!-- 주석처리 해 둘 것 -->
|
||||
<!--param name="Sql" value="INSERT INTO tb_log (message, class, priority, log_date)
|
||||
VALUES ('%m', '%l', '%p', '%d')"/>
|
||||
</appender>
|
||||
-->
|
||||
<!--
|
||||
JDBCAppender를 사용하여 case by case로 DB에 저장을 하게되면 DBMS에 많은 부담을 줄 수 있다.
|
||||
AsyncAppender를 사용하여 큐에 쌓았다가 한꺼번에 저장하는 방식을 추천한다.
|
||||
<appender name="asyncAppender" class="org.apache.log4j.AsyncAppender">
|
||||
<param name="locationInfo" value="false"/>
|
||||
<! bufferSize 모아서 보낼 로그 수(이벤트의 수). 디폴트 128
|
||||
<param name="bufferSize" value="128"/>
|
||||
<appender-ref ref="jdbcAppender" />
|
||||
</appender>
|
||||
-->
|
||||
|
||||
|
||||
<!-- DailyRollingFileAppender -->
|
||||
<appender name="dailyRollingFile" class="org.apache.log4j.DailyRollingFileAppender">
|
||||
<!-- ref.) attr : FileAppender + DatePattern -->
|
||||
<!--param name="File" value="C:/DES/workspace/projects/engineer/src/main/webapp/WEB-INF/logs/sample.log" /-->
|
||||
<param name="File" value="/DES/logs/was/pilot/console.log" />
|
||||
<param name="Append" value="true" />
|
||||
<!--
|
||||
SimpleDateFormat 을 따름. ex.) .yyyy-ww : 첫날 기준 매주마다,
|
||||
.yyyy-MM : 월단위
|
||||
.yyyy-MM-ww : 주단위
|
||||
.yyyy-MM-dd : 일단위
|
||||
.yyyy-MM-dd-a : 12시간단위
|
||||
.yyyy-MM-dd-HH : 시간단위
|
||||
.yyyy-MM-dd-HH-mm : 매분마다
|
||||
-->
|
||||
<param name="DatePattern" value="'.'yyyy-MM-dd" />
|
||||
<layout class="org.apache.log4j.PatternLayout">
|
||||
<param name="ConversionPattern" value="%d %5p [%c] %m%n" />
|
||||
</layout>
|
||||
</appender>
|
||||
|
||||
<!-- log SQL with timing information, post execution
|
||||
-->
|
||||
<logger name="aes" additivity="false">
|
||||
<level value="DEBUG" />
|
||||
<appender-ref ref="console" />
|
||||
<appender-ref ref="dailyRollingFile" />
|
||||
</logger>
|
||||
<logger name="able" additivity="false">
|
||||
<level value="DEBUG" />
|
||||
<appender-ref ref="console" />
|
||||
</logger>
|
||||
<!-- SQL Result Log -->
|
||||
<logger name="java.sql" additivity="false">
|
||||
<level value="DEBUG" />
|
||||
<appender-ref ref="console" />
|
||||
<!--appender-ref ref="jdbcAppender"/ --> <!-- Oracle DBMS TABLE 에 로그를 남기고 있음 -->
|
||||
</logger>
|
||||
<!-- controlling scope -->
|
||||
<logger name="org.springframework.web.servlet.DispatcherServlet" additivity="false">
|
||||
<level value="DEBUG" />
|
||||
<appender-ref ref="console" />
|
||||
</logger>
|
||||
<logger name="org.springframework.web.context.ContextLoader" additivity="false">
|
||||
<level value="DEBUG" />
|
||||
<appender-ref ref="console" />
|
||||
</logger>
|
||||
|
||||
<logger name="com.nexacro.xapi" additivity="false">
|
||||
<level value="FATAL" />
|
||||
<appender-ref ref="console" />
|
||||
</logger>
|
||||
|
||||
<logger name="com.nexacro.performance" additivity="false">
|
||||
<level value="TRACE" />
|
||||
<appender-ref ref="console" />
|
||||
</logger>
|
||||
|
||||
<root>
|
||||
<priority value ="INFO" />
|
||||
|
||||
<appender-ref ref="console"/>
|
||||
<!--
|
||||
<appender-ref ref="dailyRollingFile"/>
|
||||
-->
|
||||
</root>
|
||||
</log4j:configuration>
|
||||
19
src/test/resources/nexacro14_server_license.xml
Normal file
19
src/test/resources/nexacro14_server_license.xml
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<license version="1.0">
|
||||
<product>
|
||||
<name>nexacro platform</name>
|
||||
<version>14</version>
|
||||
<function>Windows, WindowsRT, MAC, iOS, Android</function>
|
||||
</product>
|
||||
<customer>
|
||||
<name>TOBESOFT</name>
|
||||
<coreCount>0</coreCount>
|
||||
<ipAddress>0.0.0.0</ipAddress>
|
||||
<targetPlatform>Runtime,HTML5</targetPlatform>
|
||||
</customer>
|
||||
<date>
|
||||
<activation>2015-09-01</activation>
|
||||
<term unit="month">2</term>
|
||||
</date>
|
||||
<key>H3UWWYFVJJT5R4JHVWCWQGAZFWTQX96NX</key>
|
||||
</license>
|
||||
Reference in New Issue
Block a user